summaryrefslogtreecommitdiff
path: root/sd/source/ui/slidesorter/controller
diff options
context:
space:
mode:
Diffstat (limited to 'sd/source/ui/slidesorter/controller')
-rw-r--r--[-rwxr-xr-x]sd/source/ui/slidesorter/controller/SlideSorterController.cxx334
-rw-r--r--sd/source/ui/slidesorter/controller/SlsAnimationFunction.cxx294
-rwxr-xr-x[-rw-r--r--]sd/source/ui/slidesorter/controller/SlsAnimator.cxx299
-rwxr-xr-x[-rw-r--r--]sd/source/ui/slidesorter/controller/SlsClipboard.cxx320
-rw-r--r--[-rwxr-xr-x]sd/source/ui/slidesorter/controller/SlsCurrentSlideManager.cxx145
-rw-r--r--sd/source/ui/slidesorter/controller/SlsDragAndDropContext.cxx199
-rw-r--r--sd/source/ui/slidesorter/controller/SlsDragAndDropContext.hxx100
-rwxr-xr-xsd/source/ui/slidesorter/controller/SlsFocusManager.cxx136
-rwxr-xr-x[-rw-r--r--]sd/source/ui/slidesorter/controller/SlsHideSlideFunction.cxx6
-rw-r--r--sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx327
-rwxr-xr-xsd/source/ui/slidesorter/controller/SlsListener.cxx139
-rwxr-xr-x[-rw-r--r--]sd/source/ui/slidesorter/controller/SlsListener.hxx13
-rw-r--r--[-rwxr-xr-x]sd/source/ui/slidesorter/controller/SlsPageSelector.cxx254
-rwxr-xr-x[-rw-r--r--]sd/source/ui/slidesorter/controller/SlsProperties.cxx46
-rw-r--r--[-rwxr-xr-x]sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx418
-rw-r--r--[-rwxr-xr-x]sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx1989
-rwxr-xr-xsd/source/ui/slidesorter/controller/SlsSelectionManager.cxx411
-rw-r--r--sd/source/ui/slidesorter/controller/SlsSelectionObserver.cxx173
-rwxr-xr-xsd/source/ui/slidesorter/controller/SlsSlideFunction.cxx2
-rw-r--r--[-rwxr-xr-x]sd/source/ui/slidesorter/controller/SlsSlotManager.cxx486
-rwxr-xr-x[-rw-r--r--]sd/source/ui/slidesorter/controller/SlsTransferable.cxx15
-rw-r--r--sd/source/ui/slidesorter/controller/SlsTransferable.hxx70
-rw-r--r--sd/source/ui/slidesorter/controller/SlsVisibleAreaManager.cxx301
-rwxr-xr-x[-rw-r--r--]sd/source/ui/slidesorter/controller/makefile.mk14
24 files changed, 4671 insertions, 1820 deletions
diff --git a/sd/source/ui/slidesorter/controller/SlideSorterController.cxx b/sd/source/ui/slidesorter/controller/SlideSorterController.cxx
index 69c2a02ddc24..8018c71e2b88 100755..100644
--- a/sd/source/ui/slidesorter/controller/SlideSorterController.cxx
+++ b/sd/source/ui/slidesorter/controller/SlideSorterController.cxx
@@ -39,17 +39,22 @@
#include "SlsSelectionCommand.hxx"
#include "controller/SlsAnimator.hxx"
#include "controller/SlsClipboard.hxx"
+#include "controller/SlsInsertionIndicatorHandler.hxx"
#include "controller/SlsScrollBarManager.hxx"
-#include "controller/SlsPageObjectFactory.hxx"
#include "controller/SlsSelectionManager.hxx"
#include "controller/SlsSlotManager.hxx"
+#include "controller/SlsTransferable.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/SlsViewOverlay.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"
@@ -91,12 +96,12 @@
#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 {
@@ -112,9 +117,12 @@ SlideSorterController::SlideSorterController (SlideSorter& rSlideSorter)
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(),
@@ -122,12 +130,11 @@ SlideSorterController::SlideSorterController (SlideSorter& rSlideSorter)
mpEditModeChangeMasterPage(NULL),
maTotalWindowArea(),
mnPaintEntranceCount(0),
- mbIsContextMenuOpen(false),
- mpProperties(new Properties())
+ mbIsContextMenuOpen(false)
{
- ::sd::Window* pWindow = mrSlideSorter.GetActiveWindow();
- OSL_ASSERT(pWindow!=NULL);
- if (pWindow != NULL)
+ SharedSdWindow pWindow (mrSlideSorter.GetContentWindow());
+ OSL_ASSERT(pWindow);
+ if (pWindow)
{
// The whole background is painted by the view and controls.
::Window* pParentWindow = pWindow->GetParent();
@@ -136,22 +143,10 @@ SlideSorterController::SlideSorterController (SlideSorter& rSlideSorter)
// Connect the view with the window that has been created by our base
// class.
- pWindow->SetBackground (Wallpaper());
- mrView.AddWindowToPaintView(pWindow);
- mrView.SetActualWin(pWindow);
- pWindow->SetCenterAllowed (false);
- pWindow->SetViewSize (mrView.GetModelArea().GetSize());
- pWindow->EnableRTL(FALSE);
-
- // Reinitialize colors in Properties with window specific values.
- mpProperties->SetBackgroundColor(
- pWindow->GetSettings().GetStyleSettings().GetWindowColor());
- mpProperties->SetTextColor(
- pWindow->GetSettings().GetStyleSettings().GetWindowTextColor());
- mpProperties->SetSelectionColor(
- pWindow->GetSettings().GetStyleSettings().GetMenuHighlightColor());
- mpProperties->SetHighlightColor(
- pWindow->GetSettings().GetStyleSettings().GetMenuHighlightColor());
+ pWindow->SetBackground(Wallpaper());
+ pWindow->SetCenterAllowed(false);
+ pWindow->SetMapMode(MapMode(MAP_PIXEL));
+ pWindow->SetViewSize(mrView.GetModelArea().GetSize());
}
}
@@ -160,8 +155,6 @@ SlideSorterController::SlideSorterController (SlideSorter& rSlideSorter)
void SlideSorterController::Init (void)
{
- mrView.HandleModelChange();
-
mpCurrentSlideManager.reset(new CurrentSlideManager(mrSlideSorter));
mpPageSelector.reset(new PageSelector(mrSlideSorter));
mpFocusManager.reset(new FocusManager(mrSlideSorter));
@@ -181,7 +174,7 @@ void SlideSorterController::Init (void)
mpListener = new Listener(mrSlideSorter);
- mpPageSelector->UpdateAllPages();
+ mpPageSelector->GetCoreSelection();
GetSelectionManager()->SelectionHasChanged();
}
@@ -210,17 +203,48 @@ SlideSorterController::~SlideSorterController (void)
+void SlideSorterController::Dispose (void)
+{
+ mpInsertionIndicatorHandler->End(Animator::AM_Immediate);
+ mpSelectionManager.reset();
+ mpAnimator->Dispose();
+}
+
+
+
+
model::SharedPageDescriptor SlideSorterController::GetPageAt (
- const Point& aPixelPosition)
+ const Point& aWindowPosition)
{
- sal_Int32 nHitPageIndex (mrView.GetPageIndexAtPoint(aPixelPosition));
+ 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);
@@ -284,10 +308,11 @@ ScrollBarManager& SlideSorterController::GetScrollBarManager (void)
-void SlideSorterController::PrePaint()
+::boost::shared_ptr<InsertionIndicatorHandler>
+ SlideSorterController::GetInsertionIndicatorHandler (void) const
{
- // forward VCLs PrePaint window event to DrawingLayer
- mrView.PrePaint();
+ OSL_ASSERT(mpInsertionIndicatorHandler.get()!=NULL);
+ return mpInsertionIndicatorHandler;
}
@@ -297,16 +322,12 @@ void SlideSorterController::Paint (
const Rectangle& rBBox,
::Window* pWindow)
{
- // if (mnPaintEntranceCount == 0)
+ if (mnPaintEntranceCount == 0)
{
++mnPaintEntranceCount;
try
{
- if (GetSelectionManager()->IsMakeSelectionVisiblePending())
- GetSelectionManager()->MakeSelectionVisible();
-
- mrView.SetApplicationDocumentColor(GetProperties()->GetBackgroundColor());
mrView.CompleteRedraw(pWindow, Region(rBBox), 0);
}
catch (const Exception&)
@@ -394,50 +415,64 @@ bool SlideSorterController::Command (
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.
- mrView.GetOverlay().GetInsertionIndicatorOverlay().SetPosition(
- pWindow->PixelToLogic(rEvent.GetMousePosPixel()));
- mrView.GetOverlay().GetInsertionIndicatorOverlay().setVisible(true);
+ mpInsertionIndicatorHandler->Start(false);
+ mpInsertionIndicatorHandler->UpdateIndicatorIcon(
+ dynamic_cast<Transferable*>(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())
{
- mbIsContextMenuOpen = true;
- if (pViewShell != NULL)
- {
- SfxDispatcher* pDispatcher = pViewShell->GetDispatcher();
- if (pDispatcher != NULL)
- pDispatcher->ExecutePopup(SdResId(nPopupId));
- }
+ // 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.
- if (pPage != NULL)
+ model::SharedPageDescriptor pDescriptor (
+ GetFocusManager().GetFocusedPageDescriptor());
+ if (pDescriptor.get() != NULL)
{
- model::SharedPageDescriptor pDescriptor (
- GetFocusManager().GetFocusedPageDescriptor());
- if (pDescriptor.get() != NULL)
- {
- Rectangle aBBox (mrView.GetPageBoundingBox (
+ Rectangle aBBox (
+ mrView.GetLayouter().GetPageObjectLayouter()->GetBoundingBox (
pDescriptor,
- view::SlideSorterView::CS_SCREEN,
- view::SlideSorterView::BBT_SHAPE));
- Point aPosition (aBBox.Center());
- mbIsContextMenuOpen = true;
- if (pViewShell != NULL)
- pViewShell->GetViewFrame()->GetDispatcher()->ExecutePopup(
- SdResId(nPopupId),
- pWindow,
- &aPosition);
- }
+ 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;
@@ -447,19 +482,44 @@ bool SlideSorterController::Command (
// it is hidden, so that a pending slide insertion slot call
// finds the right place to insert a new slide.
GetSelectionManager()->SetInsertionPosition(
- mrView.GetOverlay().GetInsertionIndicatorOverlay().GetInsertionPageIndex());
- mrView.GetOverlay().GetInsertionIndicatorOverlay().setVisible(false);
+ GetInsertionIndicatorHandler()->GetInsertionPageIndex());
}
+ pContext.reset();
bEventHasBeenHandled = true;
}
break;
case COMMAND_WHEEL:
{
- // We ignore zooming with control+mouse wheel.
const CommandWheelData* pData = rEvent.GetWheelData();
- if (pData!=NULL && pData->IsMod1())
- bEventHasBeenHandled = true;
+ 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;
}
@@ -482,7 +542,9 @@ void SlideSorterController::UnlockModelChange (void)
{
mnModelChangeLockCount -= 1;
if (mnModelChangeLockCount==0 && mbPostModelChangePending)
+ {
PostModelChange();
+ }
}
@@ -499,11 +561,9 @@ void SlideSorterController::PreModelChange (void)
mrSlideSorter.GetViewShell()->Broadcast(
ViewShellHint(ViewShellHint::HINT_COMPLEX_MODEL_CHANGE_START));
- mpPageSelector->PrepareModelChange();
GetCurrentSlideManager()->PrepareModelChange();
- ::sd::Window* pWindow = mrSlideSorter.GetActiveWindow();
- if (pWindow != NULL)
+ if (mrSlideSorter.GetContentWindow())
mrView.PreModelChange();
mbPostModelChangePending = true;
@@ -517,8 +577,8 @@ void SlideSorterController::PostModelChange (void)
mbPostModelChangePending = false;
mrModel.Resync();
- ::sd::Window* pWindow = mrSlideSorter.GetActiveWindow();
- if (pWindow != NULL)
+ SharedSdWindow pWindow (mrSlideSorter.GetContentWindow());
+ if (pWindow)
{
GetCurrentSlideManager()->HandleModelChange();
@@ -530,11 +590,9 @@ void SlideSorterController::PostModelChange (void)
// 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();
+ Rearrange(mbIsForcedRearrangePending);
}
- mpPageSelector->HandleModelChange ();
-
if (mrSlideSorter.GetViewShell() != NULL)
mrSlideSorter.GetViewShell()->Broadcast(
ViewShellHint(ViewShellHint::HINT_COMPLEX_MODEL_CHANGE_END));
@@ -564,23 +622,36 @@ IMPL_LINK(SlideSorterController, WindowEventHandler, VclWindowEvent*, pEvent)
if (pEvent != NULL)
{
::Window* pWindow = pEvent->GetWindow();
- ::sd::Window* pActiveWindow = mrSlideSorter.GetActiveWindow();
+ SharedSdWindow pActiveWindow (mrSlideSorter.GetContentWindow());
switch (pEvent->GetId())
{
case VCLEVENT_WINDOW_ACTIVATE:
case VCLEVENT_WINDOW_SHOW:
- if (pActiveWindow != NULL && pWindow == pActiveWindow->GetParent())
+ 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 != NULL && pWindow == pActiveWindow)
- GetFocusManager().ShowFocus(false);
+ if (pActiveWindow)
+ if (pWindow == pActiveWindow.get())
+ GetFocusManager().ShowFocus(false);
break;
case VCLEVENT_WINDOW_LOSEFOCUS:
- if (pActiveWindow != NULL && pWindow == pActiveWindow)
+ 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:
@@ -601,6 +672,11 @@ IMPL_LINK(SlideSorterController, WindowEventHandler, VclWindowEvent*, pEvent)
// 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;
@@ -639,10 +715,9 @@ void SlideSorterController::GetCtrlState (SfxItemSet& rSet)
||rSet.GetItemState(SID_OUTPUT_QUALITY_BLACKWHITE)==SFX_ITEM_AVAILABLE
||rSet.GetItemState(SID_OUTPUT_QUALITY_CONTRAST)==SFX_ITEM_AVAILABLE)
{
- ::sd::Window* pWindow = mrSlideSorter.GetActiveWindow();
- if (pWindow != NULL)
+ if (mrSlideSorter.GetContentWindow())
{
- ULONG nMode = pWindow->GetDrawMode();
+ ULONG nMode = mrSlideSorter.GetContentWindow()->GetDrawMode();
UINT16 nQuality = 0;
switch (nMode)
@@ -715,7 +790,7 @@ void SlideSorterController::ExecStatusBar (SfxRequest& )
void SlideSorterController::UpdateAllPages (void)
{
// Do a redraw.
- mrView.InvalidateAllWin();
+ mrSlideSorter.GetContentWindow()->Invalidate();
}
@@ -741,20 +816,35 @@ Rectangle SlideSorterController::Rearrange (bool bForce)
{
Rectangle aNewContentArea (maTotalWindowArea);
- ::boost::shared_ptr<sd::Window> pWindow = mrSlideSorter.GetContentWindow();
- if (pWindow.get() != NULL)
+ 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);
+ 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());
+ Rectangle aCurrentContentArea (pWindow->GetPosPixel(), pWindow->GetOutputSizePixel());
bSizeHasChanged = (aNewContentArea != aCurrentContentArea);
}
if (bForce || bSizeHasChanged)
@@ -767,6 +857,11 @@ Rectangle SlideSorterController::Rearrange (bool bForce)
// 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;
@@ -784,6 +879,15 @@ FunctionReference SlideSorterController::CreateSelectionFunction (SfxRequest& rR
+::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
@@ -887,8 +991,8 @@ void SlideSorterController::PageNameHasChanged (int nPageIndex, const String& rs
// that of the name change.
do
{
- ::sd::Window* pWindow = mrSlideSorter.GetActiveWindow();
- if (pWindow == NULL)
+ SharedSdWindow pWindow (mrSlideSorter.GetContentWindow());
+ if ( ! pWindow)
break;
::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
@@ -937,14 +1041,6 @@ bool SlideSorterController::IsContextMenuOpen (void) const
-::boost::shared_ptr<Properties> SlideSorterController::GetProperties (void) const
-{
- return mpProperties;
-}
-
-
-
-
void SlideSorterController::SetDocumentSlides (const Reference<container::XIndexAccess>& rxSlides)
{
if (mrModel.GetDocumentSlides() != rxSlides)
@@ -954,6 +1050,11 @@ void SlideSorterController::SetDocumentSlides (const Reference<container::XIndex
mrModel.SetDocumentSlides(rxSlides);
mrView.Layout();
+
+ // Select just the current slide.
+ PageSelector::BroadcastLock aBroadcastLock (*mpPageSelector);
+ mpPageSelector->DeselectAllPages();
+ mpPageSelector->SelectPage(mpCurrentSlideManager->GetCurrentSlide());
}
}
@@ -968,6 +1069,35 @@ void SlideSorterController::SetDocumentSlides (const Reference<container::XIndex
+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);
+ }
+ }
+}
+
+
+
+
//===== SlideSorterController::ModelChangeLock ================================
SlideSorterController::ModelChangeLock::ModelChangeLock (
diff --git a/sd/source/ui/slidesorter/controller/SlsAnimationFunction.cxx b/sd/source/ui/slidesorter/controller/SlsAnimationFunction.cxx
new file mode 100644
index 000000000000..71b6c024ae7a
--- /dev/null
+++ b/sd/source/ui/slidesorter/controller/SlsAnimationFunction.cxx
@@ -0,0 +1,294 @@
+/*************************************************************************
+ *
+ * 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 "precompiled_sd.hxx"
+#include "controller/SlsAnimationFunction.hxx"
+#include "model/SlsPageDescriptor.hxx"
+#include "view/SlideSorterView.hxx"
+
+
+#include <osl/diagnose.hxx>
+#include <rtl/math.hxx>
+
+namespace sd { namespace slidesorter { namespace controller {
+
+
+double AnimationFunction::Linear (const double nTime)
+{
+ OSL_ASSERT(nTime>=0.0 && nTime<=1.0);
+ return nTime;
+}
+
+
+
+
+double AnimationFunction::FastInSlowOut_Sine (const double nTime)
+{
+ OSL_ASSERT(nTime>=0.0 && nTime<=1.0);
+
+ const double nResult (sin(nTime * M_PI/2));
+
+ OSL_ASSERT(nResult>=0.0 && nResult<=1.0);
+ return nResult;
+}
+
+
+
+
+double AnimationFunction::FastInSlowOut_Root (const double nTime)
+{
+ OSL_ASSERT(nTime>=0.0 && nTime<=1.0);
+
+ const double nResult (sqrt(nTime));
+
+ OSL_ASSERT(nResult>=0.0 && nResult<=1.0);
+ return nResult;
+}
+
+
+
+
+double AnimationFunction::SlowInSlowOut_0to0_Sine (const double nTime)
+{
+ OSL_ASSERT(nTime>=0.0 && nTime<=1.0);
+
+ const double nResult (sin(nTime * M_PI));
+
+ OSL_ASSERT(nResult>=0.0 && nResult<=1.0);
+ return nResult;
+}
+
+
+
+
+double AnimationFunction::Vibrate_Sine (const double nTime)
+{
+ return sin(nTime*M_PI*8);
+}
+
+
+
+
+Point AnimationFunction::ScalePoint (const Point& rPoint, const double nTime)
+{
+ return Point(
+ sal_Int32(::rtl::math::round(rPoint.X() * nTime)),
+ sal_Int32(::rtl::math::round(rPoint.Y() * nTime)));
+}
+
+
+
+
+double AnimationFunction::Blend (
+ const double nStartValue,
+ const double nEndValue,
+ const double nTime)
+{
+ return nStartValue*(1-nTime) + nEndValue*nTime;
+}
+
+
+
+
+void AnimationFunction::ApplyVisualStateChange (
+ const model::SharedPageDescriptor& rpDescriptor,
+ view::SlideSorterView& rView,
+ const double nTime)
+{
+ if (rpDescriptor)
+ {
+ rpDescriptor->GetVisualState().SetVisualStateBlend(nTime);
+ rView.RequestRepaint(rpDescriptor);
+ }
+}
+
+
+
+
+void AnimationFunction::ApplyLocationOffsetChange (
+ const model::SharedPageDescriptor& rpDescriptor,
+ view::SlideSorterView& rView,
+ const Point aLocationOffset)
+{
+ if (rpDescriptor)
+ {
+ const Rectangle aOldBoundingBox(rpDescriptor->GetBoundingBox());
+ rpDescriptor->GetVisualState().SetLocationOffset(aLocationOffset);
+ rView.RequestRepaint(aOldBoundingBox);
+ rView.RequestRepaint(rpDescriptor);
+ }
+}
+
+
+
+
+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 (
+ const double nX1,
+ const double nY1,
+ const double nX2,
+ const double nY2)
+ : mnX1(nX1),
+ mnY1(nY1),
+ mnX2(nX2),
+ mnY2(nY2)
+{
+}
+
+
+
+
+AnimationBezierFunction::AnimationBezierFunction (
+ const double nX1,
+ const double nY1)
+ : mnX1(nX1),
+ mnY1(nY1),
+ mnX2(1-nY1),
+ mnY2(1-nX1)
+{
+}
+
+
+
+
+::basegfx::B2DPoint AnimationBezierFunction::operator() (const double nT)
+{
+ return ::basegfx::B2DPoint(
+ EvaluateComponent(nT, mnX1, mnX2),
+ EvaluateComponent(nT, mnY1, mnY2));
+}
+
+
+
+
+double AnimationBezierFunction::EvaluateComponent (
+ const double nT,
+ const double nV1,
+ const double nV2)
+{
+ const double nS (1-nT);
+
+ // While the control point values 1 and 2 are explicitly given the start
+ // and end values are implicitly given.
+ const double nV0 (0);
+ const double nV3 (1);
+
+ const double nV01 (nS*nV0 + nT*nV1);
+ const double nV12 (nS*nV1 + nT*nV2);
+ const double nV23 (nS*nV2 + nT*nV3);
+
+ const double nV012 (nS*nV01 + nT*nV12);
+ const double nV123 (nS*nV12 + nT*nV23);
+
+ const double nV0123 (nS*nV012 + nT*nV123);
+
+ return nV0123;
+}
+
+
+
+
+//===== AnimationParametricFunction ===========================================
+
+AnimationParametricFunction::AnimationParametricFunction (const ParametricFunction& rFunction)
+ : maY()
+{
+ const sal_Int32 nSampleCount (64);
+
+ // Sample the given parametric function.
+ ::std::vector<basegfx::B2DPoint> aPoints;
+ aPoints.reserve(nSampleCount);
+ for (sal_Int32 nIndex=0; nIndex<nSampleCount; ++nIndex)
+ {
+ const double nT (nIndex/double(nSampleCount-1));
+ aPoints.push_back(basegfx::B2DPoint(rFunction(nT)));
+ }
+
+ // Interpolate at evenly spaced points.
+ maY.clear();
+ maY.reserve(nSampleCount);
+ double nX0 (aPoints[0].getX());
+ double nY0 (aPoints[0].getY());
+ double nX1 (aPoints[1].getX());
+ double nY1 (aPoints[1].getY());
+ sal_Int32 nIndex (1);
+ for (sal_Int32 nIndex2=0; nIndex2<nSampleCount; ++nIndex2)
+ {
+ const double nX (nIndex2 / double(nSampleCount-1));
+ while (nX > nX1 && nIndex<nSampleCount)
+ {
+ nX0 = nX1;
+ nY0 = nY1;
+ nX1 = aPoints[nIndex].getX();
+ nY1 = aPoints[nIndex].getY();
+ ++nIndex;
+ }
+ const double nU ((nX-nX1) / (nX0 - nX1));
+ const double nY (nY0*nU + nY1*(1-nU));
+ maY.push_back(nY);
+ }
+}
+
+
+
+
+double AnimationParametricFunction::operator() (const double nX)
+{
+ const sal_Int32 nIndex0 (nX * maY.size());
+ const double nX0 (nIndex0 / double(maY.size()-1));
+ const sal_uInt32 nIndex1 (nIndex0 + 1);
+ const double nX1 (nIndex1 / double(maY.size()-1));
+
+ if (nIndex0<=0)
+ return maY[0];
+ else if (sal_uInt32(nIndex0)>=maY.size() || nIndex1>=maY.size())
+ return maY[maY.size()-1];
+
+ const double nU ((nX-nX1) / (nX0 - nX1));
+ return maY[nIndex0]*nU + maY[nIndex1]*(1-nU);
+}
+
+
+} } } // end of namespace ::sd::slidesorter::controller
diff --git a/sd/source/ui/slidesorter/controller/SlsAnimator.cxx b/sd/source/ui/slidesorter/controller/SlsAnimator.cxx
index 56505d9756e6..28756b3766d9 100644..100755
--- a/sd/source/ui/slidesorter/controller/SlsAnimator.cxx
+++ b/sd/source/ui/slidesorter/controller/SlsAnimator.cxx
@@ -29,6 +29,7 @@
#include "controller/SlsAnimator.hxx"
#include "view/SlideSorterView.hxx"
#include "View.hxx"
+#include <boost/bind.hpp>
namespace sd { namespace slidesorter { namespace controller {
@@ -42,27 +43,32 @@ class Animator::Animation
{
public:
Animation (
- const Animator::AnimationFunction& rAnimation,
- const double nDelta);
+ const Animator::AnimationFunctor& rAnimation,
+ const double nStartOffset,
+ const double nDuration,
+ const double nGlobalTime,
+ const Animator::AnimationId nAnimationId,
+ const Animator::FinishFunctor& rFinishFunctor);
~Animation (void);
- bool Run (void);
+ /** Run next animation step. If animation has reached its end it is
+ expired.
+ */
+ bool Run (const double nGlobalTime);
+
+ /** Typically called when an animation has finished, but also from
+ Animator::Disposed(). The finish functor is called and the
+ animation is marked as expired to prevent another run.
+ */
+ void Expire (void);
bool IsExpired (void);
- Animator::AnimationFunction maAnimation;
- double mnValue;
- double mnDelta;
-};
-
-
-
-
-class Animator::DrawLock
-{
-public:
- DrawLock (View& rView);
- ~DrawLock (void);
-private:
- View& mrView;
+ Animator::AnimationFunctor maAnimation;
+ Animator::FinishFunctor maFinishFunctor;
+ const Animator::AnimationId mnAnimationId;
+ const double mnDuration;
+ const double mnEnd;
+ const double mnGlobalTimeAtStart;
+ bool mbIsExpired;
};
@@ -71,8 +77,11 @@ private:
Animator::Animator (SlideSorter& rSlideSorter)
: mrSlideSorter(rSlideSorter),
maTimer(),
+ mbIsDisposed(false),
maAnimations(),
- mpDrawLock()
+ maElapsedTime(),
+ mpDrawLock(),
+ mnNextAnimationId(0)
{
maTimer.SetTimeout(gnResolution);
maTimer.SetTimeoutHdl(LINK(this,Animator,TimeoutHandler));
@@ -83,39 +92,161 @@ Animator::Animator (SlideSorter& rSlideSorter)
Animator::~Animator (void)
{
+ if ( ! mbIsDisposed)
+ {
+ OSL_ASSERT(mbIsDisposed);
+ Dispose();
+ }
+}
+
+
+
+
+void Animator::Dispose (void)
+{
+ mbIsDisposed = true;
+
+ AnimationList aCopy (maAnimations);
+ AnimationList::const_iterator iAnimation;
+ for (iAnimation=aCopy.begin(); iAnimation!=aCopy.end(); ++iAnimation)
+ (*iAnimation)->Expire();
+
maTimer.Stop();
- mpDrawLock.reset();
+ if (mpDrawLock)
+ {
+ mpDrawLock->Dispose();
+ mpDrawLock.reset();
+ }
}
-void Animator::AddAnimation (
- const AnimationFunction& rAnimation,
- const sal_Int32 nDuration)
+Animator::AnimationId Animator::AddAnimation (
+ const AnimationFunctor& rAnimation,
+ const sal_Int32 nStartOffset,
+ const sal_Int32 nDuration,
+ const FinishFunctor& rFinishFunctor)
{
- const double nDelta = double(gnResolution) / double(nDuration);
- maAnimations.push_back(boost::shared_ptr<Animation>(new Animation(rAnimation, nDelta)));
+ // When the animator is already disposed then ignore this call
+ // silently (well, we show an assertion, but do not throw an exception.)
+ OSL_ASSERT( ! mbIsDisposed);
+ if (mbIsDisposed)
+ return -1;
+
+ boost::shared_ptr<Animation> pAnimation (
+ new Animation(
+ rAnimation,
+ nStartOffset / 1000.0,
+ nDuration / 1000.0,
+ maElapsedTime.getElapsedTime(),
+ ++mnNextAnimationId,
+ rFinishFunctor));
+ maAnimations.push_back(pAnimation);
+
+ RequestNextFrame();
+
+ return pAnimation->mnAnimationId;
+}
+
- // Prevent redraws except for the ones in TimeoutHandler.
- // While the Animator is active it will schedule repaints regularly.
- // Repaints in between would only lead to visual artifacts.
- mpDrawLock.reset(new DrawLock(mrSlideSorter.GetView()));
- maTimer.Start();
+
+
+Animator::AnimationId Animator::AddInfiniteAnimation (
+ const AnimationFunctor& rAnimation,
+ const double nDelta)
+{
+ (void)nDelta;
+
+ // When the animator is already disposed then ignore this call
+ // silently (well, we show an assertion, but do not throw an exception.)
+ OSL_ASSERT( ! mbIsDisposed);
+ if (mbIsDisposed)
+ return -1;
+
+ boost::shared_ptr<Animation> pAnimation (
+ new Animation(
+ rAnimation,
+ 0,
+ -1,
+ maElapsedTime.getElapsedTime(),
+ mnNextAnimationId++,
+ FinishFunctor()));
+ maAnimations.push_back(pAnimation);
+
+ RequestNextFrame();
+
+ return pAnimation->mnAnimationId;
}
-bool Animator::ServeAnimations (void)
+void Animator::RemoveAnimation (const Animator::AnimationId nId)
+{
+ OSL_ASSERT( ! mbIsDisposed);
+
+ const AnimationList::iterator iAnimation (::std::find_if(
+ maAnimations.begin(),
+ maAnimations.end(),
+ ::boost::bind(
+ ::std::equal_to<Animator::AnimationId>(),
+ nId,
+ ::boost::bind(&Animation::mnAnimationId, _1))));
+ if (iAnimation != maAnimations.end())
+ {
+ OSL_ASSERT((*iAnimation)->mnAnimationId == nId);
+ (*iAnimation)->Expire();
+ maAnimations.erase(iAnimation);
+ }
+
+ if (maAnimations.empty())
+ {
+ // Reset the animation id when we can.
+ mnNextAnimationId = 0;
+
+ // No more animations => we do not have to suppress painting
+ // anymore.
+ mpDrawLock.reset();
+ }
+}
+
+
+
+
+void Animator::RemoveAllAnimations (void)
+{
+ ::std::for_each(
+ maAnimations.begin(),
+ maAnimations.end(),
+ ::boost::bind(
+ &Animation::Expire,
+ _1));
+ maAnimations.clear();
+ mnNextAnimationId = 0;
+
+ // No more animations => we do not have to suppress painting
+ // anymore.
+ mpDrawLock.reset();
+}
+
+
+
+
+bool Animator::ProcessAnimations (const double nTime)
{
bool bExpired (false);
+ OSL_ASSERT( ! mbIsDisposed);
+ if (mbIsDisposed)
+ return bExpired;
+
+
AnimationList aCopy (maAnimations);
AnimationList::const_iterator iAnimation;
for (iAnimation=aCopy.begin(); iAnimation!=aCopy.end(); ++iAnimation)
{
- bExpired |= (*iAnimation)->Run();
+ bExpired |= (*iAnimation)->Run(nTime);
}
return bExpired;
@@ -126,6 +257,10 @@ bool Animator::ServeAnimations (void)
void Animator::CleanUpAnimationList (void)
{
+ OSL_ASSERT( ! mbIsDisposed);
+ if (mbIsDisposed)
+ return;
+
AnimationList aActiveAnimations;
AnimationList::const_iterator iAnimation;
@@ -141,19 +276,35 @@ void Animator::CleanUpAnimationList (void)
+void Animator::RequestNextFrame (const double nFrameStart)
+{
+ (void)nFrameStart;
+ if ( ! maTimer.IsActive())
+ {
+ // Prevent redraws except for the ones in TimeoutHandler. While the
+ // Animator is active it will schedule repaints regularly. Repaints
+ // in between would only lead to visual artifacts.
+ mpDrawLock.reset(new view::SlideSorterView::DrawLock(mrSlideSorter));
+ maTimer.Start();
+ }
+}
+
+
+
+
IMPL_LINK(Animator, TimeoutHandler, Timer*, EMPTYARG)
{
- if (ServeAnimations())
+ if (mbIsDisposed)
+ return 0;
+
+ if (ProcessAnimations(maElapsedTime.getElapsedTime()))
CleanUpAnimationList();
// Unlock the draw lock. This should lead to a repaint.
mpDrawLock.reset();
if (maAnimations.size() > 0)
- {
- mpDrawLock.reset(new DrawLock(mrSlideSorter.GetView()));
- maTimer.Start();
- }
+ RequestNextFrame();
return 0;
}
@@ -164,16 +315,21 @@ IMPL_LINK(Animator, TimeoutHandler, Timer*, EMPTYARG)
//===== Animator::Animation ===================================================
Animator::Animation::Animation (
- const Animator::AnimationFunction& rAnimation,
- const double nDelta)
+ const Animator::AnimationFunctor& rAnimation,
+ const double nStartOffset,
+ const double nDuration,
+ const double nGlobalTime,
+ const Animator::AnimationId nId,
+ const Animator::FinishFunctor& rFinishFunctor)
: maAnimation(rAnimation),
- mnValue(0),
- mnDelta(nDelta)
+ maFinishFunctor(rFinishFunctor),
+ mnAnimationId(nId),
+ mnDuration(nDuration),
+ mnEnd(nGlobalTime + nDuration + nStartOffset),
+ mnGlobalTimeAtStart(nGlobalTime + nStartOffset),
+ mbIsExpired(false)
{
-
- maAnimation(mnValue);
- mnValue = mnDelta;
-
+ Run(nGlobalTime);
}
@@ -186,47 +342,54 @@ Animator::Animation::~Animation (void)
-bool Animator::Animation::Run (void)
+bool Animator::Animation::Run (const double nGlobalTime)
{
- if (mnValue < 1.0)
+ if ( ! mbIsExpired)
{
- maAnimation(mnValue);
- mnValue += mnDelta;
- return false;
- }
- else
- {
- maAnimation(1.0);
- return true;
+ if (mnDuration > 0)
+ {
+ if (nGlobalTime >= mnEnd)
+ {
+ maAnimation(1.0);
+ Expire();
+ }
+ else if (nGlobalTime >= mnGlobalTimeAtStart)
+ {
+ maAnimation((nGlobalTime - mnGlobalTimeAtStart) / mnDuration);
+ }
+ }
+ else if (mnDuration < 0)
+ {
+ // Animations without end have to be expired by their owner.
+ maAnimation(nGlobalTime);
+ }
}
+
+ return mbIsExpired;
}
-bool Animator::Animation::IsExpired (void)
+void Animator::Animation::Expire (void)
{
- return mnValue >= 1.0;
+ if ( ! mbIsExpired)
+ {
+ mbIsExpired = true;
+ if (maFinishFunctor)
+ maFinishFunctor();
+ }
}
-//===== Animator::DrawLock ====================================================
-
-Animator::DrawLock::DrawLock (View& rView)
- : mrView(rView)
+bool Animator::Animation::IsExpired (void)
{
- mrView.LockRedraw(TRUE);
+ return mbIsExpired;
}
-Animator::DrawLock::~DrawLock (void)
-{
- mrView.LockRedraw(FALSE);
-}
-
-
} } } // end of namespace ::sd::slidesorter::controller
diff --git a/sd/source/ui/slidesorter/controller/SlsClipboard.cxx b/sd/source/ui/slidesorter/controller/SlsClipboard.cxx
index d226a8c2e294..68ae50e091e7 100644..100755
--- a/sd/source/ui/slidesorter/controller/SlsClipboard.cxx
+++ b/sd/source/ui/slidesorter/controller/SlsClipboard.cxx
@@ -35,16 +35,18 @@
#include "model/SlsPageDescriptor.hxx"
#include "model/SlsPageEnumerationProvider.hxx"
#include "view/SlideSorterView.hxx"
-#include "view/SlsViewOverlay.hxx"
-#include "view/SlsPageObject.hxx"
+#include "view/SlsTheme.hxx"
#include "controller/SlideSorterController.hxx"
+#include "controller/SlsInsertionIndicatorHandler.hxx"
#include "controller/SlsPageSelector.hxx"
#include "controller/SlsSelectionFunction.hxx"
#include "controller/SlsCurrentSlideManager.hxx"
#include "controller/SlsScrollBarManager.hxx"
#include "controller/SlsFocusManager.hxx"
#include "controller/SlsSelectionManager.hxx"
-#include "SlsTransferable.hxx"
+#include "controller/SlsTransferable.hxx"
+#include "controller/SlsSelectionObserver.hxx"
+#include "cache/SlsPageCache.hxx"
#include "ViewShellBase.hxx"
#include "DrawViewShell.hxx"
@@ -74,6 +76,7 @@
#include <sfx2/bindings.hxx>
#include <sfx2/docfile.hxx>
#include <svx/svxids.hrc>
+#include <svx/svdstr.hrc>
#include <vcl/msgbox.hxx>
#include <tools/urlobj.hxx>
#include <rtl/ustring.hxx>
@@ -82,6 +85,43 @@
namespace sd { namespace slidesorter { namespace controller {
+class Clipboard::UndoContext
+{
+public:
+ UndoContext (
+ SdDrawDocument* pDocument,
+ const ::boost::shared_ptr<ViewShell>& rpMainViewShell,
+ const ::boost::shared_ptr<view::Theme>& rpTheme)
+ : mpDocument(pDocument),
+ mpMainViewShell(rpMainViewShell)
+ {
+ if (mpDocument!=NULL && mpDocument->IsUndoEnabled())
+ {
+ if (mpMainViewShell && mpMainViewShell->GetShellType() == ViewShell::ST_DRAW)
+ mpDocument->BegUndo(rpTheme->GetString(view::Theme::String_DragAndDropPages));
+ else
+ mpDocument->BegUndo(rpTheme->GetString(view::Theme::String_DragAndDropSlides));
+ }
+ }
+
+ ~UndoContext (void)
+ {
+ if (mpDocument!=NULL && mpDocument->IsUndoEnabled())
+ mpDocument->EndUndo();
+ if (mpMainViewShell && mpMainViewShell->GetViewFrame()!=NULL)
+ {
+ SfxBindings& rBindings = mpMainViewShell->GetViewFrame()->GetBindings();
+ rBindings.Invalidate(SID_UNDO);
+ rBindings.Invalidate(SID_REDO);
+ }
+ }
+private:
+ SdDrawDocument* mpDocument;
+ ::boost::shared_ptr<ViewShell> mpMainViewShell;
+};
+
+
+
Clipboard::Clipboard (SlideSorter& rSlideSorter)
: ViewClipboard(rSlideSorter.GetView()),
@@ -89,7 +129,10 @@ Clipboard::Clipboard (SlideSorter& rSlideSorter)
mrController(mrSlideSorter.GetController()),
maPagesToRemove(),
maPagesToSelect(),
- mbUpdateSelectionPending(false)
+ mbUpdateSelectionPending(false),
+ mpUndoContext(),
+ mpSelectionObserverContext(),
+ mnDragFinishedUserEventId(0)
{
}
@@ -98,6 +141,8 @@ Clipboard::Clipboard (SlideSorter& rSlideSorter)
Clipboard::~Clipboard (void)
{
+ if (mnDragFinishedUserEventId != 0)
+ Application::RemoveUserEvent(mnDragFinishedUserEventId);
}
@@ -143,13 +188,12 @@ void Clipboard::HandleSlotCall (SfxRequest& rRequest)
// a crash.
if (mrSlideSorter.GetModel().GetEditMode() != EM_MASTERPAGE)
{
- mrSlideSorter.GetView().LockRedraw (TRUE);
+ view::SlideSorterView::DrawLock aLock (mrSlideSorter);
+ SelectionObserver::Context aContext (mrSlideSorter);
if(xFunc.is())
xFunc->DoPaste();
else
DoPaste();
- mrController.GetSelectionManager()->MakeSelectionVisible();
- mrSlideSorter.GetView().LockRedraw(FALSE);
}
rRequest.Done();
break;
@@ -209,7 +253,7 @@ void Clipboard::DoPaste (::Window* pWindow)
sal_Int32 nInsertPageCount = PasteTransferable(nInsertPosition);
// Select the pasted pages and make the first of them the
// current page.
- mrSlideSorter.GetView().GetWindow()->GrabFocus();
+ mrSlideSorter.GetContentWindow()->GrabFocus();
SelectPageRange(nInsertPosition, nInsertPageCount);
}
}
@@ -230,14 +274,22 @@ sal_Int32 Clipboard::GetInsertionPosition (::Window* pWindow)
// selection.
// d) After the last page when there is no selection and no focus.
- view::InsertionIndicatorOverlay& rInsertionIndicatorOverlay (
- mrSlideSorter.GetView().GetOverlay().GetInsertionIndicatorOverlay());
- if (rInsertionIndicatorOverlay.isVisible())
+ ::boost::shared_ptr<controller::InsertionIndicatorHandler> pInsertionIndicatorHandler (
+ mrController.GetInsertionIndicatorHandler());
+ if (pInsertionIndicatorHandler->IsActive())
+ {
+ // Use the insertion index of an active insertion indicator.
+ nInsertPosition = pInsertionIndicatorHandler->GetInsertionPageIndex();
+ }
+ else if (mrController.GetSelectionManager()->GetInsertionPosition() >= 0)
{
- nInsertPosition = rInsertionIndicatorOverlay.GetInsertionPageIndex();
+ // Use the insertion index of an insertion indicator that has been
+ // deactivated a short while ago.
+ nInsertPosition = mrController.GetSelectionManager()->GetInsertionPosition();
}
else if (mrController.GetFocusManager().IsFocusShowing())
{
+ // Use the focus to determine the insertion position.
SdInsertPasteDlg aDialog (pWindow);
if (aDialog.Execute() == RET_OK)
{
@@ -246,10 +298,6 @@ sal_Int32 Clipboard::GetInsertionPosition (::Window* pWindow)
nInsertPosition ++;
}
}
- else
- {
- nInsertPosition = mrController.GetSelectionManager()->GetInsertionPosition();
- }
return nInsertPosition;
}
@@ -260,9 +308,9 @@ sal_Int32 Clipboard::GetInsertionPosition (::Window* pWindow)
sal_Int32 Clipboard::PasteTransferable (sal_Int32 nInsertPosition)
{
SdTransferable* pClipTransferable = SD_MOD()->pTransferClip;
- bool bMergeMasterPages = !pClipTransferable->HasSourceDoc (
- mrSlideSorter.GetModel().GetDocument());
- USHORT nInsertIndex ((USHORT)(nInsertPosition * 2 + 1));
+ model::SlideSorterModel& rModel (mrSlideSorter.GetModel());
+ bool bMergeMasterPages = !pClipTransferable->HasSourceDoc (rModel.GetDocument());
+ USHORT nInsertIndex (rModel.GetCoreIndex(nInsertPosition));
sal_Int32 nInsertPageCount (0);
if (pClipTransferable->HasPageBookmarks())
{
@@ -270,7 +318,7 @@ sal_Int32 Clipboard::PasteTransferable (sal_Int32 nInsertPosition)
const ::vos::OGuard aGuard (Application::GetSolarMutex());
nInsertPageCount = (USHORT) rBookmarkList.Count();
- mrSlideSorter.GetModel().GetDocument()->InsertBookmarkAsPage(
+ rModel.GetDocument()->InsertBookmarkAsPage(
const_cast<List*>(&rBookmarkList),
NULL,
FALSE,
@@ -293,9 +341,9 @@ sal_Int32 Clipboard::PasteTransferable (sal_Int32 nInsertPosition)
{
const ::vos::OGuard aGuard (Application::GetSolarMutex());
- bMergeMasterPages = (pDataDoc != mrSlideSorter.GetModel().GetDocument());
+ bMergeMasterPages = (pDataDoc != rModel.GetDocument());
nInsertPageCount = pDataDoc->GetSdPageCount( PK_STANDARD );
- mrSlideSorter.GetModel().GetDocument()->InsertBookmarkAsPage(
+ rModel.GetDocument()->InsertBookmarkAsPage(
NULL,
NULL,
FALSE,
@@ -332,7 +380,6 @@ void Clipboard::SelectPageRange (sal_Int32 nFirstIndex, sal_Int32 nPageCount)
if (i == 0)
{
mrController.GetCurrentSlideManager()->SwitchCurrentSlide(pDescriptor);
- mrController.GetFocusManager().SetFocusedPage(pDescriptor);
}
}
}
@@ -361,6 +408,27 @@ void Clipboard::CreateSlideTransferable (
maPagesToRemove.push_back (pDescriptor->GetPage());
}
+ // Create a small set of representatives of the selection for which
+ // previews are included into the transferable so that an insertion
+ // indicator can be rendered.
+ aSelectedPages.Rewind();
+ ::std::vector<Transferable::Representative> aRepresentatives;
+ aRepresentatives.reserve(3);
+ ::boost::shared_ptr<cache::PageCache> pPreviewCache (
+ mrSlideSorter.GetView().GetPreviewCache());
+ while (aSelectedPages.HasMoreElements())
+ {
+ model::SharedPageDescriptor pDescriptor (aSelectedPages.GetNextElement());
+ if ( ! pDescriptor || pDescriptor->GetPage()==NULL)
+ continue;
+ Bitmap aPreview (pPreviewCache->GetPreviewBitmap(pDescriptor->GetPage(), false));
+ aRepresentatives.push_back(Transferable::Representative(
+ aPreview,
+ pDescriptor->HasState(model::PageDescriptor::ST_Excluded)));
+ if (aRepresentatives.size() >= 3)
+ break;
+ }
+
if (aBookmarkList.Count() > 0)
{
mrSlideSorter.GetView().BrkAction();
@@ -369,7 +437,8 @@ void Clipboard::CreateSlideTransferable (
pDocument,
NULL,
FALSE,
- dynamic_cast<SlideSorterViewShell*>(mrSlideSorter.GetViewShell()));
+ dynamic_cast<SlideSorterViewShell*>(mrSlideSorter.GetViewShell()),
+ aRepresentatives);
if (bDrag)
SD_MOD()->pTransferDrag = pTransferable;
@@ -423,13 +492,17 @@ void Clipboard::CreateSlideTransferable (
void Clipboard::StartDrag (
- const Point&,
+ const Point& rPosition,
::Window* pWindow)
{
maPagesToRemove.clear();
maPagesToSelect.clear();
mbUpdateSelectionPending = false;
- CreateSlideTransferable (pWindow, TRUE);
+ CreateSlideTransferable(pWindow, TRUE);
+
+ mrController.GetInsertionIndicatorHandler()->UpdatePosition(
+ rPosition,
+ InsertionIndicatorHandler::UnknownMode);
}
@@ -437,15 +510,36 @@ void Clipboard::StartDrag (
void Clipboard::DragFinished (sal_Int8 nDropAction)
{
- // Hide the substitution display and insertion indicator.
- mrSlideSorter.GetView().GetOverlay().GetSubstitutionOverlay().setVisible(false);
- mrSlideSorter.GetView().GetOverlay().GetInsertionIndicatorOverlay().setVisible(false);
-
SdTransferable* pDragTransferable = SD_MOD()->pTransferDrag;
-
if (pDragTransferable != NULL)
pDragTransferable->SetView (NULL);
+ if (mnDragFinishedUserEventId == 0)
+ {
+ if ( ! Application::PostUserEvent(
+ mnDragFinishedUserEventId,
+ LINK(this, Clipboard, ProcessDragFinished),
+ reinterpret_cast<void*>(nDropAction)))
+ {
+ mnDragFinishedUserEventId = 0;
+ }
+ }
+}
+
+
+
+
+IMPL_LINK(Clipboard, ProcessDragFinished, void*, pUserData)
+{
+ const sal_Int8 nDropAction (static_cast<sal_Int8>(reinterpret_cast<sal_IntPtr>(pUserData)));
+
+ mnDragFinishedUserEventId = 0;
+
+ // Hide the substitution display and insertion indicator.
+ ::rtl::Reference<SelectionFunction> pFunction (mrController.GetCurrentSelectionFunction());
+ if (pFunction.is())
+ pFunction->NotifyDragFinished();
+
PageSelector& rSelector (mrController.GetPageSelector());
if ((nDropAction & DND_ACTION_MOVE) != 0
&& ! maPagesToRemove.empty())
@@ -458,12 +552,14 @@ void Clipboard::DragFinished (sal_Int8 nDropAction)
aDraggedPage!=maPagesToRemove.end();
aDraggedPage++)
{
- rSelector.SelectPage (*aDraggedPage);
+ rSelector.SelectPage(*aDraggedPage);
}
- mrController.GetSelectionManager()->DeleteSelectedPages ();
+ mrController.GetSelectionManager()->DeleteSelectedPages();
}
+ mpUndoContext.reset();
+ mpSelectionObserverContext.reset();
- SelectPages();
+ return 1;
}
@@ -492,14 +588,16 @@ sal_Int8 Clipboard::AcceptDrop (
USHORT nPage,
USHORT nLayer)
{
- sal_Int8 nResult = DND_ACTION_NONE;
+ sal_Int8 nAction (DND_ACTION_NONE);
- switch (IsDropAccepted())
+ const Clipboard::DropType eDropType (IsDropAccepted());
+
+ switch (eDropType)
{
case DT_PAGE:
{
// Accept a drop.
- nResult = rEvent.mnAction;
+ nAction = rEvent.mnAction;
// Use the copy action when the drop action is the default, i.e. not
// explicitly set to move or link, and when the source and
@@ -512,23 +610,27 @@ sal_Int8 Clipboard::AcceptDrop (
&& (mrSlideSorter.GetModel().GetDocument()->GetDocSh()
!= pDragTransferable->GetPageDocShell()))
{
- nResult = DND_ACTION_COPY;
+ nAction = DND_ACTION_COPY;
+ }
+ else if (mrController.GetInsertionIndicatorHandler()->IsInsertionTrivial(nAction))
+ {
+ nAction = DND_ACTION_NONE;
}
// Show the insertion marker and the substitution for a drop.
Point aPosition = pTargetWindow->PixelToLogic (rEvent.maPosPixel);
- view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay());
- rOverlay.GetInsertionIndicatorOverlay().SetPosition (aPosition);
- rOverlay.GetInsertionIndicatorOverlay().setVisible(true);
- rOverlay.GetSubstitutionOverlay().SetPosition (aPosition);
+ SelectionFunction* pSelectionFunction = dynamic_cast<SelectionFunction*>(
+ mrSlideSorter.GetViewShell()->GetCurrentFunction().get());
+ if (pSelectionFunction != NULL)
+ pSelectionFunction->MouseDragged(rEvent, nAction);
// Scroll the window when the mouse reaches the window border.
- mrController.GetScrollBarManager().AutoScroll (rEvent.maPosPixel);
+ // mrController.GetScrollBarManager().AutoScroll (rEvent.maPosPixel);
}
break;
case DT_SHAPE:
- nResult = ExecuteOrAcceptShapeDrop(
+ nAction = ExecuteOrAcceptShapeDrop(
DC_ACCEPT,
rEvent.maPosPixel,
&rEvent,
@@ -537,11 +639,13 @@ sal_Int8 Clipboard::AcceptDrop (
nPage,
nLayer);
break;
+
default:
+ nAction = DND_ACTION_NONE;
break;
}
- return nResult;
+ return nAction;
}
@@ -555,6 +659,7 @@ sal_Int8 Clipboard::ExecuteDrop (
USHORT nLayer)
{
sal_Int8 nResult = DND_ACTION_NONE;
+ mpUndoContext.reset();
switch (IsDropAccepted())
{
@@ -563,54 +668,57 @@ sal_Int8 Clipboard::ExecuteDrop (
const SdTransferable* pDragTransferable = SD_MOD()->pTransferDrag;
const Point aEventModelPosition (
pTargetWindow->PixelToLogic (rEvent.maPosPixel));
- long int nXOffset = labs (pDragTransferable->GetStartPos().X()
- - aEventModelPosition.X());
- long int nYOffset = labs (pDragTransferable->GetStartPos().Y()
- - aEventModelPosition.Y());
- const bool bContinue =
+ const sal_Int32 nXOffset (labs (pDragTransferable->GetStartPos().X()
+ - aEventModelPosition.X()));
+ const sal_Int32 nYOffset (labs (pDragTransferable->GetStartPos().Y()
+ - aEventModelPosition.Y()));
+ bool bContinue =
( pDragTransferable->GetView() != &mrSlideSorter.GetView() )
|| ( nXOffset >= 2 && nYOffset >= 2 );
+ ::boost::shared_ptr<InsertionIndicatorHandler> pInsertionIndicatorHandler(
+ mrController.GetInsertionIndicatorHandler());
// Get insertion position and then turn off the insertion indicator.
- view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay());
- rOverlay.GetInsertionIndicatorOverlay().SetPosition(
- aEventModelPosition);
- USHORT nIndex = DetermineInsertPosition (*pDragTransferable);
- OSL_TRACE ("Clipboard::AcceptDrop() called for index %d",
- nIndex);
- rOverlay.GetInsertionIndicatorOverlay().setVisible(false);
+ pInsertionIndicatorHandler->UpdatePosition(aEventModelPosition, rEvent.mnAction);
+ // USHORT nIndex = DetermineInsertPosition(*pDragTransferable);
+
+ // Do not process the insertion when it is trivial,
+ // i.e. would insert pages at their original place.
+ if (pInsertionIndicatorHandler->IsInsertionTrivial(rEvent.mnAction))
+ bContinue = false;
+
+ // Tell the insertion indicator handler to hide before the model
+ // is modified. Doing it later may result in page objects whose
+ // animation state is not properly reset because they are then
+ // in another run then before the model change.
+ pInsertionIndicatorHandler->End(Animator::AM_Immediate);
if (bContinue)
{
SlideSorterController::ModelChangeLock aModelChangeLock (mrController);
- if (pDragTransferable->GetView() == &mrSlideSorter.GetView()
- && rEvent.mnAction == DND_ACTION_MOVE)
- {
- // We are asked to move pages inside one view. For this we
- // call MoveSelectedPages() which is faster than going the
- // generic way.
-
- // Remember to select the moved pages afterwards.
- maPagesToRemove.swap(maPagesToSelect);
- maPagesToRemove.clear();
-
- USHORT nSdrModelIndex;
- if (nIndex != SDRPAGE_NOTFOUND)
- nSdrModelIndex = nIndex / 2 - 1;
- else
- nSdrModelIndex = SDRPAGE_NOTFOUND;
- mrController.GetSelectionManager()->MoveSelectedPages(nSdrModelIndex);
- mbUpdateSelectionPending = true;
- nResult = DND_ACTION_NONE;
- }
- else
- {
- // Handle a general drop operation.
- HandlePageDrop (*pDragTransferable);
- nResult = rEvent.mnAction;
- }
+ // Handle a general drop operation.
+ mpUndoContext.reset(new UndoContext (
+ mrSlideSorter.GetModel().GetDocument(),
+ mrSlideSorter.GetViewShell()->GetViewShellBase().GetMainViewShell(),
+ mrSlideSorter.GetTheme()));
+ mpSelectionObserverContext.reset(new SelectionObserver::Context(mrSlideSorter));
+
+ HandlePageDrop(*pDragTransferable);
+ nResult = rEvent.mnAction;
+
+ // We leave the undo context alive for when moving or
+ // copying inside one view then the actions in
+ // NotifyDragFinished should be covered as well as
+ // well as the ones above.
}
+
+ // Notify the receiving selection function that drag-and-drop is
+ // finished and the substitution handler can be released.
+ ::rtl::Reference<SelectionFunction> pFunction (
+ mrController.GetCurrentSelectionFunction());
+ if (pFunction.is())
+ pFunction->NotifyDragFinished();
}
break;
@@ -634,23 +742,31 @@ sal_Int8 Clipboard::ExecuteDrop (
-USHORT Clipboard::DetermineInsertPosition (const SdTransferable& )
+void Clipboard::Abort (void)
{
- USHORT nInsertPosition = SDRPAGE_NOTFOUND;
+ if (mpSelectionObserverContext)
+ {
+ mpSelectionObserverContext->Abort();
+ mpSelectionObserverContext.reset();
+ }
+}
+
+
+
+USHORT Clipboard::DetermineInsertPosition (const SdTransferable& )
+{
// Tell the model to move the dragged pages behind the one with the
// index nInsertionIndex which first has to be transformed into an index
// understandable by the document.
- view::InsertionIndicatorOverlay& rOverlay (
- mrSlideSorter.GetView().GetOverlay().GetInsertionIndicatorOverlay());
- sal_Int32 nInsertionIndex (rOverlay.GetInsertionPageIndex());
+ const sal_Int32 nInsertionIndex (
+ mrController.GetInsertionIndicatorHandler()->GetInsertionPageIndex());
- // The index returned by the overlay starts with 1 for the first slide.
- // This is now converted that to an SdModel index that also starts with 1.
+ // Convert to insertion index to that of an SdModel.
if (nInsertionIndex >= 0)
- nInsertPosition = (USHORT)nInsertionIndex * 2 + 1;
-
- return nInsertPosition;
+ return mrSlideSorter.GetModel().GetCoreIndex(nInsertionIndex);
+ else
+ return 0;
}
@@ -666,14 +782,12 @@ USHORT Clipboard::InsertSlides (
// Remember the inserted pages so that they can be selected when the
// operation is finished.
- int nDocumentIndex = nInsertPosition / 2 - 1;
- for (USHORT i=1; i<=nInsertedPageCount; i++)
- {
- model::SharedPageDescriptor pDescriptor (
- mrSlideSorter.GetModel().GetPageDescriptor(nDocumentIndex + i));
- if (pDescriptor.get() != NULL)
- maPagesToSelect.push_back (pDescriptor->GetPage());
- }
+ maPagesToSelect.clear();
+ SdDrawDocument* pDocument = mrSlideSorter.GetModel().GetDocument();
+ if (pDocument != NULL)
+ for (sal_Int32 i=0; i<=nInsertedPageCount; i+=2)
+ maPagesToSelect.push_back(
+ dynamic_cast<SdPage*>(pDocument->GetPage(nInsertPosition+i)));
mbUpdateSelectionPending |= (nInsertedPageCount>0);
@@ -739,8 +853,8 @@ sal_Int8 Clipboard::ExecuteOrAcceptShapeDrop (
model::SharedPageDescriptor pDescriptor (
mrSlideSorter.GetModel().GetPageDescriptor(
mrSlideSorter.GetView().GetPageIndexAtPoint(rPosition)));
- if (pDescriptor.get() != NULL && pDescriptor->GetPage()!=NULL)
- nPage = (pDescriptor->GetPage()->GetPageNum() - 1) / 2;
+ if (pDescriptor)
+ nPage = pDescriptor->GetPageIndex();
}
// Now comes the code that is different for the Execute and Accept:
diff --git a/sd/source/ui/slidesorter/controller/SlsCurrentSlideManager.cxx b/sd/source/ui/slidesorter/controller/SlsCurrentSlideManager.cxx
index f5864c3307a1..7b2ca60cb4f0 100755..100644
--- a/sd/source/ui/slidesorter/controller/SlsCurrentSlideManager.cxx
+++ b/sd/source/ui/slidesorter/controller/SlsCurrentSlideManager.cxx
@@ -33,8 +33,8 @@
#include "controller/SlsPageSelector.hxx"
#include "controller/SlideSorterController.hxx"
#include "controller/SlsCurrentSlideManager.hxx"
+#include "controller/SlsFocusManager.hxx"
#include "view/SlideSorterView.hxx"
-#include "view/SlsPageObjectViewObjectContact.hxx"
#include "ViewShellBase.hxx"
#include "ViewShell.hxx"
#include "DrawViewShell.hxx"
@@ -47,13 +47,18 @@ using namespace ::com::sun::star::uno;
using namespace ::sd::slidesorter::model;
+
namespace sd { namespace slidesorter { namespace controller {
+
CurrentSlideManager::CurrentSlideManager (SlideSorter& rSlideSorter)
: mrSlideSorter(rSlideSorter),
mnCurrentSlideIndex(-1),
- mpCurrentSlide()
+ mpCurrentSlide(),
+ maSwitchPageDelayTimer()
{
+ maSwitchPageDelayTimer.SetTimeout(100);
+ maSwitchPageDelayTimer.SetTimeoutHdl(LINK(this,CurrentSlideManager,SwitchPageCallback));
}
@@ -66,7 +71,22 @@ CurrentSlideManager::~CurrentSlideManager (void)
-void CurrentSlideManager::CurrentSlideHasChanged (const sal_Int32 nSlideIndex)
+void CurrentSlideManager::NotifyCurrentSlideChange (const SdPage* pPage)
+{
+ if (pPage != NULL)
+ NotifyCurrentSlideChange(
+ mrSlideSorter.GetModel().GetIndex(
+ Reference<drawing::XDrawPage>(
+ const_cast<SdPage*>(pPage)->getUnoPage(),
+ UNO_QUERY)));
+ else
+ NotifyCurrentSlideChange(-1);
+}
+
+
+
+
+void CurrentSlideManager::NotifyCurrentSlideChange (const sal_Int32 nSlideIndex)
{
if (mnCurrentSlideIndex != nSlideIndex)
{
@@ -75,8 +95,11 @@ void CurrentSlideManager::CurrentSlideHasChanged (const sal_Int32 nSlideIndex)
// Update the selection.
mrSlideSorter.GetController().GetPageSelector().DeselectAllPages();
- if (mpCurrentSlide.get() != NULL)
+ if (mpCurrentSlide)
+ {
mrSlideSorter.GetController().GetPageSelector().SelectPage(mpCurrentSlide);
+ mrSlideSorter.GetController().GetFocusManager().SetFocusedPage(mpCurrentSlide);
+ }
}
}
@@ -86,10 +109,7 @@ void CurrentSlideManager::CurrentSlideHasChanged (const sal_Int32 nSlideIndex)
void CurrentSlideManager::ReleaseCurrentSlide (void)
{
if (mpCurrentSlide.get() != NULL)
- {
- mpCurrentSlide->SetIsCurrentPage(false);
- mrSlideSorter.GetView().RequestRepaint(mpCurrentSlide);
- }
+ mrSlideSorter.GetView().SetState(mpCurrentSlide, PageDescriptor::ST_Current, false);
mpCurrentSlide.reset();
mnCurrentSlideIndex = -1;
@@ -117,48 +137,64 @@ void CurrentSlideManager::AcquireCurrentSlide (const sal_Int32 nSlideIndex)
// document.
mpCurrentSlide = mrSlideSorter.GetModel().GetPageDescriptor(mnCurrentSlideIndex);
if (mpCurrentSlide.get() != NULL)
- {
- mpCurrentSlide->SetIsCurrentPage(true);
- mrSlideSorter.GetView().RequestRepaint(mpCurrentSlide);
- }
+ mrSlideSorter.GetView().SetState(mpCurrentSlide, PageDescriptor::ST_Current, true);
}
}
-void CurrentSlideManager::SwitchCurrentSlide (const sal_Int32 nSlideIndex)
+void CurrentSlideManager::SwitchCurrentSlide (
+ const sal_Int32 nSlideIndex,
+ const bool bUpdateSelection)
{
- SwitchCurrentSlide(mrSlideSorter.GetModel().GetPageDescriptor(nSlideIndex));
+ SwitchCurrentSlide(mrSlideSorter.GetModel().GetPageDescriptor(nSlideIndex), bUpdateSelection);
}
-void CurrentSlideManager::SwitchCurrentSlide (const SharedPageDescriptor& rpDescriptor)
+void CurrentSlideManager::SwitchCurrentSlide (
+ const SharedPageDescriptor& rpDescriptor,
+ const bool bUpdateSelection)
{
- if (rpDescriptor.get() != NULL)
+ if (rpDescriptor.get() != NULL && mpCurrentSlide!=rpDescriptor)
{
- mpCurrentSlide = rpDescriptor;
- mnCurrentSlideIndex = (rpDescriptor->GetPage()->GetPageNum()-1)/2;
+ ReleaseCurrentSlide();
+ AcquireCurrentSlide((rpDescriptor->GetPage()->GetPageNum()-1)/2);
ViewShell* pViewShell = mrSlideSorter.GetViewShell();
if (pViewShell != NULL && pViewShell->IsMainViewShell())
{
+ // The slide sorter is the main view.
FrameView* pFrameView = pViewShell->GetFrameView();
if (pFrameView != NULL)
pFrameView->SetSelectedPage(sal::static_int_cast<USHORT>(mnCurrentSlideIndex));
+ mrSlideSorter.GetController().GetPageSelector().SetCoreSelection();
}
- else
+
+ // We do not tell the XController/ViewShellBase about the new
+ // slide right away. This is done asynchronously after a short
+ // delay to allow for more slide switches in the slide sorter.
+ // This goes under the assumption that slide switching inside
+ // the slide sorter is fast (no expensive redraw of the new page
+ // (unless the preview of the new slide is not yet preset)) and
+ // that slide switching in the edit view is slow (all shapes of
+ // the new slide have to be repainted.)
+ maSwitchPageDelayTimer.Start();
+
+ // We have to store the (index of the) new current slide at
+ // the tab control because there are other asynchronous
+ // notifications of the slide switching that otherwise
+ // overwrite the correct value.
+ SetCurrentSlideAtTabControl(mpCurrentSlide);
+
+ if (bUpdateSelection)
{
- // Set current page. At the moment we have to do this in two
- // different ways. The UNO way is the preferable one but, alas,
- // it does not work always correctly (after some kinds of model
- // changes). Therefore, we call DrawViewShell::SwitchPage(),
- // too.
- SetCurrentSlideAtViewShellBase(rpDescriptor);
- SetCurrentSlideAtXController(rpDescriptor);
+ mrSlideSorter.GetController().GetPageSelector().DeselectAllPages();
+ mrSlideSorter.GetController().GetPageSelector().SelectPage(rpDescriptor);
}
+ mrSlideSorter.GetController().GetFocusManager().SetFocusedPage(rpDescriptor);
}
}
@@ -180,19 +216,26 @@ void CurrentSlideManager::SetCurrentSlideAtViewShellBase (const SharedPageDescri
pDrawViewShell->SwitchPage(nPageNumber);
pDrawViewShell->GetPageTabControl()->SetCurPageId(nPageNumber+1);
}
- /*
- else
+ }
+}
+
+
+
+
+void CurrentSlideManager::SetCurrentSlideAtTabControl (const SharedPageDescriptor& rpDescriptor)
+{
+ OSL_ASSERT(rpDescriptor.get() != NULL);
+
+ ViewShellBase* pBase = mrSlideSorter.GetViewShellBase();
+ if (pBase != NULL)
+ {
+ ::boost::shared_ptr<DrawViewShell> pDrawViewShell (
+ ::boost::dynamic_pointer_cast<DrawViewShell>(pBase->GetMainViewShell()));
+ if (pDrawViewShell)
{
- presenter::PresenterViewShell* pPresenterViewShell
- = dynamic_cast<presenter::PresenterViewShell*>(pBase->GetMainViewShell());
- if (pPresenterViewShell != NULL)
- {
- pPresenterViewShell->SetCurrentSlide(
- Reference<drawing::XDrawPage>(
- rpDescriptor->GetPage()->getUnoPage(), UNO_QUERY));
- }
+ USHORT nPageNumber = (rpDescriptor->GetPage()->GetPageNum()-1)/2;
+ pDrawViewShell->GetPageTabControl()->SetCurPageId(nPageNumber+1);
}
- */
}
}
@@ -215,7 +258,7 @@ void CurrentSlideManager::SetCurrentSlideAtXController (const SharedPageDescript
aPage);
}
}
- catch (beans::UnknownPropertyException aException)
+ catch (Exception aException)
{
// We have not been able to set the current page at the main view.
// This is sad but still leaves us in a valid state. Therefore,
@@ -246,11 +289,31 @@ void CurrentSlideManager::HandleModelChange (void)
{
if (mnCurrentSlideIndex >= 0)
{
- mpCurrentSlide = mrSlideSorter.GetModel().GetPageDescriptor(
- mnCurrentSlideIndex);
+ mpCurrentSlide = mrSlideSorter.GetModel().GetPageDescriptor(mnCurrentSlideIndex);
if (mpCurrentSlide.get() != NULL)
- mpCurrentSlide->SetIsCurrentPage(true);
+ mrSlideSorter.GetView().SetState(mpCurrentSlide, PageDescriptor::ST_Current, true);
}
}
+
+
+
+IMPL_LINK(CurrentSlideManager, SwitchPageCallback, void*, EMPTYARG)
+{
+ if (mpCurrentSlide)
+ {
+ // Set current page. At the moment we have to do this in two
+ // different ways. The UNO way is the preferable one but, alas,
+ // it does not work always correctly (after some kinds of model
+ // changes). Therefore, we call DrawViewShell::SwitchPage(),
+ // too.
+ ViewShell* pViewShell = mrSlideSorter.GetViewShell();
+ if (pViewShell==NULL || ! pViewShell->IsMainViewShell())
+ SetCurrentSlideAtViewShellBase(mpCurrentSlide);
+ SetCurrentSlideAtXController(mpCurrentSlide);
+ }
+
+ return 1;
+}
+
} } } // end of namespace ::sd::slidesorter::controller
diff --git a/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.cxx b/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.cxx
new file mode 100644
index 000000000000..88b294f3202f
--- /dev/null
+++ b/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.cxx
@@ -0,0 +1,199 @@
+/*************************************************************************
+ *
+ * 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 "precompiled_sd.hxx"
+
+#include "SlsDragAndDropContext.hxx"
+
+#include "SlideSorter.hxx"
+#include "model/SlideSorterModel.hxx"
+#include "model/SlsPageEnumerationProvider.hxx"
+#include "view/SlideSorterView.hxx"
+#include "controller/SlideSorterController.hxx"
+#include "controller/SlsInsertionIndicatorHandler.hxx"
+#include "controller/SlsScrollBarManager.hxx"
+#include "controller/SlsProperties.hxx"
+#include "controller/SlsSelectionFunction.hxx"
+#include "controller/SlsSelectionManager.hxx"
+#include "controller/SlsTransferable.hxx"
+#include "DrawDocShell.hxx"
+#include "drawdoc.hxx"
+#include "app.hrc"
+#include <sfx2/bindings.hxx>
+#include <boost/bind.hpp>
+
+namespace sd { namespace slidesorter { namespace controller {
+
+DragAndDropContext::DragAndDropContext (SlideSorter& rSlideSorter)
+ : mpTargetSlideSorter(&rSlideSorter),
+ mnInsertionIndex(-1)
+{
+ ::std::vector<const SdPage*> aPages;
+
+ // No Drag-and-Drop for master pages.
+ if (rSlideSorter.GetModel().GetEditMode() != EM_PAGE)
+ return;
+
+ rSlideSorter.GetController().GetInsertionIndicatorHandler()->UpdateIndicatorIcon(
+ dynamic_cast<Transferable*>(SD_MOD()->pTransferDrag));
+}
+
+
+
+
+DragAndDropContext::~DragAndDropContext (void)
+{
+ SetTargetSlideSorter (NULL, Point(0,0), InsertionIndicatorHandler::UnknownMode, false);
+}
+
+
+
+
+void DragAndDropContext::GetPagesFromBookmarks (
+ ::std::vector<const SdPage*>& rPages,
+ sal_Int32& rnSelectionCount,
+ DrawDocShell* pDocShell,
+ const List& rBookmarks) const
+{
+ if (pDocShell == NULL)
+ return;
+
+ const SdDrawDocument* pDocument = pDocShell->GetDoc();
+ if (pDocument == NULL)
+ return;
+
+ for (ULONG nIndex=0,nCount=rBookmarks.Count(); nIndex<nCount; ++nIndex)
+ {
+ const String sPageName (*static_cast<String*>(rBookmarks.GetObject(nIndex)));
+ BOOL bIsMasterPage (FALSE);
+ const USHORT nPageIndex (pDocument->GetPageByName(sPageName, bIsMasterPage));
+ if (nPageIndex == SDRPAGE_NOTFOUND)
+ continue;
+
+ const SdPage* pPage = dynamic_cast<const SdPage*>(pDocument->GetPage(nPageIndex));
+ if (pPage != NULL)
+ rPages.push_back(pPage);
+ }
+ rnSelectionCount = rBookmarks.Count();
+}
+
+
+
+
+void DragAndDropContext::GetPagesFromSelection (
+ ::std::vector<const SdPage*>& rPages,
+ sal_Int32& rnSelectionCount,
+ model::PageEnumeration& rSelection) const
+{
+ // Show a new substitution for the selected page objects.
+ rnSelectionCount = 0;
+
+ while (rSelection.HasMoreElements())
+ {
+ model::SharedPageDescriptor pDescriptor (rSelection.GetNextElement());
+ if (rPages.size() < 3)
+ rPages.push_back(pDescriptor->GetPage());
+ ++rnSelectionCount;
+ }
+}
+
+
+
+
+void DragAndDropContext::Dispose (void)
+{
+ mnInsertionIndex = -1;
+}
+
+
+
+
+void DragAndDropContext::UpdatePosition (
+ const Point& rMousePosition,
+ const InsertionIndicatorHandler::Mode eMode,
+ const bool bAllowAutoScroll)
+{
+ if (mpTargetSlideSorter == NULL)
+ return;
+
+ if (mpTargetSlideSorter->GetProperties()->IsUIReadOnly())
+ return;
+
+ // Convert window coordinates into model coordinates (we need the
+ // window coordinates for auto-scrolling because that remains
+ // constant while scrolling.)
+ SharedSdWindow pWindow (mpTargetSlideSorter->GetContentWindow());
+ const Point aMouseModelPosition (pWindow->PixelToLogic(rMousePosition));
+ ::boost::shared_ptr<InsertionIndicatorHandler> pInsertionIndicatorHandler (
+ mpTargetSlideSorter->GetController().GetInsertionIndicatorHandler());
+
+ if ( ! (bAllowAutoScroll
+ && mpTargetSlideSorter->GetController().GetScrollBarManager().AutoScroll(
+ rMousePosition,
+ ::boost::bind(
+ &DragAndDropContext::UpdatePosition, this, rMousePosition, eMode, false))))
+ {
+ pInsertionIndicatorHandler->UpdatePosition(aMouseModelPosition, eMode);
+
+ // Remember the new insertion index.
+ mnInsertionIndex = pInsertionIndicatorHandler->GetInsertionPageIndex();
+ if (pInsertionIndicatorHandler->IsInsertionTrivial(mnInsertionIndex, eMode))
+ mnInsertionIndex = -1;
+ }
+}
+
+
+
+
+void DragAndDropContext::SetTargetSlideSorter (
+ SlideSorter* pSlideSorter,
+ const Point aMousePosition,
+ const InsertionIndicatorHandler::Mode eMode,
+ const bool bIsOverSourceView)
+{
+ if (mpTargetSlideSorter != NULL)
+ {
+ mpTargetSlideSorter->GetController().GetScrollBarManager().StopAutoScroll();
+ mpTargetSlideSorter->GetController().GetInsertionIndicatorHandler()->End(
+ Animator::AM_Animated);
+ }
+
+ mpTargetSlideSorter = pSlideSorter;
+
+ if (mpTargetSlideSorter != NULL)
+ {
+ mpTargetSlideSorter->GetController().GetInsertionIndicatorHandler()->Start(
+ bIsOverSourceView);
+ mpTargetSlideSorter->GetController().GetInsertionIndicatorHandler()->UpdatePosition(
+ aMousePosition,
+ eMode);
+
+ }
+}
+
+
+} } } // end of namespace ::sd::slidesorter::controller
diff --git a/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.hxx b/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.hxx
new file mode 100644
index 000000000000..7536f88d9474
--- /dev/null
+++ b/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.hxx
@@ -0,0 +1,100 @@
+/*************************************************************************
+ *
+ * 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_SUBSTITUTION_HANDLER_HXX
+#define SD_SLIDESORTER_SUBSTITUTION_HANDLER_HXX
+
+#include <tools/gen.hxx>
+
+#include "model/SlsSharedPageDescriptor.hxx"
+#include "controller/SlsInsertionIndicatorHandler.hxx"
+#include <vector>
+
+
+namespace sd { namespace slidesorter {
+class SlideSorter;
+} }
+
+
+
+namespace sd { namespace slidesorter { namespace controller {
+
+/** A DragAndDropContext object handles an active drag and drop operation.
+ When the mouse is moved from one slide sorter window to another the
+ target SlideSorter object is exchanged accordingly.
+*/
+class DragAndDropContext
+{
+public:
+ /** Create a substitution display of the currently selected pages or,
+ when provided, the pages in the transferable.
+ */
+ DragAndDropContext (SlideSorter& rSlideSorter);
+ ~DragAndDropContext (void);
+
+ /** Call this method (for example as reaction to ESC key press) to avoid
+ processing (ie moving or inserting) the substition when the called
+ DragAndDropContext object is destroyed.
+ */
+ void Dispose (void);
+
+ /** Move the substitution display by the distance the mouse has
+ travelled since the last call to this method or to
+ CreateSubstitution(). The given point becomes the new anchor.
+ */
+ void UpdatePosition (
+ const Point& rMousePosition,
+ const InsertionIndicatorHandler::Mode eMode,
+ const bool bAllowAutoScroll = true);
+
+ void SetTargetSlideSorter (
+ SlideSorter* pSlideSorter = NULL,
+ const Point aMousePosition = Point(0,0),
+ const InsertionIndicatorHandler::Mode eMode = InsertionIndicatorHandler::UnknownMode,
+ const bool bIsOverSourceView = false);
+
+private:
+ SlideSorter* mpTargetSlideSorter;
+ model::SharedPageDescriptor mpHitDescriptor;
+ sal_Int32 mnInsertionIndex;
+
+ void GetPagesFromBookmarks (
+ ::std::vector<const SdPage*>& rPages,
+ sal_Int32& rnSelectionCount,
+ DrawDocShell* pDocShell,
+ const List& rBookmarks) const;
+ void GetPagesFromSelection (
+ ::std::vector<const SdPage*>& rPages,
+ sal_Int32& rnSelectionCount,
+ model::PageEnumeration& rSelection) const;
+};
+
+
+
+} } } // end of namespace ::sd::slidesorter::controller
+
+#endif
diff --git a/sd/source/ui/slidesorter/controller/SlsFocusManager.cxx b/sd/source/ui/slidesorter/controller/SlsFocusManager.cxx
index dcda73d38dba..445354cd9830 100755
--- a/sd/source/ui/slidesorter/controller/SlsFocusManager.cxx
+++ b/sd/source/ui/slidesorter/controller/SlsFocusManager.cxx
@@ -31,7 +31,8 @@
#include "SlideSorter.hxx"
#include "PaneDockingWindow.hxx"
#include "controller/SlideSorterController.hxx"
-#include "controller/SlsSelectionManager.hxx"
+#include "controller/SlsCurrentSlideManager.hxx"
+#include "controller/SlsVisibleAreaManager.hxx"
#include "model/SlideSorterModel.hxx"
#include "model/SlsPageDescriptor.hxx"
#include "view/SlideSorterView.hxx"
@@ -41,12 +42,15 @@
#include "Window.hxx"
#include "sdpage.hxx"
+#define UNIFY_FOCUS_AND_CURRENT_PAGE
+
namespace sd { namespace slidesorter { namespace controller {
FocusManager::FocusManager (SlideSorter& rSlideSorter)
: mrSlideSorter(rSlideSorter),
mnPageIndex(0),
- mbPageIsFocused(false)
+ mbPageIsFocused(false),
+ mbIsVerticalWrapActive(false)
{
if (mrSlideSorter.GetModel().GetPageCount() > 0)
mnPageIndex = 0;
@@ -68,69 +72,101 @@ void FocusManager::MoveFocus (FocusMoveDirection eDirection)
{
HideFocusIndicator (GetFocusedPageDescriptor());
- int nColumnCount (mrSlideSorter.GetView().GetLayouter().GetColumnCount());
+ const sal_Int32 nColumnCount (mrSlideSorter.GetView().GetLayouter().GetColumnCount());
+ const sal_Int32 nPageCount (mrSlideSorter.GetModel().GetPageCount());
switch (eDirection)
{
case FMD_NONE:
- if (mnPageIndex >= mrSlideSorter.GetModel().GetPageCount())
- mnPageIndex = mrSlideSorter.GetModel().GetPageCount() - 1;
+ // Nothing to be done.
break;
case FMD_LEFT:
- mnPageIndex -= 1;
- if (mnPageIndex < 0)
- {
- mnPageIndex = mrSlideSorter.GetModel().GetPageCount() - 1;
- SetFocusToToolBox();
- }
+ if (mnPageIndex > 0)
+ mnPageIndex -= 1;
+ else if (mbIsVerticalWrapActive)
+ mnPageIndex = nPageCount-1;
break;
case FMD_RIGHT:
- mnPageIndex += 1;
- if (mnPageIndex >= mrSlideSorter.GetModel().GetPageCount())
- {
+ if (mnPageIndex < nPageCount-1)
+ mnPageIndex += 1;
+ else if (mbIsVerticalWrapActive)
mnPageIndex = 0;
- SetFocusToToolBox();
- }
break;
case FMD_UP:
{
- int nColumn = mnPageIndex % nColumnCount;
- mnPageIndex -= nColumnCount;
- if (mnPageIndex < 0)
+ const sal_Int32 nCandidate (mnPageIndex - nColumnCount);
+ if (nCandidate < 0)
{
- // Wrap arround to the bottom row or the one above and
- // go to the correct column.
- int nCandidate = mrSlideSorter.GetModel().GetPageCount()-1;
- int nCandidateColumn = nCandidate % nColumnCount;
- if (nCandidateColumn > nColumn)
- mnPageIndex = nCandidate - (nCandidateColumn-nColumn);
- else if (nCandidateColumn < nColumn)
- mnPageIndex = nCandidate
- - nColumnCount
- + (nColumn - nCandidateColumn);
- else
- mnPageIndex = nCandidate;
+ if (mbIsVerticalWrapActive)
+ {
+ // Wrap arround to the bottom row or the one above
+ // and go to the correct column.
+ const sal_Int32 nLastIndex (nPageCount-1);
+ const sal_Int32 nLastColumn (nLastIndex % nColumnCount);
+ const sal_Int32 nCurrentColumn (mnPageIndex%nColumnCount);
+ if (nLastColumn >= nCurrentColumn)
+ {
+ // The last row contains the current column.
+ mnPageIndex = nLastIndex - (nLastColumn-nCurrentColumn);
+ }
+ else
+ {
+ // Only the second to last row contains the current column.
+ mnPageIndex = nLastIndex - nLastColumn
+ - nColumnCount
+ + nCurrentColumn;
+ }
+ }
+ }
+ else
+ {
+ // Move the focus the previous row.
+ mnPageIndex = nCandidate;
}
}
break;
case FMD_DOWN:
{
- int nColumn = mnPageIndex % nColumnCount;
- mnPageIndex += nColumnCount;
- if (mnPageIndex >= mrSlideSorter.GetModel().GetPageCount())
+ const sal_Int32 nCandidate (mnPageIndex + nColumnCount);
+ if (nCandidate >= nPageCount)
+ {
+ if (mbIsVerticalWrapActive)
+ {
+ // Wrap arround to the correct column.
+ mnPageIndex = mnPageIndex % nColumnCount;
+ }
+ else
+ {
+ // Do not move the focus.
+ }
+ }
+ else
{
- // Wrap arround to the correct column.
- mnPageIndex = nColumn;
+ // Move the focus to the next row.
+ mnPageIndex = nCandidate;
}
}
break;
}
+ if (mnPageIndex < 0)
+ {
+ OSL_ASSERT(mnPageIndex>=0);
+ mnPageIndex = 0;
+ }
+ else if (mnPageIndex >= nPageCount)
+ {
+ OSL_ASSERT(mnPageIndex<nPageCount);
+ mnPageIndex = nPageCount - 1;
+ }
+
if (mbPageIsFocused)
+ {
ShowFocusIndicator(GetFocusedPageDescriptor(), true);
+ }
}
}
@@ -172,7 +208,7 @@ bool FocusManager::ToggleFocus (void)
bool FocusManager::HasFocus (void) const
{
- return mrSlideSorter.GetView().GetWindow()->HasFocus();
+ return mrSlideSorter.GetContentWindow()->HasFocus();
}
@@ -193,7 +229,7 @@ sal_Int32 FocusManager::GetFocusedPageIndex (void) const
-
+/*
void FocusManager::FocusPage (sal_Int32 nPageIndex)
{
if (nPageIndex != mnPageIndex)
@@ -206,7 +242,7 @@ void FocusManager::FocusPage (sal_Int32 nPageIndex)
if (HasFocus() && !IsFocusShowing())
ShowFocus();
}
-
+*/
@@ -231,6 +267,14 @@ void FocusManager::SetFocusedPage (sal_Int32 nPageIndex)
+void FocusManager::SetFocusedPageToCurrentPage (void)
+{
+ SetFocusedPage(mrSlideSorter.GetController().GetCurrentSlideManager()->GetCurrentSlide());
+}
+
+
+
+
bool FocusManager::IsFocusShowing (void) const
{
return HasFocus() && mbPageIsFocused;
@@ -243,8 +287,7 @@ void FocusManager::HideFocusIndicator (const model::SharedPageDescriptor& rpDesc
{
if (rpDescriptor.get() != NULL)
{
- rpDescriptor->RemoveFocus();
- mrSlideSorter.GetView().RequestRepaint(rpDescriptor);
+ mrSlideSorter.GetView().SetState(rpDescriptor, model::PageDescriptor::ST_Focused, false);
}
}
@@ -257,21 +300,16 @@ void FocusManager::ShowFocusIndicator (
{
if (rpDescriptor.get() != NULL)
{
- rpDescriptor->SetFocus ();
+ mrSlideSorter.GetView().SetState(rpDescriptor, model::PageDescriptor::ST_Focused, true);
if (bScrollToFocus)
{
// Scroll the focused page object into the visible area and repaint
// it, so that the focus indicator becomes visible.
- view::SlideSorterView& rView (mrSlideSorter.GetView());
- mrSlideSorter.GetController().GetSelectionManager()->MakeRectangleVisible (
- rView.GetPageBoundingBox (
- GetFocusedPageDescriptor(),
- view::SlideSorterView::CS_MODEL,
- view::SlideSorterView::BBT_INFO));
+ mrSlideSorter.GetController().GetVisibleAreaManager().RequestVisible(rpDescriptor,true);
}
+ mrSlideSorter.GetView().RequestRepaint(rpDescriptor);
- mrSlideSorter.GetView().RequestRepaint (rpDescriptor);
NotifyFocusChangeListeners();
}
}
diff --git a/sd/source/ui/slidesorter/controller/SlsHideSlideFunction.cxx b/sd/source/ui/slidesorter/controller/SlsHideSlideFunction.cxx
index 666d4b017302..dbb65b0f657a 100644..100755
--- a/sd/source/ui/slidesorter/controller/SlsHideSlideFunction.cxx
+++ b/sd/source/ui/slidesorter/controller/SlsHideSlideFunction.cxx
@@ -109,8 +109,10 @@ void HideSlideFunction::DoExecute (SfxRequest& rRequest)
while (aSelectedPages.HasMoreElements())
{
model::SharedPageDescriptor pDescriptor (aSelectedPages.GetNextElement());
- pDescriptor->GetPage()->SetExcluded (eState==EXCLUDED);
- static_cast<view::SlideSorterView*>(mpView)->RequestRepaint(pDescriptor);
+ static_cast<view::SlideSorterView*>(mpView)->SetState(
+ pDescriptor,
+ model::PageDescriptor::ST_Excluded,
+ eState==EXCLUDED);
}
}
diff --git a/sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx b/sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx
new file mode 100644
index 000000000000..882adab932a8
--- /dev/null
+++ b/sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx
@@ -0,0 +1,327 @@
+/*************************************************************************
+ *
+ * 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 "precompiled_sd.hxx"
+
+#include "controller/SlsInsertionIndicatorHandler.hxx"
+#include "controller/SlsProperties.hxx"
+#include "view/SlideSorterView.hxx"
+#include "view/SlsLayouter.hxx"
+#include "view/SlsInsertionIndicatorOverlay.hxx"
+#include "model/SlideSorterModel.hxx"
+#include "model/SlsPageEnumerationProvider.hxx"
+#include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
+
+#include "SlideSorter.hxx"
+
+using namespace ::com::sun::star::datatransfer::dnd::DNDConstants;
+
+namespace sd { namespace slidesorter { namespace controller {
+
+
+InsertionIndicatorHandler::InsertionIndicatorHandler (SlideSorter& rSlideSorter)
+ : mrSlideSorter(rSlideSorter),
+ mpInsertAnimator(),
+ mpInsertionIndicatorOverlay(new view::InsertionIndicatorOverlay(rSlideSorter)),
+ maInsertPosition(),
+ meMode(MoveMode),
+ mbIsActive(false),
+ mbIsReadOnly(mrSlideSorter.GetModel().IsReadOnly()),
+ mbIsOverSourceView(true),
+ maIconSize(0,0),
+ mbIsForcedShow(false)
+{
+}
+
+
+
+
+InsertionIndicatorHandler::~InsertionIndicatorHandler (void)
+{
+}
+
+
+
+
+void InsertionIndicatorHandler::Start (const bool bIsOverSourceView)
+{
+ if (mbIsActive)
+ {
+ OSL_ASSERT(!mbIsActive);
+ }
+
+ mbIsReadOnly = mrSlideSorter.GetModel().IsReadOnly();
+ if (mbIsReadOnly)
+ return;
+
+ mbIsActive = true;
+ mbIsOverSourceView = bIsOverSourceView;
+}
+
+
+
+
+void InsertionIndicatorHandler::End (const controller::Animator::AnimationMode eMode)
+{
+ if (mbIsForcedShow || ! mbIsActive || mbIsReadOnly)
+ return;
+
+ GetInsertAnimator()->Reset(eMode);
+
+ mbIsActive = false;
+ // maInsertPosition = view::InsertPosition();
+ meMode = UnknownMode;
+
+ mpInsertionIndicatorOverlay->Hide();
+ mpInsertionIndicatorOverlay.reset(new view::InsertionIndicatorOverlay(mrSlideSorter));
+}
+
+
+
+
+void InsertionIndicatorHandler::ForceShow (void)
+{
+ mbIsForcedShow = true;
+}
+
+
+
+
+void InsertionIndicatorHandler::ForceEnd (void)
+{
+ mbIsForcedShow = false;
+ End(Animator::AM_Immediate);
+}
+
+
+
+
+void InsertionIndicatorHandler::UpdateIndicatorIcon (const Transferable* pTransferable)
+{
+ mpInsertionIndicatorOverlay->Create(pTransferable);
+ maIconSize = mpInsertionIndicatorOverlay->GetSize();
+}
+
+
+
+
+InsertionIndicatorHandler::Mode InsertionIndicatorHandler::GetModeFromDndAction (
+ const sal_Int8 nDndAction)
+{
+ if ((nDndAction & ACTION_MOVE) != 0)
+ return MoveMode;
+ else if ((nDndAction & ACTION_COPY) != 0)
+ return CopyMode;
+ else
+ return UnknownMode;
+}
+
+
+
+
+void InsertionIndicatorHandler::UpdatePosition (
+ const Point& rMouseModelPosition,
+ const Mode eMode)
+{
+ if ( ! mbIsActive)
+ return;
+
+ if (mbIsReadOnly)
+ return;
+
+ SetPosition(rMouseModelPosition, eMode);
+}
+
+
+
+
+void InsertionIndicatorHandler::UpdatePosition (
+ const Point& rMouseModelPosition,
+ const sal_Int8 nDndAction)
+{
+ UpdatePosition(rMouseModelPosition, GetModeFromDndAction(nDndAction));
+}
+
+
+
+
+bool InsertionIndicatorHandler::IsActive (void) const
+{
+ return mbIsActive;
+}
+
+
+
+
+sal_Int32 InsertionIndicatorHandler::GetInsertionPageIndex (void) const
+{
+ if (mbIsReadOnly)
+ return -1;
+ else
+ return maInsertPosition.GetIndex();
+}
+
+
+
+
+void InsertionIndicatorHandler::SetPosition (
+ const Point& rPoint,
+ const Mode eMode)
+{
+ view::Layouter& rLayouter (mrSlideSorter.GetView().GetLayouter());
+
+ const view::InsertPosition aInsertPosition (rLayouter.GetInsertPosition(
+ rPoint,
+ maIconSize,
+ mrSlideSorter.GetModel()));
+
+ static sal_Int32 TargetIndex (1);
+ if (aInsertPosition.GetIndex() == TargetIndex)
+ {
+ const view::InsertPosition aPosition (rLayouter.GetInsertPosition(
+ rPoint,
+ maIconSize,
+ mrSlideSorter.GetModel()));
+ const view::InsertPosition aPosition2 (rLayouter.GetInsertPosition(
+ rPoint,
+ maIconSize,
+ mrSlideSorter.GetModel()));
+ }
+
+ if (maInsertPosition != aInsertPosition
+ || meMode != eMode
+ // || ! mpInsertionIndicatorOverlay->IsVisible()
+ )
+ {
+ maInsertPosition = aInsertPosition;
+ meMode = eMode;
+ mbIsInsertionTrivial = IsInsertionTrivial(maInsertPosition.GetIndex(), eMode);
+ if (maInsertPosition.GetIndex()>=0 && ! mbIsInsertionTrivial)
+ {
+ mpInsertionIndicatorOverlay->SetLocation(maInsertPosition.GetLocation());
+
+ GetInsertAnimator()->SetInsertPosition(maInsertPosition);
+ mpInsertionIndicatorOverlay->Show();
+ }
+ else
+ {
+ GetInsertAnimator()->Reset(Animator::AM_Animated);
+ mpInsertionIndicatorOverlay->Hide();
+ }
+ }
+}
+
+
+
+
+::boost::shared_ptr<view::InsertAnimator> InsertionIndicatorHandler::GetInsertAnimator (void)
+{
+ if ( ! mpInsertAnimator)
+ mpInsertAnimator.reset(new view::InsertAnimator(mrSlideSorter));
+ return mpInsertAnimator;
+}
+
+
+
+
+bool InsertionIndicatorHandler::IsInsertionTrivial (
+ const sal_Int32 nInsertionIndex,
+ const Mode eMode) const
+{
+ if (eMode == CopyMode)
+ return false;
+ else if (eMode == UnknownMode)
+ return true;
+
+ if ( ! mbIsOverSourceView)
+ return false;
+
+ // Iterate over all selected pages and check whether there are
+ // holes. While we do this we remember the indices of the first and
+ // last selected page as preparation for the next step.
+ sal_Int32 nCurrentIndex = -1;
+ sal_Int32 nFirstIndex = -1;
+ sal_Int32 nLastIndex = -1;
+ model::PageEnumeration aSelectedPages (
+ model::PageEnumerationProvider::CreateSelectedPagesEnumeration(
+ mrSlideSorter.GetModel()));
+ while (aSelectedPages.HasMoreElements())
+ {
+ model::SharedPageDescriptor pDescriptor (aSelectedPages.GetNextElement());
+
+ // Get the page number and compare it to the last one.
+ const sal_Int32 nPageNumber (pDescriptor->GetPageIndex());
+ if (nCurrentIndex>=0 && nPageNumber>(nCurrentIndex+1))
+ return false;
+ else
+ nCurrentIndex = nPageNumber;
+
+ // Remember indices of the first and last page of the selection.
+ if (nFirstIndex == -1)
+ nFirstIndex = nPageNumber;
+ nLastIndex = nPageNumber;
+ }
+
+ // When we come here then the selection has no holes. We still have
+ // to check that the insertion position is not directly in front or
+ // directly behind the selection and thus moving the selection there
+ // would not change the model.
+ if (nInsertionIndex<nFirstIndex || nInsertionIndex>(nLastIndex+1))
+ return false;
+
+ return true;
+}
+
+
+
+
+bool InsertionIndicatorHandler::IsInsertionTrivial (const sal_Int8 nDndAction)
+{
+ return IsInsertionTrivial(GetInsertionPageIndex(), GetModeFromDndAction(nDndAction));
+}
+
+
+
+
+//===== InsertionIndicatorHandler::ForceShowContext ===========================
+
+InsertionIndicatorHandler::ForceShowContext::ForceShowContext (
+ const ::boost::shared_ptr<InsertionIndicatorHandler>& rpHandler)
+ : mpHandler(rpHandler)
+{
+ mpHandler->ForceShow();
+}
+
+
+
+
+InsertionIndicatorHandler::ForceShowContext::~ForceShowContext (void)
+{
+ mpHandler->ForceEnd();
+}
+
+} } } // end of namespace ::sd::slidesorter::controller
diff --git a/sd/source/ui/slidesorter/controller/SlsListener.cxx b/sd/source/ui/slidesorter/controller/SlsListener.cxx
index 94b3b4afe717..9f1218013e16 100755
--- a/sd/source/ui/slidesorter/controller/SlsListener.cxx
+++ b/sd/source/ui/slidesorter/controller/SlsListener.cxx
@@ -25,8 +25,8 @@
*
************************************************************************/
-// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sd.hxx"
+
#include "SlsListener.hxx"
#include "SlideSorter.hxx"
@@ -35,9 +35,15 @@
#include "controller/SlideSorterController.hxx"
#include "controller/SlsPageSelector.hxx"
#include "controller/SlsCurrentSlideManager.hxx"
+#include "controller/SlsSelectionManager.hxx"
+#include "controller/SlsSelectionObserver.hxx"
#include "model/SlideSorterModel.hxx"
+#include "model/SlsPageEnumerationProvider.hxx"
#include "view/SlideSorterView.hxx"
+#include "cache/SlsPageCache.hxx"
+#include "cache/SlsPageCacheManager.hxx"
#include "drawdoc.hxx"
+#include "DrawDocShell.hxx"
#include "glob.hrc"
#include "ViewShellBase.hxx"
@@ -75,7 +81,8 @@ Listener::Listener (
mxFrameWeak(),
mpModelChangeLock()
{
- StartListening (*mrSlideSorter.GetModel().GetDocument());
+ StartListening(*mrSlideSorter.GetModel().GetDocument());
+ StartListening(*mrSlideSorter.GetModel().GetDocument()->GetDocSh());
mbListeningToDocument = true;
// Connect to the UNO document.
@@ -127,7 +134,7 @@ Listener::Listener (
if (pMainViewShell != NULL
&& pMainViewShell!=pViewShell)
{
- StartListening (*pMainViewShell);
+ StartListening(*pMainViewShell);
}
Link aLink (LINK(this, Listener, EventMultiplexerCallback));
@@ -157,7 +164,8 @@ void Listener::ReleaseListeners (void)
{
if (mbListeningToDocument)
{
- EndListening (*mrSlideSorter.GetModel().GetDocument());
+ EndListening(*mrSlideSorter.GetModel().GetDocument()->GetDocSh());
+ EndListening(*mrSlideSorter.GetModel().GetDocument());
mbListeningToDocument = false;
}
@@ -303,18 +311,15 @@ void Listener::Notify (
if (rHint.ISA(SdrHint))
{
SdrHint& rSdrHint (*PTR_CAST(SdrHint,&rHint));
- if(rSdrHint.GetKind() == HINT_PAGEORDERCHG )
+ switch (rSdrHint.GetKind())
{
- if (rBroadcaster.ISA(SdDrawDocument))
- {
- SdDrawDocument& rDocument (
- static_cast<SdDrawDocument&>(rBroadcaster));
- if (rDocument.GetMasterSdPageCount(PK_STANDARD)
- == rDocument.GetMasterSdPageCount(PK_NOTES))
- {
- mrController.HandleModelChange();
- }
- }
+ case HINT_PAGEORDERCHG:
+ if (&rBroadcaster == mrSlideSorter.GetModel().GetDocument())
+ HandleModelChange(rSdrHint.GetPage());
+ break;
+
+ default:
+ break;
}
}
else if (rHint.ISA(ViewShellHint))
@@ -351,6 +356,16 @@ void Listener::Notify (
break;
}
}
+ else if (rHint.ISA(SfxSimpleHint))
+ {
+ SfxSimpleHint& rSfxSimpleHint (*PTR_CAST(SfxSimpleHint,&rHint));
+ switch (rSfxSimpleHint.GetId())
+ {
+ case SFX_HINT_DOCCHANGED:
+ mrController.CheckForMasterPageAssignment();
+ break;
+ }
+ }
}
@@ -392,7 +407,7 @@ IMPL_LINK(Listener, EventMultiplexerCallback, ::sd::tools::EventMultiplexerEvent
case tools::EventMultiplexerEvent::EID_CONTROLLER_ATTACHED:
{
ConnectToController();
- mrController.GetPageSelector().UpdateAllPages();
+ // mrController.GetPageSelector().GetCoreSelection();
UpdateEditMode();
}
break;
@@ -402,6 +417,12 @@ IMPL_LINK(Listener, EventMultiplexerCallback, ::sd::tools::EventMultiplexerEvent
DisconnectFromController();
break;
+ case tools::EventMultiplexerEvent::EID_SHAPE_CHANGED:
+ case tools::EventMultiplexerEvent::EID_SHAPE_INSERTED:
+ case tools::EventMultiplexerEvent::EID_SHAPE_REMOVED:
+ HandleShapeModification(static_cast<const SdrPage*>(pEvent->mpUserData));
+ break;
+
default:
break;
}
@@ -463,7 +484,7 @@ void SAL_CALL Listener::propertyChange (
static const ::rtl::OUString sEditModePropertyName (
RTL_CONSTASCII_USTRINGPARAM("IsMasterPageMode"));
- if (rEvent.PropertyName.equals (sCurrentPagePropertyName))
+ if (rEvent.PropertyName.equals(sCurrentPagePropertyName))
{
Any aCurrentPage = rEvent.NewValue;
Reference<beans::XPropertySet> xPageSet (aCurrentPage, UNO_QUERY);
@@ -475,13 +496,13 @@ void SAL_CALL Listener::propertyChange (
String(RTL_CONSTASCII_USTRINGPARAM("Number")));
sal_Int32 nCurrentPage = 0;
aPageNumber >>= nCurrentPage;
- mrController.GetPageSelector().UpdateAllPages ();
+ mrController.GetPageSelector().GetCoreSelection();
// The selection is already set but we call SelectPage()
// nevertheless in order to make the new current page the
// last recently selected page of the PageSelector. This is
// used when making the selection visible.
mrController.GetPageSelector().SelectPage(nCurrentPage-1);
- mrController.GetCurrentSlideManager()->CurrentSlideHasChanged(nCurrentPage-1);
+ mrController.GetCurrentSlideManager()->NotifyCurrentSlideChange(nCurrentPage-1);
}
catch (beans::UnknownPropertyException aEvent)
{
@@ -520,7 +541,7 @@ void SAL_CALL Listener::frameAction (const frame::FrameActionEvent& rEvent)
case frame::FrameAction_COMPONENT_REATTACHED:
{
ConnectToController();
- mrController.GetPageSelector().UpdateAllPages();
+ mrController.GetPageSelector().GetCoreSelection();
UpdateEditMode();
}
break;
@@ -580,6 +601,84 @@ void Listener::UpdateEditMode (void)
+void Listener::HandleModelChange (const SdrPage* pPage)
+{
+ // Notify model and selection observer about the page. The return value
+ // of the model call acts as filter as to which events to pass to the
+ // selection observer.
+ if (mrSlideSorter.GetModel().NotifyPageEvent(pPage))
+ {
+ // The page of the hint belongs (or belonged) to the model.
+
+ // Tell the cache manager that the preview bitmaps for a deleted
+ // page can be removed from all caches.
+ if (pPage!=NULL && ! pPage->IsInserted())
+ cache::PageCacheManager::Instance()->ReleasePreviewBitmap(pPage);
+
+ mrController.GetSelectionManager()->GetSelectionObserver()->NotifyPageEvent(pPage);
+ }
+
+ // Tell the controller about the model change only when the document is
+ // in a sane state, not just in the middle of a larger change.
+ SdDrawDocument* pDocument (mrSlideSorter.GetModel().GetDocument());
+ if (pDocument != NULL
+ && pDocument->GetMasterSdPageCount(PK_STANDARD) == pDocument->GetMasterSdPageCount(PK_NOTES))
+ {
+ // A model change can make updates of some text fields necessary
+ // (like page numbers and page count.) Invalidate all previews in
+ // the cache to cope with this. Doing this on demand would be a
+ // nice optimization.
+ cache::PageCacheManager::Instance()->InvalidateAllPreviewBitmaps(pDocument->getUnoModel());
+
+ mrController.HandleModelChange();
+ }
+}
+
+
+
+void Listener::HandleShapeModification (const SdrPage* pPage)
+{
+ if (pPage == NULL)
+ return;
+
+ // Invalidate the preview of the page (in all slide sorters that display
+ // it.)
+ ::boost::shared_ptr<cache::PageCacheManager> pCacheManager (cache::PageCacheManager::Instance());
+ if ( ! pCacheManager)
+ return;
+ SdDrawDocument* pDocument = mrSlideSorter.GetModel().GetDocument();
+ if (pDocument == NULL)
+ {
+ OSL_ASSERT(pDocument!=NULL);
+ return;
+ }
+ pCacheManager->InvalidatePreviewBitmap(pDocument->getUnoModel(), pPage);
+ mrSlideSorter.GetView().GetPreviewCache()->RequestPreviewBitmap(pPage);
+
+ // When the page is a master page then invalidate the previews of all
+ // pages that are linked to this master page.
+ if (pPage->IsMasterPage())
+ {
+ for (USHORT nIndex=0,nCount=pDocument->GetSdPageCount(PK_STANDARD);
+ nIndex<nCount;
+ ++nIndex)
+ {
+ const SdPage* pCandidate = pDocument->GetSdPage(nIndex, PK_STANDARD);
+ if (pCandidate!=NULL && pCandidate->TRG_HasMasterPage())
+ {
+ if (&pCandidate->TRG_GetMasterPage() == pPage)
+ pCacheManager->InvalidatePreviewBitmap(pDocument->getUnoModel(), pCandidate);
+ }
+ else
+ {
+ OSL_ASSERT(pCandidate!=NULL && pCandidate->TRG_HasMasterPage());
+ }
+ }
+ }
+}
+
+
+
void Listener::ThrowIfDisposed (void)
throw (::com::sun::star::lang::DisposedException)
diff --git a/sd/source/ui/slidesorter/controller/SlsListener.hxx b/sd/source/ui/slidesorter/controller/SlsListener.hxx
index 5613452a1b59..7f65435ff738 100644..100755
--- a/sd/source/ui/slidesorter/controller/SlsListener.hxx
+++ b/sd/source/ui/slidesorter/controller/SlsListener.hxx
@@ -31,9 +31,7 @@
#include "MutexOwner.hxx"
#include "controller/SlideSorterController.hxx"
#include <com/sun/star/document/XEventListener.hpp>
-#ifndef _COM_SUN_STAR_DOCUMENT_XPROPERTYCHANGELISTENER_HPP_
#include <com/sun/star/beans/XPropertyChangeListener.hpp>
-#endif
#include <com/sun/star/accessibility/XAccessibleEventListener.hpp>
#include <com/sun/star/lang/DisposedException.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
@@ -171,6 +169,17 @@ private:
*/
void UpdateEditMode (void);
+ /** Handle a change in the order of slides or when the set of slides has
+ changed, i.e. a slide has been created.
+ */
+ void HandleModelChange (const SdrPage* pPage);
+
+ /** Handle a modification to a shape on the given page. When this is a
+ regular page then update its preview. When it is a master page then
+ additionally update the previews of all pages linked to it.
+ */
+ void HandleShapeModification (const SdrPage* pPage);
+
/** This method throws a DisposedException when the object has already been
disposed.
*/
diff --git a/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx b/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx
index 0e8f5e100d1c..51eb81fae214 100755..100644
--- a/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx
+++ b/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx
@@ -33,6 +33,9 @@
#include "SlideSorterViewShell.hxx"
#include "controller/SlideSorterController.hxx"
#include "controller/SlsSelectionManager.hxx"
+#include "controller/SlsAnimator.hxx"
+#include "controller/SlsCurrentSlideManager.hxx"
+#include "controller/SlsVisibleAreaManager.hxx"
#include "model/SlsPageDescriptor.hxx"
#include "model/SlsPageEnumerationProvider.hxx"
#include "model/SlideSorterModel.hxx"
@@ -44,14 +47,16 @@
#include "ViewShellBase.hxx"
#include <com/sun/star/drawing/XDrawView.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
+#include <boost/bind.hpp>
+
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::sd::slidesorter::model;
using namespace ::sd::slidesorter::view;
-namespace sd { namespace slidesorter { namespace controller {
+namespace sd { namespace slidesorter { namespace controller {
PageSelector::PageSelector (SlideSorter& rSlideSorter)
: mrModel(rSlideSorter.GetModel()),
@@ -61,7 +66,10 @@ PageSelector::PageSelector (SlideSorter& rSlideSorter)
mnBroadcastDisableLevel(0),
mbSelectionChangeBroadcastPending(false),
mpMostRecentlySelectedPage(),
- mpSelectionAnchor()
+ mpSelectionAnchor(),
+ mpCurrentPage(),
+ mnUpdateLockCount(0),
+ mbIsUpdateCurrentPagePending(false)
{
CountSelectedPages ();
}
@@ -71,9 +79,12 @@ PageSelector::PageSelector (SlideSorter& rSlideSorter)
void PageSelector::SelectAllPages (void)
{
+ VisibleAreaManager::TemporaryDisabler aDisabler (mrSlideSorter);
+ PageSelector::UpdateLock aLock (*this);
+
int nPageCount = mrModel.GetPageCount();
for (int nPageIndex=0; nPageIndex<nPageCount; nPageIndex++)
- SelectPage (nPageIndex);
+ SelectPage(nPageIndex);
}
@@ -81,21 +92,26 @@ void PageSelector::SelectAllPages (void)
void PageSelector::DeselectAllPages (void)
{
+ VisibleAreaManager::TemporaryDisabler aDisabler (mrSlideSorter);
+ PageSelector::UpdateLock aLock (*this);
+
int nPageCount = mrModel.GetPageCount();
for (int nPageIndex=0; nPageIndex<nPageCount; nPageIndex++)
- DeselectPage (nPageIndex);
+ DeselectPage(nPageIndex);
+
DBG_ASSERT (mnSelectedPageCount==0,
"PageSelector::DeselectAllPages: the selected pages counter is not 0");
mnSelectedPageCount = 0;
- mpMostRecentlySelectedPage.reset();
mpSelectionAnchor.reset();
}
-void PageSelector::UpdateAllPages (void)
+void PageSelector::GetCoreSelection (void)
{
+ PageSelector::UpdateLock aLock (*this);
+
bool bSelectionHasChanged (true);
mnSelectedPageCount = 0;
model::PageEnumeration aAllPages (
@@ -103,13 +119,14 @@ void PageSelector::UpdateAllPages (void)
while (aAllPages.HasMoreElements())
{
model::SharedPageDescriptor pDescriptor (aAllPages.GetNextElement());
- if (pDescriptor->UpdateSelection())
+ if (pDescriptor->GetCoreSelection())
{
+ mrSlideSorter.GetController().GetVisibleAreaManager().RequestVisible(pDescriptor);
mrSlideSorter.GetView().RequestRepaint(pDescriptor);
bSelectionHasChanged = true;
}
- if (pDescriptor->IsSelected())
+ if (pDescriptor->HasState(PageDescriptor::ST_Selected))
mnSelectedPageCount++;
}
@@ -125,6 +142,20 @@ void PageSelector::UpdateAllPages (void)
+void PageSelector::SetCoreSelection (void)
+{
+ model::PageEnumeration aAllPages (
+ model::PageEnumerationProvider::CreateAllPagesEnumeration(mrModel));
+ while (aAllPages.HasMoreElements())
+ {
+ model::SharedPageDescriptor pDescriptor (aAllPages.GetNextElement());
+ pDescriptor->SetCoreSelection();
+ }
+}
+
+
+
+
void PageSelector::SelectPage (int nPageIndex)
{
SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nPageIndex));
@@ -137,7 +168,7 @@ void PageSelector::SelectPage (int nPageIndex)
void PageSelector::SelectPage (const SdPage* pPage)
{
- int nPageIndex = (pPage->GetPageNum()-1) / 2;
+ const sal_Int32 nPageIndex (mrModel.GetIndex(pPage));
SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nPageIndex));
if (pDescriptor.get()!=NULL && pDescriptor->GetPage()==pPage)
SelectPage(pDescriptor);
@@ -148,9 +179,11 @@ void PageSelector::SelectPage (const SdPage* pPage)
void PageSelector::SelectPage (const SharedPageDescriptor& rpDescriptor)
{
- if (rpDescriptor.get()!=NULL && rpDescriptor->Select())
+ if (rpDescriptor.get()!=NULL
+ && mrSlideSorter.GetView().SetState(rpDescriptor, PageDescriptor::ST_Selected, true))
{
- mnSelectedPageCount ++;
+ ++mnSelectedPageCount;
+ mrSlideSorter.GetController().GetVisibleAreaManager().RequestVisible(rpDescriptor,true);
mrSlideSorter.GetView().RequestRepaint(rpDescriptor);
mpMostRecentlySelectedPage = rpDescriptor;
@@ -161,27 +194,49 @@ void PageSelector::SelectPage (const SharedPageDescriptor& rpDescriptor)
mbSelectionChangeBroadcastPending = true;
else
mrController.GetSelectionManager()->SelectionHasChanged();
+ UpdateCurrentPage();
+
+ CheckConsistency();
}
}
-void PageSelector::DeselectPage (int nPageIndex)
+void PageSelector::DeselectPage (
+ int nPageIndex,
+ const bool bUpdateCurrentPage)
{
model::SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nPageIndex));
if (pDescriptor.get() != NULL)
- DeselectPage(pDescriptor);
+ DeselectPage(pDescriptor, bUpdateCurrentPage);
}
-void PageSelector::DeselectPage (const SharedPageDescriptor& rpDescriptor)
+void PageSelector::DeselectPage (
+ const SdPage* pPage,
+ const bool bUpdateCurrentPage)
{
- if (rpDescriptor.get()!=NULL && rpDescriptor->Deselect())
+ const sal_Int32 nPageIndex (mrModel.GetIndex(pPage));
+ SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nPageIndex));
+ if (pDescriptor.get()!=NULL && pDescriptor->GetPage()==pPage)
+ DeselectPage(pDescriptor, bUpdateCurrentPage);
+}
+
+
+
+
+void PageSelector::DeselectPage (
+ const SharedPageDescriptor& rpDescriptor,
+ const bool bUpdateCurrentPage)
+{
+ if (rpDescriptor.get()!=NULL
+ && mrSlideSorter.GetView().SetState(rpDescriptor, PageDescriptor::ST_Selected, false))
{
- mnSelectedPageCount --;
+ --mnSelectedPageCount;
+ mrSlideSorter.GetController().GetVisibleAreaManager().RequestVisible(rpDescriptor);
mrSlideSorter.GetView().RequestRepaint(rpDescriptor);
if (mpMostRecentlySelectedPage == rpDescriptor)
mpMostRecentlySelectedPage.reset();
@@ -189,6 +244,29 @@ void PageSelector::DeselectPage (const SharedPageDescriptor& rpDescriptor)
mbSelectionChangeBroadcastPending = true;
else
mrController.GetSelectionManager()->SelectionHasChanged();
+ if (bUpdateCurrentPage)
+ UpdateCurrentPage();
+
+ CheckConsistency();
+ }
+}
+
+
+
+
+void PageSelector::CheckConsistency (void) const
+{
+ int nSelectionCount (0);
+ for (int nPageIndex=0,nPageCount=mrModel.GetPageCount(); nPageIndex<nPageCount; nPageIndex++)
+ {
+ SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nPageIndex));
+ assert(pDescriptor);
+ if (pDescriptor->HasState(PageDescriptor::ST_Selected))
+ ++nSelectionCount;
+ }
+ if (nSelectionCount!=mnSelectedPageCount)
+ {
+ assert(nSelectionCount==mnSelectedPageCount);
}
}
@@ -199,7 +277,7 @@ bool PageSelector::IsPageSelected (int nPageIndex)
{
SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nPageIndex));
if (pDescriptor.get() != NULL)
- return pDescriptor->IsSelected();
+ return pDescriptor->HasState(PageDescriptor::ST_Selected);
else
return false;
}
@@ -223,30 +301,6 @@ int PageSelector::GetSelectedPageCount (void) const
-void PageSelector::PrepareModelChange (void)
-{
- DeselectAllPages ();
-}
-
-
-
-
-void PageSelector::HandleModelChange (void)
-{
- UpdateAllPages();
-}
-
-
-
-
-SharedPageDescriptor PageSelector::GetMostRecentlySelectedPage (void) const
-{
- return mpMostRecentlySelectedPage;
-}
-
-
-
-
SharedPageDescriptor PageSelector::GetSelectionAnchor (void) const
{
return mpSelectionAnchor;
@@ -270,13 +324,13 @@ void PageSelector::CountSelectedPages (void)
-void PageSelector::EnableBroadcasting (bool bMakeSelectionVisible)
+void PageSelector::EnableBroadcasting (void)
{
if (mnBroadcastDisableLevel > 0)
mnBroadcastDisableLevel --;
if (mnBroadcastDisableLevel==0 && mbSelectionChangeBroadcastPending)
{
- mrController.GetSelectionManager()->SelectionHasChanged(bMakeSelectionVisible);
+ mrController.GetSelectionManager()->SelectionHasChanged();
mbSelectionChangeBroadcastPending = false;
}
}
@@ -301,7 +355,7 @@ void PageSelector::DisableBroadcasting (void)
for (int nIndex=0; nIndex<nPageCount; nIndex++)
{
SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nIndex));
- if (pDescriptor.get()!=NULL && pDescriptor->IsSelected())
+ if (pDescriptor.get()!=NULL && pDescriptor->HasState(PageDescriptor::ST_Selected))
pSelection->push_back(pDescriptor->GetPage());
}
@@ -311,14 +365,124 @@ void PageSelector::DisableBroadcasting (void)
-void PageSelector::SetPageSelection (const ::boost::shared_ptr<PageSelection>& rpSelection)
+void PageSelector::SetPageSelection (
+ const ::boost::shared_ptr<PageSelection>& rpSelection,
+ const bool bUpdateCurrentPage)
{
PageSelection::const_iterator iPage;
for (iPage=rpSelection->begin(); iPage!=rpSelection->end(); ++iPage)
SelectPage(*iPage);
+ if (bUpdateCurrentPage)
+ UpdateCurrentPage();
}
+void PageSelector::UpdateCurrentPage (const bool bUpdateOnlyWhenPending)
+{
+ if (mnUpdateLockCount > 0)
+ {
+ mbIsUpdateCurrentPagePending = true;
+ return;
+ }
+
+ if ( ! mbIsUpdateCurrentPagePending && bUpdateOnlyWhenPending)
+ return;
+
+ mbIsUpdateCurrentPagePending = false;
+
+ // Make the first selected page the current page.
+ const sal_Int32 nPageCount (GetPageCount());
+ for (sal_Int32 nIndex=0; nIndex<nPageCount; ++nIndex)
+ {
+ SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nIndex));
+ if (pDescriptor && pDescriptor->HasState(PageDescriptor::ST_Selected))
+ {
+ // Switching the current slide normally sets also the selection
+ // to just the new current slide. To prevent that, we store
+ // (and at the end of this scope restore) the current selection.
+ ::boost::shared_ptr<PageSelection> pSelection (GetPageSelection());
+
+ mrController.GetCurrentSlideManager()->SwitchCurrentSlide(pDescriptor);
+
+ // Restore the selection and prevent a recursive call to
+ // UpdateCurrentPage().
+ SetPageSelection(pSelection, false);
+ return;
+ }
+ }
+
+ // No page is selected. Do not change the current slide.
+}
+
+
+
+
+//===== PageSelector::UpdateLock ==============================================
+
+PageSelector::UpdateLock::UpdateLock (SlideSorter& rSlideSorter)
+ : mpSelector(&rSlideSorter.GetController().GetPageSelector())
+{
+ ++mpSelector->mnUpdateLockCount;
+}
+
+
+
+
+PageSelector::UpdateLock::UpdateLock (PageSelector& rSelector)
+ : mpSelector(&rSelector)
+{
+ ++mpSelector->mnUpdateLockCount;
+}
+
+
+
+
+PageSelector::UpdateLock::~UpdateLock (void)
+{
+ Release();
+}
+
+void PageSelector::UpdateLock::Release (void)
+{
+ if (mpSelector != NULL)
+ {
+ --mpSelector->mnUpdateLockCount;
+ OSL_ASSERT(mpSelector->mnUpdateLockCount >= 0);
+ if (mpSelector->mnUpdateLockCount == 0)
+ mpSelector->UpdateCurrentPage(true);
+
+ mpSelector = NULL;
+ }
+}
+
+
+
+
+//===== PageSelector::BroadcastLock ==============================================
+
+PageSelector::BroadcastLock::BroadcastLock (SlideSorter& rSlideSorter)
+ : mrSelector(rSlideSorter.GetController().GetPageSelector())
+{
+ mrSelector.DisableBroadcasting();
+}
+
+
+
+
+PageSelector::BroadcastLock::BroadcastLock (PageSelector& rSelector)
+ : mrSelector(rSelector)
+{
+ mrSelector.DisableBroadcasting();
+}
+
+
+
+
+PageSelector::BroadcastLock::~BroadcastLock (void)
+{
+ mrSelector.EnableBroadcasting();
+}
+
} } } // end of namespace ::sd::slidesorter::controller
diff --git a/sd/source/ui/slidesorter/controller/SlsProperties.cxx b/sd/source/ui/slidesorter/controller/SlsProperties.cxx
index 7382d769bbe2..532047cfaefe 100644..100755
--- a/sd/source/ui/slidesorter/controller/SlsProperties.cxx
+++ b/sd/source/ui/slidesorter/controller/SlsProperties.cxx
@@ -37,13 +37,16 @@ Properties::Properties (void)
mbIsShowSelection(true),
mbIsShowFocus(true),
mbIsCenterSelection(false),
- mbIsSmoothSelectionScrolling(false),
+ mbIsSmoothSelectionScrolling(true),
mbIsSuspendPreviewUpdatesDuringFullScreenPresentation(true),
maBackgroundColor(Application::GetSettings().GetStyleSettings().GetWindowColor()),
maTextColor(Application::GetSettings().GetStyleSettings().GetActiveTextColor()),
- maSelectionColor(Application::GetSettings().GetStyleSettings().GetMenuHighlightColor()),
+ maSelectionColor(Application::GetSettings().GetStyleSettings().GetHighlightColor()),
maHighlightColor(Application::GetSettings().GetStyleSettings().GetMenuHighlightColor()),
- mbIsUIReadOnly(false)
+ mbIsUIReadOnly(false),
+ mbIsOnlyPreviewTriggersMouseOver(true),
+ mbIsHighContrastModeActive(
+ Application::GetSettings().GetStyleSettings().GetHighContrastMode())
{
}
@@ -57,6 +60,19 @@ Properties::~Properties (void)
+void Properties::HandleDataChangeEvent (void)
+{
+ maBackgroundColor = Application::GetSettings().GetStyleSettings().GetWindowColor();
+ maTextColor = Application::GetSettings().GetStyleSettings().GetActiveTextColor();
+ maSelectionColor = Application::GetSettings().GetStyleSettings().GetHighlightColor();
+ maHighlightColor = Application::GetSettings().GetStyleSettings().GetMenuHighlightColor();
+ mbIsHighContrastModeActive
+ = Application::GetSettings().GetStyleSettings().GetHighContrastMode();
+}
+
+
+
+
bool Properties::IsHighlightCurrentSlide (void) const
{
return mbIsHighlightCurrentSlide;
@@ -230,4 +246,28 @@ void Properties::SetUIReadOnly (const bool bIsUIReadOnly)
}
+
+
+bool Properties::IsOnlyPreviewTriggersMouseOver (void) const
+{
+ return mbIsOnlyPreviewTriggersMouseOver;
+}
+
+
+
+
+void Properties::SetOnlyPreviewTriggersMouseOver (const bool bFlag)
+{
+ mbIsOnlyPreviewTriggersMouseOver = bFlag;
+}
+
+
+
+
+bool Properties::IsHighContrastModeActive (void) const
+{
+ return mbIsHighContrastModeActive;
+}
+
+
} } } // end of namespace ::sd::slidesorter::controller
diff --git a/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx b/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx
index 5ee7f6f58b82..c94dd6d550b0 100755..100644
--- a/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx
+++ b/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx
@@ -31,11 +31,12 @@
#include "SlideSorter.hxx"
#include "controller/SlideSorterController.hxx"
+#include "controller/SlsVisibleAreaManager.hxx"
#include "model/SlideSorterModel.hxx"
#include "model/SlsPageDescriptor.hxx"
#include "view/SlideSorterView.hxx"
#include "view/SlsLayouter.hxx"
-#include "view/SlsViewOverlay.hxx"
+#include "view/SlsTheme.hxx"
#include "Window.hxx"
#include "sdpage.hxx"
@@ -51,11 +52,15 @@ ScrollBarManager::ScrollBarManager (SlideSorter& rSlideSorter)
mpVerticalScrollBar(mrSlideSorter.GetVerticalScrollBar()),
mnHorizontalPosition (0),
mnVerticalPosition (0),
- maScrollBorder (10,10),
- mnHorizontalScrollFactor (0.1),
- mnVerticalScrollFactor (0.1),
+ maScrollBorder (20,20),
+ mnHorizontalScrollFactor (0.15),
+ mnVerticalScrollFactor (0.25),
mpScrollBarFiller(mrSlideSorter.GetScrollBarFiller()),
- mpContentWindow(mrSlideSorter.GetContentWindow())
+ maAutoScrollTimer(),
+ maAutoScrollOffset(0,0),
+ mbIsAutoScrollActive(false),
+ mpContentWindow(mrSlideSorter.GetContentWindow()),
+ maAutoScrollFunctor()
{
// Hide the scroll bars by default to prevent display errors while
// switching between view shells: In the short time between initiating
@@ -66,7 +71,7 @@ ScrollBarManager::ScrollBarManager (SlideSorter& rSlideSorter)
mpVerticalScrollBar->Hide();
mpScrollBarFiller->Hide();
- maAutoScrollTimer.SetTimeout(50);
+ maAutoScrollTimer.SetTimeout(25);
maAutoScrollTimer.SetTimeoutHdl (
LINK(this, ScrollBarManager, AutoScrollTimeoutHandler));
}
@@ -91,17 +96,15 @@ void ScrollBarManager::LateInitialization (void)
void ScrollBarManager::Connect (void)
{
if (mpVerticalScrollBar != NULL)
+ {
mpVerticalScrollBar->SetScrollHdl (
- LINK(
- this,
- ScrollBarManager,
- VerticalScrollBarHandler));
+ LINK(this, ScrollBarManager, VerticalScrollBarHandler));
+ }
if (mpHorizontalScrollBar != NULL)
- mpHorizontalScrollBar->SetScrollHdl (
- LINK(
- this,
- ScrollBarManager,
- HorizontalScrollBarHandler));
+ {
+ mpHorizontalScrollBar->SetScrollHdl(
+ LINK(this, ScrollBarManager, HorizontalScrollBarHandler));
+ }
}
@@ -110,9 +113,13 @@ void ScrollBarManager::Connect (void)
void ScrollBarManager::Disconnect (void)
{
if (mpVerticalScrollBar != NULL)
+ {
mpVerticalScrollBar->SetScrollHdl (Link());
+ }
if (mpHorizontalScrollBar != NULL)
+ {
mpHorizontalScrollBar->SetScrollHdl (Link());
+ }
}
@@ -129,12 +136,24 @@ void ScrollBarManager::Disconnect (void)
window changes and a second call to the layouter becomes necessary.
That call is made anyway after this method returns.
*/
-Rectangle ScrollBarManager::PlaceScrollBars (const Rectangle& rAvailableArea)
+Rectangle ScrollBarManager::PlaceScrollBars (
+ const Rectangle& rAvailableArea,
+ const bool bIsHorizontalScrollBarAllowed,
+ const bool bIsVerticalScrollBarAllowed)
{
- Rectangle aRemainingSpace (DetermineScrollBarVisibilities(rAvailableArea));
- PlaceHorizontalScrollBar (rAvailableArea);
- PlaceVerticalScrollBar (rAvailableArea);
- PlaceFiller (rAvailableArea);
+ Rectangle aRemainingSpace (DetermineScrollBarVisibilities(
+ rAvailableArea,
+ bIsHorizontalScrollBarAllowed,
+ bIsVerticalScrollBarAllowed));
+
+ if (mpHorizontalScrollBar!=NULL && mpHorizontalScrollBar->IsVisible())
+ PlaceHorizontalScrollBar (rAvailableArea);
+
+ if (mpVerticalScrollBar!=NULL && mpVerticalScrollBar->IsVisible())
+ PlaceVerticalScrollBar (rAvailableArea);
+
+ if (mpScrollBarFiller!=NULL && mpScrollBarFiller->IsVisible())
+ PlaceFiller (rAvailableArea);
return aRemainingSpace;
}
@@ -144,25 +163,21 @@ Rectangle ScrollBarManager::PlaceScrollBars (const Rectangle& rAvailableArea)
void ScrollBarManager::PlaceHorizontalScrollBar (const Rectangle& aAvailableArea)
{
- if (mpHorizontalScrollBar != NULL
- && mpHorizontalScrollBar->IsVisible())
- {
- // Save the current relative position.
- mnHorizontalPosition = double(mpHorizontalScrollBar->GetThumbPos())
- / double(mpHorizontalScrollBar->GetRange().Len());
-
- // Place the scroll bar.
- Size aScrollBarSize (mpHorizontalScrollBar->GetSizePixel());
- mpHorizontalScrollBar->SetPosSizePixel (
- Point(aAvailableArea.Left(),
- aAvailableArea.Bottom()-aScrollBarSize.Height()+1),
- Size (aAvailableArea.GetWidth() - GetVerticalScrollBarWidth(),
- aScrollBarSize.Height()));
-
- // Restore the relative position.
- mpHorizontalScrollBar->SetThumbPos(
- (long)(0.5 + mnHorizontalPosition * mpHorizontalScrollBar->GetRange().Len()));
- }
+ // Save the current relative position.
+ mnHorizontalPosition = double(mpHorizontalScrollBar->GetThumbPos())
+ / double(mpHorizontalScrollBar->GetRange().Len());
+
+ // Place the scroll bar.
+ Size aScrollBarSize (mpHorizontalScrollBar->GetSizePixel());
+ mpHorizontalScrollBar->SetPosSizePixel (
+ Point(aAvailableArea.Left(),
+ aAvailableArea.Bottom()-aScrollBarSize.Height()+1),
+ Size (aAvailableArea.GetWidth() - GetVerticalScrollBarWidth(),
+ aScrollBarSize.Height()));
+
+ // Restore the relative position.
+ mpHorizontalScrollBar->SetThumbPos(
+ (long)(0.5 + mnHorizontalPosition * mpHorizontalScrollBar->GetRange().Len()));
}
@@ -170,26 +185,17 @@ void ScrollBarManager::PlaceHorizontalScrollBar (const Rectangle& aAvailableArea
void ScrollBarManager::PlaceVerticalScrollBar (const Rectangle& aArea)
{
- if (mpVerticalScrollBar != NULL
- && mpVerticalScrollBar->IsVisible())
- {
- view::Layouter::DoublePoint aLayouterPosition
- = mrSlideSorter.GetView().GetLayouter().ConvertModelToLayouterCoordinates (
- Point (0, mpVerticalScrollBar->GetThumbPos()));
-
- // Place the scroll bar.
- Size aScrollBarSize (mpVerticalScrollBar->GetSizePixel());
- Point aPosition (aArea.Right()-aScrollBarSize.Width()+1, aArea.Top());
- Size aSize (aScrollBarSize.Width(), aArea.GetHeight() - GetHorizontalScrollBarHeight());
- mpVerticalScrollBar->SetPosSizePixel(aPosition, aSize);
-
- // Restore the position.
- mpVerticalScrollBar->SetThumbPos(
- mrSlideSorter.GetView().GetLayouter().ConvertLayouterToModelCoordinates(
- aLayouterPosition).Y());
- mnVerticalPosition = double(mpVerticalScrollBar->GetThumbPos())
- / double(mpVerticalScrollBar->GetRange().Len());
- }
+ const double nThumbPosition (mpVerticalScrollBar->GetThumbPos());
+
+ // Place the scroll bar.
+ Size aScrollBarSize (mpVerticalScrollBar->GetSizePixel());
+ Point aPosition (aArea.Right()-aScrollBarSize.Width()+1, aArea.Top());
+ Size aSize (aScrollBarSize.Width(), aArea.GetHeight() - GetHorizontalScrollBarHeight());
+ mpVerticalScrollBar->SetPosSizePixel(aPosition, aSize);
+
+ // Restore the position.
+ mpVerticalScrollBar->SetThumbPos(nThumbPosition);
+ mnVerticalPosition = nThumbPosition / double(mpVerticalScrollBar->GetRange().Len());
}
@@ -197,23 +203,13 @@ void ScrollBarManager::PlaceVerticalScrollBar (const Rectangle& aArea)
void ScrollBarManager::PlaceFiller (const Rectangle& aArea)
{
- // Place the filler when both scroll bars are visible.
- if (mpHorizontalScrollBar != NULL
- && mpVerticalScrollBar != NULL
- && mpHorizontalScrollBar->IsVisible()
- && mpVerticalScrollBar->IsVisible())
- {
- mpScrollBarFiller->SetPosSizePixel(
- Point(
- aArea.Right()-mpVerticalScrollBar->GetSizePixel().Width()+1,
- aArea.Bottom()-mpHorizontalScrollBar->GetSizePixel().Height()+1),
- Size (
- mpVerticalScrollBar->GetSizePixel().Width(),
- mpHorizontalScrollBar->GetSizePixel().Height()));
- mpScrollBarFiller->Show();
- }
- else
- mpScrollBarFiller->Hide();
+ mpScrollBarFiller->SetPosSizePixel(
+ Point(
+ aArea.Right()-mpVerticalScrollBar->GetSizePixel().Width()+1,
+ aArea.Bottom()-mpHorizontalScrollBar->GetSizePixel().Height()+1),
+ Size (
+ mpVerticalScrollBar->GetSizePixel().Width(),
+ mpHorizontalScrollBar->GetSizePixel().Height()));
}
@@ -222,7 +218,7 @@ void ScrollBarManager::PlaceFiller (const Rectangle& aArea)
void ScrollBarManager::UpdateScrollBars (bool bResetThumbPosition, bool bUseScrolling)
{
Rectangle aModelArea (mrSlideSorter.GetView().GetModelArea());
- ::sd::Window* pWindow = mrSlideSorter.GetView().GetWindow();
+ SharedSdWindow pWindow (mrSlideSorter.GetContentWindow());
Size aWindowModelSize (pWindow->PixelToLogic(pWindow->GetSizePixel()));
// The horizontal scroll bar is only shown when the window is
@@ -306,14 +302,13 @@ IMPL_LINK(ScrollBarManager, VerticalScrollBarHandler, ScrollBar*, pScrollBar)
if (pScrollBar!=NULL
&& pScrollBar==mpVerticalScrollBar.get()
&& pScrollBar->IsVisible()
- && mrSlideSorter.GetView().GetWindow()!=NULL)
+ && mrSlideSorter.GetContentWindow()!=NULL)
{
double nRelativePosition = double(pScrollBar->GetThumbPos())
/ double(pScrollBar->GetRange().Len());
mrSlideSorter.GetView().InvalidatePageObjectVisibilities();
- mrSlideSorter.GetView().GetWindow()->SetVisibleXY (
- -1,
- nRelativePosition);
+ mrSlideSorter.GetContentWindow()->SetVisibleXY(-1, nRelativePosition);
+ mrSlideSorter.GetController().GetVisibleAreaManager().DeactivateCurrentSlideTracking();
}
return TRUE;
}
@@ -326,12 +321,13 @@ IMPL_LINK(ScrollBarManager, HorizontalScrollBarHandler, ScrollBar*, pScrollBar)
if (pScrollBar!=NULL
&& pScrollBar==mpHorizontalScrollBar.get()
&& pScrollBar->IsVisible()
- && mrSlideSorter.GetView().GetWindow()!=NULL)
+ && mrSlideSorter.GetContentWindow()!=NULL)
{
double nRelativePosition = double(pScrollBar->GetThumbPos())
/ double(pScrollBar->GetRange().Len());
mrSlideSorter.GetView().InvalidatePageObjectVisibilities();
- mrSlideSorter.GetView().GetWindow()->SetVisibleXY (nRelativePosition, -1);
+ mrSlideSorter.GetContentWindow()->SetVisibleXY(nRelativePosition, -1);
+ mrSlideSorter.GetController().GetVisibleAreaManager().DeactivateCurrentSlideTracking();
}
return TRUE;
}
@@ -346,7 +342,7 @@ void ScrollBarManager::SetWindowOrigin (
mnHorizontalPosition = nHorizontalPosition;
mnVerticalPosition = nVerticalPosition;
- ::sd::Window* pWindow = mrSlideSorter.GetView().GetWindow();
+ SharedSdWindow pWindow (mrSlideSorter.GetContentWindow());
Size aViewSize (pWindow->GetViewSize());
Point aOrigin (
(long int) (mnHorizontalPosition * aViewSize.Width()),
@@ -371,31 +367,42 @@ void ScrollBarManager::SetWindowOrigin (
b) when not showing a scroll bar the area used by the page objects fits
into the available area in the scroll bars orientation.
*/
-Rectangle ScrollBarManager::DetermineScrollBarVisibilities (const Rectangle& rAvailableArea)
+Rectangle ScrollBarManager::DetermineScrollBarVisibilities (
+ const Rectangle& rAvailableArea,
+ const bool bIsHorizontalScrollBarAllowed,
+ const bool bIsVerticalScrollBarAllowed)
{
// Test which combination of scroll bars is the best.
bool bShowHorizontal = false;
bool bShowVertical = false;
- do
+ if (mrSlideSorter.GetModel().GetPageCount() == 0)
{
- if (mrSlideSorter.GetModel().GetPageCount() == 0)
- // No pages => no scroll bars.
- break;
-
- if (TestScrollBarVisibilities(bShowHorizontal=false, bShowVertical=false, rAvailableArea))
- break;
- if (TestScrollBarVisibilities(bShowHorizontal=true, bShowVertical=false, rAvailableArea))
- break;
- if (TestScrollBarVisibilities(bShowHorizontal=false, bShowVertical=true, rAvailableArea))
- break;
- if (TestScrollBarVisibilities(bShowHorizontal=true, bShowVertical=true, rAvailableArea))
- break;
+ // No pages => no scroll bars.
+ }
+ else if (TestScrollBarVisibilities(false, false, rAvailableArea))
+ {
+ // Nothing to be done.
+ }
+ else if (bIsHorizontalScrollBarAllowed
+ && TestScrollBarVisibilities(true, false, rAvailableArea))
+ {
+ bShowHorizontal = true;
+ }
+ else if (bIsVerticalScrollBarAllowed
+ && TestScrollBarVisibilities(false, true, rAvailableArea))
+ {
+ bShowVertical = true;
+ }
+ else
+ {
+ bShowHorizontal = true;
+ bShowVertical = true;
}
- while (false);
// Make the visibility of the scroll bars permanent.
mpVerticalScrollBar->Show(bShowVertical);
mpHorizontalScrollBar->Show(bShowHorizontal);
+ mpScrollBarFiller->Show(bShowVertical && bShowHorizontal);
// Adapt the remaining space accordingly.
Rectangle aRemainingSpace (rAvailableArea);
@@ -415,7 +422,7 @@ bool ScrollBarManager::TestScrollBarVisibilities (
bool bVerticalScrollBarVisible,
const Rectangle& rAvailableArea)
{
- bool bAreVisibilitiesOK = true;
+ model::SlideSorterModel& rModel (mrSlideSorter.GetModel());
// Adapt the available size by subtracting the sizes of the scroll bars
// visible in this combination.
@@ -427,74 +434,81 @@ bool ScrollBarManager::TestScrollBarVisibilities (
// Tell the view to rearrange its page objects and check whether the
// page objects can be shown without clipping.
- bool bRearrangeSuccess (false);
- if (mrSlideSorter.GetView().GetOrientation() == view::SlideSorterView::HORIZONTAL)
- {
- bRearrangeSuccess = mrSlideSorter.GetView().GetLayouter().RearrangeHorizontal (
- aBrowserSize,
- mrSlideSorter.GetModel().GetPageDescriptor(0)->GetPage()->GetSize(),
- mpContentWindow.get(),
- mrSlideSorter.GetModel().GetPageCount());
- }
- else
- {
- bRearrangeSuccess = mrSlideSorter.GetView().GetLayouter().RearrangeVertical (
- aBrowserSize,
- mrSlideSorter.GetModel().GetPageDescriptor(0)->GetPage()->GetSize(),
- mpContentWindow.get());
- }
+ bool bRearrangeSuccess (mrSlideSorter.GetView().GetLayouter().Rearrange (
+ mrSlideSorter.GetView().GetOrientation(),
+ aBrowserSize,
+ rModel.GetPageDescriptor(0)->GetPage()->GetSize(),
+ rModel.GetPageCount()));
if (bRearrangeSuccess)
{
- Size aPageSize = mrSlideSorter.GetView().GetLayouter().GetPageBox (
- mrSlideSorter.GetModel().GetPageCount()).GetSize();
+ Size aPageSize = mrSlideSorter.GetView().GetLayouter().GetTotalBoundingBox().GetSize();
Size aWindowModelSize = mpContentWindow->PixelToLogic(aBrowserSize);
- bool bHorizontallyClipped = (aPageSize.Width() > aWindowModelSize.Width());
- bool bVerticallyClipped = (aPageSize.Height() > aWindowModelSize.Height());
- bAreVisibilitiesOK = (bHorizontallyClipped == bHorizontalScrollBarVisible)
- && (bVerticallyClipped == bVerticalScrollBarVisible);
+ // The content may be clipped, i.e. not fully visible, in one
+ // direction only when the scroll bar is visible in that direction.
+ if (aPageSize.Width() > aWindowModelSize.Width())
+ if ( ! bHorizontalScrollBarVisible)
+ return false;
+ if (aPageSize.Height() > aWindowModelSize.Height())
+ if ( ! bVerticalScrollBarVisible)
+ return false;
+
+ return true;
}
else
- bAreVisibilitiesOK = false;
-
- return bAreVisibilitiesOK;
+ return false;
}
-void ScrollBarManager::SetTop (const sal_Int32 nNewTop)
+void ScrollBarManager::SetTopLeft (const Point aNewTopLeft)
{
- if (mpVerticalScrollBar != NULL
- && mpVerticalScrollBar->GetThumbPos() != nNewTop)
- {
- // Flush pending repaints before scrolling to avoid temporary artifacts.
- mrSlideSorter.GetView().GetWindow()->Update();
+ if (( ! mpVerticalScrollBar
+ || mpVerticalScrollBar->GetThumbPos() == aNewTopLeft.Y())
+ && ( ! mpHorizontalScrollBar
+ || mpHorizontalScrollBar->GetThumbPos() == aNewTopLeft.X()))
+ return;
+
+ // Flush pending repaints before scrolling to avoid temporary artifacts.
+ mrSlideSorter.GetContentWindow()->Update();
- mpVerticalScrollBar->SetThumbPos(nNewTop);
- mnVerticalPosition = double(nNewTop) / double(mpVerticalScrollBar->GetRange().Len());
- mrSlideSorter.GetView().GetWindow()->SetVisibleXY (
- mnHorizontalPosition, mnVerticalPosition);
+ if (mpVerticalScrollBar)
+ {
+ mpVerticalScrollBar->SetThumbPos(aNewTopLeft.Y());
+ mnVerticalPosition = aNewTopLeft.Y() / double(mpVerticalScrollBar->GetRange().Len());
+ }
+ if (mpHorizontalScrollBar)
+ {
+ mpHorizontalScrollBar->SetThumbPos(aNewTopLeft.X());
+ mnHorizontalPosition = aNewTopLeft.X() / double(mpHorizontalScrollBar->GetRange().Len());
}
+
+ mrSlideSorter.GetContentWindow()->SetVisibleXY(mnHorizontalPosition, mnVerticalPosition);
+ mrSlideSorter.GetView().InvalidatePageObjectVisibilities();
}
-void ScrollBarManager::SetLeft (const sal_Int32 nNewLeft)
+sal_Int32 ScrollBarManager::GetTop (void) const
{
- if (mpHorizontalScrollBar != NULL
- && mpHorizontalScrollBar->GetThumbPos() != nNewLeft)
- {
- // Flush pending repaints before scrolling to avoid temporary artifacts.
- mrSlideSorter.GetView().GetWindow()->Update();
+ if (mpVerticalScrollBar != NULL)
+ return mpVerticalScrollBar->GetThumbPos();
+ else
+ return 0;
+}
- mpHorizontalScrollBar->SetThumbPos(nNewLeft);
- mnHorizontalPosition = double(nNewLeft) / double(mpHorizontalScrollBar->GetRange().Len());
- mrSlideSorter.GetView().GetWindow()->SetVisibleXY (
- mnHorizontalPosition, mnVerticalPosition);
- }
+
+
+
+sal_Int32 ScrollBarManager::GetLeft (void) const
+{
+ if (mpHorizontalScrollBar != NULL)
+ return mpHorizontalScrollBar->GetThumbPos();
+ else
+ return 0;
}
@@ -524,7 +538,7 @@ int ScrollBarManager::GetHorizontalScrollBarHeight (void) const
void ScrollBarManager::CalcAutoScrollOffset (const Point& rMouseWindowPosition)
{
- ::sd::Window* pWindow = mrSlideSorter.GetView().GetWindow();
+ SharedSdWindow pWindow (mrSlideSorter.GetContentWindow());
int nDx = 0;
int nDy = 0;
@@ -579,14 +593,16 @@ void ScrollBarManager::CalcAutoScrollOffset (const Point& rMouseWindowPosition)
-bool ScrollBarManager::AutoScroll (const Point& rMouseWindowPosition)
+bool ScrollBarManager::AutoScroll (
+ const Point& rMouseWindowPosition,
+ const ::boost::function<void(void)>& rAutoScrollFunctor)
{
- CalcAutoScrollOffset (rMouseWindowPosition);
- bool bResult = RepeatAutoScroll();
- if (bResult)
- {
- maAutoScrollTimer.Start();
- }
+ maAutoScrollFunctor = rAutoScrollFunctor;
+ CalcAutoScrollOffset(rMouseWindowPosition);
+ bool bResult (true);
+ if ( ! mbIsAutoScrollActive)
+ bResult = RepeatAutoScroll();
+
return bResult;
}
@@ -596,6 +612,7 @@ bool ScrollBarManager::AutoScroll (const Point& rMouseWindowPosition)
void ScrollBarManager::StopAutoScroll (void)
{
maAutoScrollTimer.Stop();
+ mbIsAutoScrollActive = false;
}
@@ -607,13 +624,23 @@ bool ScrollBarManager::RepeatAutoScroll (void)
{
if (mrSlideSorter.GetViewShell() != NULL)
{
- mrSlideSorter.GetViewShell()->ScrollLines(
+ mrSlideSorter.GetViewShell()->Scroll(
maAutoScrollOffset.Width(),
- maAutoScrollOffset.Height());
+ maAutoScrollOffset.Height());
+ mrSlideSorter.GetView().InvalidatePageObjectVisibilities();
+
+ if (maAutoScrollFunctor)
+ maAutoScrollFunctor();
+
+ mbIsAutoScrollActive = true;
+ maAutoScrollTimer.Start();
+
return true;
}
}
+ maAutoScrollFunctor = ::boost::function<void(void)>();
+ mbIsAutoScrollActive = false;
return false;
}
@@ -628,4 +655,83 @@ IMPL_LINK(ScrollBarManager, AutoScrollTimeoutHandler, Timer *, EMPTYARG)
}
+
+
+void ScrollBarManager::Scroll(
+ const Orientation eOrientation,
+ const Unit eUnit,
+ const sal_Int32 nDistance)
+{
+ bool bIsVertical (false);
+ switch (eOrientation)
+ {
+ case Orientation_Horizontal: bIsVertical = false; break;
+ case Orientation_Vertical: bIsVertical = true; break;
+ default:
+ OSL_ASSERT(eOrientation==Orientation_Horizontal || eOrientation==Orientation_Vertical);
+ return;
+ }
+
+ Point aNewTopLeft (
+ mpHorizontalScrollBar ? mpHorizontalScrollBar->GetThumbPos() : 0,
+ mpVerticalScrollBar ? mpVerticalScrollBar->GetThumbPos() : 0);
+ switch (eUnit)
+ {
+ case Unit_Pixel:
+ if (bIsVertical)
+ aNewTopLeft.Y() += nDistance;
+ else
+ aNewTopLeft.X() += nDistance;
+ break;
+
+ case Unit_Slide:
+ {
+ view::Layouter& rLayouter (mrSlideSorter.GetView().GetLayouter());
+
+ // Calculate estimate of new location.
+ if (bIsVertical)
+ aNewTopLeft.Y() += nDistance * rLayouter.GetPageObjectSize().Height();
+ else
+ aNewTopLeft.X() += nDistance * rLayouter.GetPageObjectSize().Width();
+
+ // Adapt location to show whole slides.
+ if (bIsVertical)
+ if (nDistance > 0)
+ {
+ const sal_Int32 nIndex (rLayouter.GetIndexAtPoint(
+ Point(aNewTopLeft.X(), aNewTopLeft.Y()+mpVerticalScrollBar->GetVisibleSize()),
+ true));
+ aNewTopLeft.Y() = rLayouter.GetPageObjectBox(nIndex,true).Bottom()
+ - mpVerticalScrollBar->GetVisibleSize();
+ }
+ else
+ {
+ const sal_Int32 nIndex (rLayouter.GetIndexAtPoint(
+ Point(aNewTopLeft.X(), aNewTopLeft.Y()),
+ true));
+ aNewTopLeft.Y() = rLayouter.GetPageObjectBox(nIndex,true).Top();
+ }
+ else
+ if (nDistance > 0)
+ {
+ const sal_Int32 nIndex (rLayouter.GetIndexAtPoint(
+ Point(aNewTopLeft.X()+mpVerticalScrollBar->GetVisibleSize(), aNewTopLeft.Y()),
+ true));
+ aNewTopLeft.X() = rLayouter.GetPageObjectBox(nIndex,true).Right()
+ - mpVerticalScrollBar->GetVisibleSize();
+ }
+ else
+ {
+ const sal_Int32 nIndex (rLayouter.GetIndexAtPoint(
+ Point(aNewTopLeft.X(), aNewTopLeft.Y()),
+ true));
+ aNewTopLeft.X() = rLayouter.GetPageObjectBox(nIndex,true).Left();
+ }
+ }
+ }
+ mrSlideSorter.GetController().GetVisibleAreaManager().DeactivateCurrentSlideTracking();
+ SetTopLeft(aNewTopLeft);
+}
+
+
} } } // end of namespace ::sd::slidesorter::controller
diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx
index c1d742ce7158..1d4d075fc3ce 100755..100644
--- a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx
+++ b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx
@@ -31,38 +31,49 @@
#include "SlideSorter.hxx"
#include "SlideSorterViewShell.hxx"
+#include "SlsDragAndDropContext.hxx"
+#include "controller/SlsTransferable.hxx"
#include "controller/SlideSorterController.hxx"
#include "controller/SlsPageSelector.hxx"
#include "controller/SlsFocusManager.hxx"
#include "controller/SlsScrollBarManager.hxx"
#include "controller/SlsClipboard.hxx"
#include "controller/SlsCurrentSlideManager.hxx"
+#include "controller/SlsInsertionIndicatorHandler.hxx"
#include "controller/SlsSelectionManager.hxx"
#include "controller/SlsProperties.hxx"
+#include "controller/SlsProperties.hxx"
+#include "controller/SlsSlotManager.hxx"
+#include "controller/SlsVisibleAreaManager.hxx"
#include "model/SlideSorterModel.hxx"
#include "model/SlsPageDescriptor.hxx"
#include "model/SlsPageEnumerationProvider.hxx"
#include "view/SlideSorterView.hxx"
-#include "view/SlsViewOverlay.hxx"
#include "view/SlsLayouter.hxx"
-#include "view/SlsPageObjectViewObjectContact.hxx"
+#include "view/SlsPageObjectLayouter.hxx"
+#include "view/SlsButtonBar.hxx"
#include "framework/FrameworkHelper.hxx"
#include "ViewShellBase.hxx"
#include "DrawController.hxx"
-#include <vcl/sound.hxx>
-#include <sfx2/viewfrm.hxx>
-#include <sfx2/dispatch.hxx>
-#include <svx/svdpagv.hxx>
-#include <vcl/msgbox.hxx>
#include "Window.hxx"
#include "sdpage.hxx"
#include "drawdoc.hxx"
+#include "DrawDocShell.hxx"
+#include "sdxfer.hxx"
#include "ViewShell.hxx"
#include "ViewShellBase.hxx"
#include "FrameView.hxx"
#include "app.hrc"
#include "sdresid.hxx"
#include "strings.hrc"
+#include <vcl/sound.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/dispatch.hxx>
+#include <svx/svdpagv.hxx>
+#include <vcl/msgbox.hxx>
+#include <svx/svxids.hrc>
+#include <boost/bind.hpp>
+#include <boost/optional.hpp>
namespace {
static const sal_uInt32 SINGLE_CLICK (0x00000001);
@@ -73,109 +84,304 @@ static const sal_uInt32 MIDDLE_BUTTON (0x00000040);
static const sal_uInt32 BUTTON_DOWN (0x00000100);
static const sal_uInt32 BUTTON_UP (0x00000200);
static const sal_uInt32 MOUSE_MOTION (0x00000400);
+static const sal_uInt32 MOUSE_DRAG (0x00000800);
// The rest leaves the lower 16 bit untouched so that it can be used with
// key codes.
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 SHIFT_MODIFIER (0x00100000);
-static const sal_uInt32 CONTROL_MODIFIER (0x00200000);
-static const sal_uInt32 SUBSTITUTION_VISIBLE (0x01000000);
-static const sal_uInt32 RECTANGLE_VISIBLE (0x02000000);
+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);
static const sal_uInt32 KEY_EVENT (0x10000000);
// Some absent events are defined so they can be expressed explicitly.
static const sal_uInt32 NO_MODIFIER (0x00000000);
-static const sal_uInt32 SUBSTITUTION_NOT_VISIBLE (0x00000000);
static const sal_uInt32 NOT_OVER_PAGE (0x00000000);
+// Masks
+static const sal_uInt32 MODIFIER_MASK (SHIFT_MODIFIER | CONTROL_MODIFIER);
+static const sal_uInt32 BUTTON_MASK (LEFT_BUTTON | RIGHT_BUTTON | MIDDLE_BUTTON);
} // end of anonymous namespace
+
+// Define some macros to make the following switch statement more readable.
+#define ANY_MODIFIER(code) \
+ code|NO_MODIFIER: \
+ case code|SHIFT_MODIFIER: \
+ case code|CONTROL_MODIFIER
+
namespace sd { namespace slidesorter { namespace controller {
-class SelectionFunction::SubstitutionHandler
+//===== SelectionFunction::EventDescriptor ====================================
+
+class SelectionFunction::EventDescriptor
{
public:
- SubstitutionHandler (SlideSorter& rSlideSorter);
- ~SubstitutionHandler (void);
+ Point maMousePosition;
+ Point maMouseModelPosition;
+ model::SharedPageDescriptor mpHitDescriptor;
+ SdrPage* mpHitPage;
+ sal_uInt32 mnEventCode;
+ bool mbIsOverButton;
+ InsertionIndicatorHandler::Mode meDragMode;
+ bool mbMakeSelectionVisible;
+ bool mbIsLeaving;
- /** Create a substitution display of the currently selected pages and
- use the given position as the anchor point.
+ EventDescriptor (
+ sal_uInt32 nEventType,
+ const MouseEvent& rEvent,
+ SlideSorter& rSlideSorter);
+ EventDescriptor (
+ sal_uInt32 nEventType,
+ const AcceptDropEvent& rEvent,
+ const sal_Int8 nDragAction,
+ SlideSorter& rSlideSorter);
+ EventDescriptor (
+ const KeyEvent& rEvent,
+ SlideSorter& rSlideSorter);
+
+ void SetDragMode (const InsertionIndicatorHandler::Mode eMode);
+
+private:
+ /** Compute a numerical code that describes a mouse event and that can
+ be used for fast look up of the appropriate reaction.
*/
- void Start (const Point& rMouseModelPosition);
+ sal_uInt32 EncodeMouseEvent (const MouseEvent& rEvent) const;
- /** Move the substitution display by the distance the mouse has
- travelled since the last call to this method or to
- CreateSubstitution(). The given point becomes the new anchor.
+ /** Compute a numerical code that describes a key event and that can
+ be used for fast look up of the appropriate reaction.
*/
- void UpdatePosition (const Point& rMouseModelPosition);
+ sal_uInt32 EncodeKeyEvent (const KeyEvent& rEvent) const;
- /** Move the substitution display of the currently selected pages.
+ /** Compute a numerical code that describes the current state like
+ whether the selection rectangle is visible or whether the page under
+ the mouse or the one that has the focus is selected.
*/
- void Process (void);
+ sal_uInt32 EncodeState (void) const;
+};
- void End (void);
- bool HasBeenMoved (void) const;
-private:
+
+//===== SelectionFunction::ModeHandler ========================================
+
+class SelectionFunction::ModeHandler
+{
+public:
+ ModeHandler (
+ SlideSorter& rSlideSorter,
+ SelectionFunction& rSelectionFunction,
+ const bool bIsMouseOverIndicatorAllowed);
+ virtual ~ModeHandler (void);
+
+ virtual Mode GetMode (void) const = 0;
+ virtual void Abort (void) = 0;
+ virtual void ProcessEvent (EventDescriptor& rDescriptor);
+
+ /** Set the selection to exactly the specified page and also set it as
+ the current page.
+ */
+ void SetCurrentPage (const model::SharedPageDescriptor& rpDescriptor);
+
+ /// Deselect all pages.
+ void DeselectAllPages (void);
+ void SelectOnePage (const model::SharedPageDescriptor& rpDescriptor);
+
+ /** When the view on which this selection function is working is the
+ main view then the view is switched to the regular editing view.
+ */
+ void SwitchView (const model::SharedPageDescriptor& rpDescriptor);
+
+ void StartDrag (
+ const Point& rMousePosition,
+ const InsertionIndicatorHandler::Mode eMode);
+
+ bool IsMouseOverIndicatorAllowed (void) const;
+
+protected:
SlideSorter& mrSlideSorter;
+ SelectionFunction& mrSelectionFunction;
+
+ virtual bool ProcessButtonDownEvent (EventDescriptor& rDescriptor);
+ virtual bool ProcessButtonUpEvent (EventDescriptor& rDescriptor);
+ virtual bool ProcessMotionEvent (EventDescriptor& rDescriptor);
+ virtual bool ProcessDragEvent (EventDescriptor& rDescriptor);
+ virtual bool HandleUnprocessedEvent (EventDescriptor& rDescriptor);
- bool mbHasBeenMoved;
+ void ReprocessEvent (EventDescriptor& rDescriptor);
- /** Determine whether there is a) a substitution and b) its insertion at
- the current position of the insertion marker would alter the
- document. This would be the case when the substitution has been
- moved or is not consecutive.
+private:
+ const bool mbIsMouseOverIndicatorAllowed;
+};
+
+
+/** This is the default handler for processing events. It activates the
+ multi selection or drag-and-drop when the right conditions are met.
+*/
+class NormalModeHandler : public SelectionFunction::ModeHandler
+{
+public:
+ NormalModeHandler (
+ SlideSorter& rSlideSorter,
+ SelectionFunction& rSelectionFunction);
+ virtual ~NormalModeHandler (void);
+
+ virtual SelectionFunction::Mode GetMode (void) const;
+ virtual void Abort (void);
+
+ void ResetButtonDownLocation (void);
+
+protected:
+ virtual bool ProcessButtonDownEvent (SelectionFunction::EventDescriptor& rDescriptor);
+ virtual bool ProcessButtonUpEvent (SelectionFunction::EventDescriptor& rDescriptor);
+ virtual bool ProcessMotionEvent (SelectionFunction::EventDescriptor& rDescriptor);
+ virtual bool ProcessDragEvent (SelectionFunction::EventDescriptor& rDescriptor);
+
+private:
+ ::boost::optional<Point> maButtonDownLocation;
+
+ /** Select all pages between and including the selection anchor and the
+ specified page.
*/
- bool IsSubstitutionInsertionNonTrivial (void) const;
+ void RangeSelect (const model::SharedPageDescriptor& rpDescriptor);
};
-class SelectionFunction::EventDescriptor
+/** Handle events during a multi selection, which typically is started by
+ pressing the left mouse button when not over a page.
+*/
+class MultiSelectionModeHandler : public SelectionFunction::ModeHandler
{
public:
+ /** Start a rectangle selection at the given position.
+ */
+ MultiSelectionModeHandler (
+ SlideSorter& rSlideSorter,
+ SelectionFunction& rSelectionFunction,
+ const Point& rMouseModelPosition,
+ const sal_uInt32 nEventCode);
+ virtual ~MultiSelectionModeHandler (void);
- Point maMousePosition;
- Point maMouseModelPosition;
- ::boost::weak_ptr<model::PageDescriptor> mpHitDescriptor;
- SdrPage* mpHitPage;
- sal_uInt32 mnEventCode;
+ virtual SelectionFunction::Mode GetMode (void) const;
+ virtual void Abort (void);
+ virtual void ProcessEvent (SelectionFunction::EventDescriptor& rDescriptor);
- EventDescriptor (
- sal_uInt32 nEventType,
- const MouseEvent& rEvent,
- SlideSorter& rSlideSorter);
- EventDescriptor (
- const KeyEvent& rEvent,
- SlideSorter& rSlideSorter);
+ enum SelectionMode { SM_Normal, SM_Add, SM_Toggle };
+
+ void SetSelectionMode (const SelectionMode eSelectionMode);
+ void SetSelectionModeFromModifier (const sal_uInt32 nEventCode);
+
+protected:
+ virtual bool ProcessButtonUpEvent (SelectionFunction::EventDescriptor& rDescriptor);
+ virtual bool ProcessMotionEvent (SelectionFunction::EventDescriptor& rDescriptor);
+ virtual bool HandleUnprocessedEvent (SelectionFunction::EventDescriptor& rDescriptor);
+
+private:
+ SelectionMode meSelectionMode;
+ Point maSecondCorner;
+ Pointer maSavedPointer;
+ sal_Int32 mnAnchorIndex;
+ sal_Int32 mnSecondIndex;
+ view::ButtonBar::Lock maButtonBarLock;
+
+ virtual void UpdateModelPosition (const Point& rMouseModelPosition);
+ virtual void UpdateSelection (void);
+
+ /** Update the rectangle selection so that the given position becomes
+ the new second point of the selection rectangle.
+ */
+ void UpdatePosition (
+ const Point& rMousePosition,
+ const bool bAllowAutoScroll);
+
+ void UpdateSelectionState (
+ const model::SharedPageDescriptor& rpDescriptor,
+ const bool bIsInSelection) const;
};
+/** Handle events during drag-and-drop.
+*/
+class DragAndDropModeHandler : public SelectionFunction::ModeHandler
+{
+public:
+ DragAndDropModeHandler (
+ SlideSorter& rSlideSorter,
+ SelectionFunction& rSelectionFunction,
+ const Point& rMousePosition,
+ ::Window* pWindow);
+ virtual ~DragAndDropModeHandler (void);
+
+ virtual SelectionFunction::Mode GetMode (void) const;
+ virtual void Abort (void);
+
+protected:
+ virtual bool ProcessButtonUpEvent (SelectionFunction::EventDescriptor& rDescriptor);
+ virtual bool ProcessDragEvent (SelectionFunction::EventDescriptor& rDescriptor);
+
+private:
+ ::boost::scoped_ptr<DragAndDropContext> mpDragAndDropContext;
+};
+
+
+/** 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);
SelectionFunction::SelectionFunction (
SlideSorter& rSlideSorter,
SfxRequest& rRequest)
- : SlideFunction (rSlideSorter, rRequest),
+ : FuPoor (
+ rSlideSorter.GetViewShell(),
+ rSlideSorter.GetContentWindow().get(),
+ &rSlideSorter.GetView(),
+ rSlideSorter.GetModel().GetDocument(),
+ rRequest),
mrSlideSorter(rSlideSorter),
mrController(mrSlideSorter.GetController()),
mbDragSelection(false),
maInsertionMarkerBox(),
mbProcessingMouseButtonDown(false),
- mpSubstitutionHandler(new SubstitutionHandler(mrSlideSorter))
+ mnShiftKeySelectionAnchor(-1),
+ mpModeHandler(new NormalModeHandler(rSlideSorter, *this))
{
- //af aDelayToScrollTimer.SetTimeout(50);
- aDragTimer.SetTimeoutHdl( LINK( this, SelectionFunction, DragSlideHdl ) );
}
+
+
+
SelectionFunction::~SelectionFunction (void)
{
- aDragTimer.Stop();
+ mpModeHandler.reset();
}
@@ -196,9 +402,10 @@ BOOL SelectionFunction::MouseButtonDown (const MouseEvent& rEvent)
{
// #95491# remember button state for creation of own MouseEvents
SetMouseButtonCode (rEvent.GetButtons());
+ aMDPos = rEvent.GetPosPixel();
mbProcessingMouseButtonDown = true;
- mpWindow->CaptureMouse();
+ // mpWindow->CaptureMouse();
ProcessMouseEvent(BUTTON_DOWN, rEvent);
@@ -210,45 +417,7 @@ BOOL SelectionFunction::MouseButtonDown (const MouseEvent& rEvent)
BOOL SelectionFunction::MouseMove (const MouseEvent& rEvent)
{
- Point aMousePosition (rEvent.GetPosPixel());
-
- // Determine page under mouse and show the mouse over effect.
- model::SharedPageDescriptor pHitDescriptor (mrController.GetPageAt(aMousePosition));
- view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay());
- rOverlay.GetMouseOverIndicatorOverlay().SetSlideUnderMouse(
- rEvent.IsLeaveWindow() ? model::SharedPageDescriptor() : pHitDescriptor);
- if (pHitDescriptor.get() != NULL)
- rOverlay.GetMouseOverIndicatorOverlay().setVisible(true);
- else
- rOverlay.GetMouseOverIndicatorOverlay().setVisible(false);
-
- // Allow one mouse move before the drag timer is disabled.
- if (aDragTimer.IsActive())
- {
- if (bFirstMouseMove)
- bFirstMouseMove = FALSE;
- else
- aDragTimer.Stop();
- }
-
- Rectangle aRectangle (Point(0,0),mpWindow->GetOutputSizePixel());
- if ( ! aRectangle.IsInside(aMousePosition)
- && rOverlay.GetSubstitutionOverlay().isVisible())
- {
- // Mouse left the window with pressed left button. Make it a drag.
- StartDrag();
- }
- else
- {
- // Call ProcessMouseEvent() only when one of the buttons is
- // pressed. This prevents calling the method on every motion.
- if (rEvent.GetButtons() != 0
- && mbProcessingMouseButtonDown)
- {
- ProcessMouseEvent(MOUSE_MOTION, rEvent);
- }
- }
-
+ ProcessMouseEvent(MOUSE_MOTION, rEvent);
return TRUE;
}
@@ -259,16 +428,10 @@ BOOL SelectionFunction::MouseButtonUp (const MouseEvent& rEvent)
{
mrController.GetScrollBarManager().StopAutoScroll ();
- // #95491# remember button state for creation of own MouseEvents
- SetMouseButtonCode (rEvent.GetButtons());
-
- if (aDragTimer.IsActive())
- aDragTimer.Stop();
-
ProcessMouseEvent(BUTTON_UP, rEvent);
mbProcessingMouseButtonDown = false;
- mpWindow->ReleaseMouse();
+// mpWindow->ReleaseMouse();
return TRUE;
}
@@ -276,39 +439,62 @@ BOOL SelectionFunction::MouseButtonUp (const MouseEvent& rEvent)
+void SelectionFunction::NotifyDragFinished (void)
+{
+ SwitchToNormalMode();
+}
+
+
+
+
BOOL SelectionFunction::KeyInput (const KeyEvent& rEvent)
{
+ view::SlideSorterView::DrawLock aDrawLock (mrSlideSorter);
+ PageSelector::UpdateLock aLock (mrSlideSorter);
FocusManager& rFocusManager (mrController.GetFocusManager());
BOOL bResult = FALSE;
- switch (rEvent.GetKeyCode().GetCode())
+ const KeyCode& rCode (rEvent.GetKeyCode());
+ switch (rCode.GetCode())
{
case KEY_RETURN:
- if (rFocusManager.HasFocus())
+ {
+ model::SharedPageDescriptor pDescriptor (rFocusManager.GetFocusedPageDescriptor());
+ ViewShell* pViewShell = mrSlideSorter.GetViewShell();
+ if (rFocusManager.HasFocus() && pDescriptor && pViewShell!=NULL)
{
- model::SharedPageDescriptor pDescriptor (rFocusManager.GetFocusedPageDescriptor());
- if (pDescriptor.get() != NULL)
+ // The Return key triggers different functions depending on
+ // whether the slide sorter is the main view or displayed in
+ // the right pane.
+ if (pViewShell->IsMainViewShell())
+ {
+ mpModeHandler->SetCurrentPage(pDescriptor);
+ mpModeHandler->SwitchView(pDescriptor);
+ }
+ else
{
- SetCurrentPage(pDescriptor);
- SwitchView(pDescriptor);
+ pViewShell->GetDispatcher()->Execute(
+ SID_INSERTPAGE,
+ SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD);
}
bResult = TRUE;
}
break;
+ }
case KEY_TAB:
if ( ! rFocusManager.IsFocusShowing())
+ {
rFocusManager.ShowFocus();
- else
- if (rEvent.GetKeyCode().IsShift())
- rFocusManager.MoveFocus (FocusManager::FMD_LEFT);
- else
- rFocusManager.MoveFocus (FocusManager::FMD_RIGHT);
- bResult = TRUE;
+ bResult = TRUE;
+ }
break;
case KEY_ESCAPE:
- rFocusManager.SetFocusToToolBox();
+ // When there is an active multiselection or drag-and-drop
+ // operation then stop that.
+ mpModeHandler->Abort();
+ SwitchToNormalMode();
bResult = TRUE;
break;
@@ -316,12 +502,10 @@ BOOL SelectionFunction::KeyInput (const KeyEvent& rEvent)
{
// Toggle the selection state.
model::SharedPageDescriptor pDescriptor (rFocusManager.GetFocusedPageDescriptor());
- if (pDescriptor.get() != NULL)
+ if (pDescriptor && rCode.IsMod1())
{
- // Doing a multi selection by default. Can we ask the event
- // for the state of the shift key?
- if (pDescriptor->IsSelected())
- mrController.GetPageSelector().DeselectPage(pDescriptor);
+ if (pDescriptor->HasState(model::PageDescriptor::ST_Selected))
+ mrController.GetPageSelector().DeselectPage(pDescriptor, false);
else
mrController.GetPageSelector().SelectPage(pDescriptor);
}
@@ -332,25 +516,25 @@ BOOL SelectionFunction::KeyInput (const KeyEvent& rEvent)
// Move the focus indicator left.
case KEY_LEFT:
- rFocusManager.MoveFocus (FocusManager::FMD_LEFT);
+ MoveFocus(FocusManager::FMD_LEFT, rCode.IsShift(), rCode.IsMod1());
bResult = TRUE;
break;
// Move the focus indicator right.
case KEY_RIGHT:
- rFocusManager.MoveFocus (FocusManager::FMD_RIGHT);
+ MoveFocus(FocusManager::FMD_RIGHT, rCode.IsShift(), rCode.IsMod1());
bResult = TRUE;
break;
// Move the focus indicator up.
case KEY_UP:
- rFocusManager.MoveFocus (FocusManager::FMD_UP);
+ MoveFocus(FocusManager::FMD_UP, rCode.IsShift(), rCode.IsMod1());
bResult = TRUE;
break;
// Move the focus indicator down.
case KEY_DOWN:
- rFocusManager.MoveFocus (FocusManager::FMD_DOWN);
+ MoveFocus(FocusManager::FMD_DOWN, rCode.IsShift(), rCode.IsMod1());
bResult = TRUE;
break;
@@ -366,36 +550,35 @@ BOOL SelectionFunction::KeyInput (const KeyEvent& rEvent)
bResult = TRUE;
break;
+ case KEY_HOME:
+ GotoPage(0);
+ bResult = TRUE;
+ break;
+
+ case KEY_END:
+ GotoPage(mrSlideSorter.GetModel().GetPageCount()-1);
+ bResult = TRUE;
+ break;
+
case KEY_DELETE:
case KEY_BACKSPACE:
{
- if (mrController.GetProperties()->IsUIReadOnly())
+ if (mrSlideSorter.GetProperties()->IsUIReadOnly())
break;
- int nSelectedPagesCount = 0;
-
- // Count the selected pages and look if there any objects on any
- // of the selected pages so that we can warn the user and
- // prevent an accidental deletion.
- model::PageEnumeration aSelectedPages (
- model::PageEnumerationProvider::CreateSelectedPagesEnumeration(
- mrSlideSorter.GetModel()));
- while (aSelectedPages.HasMoreElements())
- {
- nSelectedPagesCount++;
- aSelectedPages.GetNextElement();
- }
-
- if (nSelectedPagesCount > 0)
- mrController.GetSelectionManager()->DeleteSelectedPages();
+ mrController.GetSelectionManager()->DeleteSelectedPages(rCode.GetCode()==KEY_DELETE);
+ mnShiftKeySelectionAnchor = -1;
bResult = TRUE;
}
break;
case KEY_F10:
- if (rEvent.GetKeyCode().IsShift())
- ProcessKeyEvent(rEvent);
+ if (rCode.IsShift())
+ {
+ mpModeHandler->SelectOnePage(
+ mrSlideSorter.GetController().GetFocusManager().GetFocusedPageDescriptor());
+ }
break;
default:
@@ -403,7 +586,7 @@ BOOL SelectionFunction::KeyInput (const KeyEvent& rEvent)
}
if ( ! bResult)
- bResult = SlideFunction::KeyInput (rEvent);
+ bResult = FuPoor::KeyInput(rEvent);
return bResult;
}
@@ -411,6 +594,73 @@ BOOL SelectionFunction::KeyInput (const KeyEvent& rEvent)
+void SelectionFunction::MoveFocus (
+ const FocusManager::FocusMoveDirection eDirection,
+ const bool bIsShiftDown,
+ const bool bIsControlDown)
+{
+ // Remember the anchor of shift key multi selection.
+ if (bIsShiftDown)
+ {
+ if (mnShiftKeySelectionAnchor<0)
+ {
+ model::SharedPageDescriptor pFocusedDescriptor (
+ mrController.GetFocusManager().GetFocusedPageDescriptor());
+ mnShiftKeySelectionAnchor = pFocusedDescriptor->GetPageIndex();
+ }
+ }
+ else if ( ! bIsControlDown)
+ ResetShiftKeySelectionAnchor();
+
+ mrController.GetFocusManager().MoveFocus(eDirection);
+
+ PageSelector& rSelector (mrController.GetPageSelector());
+ model::SharedPageDescriptor pFocusedDescriptor (
+ mrController.GetFocusManager().GetFocusedPageDescriptor());
+ if (bIsShiftDown)
+ {
+ // When shift is pressed then select all pages in the range between
+ // the currently and the previously focused pages, including them.
+ if (pFocusedDescriptor)
+ {
+ sal_Int32 nPageRangeEnd (pFocusedDescriptor->GetPageIndex());
+ model::PageEnumeration aPages (
+ model::PageEnumerationProvider::CreateAllPagesEnumeration(
+ mrSlideSorter.GetModel()));
+ while (aPages.HasMoreElements())
+ {
+ model::SharedPageDescriptor pDescriptor (aPages.GetNextElement());
+ if (pDescriptor)
+ {
+ const sal_Int32 nPageIndex(pDescriptor->GetPageIndex());
+ if ((nPageIndex>=mnShiftKeySelectionAnchor && nPageIndex<=nPageRangeEnd)
+ || (nPageIndex<=mnShiftKeySelectionAnchor && nPageIndex>=nPageRangeEnd))
+ {
+ rSelector.SelectPage(pDescriptor);
+ }
+ else
+ {
+ rSelector.DeselectPage(pDescriptor);
+ }
+ }
+ }
+ }
+ }
+ else if (bIsControlDown)
+ {
+ // When control is pressed then do not alter the selection or the
+ // current page, just move the focus.
+ }
+ else
+ {
+ // Without shift just select the focused page.
+ mpModeHandler->SelectOnePage(pFocusedDescriptor);
+ }
+}
+
+
+
+
void SelectionFunction::Activate()
{
FuPoor::Activate();
@@ -442,7 +692,7 @@ void SelectionFunction::ScrollEnd (void)
void SelectionFunction::DoCut (void)
{
- if ( ! mrController.GetProperties()->IsUIReadOnly())
+ if ( ! mrSlideSorter.GetProperties()->IsUIReadOnly())
{
mrController.GetClipboard().DoCut();
}
@@ -461,7 +711,7 @@ void SelectionFunction::DoCopy (void)
void SelectionFunction::DoPaste (void)
{
- if ( ! mrController.GetProperties()->IsUIReadOnly())
+ if ( ! mrSlideSorter.GetProperties()->IsUIReadOnly())
{
mrController.GetClipboard().DoPaste();
}
@@ -470,258 +720,316 @@ void SelectionFunction::DoPaste (void)
-void SelectionFunction::Paint (const Rectangle&, ::sd::Window* )
+bool SelectionFunction::cancel (void)
{
+ mrController.GetFocusManager().ToggleFocus();
+ return true;
}
-IMPL_LINK( SelectionFunction, DragSlideHdl, Timer*, EMPTYARG )
+void SelectionFunction::GotoNextPage (int nOffset)
{
- StartDrag();
- return 0;
+ model::SharedPageDescriptor pDescriptor
+ = mrController.GetCurrentSlideManager()->GetCurrentSlide();
+ if (pDescriptor.get() != NULL)
+ {
+ SdPage* pPage = pDescriptor->GetPage();
+ OSL_ASSERT(pPage!=NULL);
+ sal_Int32 nIndex = (pPage->GetPageNum()-1) / 2;
+ GotoPage(nIndex + nOffset);
+ }
+ ResetShiftKeySelectionAnchor();
}
-void SelectionFunction::StartDrag (void)
+void SelectionFunction::GotoPage (int nIndex)
{
- if (mbPageHit
- && ! mrController.GetProperties()->IsUIReadOnly())
+ USHORT nPageCount = (USHORT)mrSlideSorter.GetModel().GetPageCount();
+
+ if (nIndex >= nPageCount)
+ nIndex = nPageCount - 1;
+ if (nIndex < 0)
+ nIndex = 0;
+
+ mrController.GetFocusManager().SetFocusedPage(nIndex);
+ model::SharedPageDescriptor pNextPageDescriptor (
+ mrSlideSorter.GetModel().GetPageDescriptor (nIndex));
+ if (pNextPageDescriptor.get() != NULL)
+ mpModeHandler->SetCurrentPage(pNextPageDescriptor);
+ else
{
- view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay());
- mpSubstitutionHandler->Start(rOverlay.GetSubstitutionOverlay().GetPosition());
- mbPageHit = false;
- mpWindow->ReleaseMouse();
-
- if (mrSlideSorter.GetViewShell() != NULL)
- {
- SlideSorterViewShell* pSlideSorterViewShell
- = dynamic_cast<SlideSorterViewShell*>(mrSlideSorter.GetViewShell());
- pSlideSorterViewShell->StartDrag (
- rOverlay.GetSubstitutionOverlay().GetPosition(),
- mpWindow);
- }
+ OSL_ASSERT(pNextPageDescriptor.get() != NULL);
}
+ ResetShiftKeySelectionAnchor();
}
-bool SelectionFunction::cancel (void)
+void SelectionFunction::ProcessMouseEvent (sal_uInt32 nEventType, const MouseEvent& rEvent)
{
- mrController.GetFocusManager().ToggleFocus();
- return true;
+ // #95491# remember button state for creation of own MouseEvents
+ SetMouseButtonCode (rEvent.GetButtons());
+
+ EventDescriptor aEventDescriptor (nEventType, rEvent, mrSlideSorter);
+ ProcessEvent(aEventDescriptor);
}
-void SelectionFunction::SelectHitPage (const model::SharedPageDescriptor& rpDescriptor)
+void SelectionFunction::MouseDragged (
+ const AcceptDropEvent& rEvent,
+ const sal_Int8 nDragAction)
{
- mrController.GetPageSelector().SelectPage(rpDescriptor);
+ EventDescriptor aEventDescriptor (MOUSE_DRAG, rEvent, nDragAction, mrSlideSorter);
+ ProcessEvent(aEventDescriptor);
}
-void SelectionFunction::DeselectHitPage (const model::SharedPageDescriptor& rpDescriptor)
+void SelectionFunction::ProcessKeyEvent (const KeyEvent& rEvent)
{
- mrController.GetPageSelector().DeselectPage(rpDescriptor);
+ EventDescriptor aEventDescriptor (rEvent, mrSlideSorter);
+ ProcessEvent(aEventDescriptor);
}
-void SelectionFunction::DeselectAllPages (void)
+void SelectionFunction::ProcessEvent (EventDescriptor& rDescriptor)
{
- mrController.GetPageSelector().DeselectAllPages();
+ // The call to ProcessEvent may switch to another mode handler.
+ // Prevent the untimely destruction of the called handler by aquiring a
+ // temporary reference here.
+ ::boost::shared_ptr<ModeHandler> pModeHandler (mpModeHandler);
+ pModeHandler->ProcessEvent(rDescriptor);
}
-void SelectionFunction::StartRectangleSelection (const Point& rMouseModelPosition)
+bool Match (
+ const sal_uInt32 nEventCode,
+ const sal_uInt32 nPositivePattern)
{
- if (mrController.GetProperties()->IsShowSelection())
- {
- mrSlideSorter.GetView().GetOverlay().GetSelectionRectangleOverlay().Start(
- rMouseModelPosition);
- }
+ return (nEventCode & nPositivePattern)==nPositivePattern;
+}
+
+
+
+
+void SelectionFunction::SwitchToNormalMode (void)
+{
+ if (mpModeHandler->GetMode() != NormalMode)
+ SwitchMode(::boost::shared_ptr<ModeHandler>(
+ new NormalModeHandler(mrSlideSorter, *this)));
}
-void SelectionFunction::UpdateRectangleSelection (const Point& rMouseModelPosition)
+void SelectionFunction::SwitchToDragAndDropMode (const Point aMousePosition)
{
- if (mrController.GetProperties()->IsShowSelection())
+ if (mpModeHandler->GetMode() != DragAndDropMode)
{
- mrSlideSorter.GetView().GetOverlay().GetSelectionRectangleOverlay().Update(
- rMouseModelPosition);
+ SwitchMode(::boost::shared_ptr<ModeHandler>(
+ new DragAndDropModeHandler(mrSlideSorter, *this, aMousePosition, mpWindow)));
}
}
-void SelectionFunction::ProcessRectangleSelection (bool bToggleSelection)
+void SelectionFunction::SwitchToMultiSelectionMode (
+ const Point aMousePosition,
+ const sal_uInt32 nEventCode)
{
- if ( ! mrController.GetProperties()->IsShowSelection())
- return;
+ if (mpModeHandler->GetMode() != MultiSelectionMode)
+ SwitchMode(::boost::shared_ptr<ModeHandler>(
+ new MultiSelectionModeHandler(mrSlideSorter, *this, aMousePosition, nEventCode)));
+}
- view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay());
- if (rOverlay.GetSelectionRectangleOverlay().isVisible())
+
+
+
+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)
{
- PageSelector& rSelector (mrController.GetPageSelector());
-
- rOverlay.GetSelectionRectangleOverlay().setVisible(false);
-
- // Select all pages whose page object lies completly inside the drag
- // rectangle.
- const Rectangle& rSelectionRectangle (
- rOverlay.GetSelectionRectangleOverlay().GetSelectionRectangle());
- model::PageEnumeration aPages (
- model::PageEnumerationProvider::CreateAllPagesEnumeration(
- mrSlideSorter.GetModel()));
- while (aPages.HasMoreElements())
- {
- model::SharedPageDescriptor pDescriptor (aPages.GetNextElement());
- Rectangle aPageBox (mrSlideSorter.GetView().GetPageBoundingBox(
- pDescriptor,
- view::SlideSorterView::CS_MODEL,
- view::SlideSorterView::BBT_SHAPE));
- if (rSelectionRectangle.IsOver(aPageBox))
- {
- // When we are extending the selection (shift key is
- // pressed) then toggle the selection state of the page.
- // Otherwise select it: this results in the previously
- // selected pages becoming deslected.
- if (bToggleSelection && pDescriptor->IsSelected())
- rSelector.DeselectPage(pDescriptor);
- else
- rSelector.SelectPage(pDescriptor);
- }
- }
+ SwitchMode(::boost::shared_ptr<ModeHandler>(new ButtonModeHandler(mrSlideSorter, *this)));
+ return true;
}
+ else
+ return false;
}
-void SelectionFunction::PrepareMouseMotion (const Point& )
+void SelectionFunction::SwitchMode (const ::boost::shared_ptr<ModeHandler>& rpHandler)
{
- if ( ! mrController.GetProperties()->IsUIReadOnly())
+ // Not all modes allow mouse over indicator.
+ if (mpModeHandler->IsMouseOverIndicatorAllowed() != rpHandler->IsMouseOverIndicatorAllowed())
{
- bFirstMouseMove = TRUE;
- aDragTimer.Start();
+ if ( ! rpHandler->IsMouseOverIndicatorAllowed())
+ {
+ mrSlideSorter.GetView().SetPageUnderMouse(model::SharedPageDescriptor());
+ mrSlideSorter.GetView().GetButtonBar().ResetPage();
+ }
+ else
+ mrSlideSorter.GetView().UpdatePageUnderMouse(false);
}
+
+ mpModeHandler = rpHandler;
}
-void SelectionFunction::RangeSelect (const model::SharedPageDescriptor& rpDescriptor)
+void SelectionFunction::ResetShiftKeySelectionAnchor (void)
{
- PageSelector& rSelector (mrController.GetPageSelector());
+ mnShiftKeySelectionAnchor = -1;
+}
- model::SharedPageDescriptor pAnchor (rSelector.GetSelectionAnchor());
- DeselectAllPages();
- if (pAnchor.get() != NULL)
- {
- // Select all pages between the anchor and the given one, including
- // the two.
- USHORT nAnchorIndex ((pAnchor->GetPage()->GetPageNum()-1) / 2);
- USHORT nOtherIndex ((rpDescriptor->GetPage()->GetPageNum()-1) / 2);
- // Iterate over all pages in the range. Start with the anchor
- // page. This way the PageSelector will recognize it again as
- // anchor (the first selected page after a DeselectAllPages()
- // becomes the anchor.)
- USHORT nStep = (nAnchorIndex < nOtherIndex) ? +1 : -1;
- USHORT nIndex = nAnchorIndex;
- while (true)
- {
- rSelector.SelectPage(nIndex);
- if (nIndex == nOtherIndex)
- break;
- nIndex = nIndex + nStep;
- }
+
+void SelectionFunction::ResetMouseAnchor (void)
+{
+ if (mpModeHandler && mpModeHandler->GetMode() == NormalMode)
+ {
+ ::boost::shared_ptr<NormalModeHandler> pHandler (
+ ::boost::dynamic_pointer_cast<NormalModeHandler>(mpModeHandler));
+ if (pHandler)
+ pHandler->ResetButtonDownLocation();
}
}
-void SelectionFunction::GotoNextPage (int nOffset)
+//===== EventDescriptor =======================================================
+
+SelectionFunction::EventDescriptor::EventDescriptor (
+ const sal_uInt32 nEventType,
+ const MouseEvent& rEvent,
+ SlideSorter& rSlideSorter)
+ : maMousePosition(rEvent.GetPosPixel()),
+ maMouseModelPosition(),
+ mpHitDescriptor(),
+ mpHitPage(),
+ mnEventCode(nEventType),
+ mbIsOverButton(rSlideSorter.GetView().GetButtonBar().IsMouseOverButton()),
+ meDragMode(InsertionIndicatorHandler::MoveMode),
+ mbMakeSelectionVisible(true),
+ mbIsLeaving(false)
{
- model::SharedPageDescriptor pDescriptor
- = mrController.GetCurrentSlideManager()->GetCurrentSlide();
- if (pDescriptor.get() != NULL)
+ maMouseModelPosition = rSlideSorter.GetContentWindow()->PixelToLogic(maMousePosition);
+ mpHitDescriptor = rSlideSorter.GetController().GetPageAt(maMousePosition);
+ if (mpHitDescriptor)
{
- SdPage* pPage = pDescriptor->GetPage();
- OSL_ASSERT(pPage!=NULL);
- sal_Int32 nIndex = (pPage->GetPageNum()-1) / 2;
- nIndex += nOffset;
- USHORT nPageCount = (USHORT)mrSlideSorter.GetModel().GetPageCount();
-
- if (nIndex >= nPageCount)
- nIndex = nPageCount - 1;
- if (nIndex < 0)
- nIndex = 0;
-
- mrController.GetFocusManager().SetFocusedPage(nIndex);
- model::SharedPageDescriptor pNextPageDescriptor (
- mrSlideSorter.GetModel().GetPageDescriptor (nIndex));
- if (pNextPageDescriptor.get() != NULL)
- SetCurrentPage(pNextPageDescriptor);
- else
- {
- OSL_ASSERT(pNextPageDescriptor.get() != NULL);
- }
+ mpHitPage = mpHitDescriptor->GetPage();
}
+
+ mnEventCode |= EncodeMouseEvent(rEvent);
+ mnEventCode |= EncodeState();
+
+ // Detect the mouse leaving the window. When not button is pressed then
+ // we can call IsLeaveWindow at the event. Otherwise we have to make an
+ // explicit test.
+ mbIsLeaving = rEvent.IsLeaveWindow()
+ || ! Rectangle(Point(0,0),
+ rSlideSorter.GetContentWindow()->GetOutputSizePixel()).IsInside(maMousePosition);
}
-void SelectionFunction::ProcessMouseEvent (sal_uInt32 nEventType, const MouseEvent& rEvent)
+SelectionFunction::EventDescriptor::EventDescriptor (
+ const sal_uInt32 nEventType,
+ const AcceptDropEvent& rEvent,
+ const sal_Int8 nDragAction,
+ SlideSorter& rSlideSorter)
+ : maMousePosition(rEvent.maPosPixel),
+ maMouseModelPosition(),
+ mpHitDescriptor(),
+ mpHitPage(),
+ mnEventCode(nEventType),
+ mbIsOverButton(rSlideSorter.GetView().GetButtonBar().IsMouseOverButton()),
+ meDragMode(InsertionIndicatorHandler::GetModeFromDndAction(nDragAction)),
+ mbMakeSelectionVisible(true),
+ mbIsLeaving(false)
{
- // #95491# remember button state for creation of own MouseEvents
- SetMouseButtonCode (rEvent.GetButtons());
+ maMouseModelPosition = rSlideSorter.GetContentWindow()->PixelToLogic(maMousePosition);
+ mpHitDescriptor = rSlideSorter.GetController().GetPageAt(maMousePosition);
+ if (mpHitDescriptor)
+ {
+ mpHitPage = mpHitDescriptor->GetPage();
+ }
+
+ mnEventCode |= EncodeState();
+
+ // Detect the mouse leaving the window. When not button is pressed then
+ // we can call IsLeaveWindow at the event. Otherwise we have to make an
+ // explicit test.
+ mbIsLeaving = rEvent.mbLeaving
+ || ! Rectangle(Point(0,0),
+ rSlideSorter.GetContentWindow()->GetOutputSizePixel()).IsInside(maMousePosition);
+}
- // 1. Compute some frequently used values relating to the event.
- ::std::auto_ptr<EventDescriptor> pEventDescriptor (
- new EventDescriptor(nEventType, rEvent, mrSlideSorter));
- // 2. Compute a numerical code that describes the event and that is used
- // for fast look-up of the associated reaction.
- pEventDescriptor->mnEventCode = EncodeMouseEvent(*pEventDescriptor, rEvent);
- // 3. Process the event.
- EventPreprocessing(*pEventDescriptor);
- if ( ! EventProcessing(*pEventDescriptor))
+
+SelectionFunction::EventDescriptor::EventDescriptor (
+ const KeyEvent& rEvent,
+ SlideSorter& rSlideSorter)
+ : maMousePosition(),
+ maMouseModelPosition(),
+ mpHitDescriptor(),
+ mpHitPage(),
+ mnEventCode(KEY_EVENT),
+ mbIsOverButton(rSlideSorter.GetView().GetButtonBar().IsMouseOverButton()),
+ meDragMode(InsertionIndicatorHandler::MoveMode),
+ mbMakeSelectionVisible(true),
+ mbIsLeaving(false)
+{
+ model::SharedPageDescriptor pHitDescriptor (
+ rSlideSorter.GetController().GetFocusManager().GetFocusedPageDescriptor());
+ if (pHitDescriptor.get() != NULL)
{
- OSL_TRACE ("can not handle event code %x", pEventDescriptor->mnEventCode);
+ mpHitPage = pHitDescriptor->GetPage();
+ mpHitDescriptor = pHitDescriptor;
}
- EventPostprocessing(*pEventDescriptor);
- if (nEventType == BUTTON_UP)
- mbPageHit = false;
+ mnEventCode |= EncodeKeyEvent(rEvent) | EncodeState();
}
-sal_uInt32 SelectionFunction::EncodeMouseEvent (
- const EventDescriptor& rDescriptor,
+void SelectionFunction::EventDescriptor::SetDragMode (const InsertionIndicatorHandler::Mode eMode)
+{
+ meDragMode = eMode;
+}
+
+
+
+
+sal_uInt32 SelectionFunction::EventDescriptor::EncodeMouseEvent (
const MouseEvent& rEvent) const
{
// Initialize with the type of mouse event.
- sal_uInt32 nEventCode (rDescriptor.mnEventCode & (BUTTON_DOWN | BUTTON_UP | MOUSE_MOTION));
+ sal_uInt32 nEventCode (mnEventCode & (BUTTON_DOWN | BUTTON_UP | MOUSE_MOTION));
// Detect the affected button.
switch (rEvent.GetButtons())
@@ -738,28 +1046,16 @@ sal_uInt32 SelectionFunction::EncodeMouseEvent (
case 2: nEventCode |= DOUBLE_CLICK; break;
}
- // Detect whether the event has happened over a page object.
- if (rDescriptor.mpHitPage != NULL && ! rDescriptor.mpHitDescriptor.expired())
- {
- model::SharedPageDescriptor pHitDescriptor (rDescriptor.mpHitDescriptor);
- if (pHitDescriptor->IsSelected())
- nEventCode |= OVER_SELECTED_PAGE;
- else
- nEventCode |= OVER_UNSELECTED_PAGE;
- }
-
// Detect pressed modifier keys.
if (rEvent.IsShift())
nEventCode |= SHIFT_MODIFIER;
if (rEvent.IsMod1())
nEventCode |= CONTROL_MODIFIER;
- // Detect whether we are dragging pages or dragging a selection rectangle.
- view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay());
- if (rOverlay.GetSubstitutionOverlay().isVisible())
- nEventCode |= SUBSTITUTION_VISIBLE;
- if (rOverlay.GetSelectionRectangleOverlay().isVisible())
- nEventCode |= RECTANGLE_VISIBLE;
+ // Detect whether the mouse is over one of the active elements inside a
+ // page object.
+ if (mbIsOverButton)
+ nEventCode |= OVER_BUTTON;
return nEventCode;
}
@@ -767,551 +1063,962 @@ sal_uInt32 SelectionFunction::EncodeMouseEvent (
-void SelectionFunction::ProcessKeyEvent (const KeyEvent& rEvent)
+sal_uInt32 SelectionFunction::EventDescriptor::EncodeKeyEvent (const KeyEvent& rEvent) const
{
- // 1. Compute some frequently used values relating to the event.
- ::std::auto_ptr<EventDescriptor> pEventDescriptor (
- new EventDescriptor(rEvent, mrSlideSorter));
+ // The key code in the lower 16 bit.
+ sal_uInt32 nEventCode (rEvent.GetKeyCode().GetCode());
- // 2. Encode the event.
- pEventDescriptor->mnEventCode = EncodeKeyEvent(*pEventDescriptor, rEvent);
+ // Detect pressed modifier keys.
+ if (rEvent.GetKeyCode().IsShift())
+ nEventCode |= SHIFT_MODIFIER;
+ if (rEvent.GetKeyCode().IsMod1())
+ nEventCode |= CONTROL_MODIFIER;
- // 3. Process the event.
- EventPreprocessing(*pEventDescriptor);
- if ( ! EventProcessing(*pEventDescriptor))
- OSL_TRACE ("can not handle event code %x", pEventDescriptor->mnEventCode);
- EventPostprocessing(*pEventDescriptor);
+ return nEventCode;
}
-sal_uInt32 SelectionFunction::EncodeKeyEvent (
- const EventDescriptor& rDescriptor,
- const KeyEvent& rEvent) const
+sal_uInt32 SelectionFunction::EventDescriptor::EncodeState (void) const
{
- // Initialize as key event.
- sal_uInt32 nEventCode (KEY_EVENT);
-
- // Add the actual key code in the lower 16 bit.
- nEventCode |= rEvent.GetKeyCode().GetCode();
-
- // Detect pressed modifier keys.
- if (rEvent.GetKeyCode().IsShift())
- nEventCode |= SHIFT_MODIFIER;
- if (rEvent.GetKeyCode().IsMod1())
- nEventCode |= CONTROL_MODIFIER;
+ sal_uInt32 nEventCode (0);
// Detect whether the event has happened over a page object.
- if (rDescriptor.mpHitPage != NULL && ! rDescriptor.mpHitDescriptor.expired())
+ if (mpHitPage!=NULL && mpHitDescriptor)
{
- model::SharedPageDescriptor pHitDescriptor (rDescriptor.mpHitDescriptor);
- if (pHitDescriptor->IsSelected())
+ if (mpHitDescriptor->HasState(model::PageDescriptor::ST_Selected))
nEventCode |= OVER_SELECTED_PAGE;
else
nEventCode |= OVER_UNSELECTED_PAGE;
- }
- // Detect whether we are dragging pages or dragging a selection rectangle.
- view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay());
- if (rOverlay.GetSubstitutionOverlay().isVisible())
- nEventCode |= SUBSTITUTION_VISIBLE;
- if (rOverlay.GetSelectionRectangleOverlay().isVisible())
- nEventCode |= RECTANGLE_VISIBLE;
+ // Detect whether the mouse is over one of the active elements
+ // inside a page object.
+ if (mbIsOverButton)
+ nEventCode |= OVER_BUTTON;
+ }
return nEventCode;
}
-void SelectionFunction::EventPreprocessing (const EventDescriptor& rDescriptor)
+
+//===== SelectionFunction::ModeHandler ========================================
+
+SelectionFunction::ModeHandler::ModeHandler (
+ SlideSorter& rSlideSorter,
+ SelectionFunction& rSelectionFunction,
+ const bool bIsMouseOverIndicatorAllowed)
+ : mrSlideSorter(rSlideSorter),
+ mrSelectionFunction(rSelectionFunction),
+ mbIsMouseOverIndicatorAllowed(bIsMouseOverIndicatorAllowed)
+{
+}
+
+
+
+
+SelectionFunction::ModeHandler::~ModeHandler (void)
{
- // Some general processing that is not specific to the exact event code.
- if (rDescriptor.mnEventCode & BUTTON_DOWN)
- mbPageHit = (rDescriptor.mpHitPage!=NULL);
+}
+
+
- // Set the focus to the slide under the mouse.
- if (rDescriptor.mpHitPage != NULL)
- mrController.GetFocusManager().FocusPage((rDescriptor.mpHitPage->GetPageNum()-1)/2);
+
+void SelectionFunction::ModeHandler::ReprocessEvent (EventDescriptor& rDescriptor)
+{
+ mrSelectionFunction.ProcessEvent(rDescriptor);
}
-bool SelectionFunction::EventProcessing (const EventDescriptor& rDescriptor)
+void SelectionFunction::ModeHandler::ProcessEvent (
+ SelectionFunction::EventDescriptor& rDescriptor)
{
- // Define some macros to make the following switch statement more readable.
-#define ANY_MODIFIER(code) \
- code|NO_MODIFIER: \
- case code|SHIFT_MODIFIER: \
- case code|CONTROL_MODIFIER
-#define ANY_PAGE(code) \
- code|NOT_OVER_PAGE: \
- case code|OVER_UNSELECTED_PAGE: \
- case code|OVER_SELECTED_PAGE
-#define ANY_PAGE_AND_MODIFIER(code) \
- ANY_PAGE(code|NO_MODIFIER): \
- case ANY_PAGE(code|SHIFT_MODIFIER): \
- case ANY_PAGE(code|CONTROL_MODIFIER)
+ PageSelector::BroadcastLock aBroadcastLock (mrSlideSorter);
+ PageSelector::UpdateLock aUpdateLock (mrSlideSorter);
+
+ bool bIsProcessed (false);
+ switch (rDescriptor.mnEventCode & (BUTTON_DOWN | BUTTON_UP | MOUSE_MOTION | MOUSE_DRAG))
+ {
+ case BUTTON_DOWN:
+ bIsProcessed = ProcessButtonDownEvent(rDescriptor);
+ break;
+
+ case BUTTON_UP:
+ bIsProcessed = ProcessButtonUpEvent(rDescriptor);
+ break;
+
+ case MOUSE_MOTION:
+ bIsProcessed = ProcessMotionEvent(rDescriptor);
+ break;
+
+ case MOUSE_DRAG:
+ bIsProcessed = ProcessDragEvent(rDescriptor);
+ break;
+ }
+
+ if ( ! bIsProcessed)
+ HandleUnprocessedEvent(rDescriptor);
+}
+
+
+
+
+bool SelectionFunction::ModeHandler::ProcessButtonDownEvent (EventDescriptor&)
+{
+ return false;
+}
+
+
+
+
+bool SelectionFunction::ModeHandler::ProcessButtonUpEvent (EventDescriptor&)
+{
+ mrSelectionFunction.SwitchToNormalMode();
+ return false;
+}
+
+
+
+
+bool SelectionFunction::ModeHandler::ProcessMotionEvent (EventDescriptor& rDescriptor)
+{
+ if (mbIsMouseOverIndicatorAllowed)
+ mrSlideSorter.GetView().UpdatePageUnderMouse(
+ rDescriptor.maMousePosition,
+ (rDescriptor.mnEventCode & LEFT_BUTTON) != 0,
+ true);
+
+ if (rDescriptor.mbIsLeaving)
+ {
+ mrSelectionFunction.SwitchToNormalMode();
+ mrSlideSorter.GetView().SetPageUnderMouse(model::SharedPageDescriptor());
+
+ return true;
+ }
+ else
+ return false;
+}
+
+
+
+
+bool SelectionFunction::ModeHandler::ProcessDragEvent (EventDescriptor&)
+{
+ return false;
+}
+
+
+
+
+bool SelectionFunction::ModeHandler::HandleUnprocessedEvent (EventDescriptor&)
+{
+ return false;
+}
+
+
+
+
+void SelectionFunction::ModeHandler::SetCurrentPage (
+ const model::SharedPageDescriptor& rpDescriptor)
+{
+ SelectOnePage(rpDescriptor);
+ mrSlideSorter.GetController().GetCurrentSlideManager()->SwitchCurrentSlide(rpDescriptor);
+}
+
+
- bool bResult (true);
- bool bMakeSelectionVisible (true);
+void SelectionFunction::ModeHandler::DeselectAllPages (void)
+{
+ mrSlideSorter.GetController().GetPageSelector().DeselectAllPages();
+ mrSelectionFunction.ResetShiftKeySelectionAnchor();
+}
+
+
+
+
+void SelectionFunction::ModeHandler::SelectOnePage (
+ const model::SharedPageDescriptor& rpDescriptor)
+{
+ DeselectAllPages();
+ mrSlideSorter.GetController().GetPageSelector().SelectPage(rpDescriptor);
+}
+
+
+
+
+void SelectionFunction::ModeHandler::SwitchView (const model::SharedPageDescriptor& rpDescriptor)
+{
+ // Switch to the draw view. This is done only when the current
+ // view is the main view.
+ ViewShell* pViewShell = mrSlideSorter.GetViewShell();
+ if (pViewShell!=NULL && pViewShell->IsMainViewShell())
+ {
+ if (rpDescriptor.get()!=NULL && rpDescriptor->GetPage()!=NULL)
+ {
+ mrSlideSorter.GetModel().GetDocument()->SetSelected(rpDescriptor->GetPage(), TRUE);
+ pViewShell->GetFrameView()->SetSelectedPage(
+ (rpDescriptor->GetPage()->GetPageNum()-1)/2);
+ }
+ if (mrSlideSorter.GetViewShellBase() != NULL)
+ framework::FrameworkHelper::Instance(*mrSlideSorter.GetViewShellBase())->RequestView(
+ framework::FrameworkHelper::msImpressViewURL,
+ framework::FrameworkHelper::msCenterPaneURL);
+ }
+}
+
+
+
+
+void SelectionFunction::ModeHandler::StartDrag (
+ const Point& rMousePosition,
+ const InsertionIndicatorHandler::Mode eMode)
+{
+ (void)eMode;
+ // Do not start a drag-and-drop operation when one is already active.
+ // (when dragging pages from one document into another, pressing a
+ // modifier key can trigger a MouseMotion event in the originating
+ // window (focus still in there). Together with the mouse button pressed
+ // (drag-and-drop is active) this triggers the start of drag-and-drop.)
+ if (SD_MOD()->pTransferDrag != NULL)
+ return;
+
+ if ( ! mrSlideSorter.GetProperties()->IsUIReadOnly())
+ {
+ mrSelectionFunction.SwitchToDragAndDropMode(rMousePosition);
+ }
+}
+
+
+
+
+bool SelectionFunction::ModeHandler::IsMouseOverIndicatorAllowed (void) const
+{
+ return mbIsMouseOverIndicatorAllowed;
+}
+
+
+
+
+//===== NormalModeHandler =====================================================
+
+NormalModeHandler::NormalModeHandler (
+ SlideSorter& rSlideSorter,
+ SelectionFunction& rSelectionFunction)
+ : ModeHandler(rSlideSorter, rSelectionFunction, true),
+ maButtonDownLocation()
+{
+}
+
+
+
+
+NormalModeHandler::~NormalModeHandler (void)
+{
+}
+
+
+
+
+SelectionFunction::Mode NormalModeHandler::GetMode (void) const
+{
+ return SelectionFunction::NormalMode;
+}
+
+
+
+
+void NormalModeHandler::Abort (void)
+{
+}
+
- mrController.GetPageSelector().DisableBroadcasting();
- // 2b. With the event code determine the type of operation with which to
- // react to the event.
- // Acquire a shared_ptr to the hit page descriptor.
- model::SharedPageDescriptor pHitDescriptor;
- if ( ! rDescriptor.mpHitDescriptor.expired())
- pHitDescriptor = model::SharedPageDescriptor(rDescriptor.mpHitDescriptor);
+bool NormalModeHandler::ProcessButtonDownEvent (
+ SelectionFunction::EventDescriptor& rDescriptor)
+{
+ // Remember the location where the left button is pressed. With
+ // that we can filter away motion events that are caused by key
+ // presses. We also can tune the minimal motion distance that
+ // triggers a drag-and-drop operation.
+ if ((rDescriptor.mnEventCode & BUTTON_DOWN) != 0)
+ maButtonDownLocation = rDescriptor.maMousePosition;
switch (rDescriptor.mnEventCode)
{
case BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | OVER_UNSELECTED_PAGE:
- SetCurrentPage(pHitDescriptor);
- PrepareMouseMotion(mpWindow->PixelToLogic(rDescriptor.maMousePosition));
- mpSubstitutionHandler->Start(rDescriptor.maMouseModelPosition);
- break;
-
- case BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE:
- SetCurrentPage(pHitDescriptor);
- mpSubstitutionHandler->End();
+ SetCurrentPage(rDescriptor.mpHitDescriptor);
break;
case BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE:
- PrepareMouseMotion(mpWindow->PixelToLogic(rDescriptor.maMousePosition));
- mpSubstitutionHandler->Start(rDescriptor.maMouseModelPosition);
break;
case BUTTON_DOWN | LEFT_BUTTON | DOUBLE_CLICK | OVER_SELECTED_PAGE:
case BUTTON_DOWN | LEFT_BUTTON | DOUBLE_CLICK | OVER_UNSELECTED_PAGE:
// A double click allways shows the selected slide in the center
// pane in an edit view.
- SetCurrentPage(pHitDescriptor);
- SwitchView(pHitDescriptor);
- break;
-
- // Multi selection with the control modifier.
- case BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE | CONTROL_MODIFIER:
- DeselectHitPage(pHitDescriptor);
- PrepareMouseMotion(mpWindow->PixelToLogic(rDescriptor.maMousePosition));
- break;
-
- case BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK | OVER_UNSELECTED_PAGE | CONTROL_MODIFIER:
- SelectHitPage(pHitDescriptor);
- PrepareMouseMotion(mpWindow->PixelToLogic(rDescriptor.maMousePosition));
-
+ SetCurrentPage(rDescriptor.mpHitDescriptor);
+ SwitchView(rDescriptor.mpHitDescriptor);
break;
- // Range selection with the shift modifier.
case BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE | SHIFT_MODIFIER:
case BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | OVER_UNSELECTED_PAGE | SHIFT_MODIFIER:
- RangeSelect(pHitDescriptor);
+ // Range selection with the shift modifier.
+ RangeSelect(rDescriptor.mpHitDescriptor);
break;
- // Was: Preview of the page transition effect.
- case BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | OVER_FADE_INDICATOR:
- // No action.
+ 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.
+ // Right button for context menu.
case BUTTON_DOWN | RIGHT_BUTTON | SINGLE_CLICK | OVER_UNSELECTED_PAGE:
- case KEY_EVENT | KEY_F10 | SHIFT_MODIFIER | OVER_UNSELECTED_PAGE:
// Single right click and shift+F10 select as preparation to
// show the context menu. Change the selection only when the
// page under the mouse is not selected. In this case the
// selection is set to this single page. Otherwise the
// selection is not modified.
- DeselectAllPages();
- SelectHitPage(pHitDescriptor);
- SetCurrentPage(pHitDescriptor);
- bMakeSelectionVisible = false;
+ SetCurrentPage(rDescriptor.mpHitDescriptor);
+ rDescriptor.mbMakeSelectionVisible = false;
break;
case BUTTON_DOWN | RIGHT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE:
- case KEY_EVENT | KEY_F10 | OVER_SELECTED_PAGE | SHIFT_MODIFIER:
// Do not change the selection. Just adjust the insertion indicator.
- bMakeSelectionVisible = false;
+ rDescriptor.mbMakeSelectionVisible = false;
break;
case BUTTON_DOWN | RIGHT_BUTTON | SINGLE_CLICK | NOT_OVER_PAGE:
- // The Shift+F10 key event is here just for completeness. It should
- // not be possible to really receive this (not being over a page.)
- case KEY_EVENT | KEY_F10 | SHIFT_MODIFIER | NOT_OVER_PAGE:
+ // Remember the current selection so that when a multi selection
+ // is started, we can restore the previous selection.
+ mrSlideSorter.GetModel().SaveCurrentSelection();
DeselectAllPages();
- bMakeSelectionVisible = false;
break;
- // A mouse motion without visible substitution starts that.
- case ANY_MODIFIER(MOUSE_MOTION | LEFT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE):
- mrController.GetScrollBarManager().AutoScroll(rDescriptor.maMousePosition);
- mpSubstitutionHandler->Start(rDescriptor.maMouseModelPosition);
+ case ANY_MODIFIER(BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | NOT_OVER_PAGE):
+ // Remember the current selection so that when a multi selection
+ // is started, we can restore the previous selection.
+ mrSlideSorter.GetModel().SaveCurrentSelection();
+ DeselectAllPages();
break;
- // Move substitution.
- case ANY_PAGE_AND_MODIFIER(MOUSE_MOTION | LEFT_BUTTON | SINGLE_CLICK | SUBSTITUTION_VISIBLE):
- if ((rDescriptor.mnEventCode & CONTROL_MODIFIER) != 0)
- StartDrag();
- mrController.GetScrollBarManager().AutoScroll(rDescriptor.maMousePosition);
- mpSubstitutionHandler->UpdatePosition(rDescriptor.maMouseModelPosition);
+ default:
+ return false;
+ }
+ return true;
+}
+
+
+
+
+bool NormalModeHandler::ProcessButtonUpEvent (
+ SelectionFunction::EventDescriptor& rDescriptor)
+{
+ bool bIsProcessed (true);
+ switch (rDescriptor.mnEventCode)
+ {
+ case BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE:
+ SetCurrentPage(rDescriptor.mpHitDescriptor);
break;
- // Place substitution.
- case ANY_PAGE_AND_MODIFIER(BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK | SUBSTITUTION_VISIBLE):
- // When the substitution has not been moved the button up event
- // is taken to be part of a single click. The selected pages
- // are therefore not moved (which technically would be necessary
- // for unconsecutive multi selections). Instead the page under
- // the mouse becomes the only selected page.
- if (mpSubstitutionHandler->HasBeenMoved())
- {
- // The following Process() call may lead to the desctruction
- // of pHitDescriptor so release our reference to it.
- pHitDescriptor.reset();
- mpSubstitutionHandler->Process();
- }
- else
- if (pHitDescriptor != NULL)
- SetCurrentPage(pHitDescriptor);
- mpSubstitutionHandler->End();
+ // Multi selection with the control modifier.
+ case BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE | CONTROL_MODIFIER:
+ mrSlideSorter.GetController().GetPageSelector().DeselectPage(
+ rDescriptor.mpHitDescriptor);
break;
- // Rectangle selection.
- case BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | NOT_OVER_PAGE | NO_MODIFIER:
- DeselectAllPages();
- StartRectangleSelection(rDescriptor.maMouseModelPosition);
+ 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);
+ break;
+ case BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK | NOT_OVER_PAGE:
break;
- case BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | NOT_OVER_PAGE | SHIFT_MODIFIER:
- case BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | NOT_OVER_PAGE | CONTROL_MODIFIER:
- StartRectangleSelection(rDescriptor.maMouseModelPosition);
+ default:
+ bIsProcessed = false;
break;
+ }
+ mrSelectionFunction.SwitchToNormalMode();
+ return bIsProcessed;
+}
- case ANY_MODIFIER(MOUSE_MOTION | LEFT_BUTTON | SINGLE_CLICK | NOT_OVER_PAGE):
+
+
+
+
+bool NormalModeHandler::ProcessMotionEvent (
+ SelectionFunction::EventDescriptor& rDescriptor)
+{
+ if (ModeHandler::ProcessMotionEvent(rDescriptor))
+ return true;
+
+ bool bIsProcessed (true);
+ switch (rDescriptor.mnEventCode)
+ {
case ANY_MODIFIER(MOUSE_MOTION | LEFT_BUTTON | SINGLE_CLICK | OVER_UNSELECTED_PAGE):
- case ANY_PAGE_AND_MODIFIER(MOUSE_MOTION | LEFT_BUTTON | SINGLE_CLICK | RECTANGLE_VISIBLE):
- mrController.GetScrollBarManager().AutoScroll(rDescriptor.maMousePosition);
- UpdateRectangleSelection(rDescriptor.maMouseModelPosition);
- break;
+ // SetCurrentPage(rDescriptor.mpHitDescriptor);
+ // Fallthrough
- case ANY_PAGE(BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK | RECTANGLE_VISIBLE | NO_MODIFIER):
- ProcessRectangleSelection(false);
- break;
+ // A mouse motion without visible substitution starts that.
+ case ANY_MODIFIER(MOUSE_MOTION | LEFT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE):
+ {
+ if (maButtonDownLocation)
+ {
+ const sal_Int32 nDistance (maButtonDownLocation
+ ? ::std::max (
+ abs(maButtonDownLocation->X() - rDescriptor.maMousePosition.X()),
+ abs(maButtonDownLocation->Y() - rDescriptor.maMousePosition.Y()))
+ : 0);
+ if (nDistance > 3)
+ StartDrag(
+ rDescriptor.maMousePosition,
+ (rDescriptor.mnEventCode & CONTROL_MODIFIER) != 0
+ ? InsertionIndicatorHandler::CopyMode
+ : InsertionIndicatorHandler::MoveMode);
+ }
+ }
+ break;
- case ANY_PAGE(BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK | RECTANGLE_VISIBLE | SHIFT_MODIFIER):
- case ANY_PAGE(BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK | RECTANGLE_VISIBLE | CONTROL_MODIFIER):
- ProcessRectangleSelection(true);
+ // A mouse motion not over a page starts a rectangle selection.
+ case ANY_MODIFIER(MOUSE_MOTION | LEFT_BUTTON | SINGLE_CLICK | NOT_OVER_PAGE):
+ mrSelectionFunction.SwitchToMultiSelectionMode(
+ rDescriptor.maMouseModelPosition,
+ rDescriptor.mnEventCode);
break;
default:
- bResult = false;
+ bIsProcessed = false;
break;
}
- mrController.GetPageSelector().EnableBroadcasting(bMakeSelectionVisible);
+ return bIsProcessed;
+}
- return bResult;
+
+
+
+bool NormalModeHandler::ProcessDragEvent (SelectionFunction::EventDescriptor& rDescriptor)
+{
+ mrSelectionFunction.SwitchToDragAndDropMode(rDescriptor.maMousePosition);
+ ReprocessEvent(rDescriptor);
+ return true;
}
-void SelectionFunction::EventPostprocessing (const EventDescriptor& rDescriptor)
+void NormalModeHandler::RangeSelect (const model::SharedPageDescriptor& rpDescriptor)
{
- if (rDescriptor.mnEventCode & BUTTON_UP)
+ PageSelector::UpdateLock aLock (mrSlideSorter);
+ PageSelector& rSelector (mrSlideSorter.GetController().GetPageSelector());
+
+ model::SharedPageDescriptor pAnchor (rSelector.GetSelectionAnchor());
+ DeselectAllPages();
+
+ if (pAnchor.get() != NULL)
{
- view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay());
-
- mpWindow->ReleaseMouse();
-
- // The overlays should not be visible anymore. Warn when one of
- // them still is. An exception is th insertion indicator in the
- // case that the context menu is visible.
- DBG_ASSERT(
- mrController.IsContextMenuOpen()
- || !rOverlay.GetInsertionIndicatorOverlay().isVisible(),
- "slidesorter::SelectionFunction: insertion indicator still visible");
- DBG_ASSERT(
- !rOverlay.GetSubstitutionOverlay().isVisible(),
- "slidesorter::SelectionFunction: substitution still visible");
- DBG_ASSERT(
- !rOverlay.GetSelectionRectangleOverlay().isVisible(),
- "slidesorter::SelectionFunction: selection rectangle still visible");
-
- // Now turn them off.
- if ( ! mrController.IsContextMenuOpen())
- rOverlay.GetInsertionIndicatorOverlay().setVisible(false);
- rOverlay.GetSubstitutionOverlay().setVisible(false);
- rOverlay.GetSelectionRectangleOverlay().setVisible(false);
+ // Select all pages between the anchor and the given one, including
+ // the two.
+ const USHORT nAnchorIndex ((pAnchor->GetPage()->GetPageNum()-1) / 2);
+ const USHORT nOtherIndex ((rpDescriptor->GetPage()->GetPageNum()-1) / 2);
+
+ // Iterate over all pages in the range. Start with the anchor
+ // page. This way the PageSelector will recognize it again as
+ // anchor (the first selected page after a DeselectAllPages()
+ // becomes the anchor.)
+ const USHORT nStep ((nAnchorIndex < nOtherIndex) ? +1 : -1);
+ USHORT nIndex (nAnchorIndex);
+ while (true)
+ {
+ rSelector.SelectPage(nIndex);
+ if (nIndex == nOtherIndex)
+ break;
+ nIndex = nIndex + nStep;
+ }
}
}
-void SelectionFunction::SetCurrentPage (const model::SharedPageDescriptor& rpDescriptor)
+void NormalModeHandler::ResetButtonDownLocation (void)
{
- PageSelector& rSelector (mrController.GetPageSelector());
- rSelector.DeselectAllPages ();
- rSelector.SelectPage(rpDescriptor);
+ maButtonDownLocation = ::boost::optional<Point>();
+}
+
+
- mrController.GetCurrentSlideManager()->SwitchCurrentSlide(rpDescriptor);
+
+//===== MultiSelectionModeHandler =============================================
+
+MultiSelectionModeHandler::MultiSelectionModeHandler (
+ SlideSorter& rSlideSorter,
+ SelectionFunction& rSelectionFunction,
+ const Point& rMouseModelPosition,
+ const sal_uInt32 nEventCode)
+ : ModeHandler(rSlideSorter, rSelectionFunction, false),
+ meSelectionMode(SM_Normal),
+ maSecondCorner(rMouseModelPosition),
+ maSavedPointer(mrSlideSorter.GetContentWindow()->GetPointer()),
+ mnAnchorIndex(-1),
+ mnSecondIndex(-1),
+ maButtonBarLock(rSlideSorter)
+{
+ const Pointer aSelectionPointer (POINTER_TEXT);
+ mrSlideSorter.GetContentWindow()->SetPointer(aSelectionPointer);
+ SetSelectionModeFromModifier(nEventCode);
}
-void SelectionFunction::SwitchView (const model::SharedPageDescriptor& rpDescriptor)
+
+MultiSelectionModeHandler::~MultiSelectionModeHandler (void)
{
- // Switch to the draw view. This is done only when the current
- // view is the main view.
- ViewShell* pViewShell = mrSlideSorter.GetViewShell();
- if (pViewShell!=NULL && pViewShell->IsMainViewShell())
+ mrSlideSorter.GetContentWindow()->SetPointer(maSavedPointer);
+}
+
+
+
+
+SelectionFunction::Mode MultiSelectionModeHandler::GetMode (void) const
+{
+ return SelectionFunction::MultiSelectionMode;
+}
+
+
+
+
+void MultiSelectionModeHandler::Abort (void)
+{
+ mrSlideSorter.GetView().RequestRepaint(mrSlideSorter.GetModel().RestoreSelection());
+}
+
+
+
+
+void MultiSelectionModeHandler::ProcessEvent (
+ SelectionFunction::EventDescriptor& rDescriptor)
+{
+ // During a multi selection we do not want sudden jumps of the
+ // visible area caused by moving newly selected pages into view.
+ // Therefore disable that temporarily. The disabler object is
+ // released at the end of the event processing, after the focus and
+ // current slide have been updated.
+ VisibleAreaManager::TemporaryDisabler aDisabler (mrSlideSorter);
+
+ ModeHandler::ProcessEvent(rDescriptor);
+}
+
+
+
+
+bool MultiSelectionModeHandler::ProcessButtonUpEvent (
+ SelectionFunction::EventDescriptor& rDescriptor)
+{
+ if (Match(rDescriptor.mnEventCode, BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK))
{
- if (rpDescriptor.get()!=NULL && rpDescriptor->GetPage()!=NULL)
- {
- mrSlideSorter.GetModel().GetDocument()->SetSelected(rpDescriptor->GetPage(), TRUE);
- mpViewShell->GetFrameView()->SetSelectedPage(
- (rpDescriptor->GetPage()->GetPageNum()-1)/2);
- }
- if (mrSlideSorter.GetViewShellBase() != NULL)
- framework::FrameworkHelper::Instance(*mrSlideSorter.GetViewShellBase())->RequestView(
- framework::FrameworkHelper::msImpressViewURL,
- framework::FrameworkHelper::msCenterPaneURL);
+ mrSelectionFunction.SwitchToNormalMode();
+ return true;
}
+ else
+ return false;
}
-//===== EventDescriptor =======================================================
+bool MultiSelectionModeHandler::ProcessMotionEvent (
+ SelectionFunction::EventDescriptor& rDescriptor)
+{
+ // The selection rectangle is visible. Handle events accordingly.
+ if (Match(rDescriptor.mnEventCode, MOUSE_MOTION | LEFT_BUTTON | SINGLE_CLICK))
+ {
+ SetSelectionModeFromModifier(rDescriptor.mnEventCode);
+ UpdatePosition(rDescriptor.maMousePosition, true);
+ rDescriptor.mbMakeSelectionVisible = false;
+ return true;
+ }
+ else
+ return false;
+}
-SelectionFunction::EventDescriptor::EventDescriptor (
- sal_uInt32 nEventType,
- const MouseEvent& rEvent,
- SlideSorter& rSlideSorter)
- : maMousePosition(),
- maMouseModelPosition(),
- mpHitDescriptor(),
- mpHitPage(),
- mnEventCode(nEventType)
+
+
+bool MultiSelectionModeHandler::HandleUnprocessedEvent (
+ SelectionFunction::EventDescriptor& rDescriptor)
{
- ::Window* pWindow = rSlideSorter.GetActiveWindow();
+ if ( ! ModeHandler::HandleUnprocessedEvent(rDescriptor))
+ {
+ // If the event has not been processed then stop multi selection.
+ mrSelectionFunction.SwitchToNormalMode();
+ ReprocessEvent(rDescriptor);
+ }
+ return true;
+}
- maMousePosition = rEvent.GetPosPixel();
- maMouseModelPosition = pWindow->PixelToLogic(maMousePosition);
- model::SharedPageDescriptor pHitDescriptor (
- rSlideSorter.GetController().GetPageAt(maMousePosition));
- if (pHitDescriptor.get() != NULL)
+
+
+
+void MultiSelectionModeHandler::UpdatePosition (
+ const Point& rMousePosition,
+ const bool bAllowAutoScroll)
+{
+ VisibleAreaManager::TemporaryDisabler aDisabler (mrSlideSorter);
+
+ // Convert window coordinates into model coordinates (we need the
+ // window coordinates for auto-scrolling because that remains
+ // constant while scrolling.)
+ SharedSdWindow pWindow (mrSlideSorter.GetContentWindow());
+ const Point aMouseModelPosition (pWindow->PixelToLogic(rMousePosition));
+
+ if ( ! (bAllowAutoScroll && mrSlideSorter.GetController().GetScrollBarManager().AutoScroll(
+ rMousePosition,
+ ::boost::bind(
+ &MultiSelectionModeHandler::UpdatePosition,
+ this,
+ rMousePosition,
+ false))))
{
- mpHitDescriptor = pHitDescriptor;
- mpHitPage = pHitDescriptor->GetPage();
+ UpdateModelPosition(aMouseModelPosition);
}
}
+void MultiSelectionModeHandler::SetSelectionModeFromModifier (
+ const sal_uInt32 nEventCode)
+{
+ switch (nEventCode & MODIFIER_MASK)
+ {
+ case NO_MODIFIER:
+ SetSelectionMode(SM_Normal);
+ break;
-SelectionFunction::EventDescriptor::EventDescriptor (
- const KeyEvent&,
- SlideSorter& rSlideSorter)
- : maMousePosition(),
- maMouseModelPosition(),
- mpHitDescriptor(),
- mpHitPage(),
- mnEventCode(0)
+ case SHIFT_MODIFIER:
+ SetSelectionMode(SM_Add);
+ break;
+
+ case CONTROL_MODIFIER:
+ SetSelectionMode(SM_Toggle);
+ break;
+ }
+}
+
+
+
+
+void MultiSelectionModeHandler::SetSelectionMode (const SelectionMode eSelectionMode)
{
- mpHitDescriptor = rSlideSorter.GetController().GetFocusManager().GetFocusedPageDescriptor();
- model::SharedPageDescriptor pHitDescriptor (
- rSlideSorter.GetController().GetFocusManager().GetFocusedPageDescriptor());
- if (pHitDescriptor.get() != NULL)
+ if (meSelectionMode != eSelectionMode)
{
- mpHitPage = pHitDescriptor->GetPage();
- mpHitDescriptor = pHitDescriptor;
+ meSelectionMode = eSelectionMode;
+ UpdateSelection();
}
}
+void MultiSelectionModeHandler::UpdateSelectionState (
+ const model::SharedPageDescriptor& rpDescriptor,
+ const bool bIsInSelection) const
+{
+ // Determine whether the page was selected before the rectangle
+ // selection was started.
+ const bool bWasSelected (rpDescriptor->HasState(model::PageDescriptor::ST_WasSelected));
+
+ // Combine the two selection states depending on the selection mode.
+ bool bSelect (false);
+ switch(meSelectionMode)
+ {
+ case SM_Normal:
+ bSelect = bIsInSelection;
+ break;
-//===== SubstitutionHandler ===================================================
+ case SM_Add:
+ bSelect = bIsInSelection || bWasSelected;
+ break;
-SelectionFunction::SubstitutionHandler::SubstitutionHandler (SlideSorter& rSlideSorter)
- : mrSlideSorter(rSlideSorter),
- mbHasBeenMoved(false)
+ case SM_Toggle:
+ if (bIsInSelection)
+ bSelect = !bWasSelected;
+ else
+ bSelect = bWasSelected;
+ break;
+ }
+
+ // Set the new selection state.
+ if (bSelect)
+ mrSlideSorter.GetController().GetPageSelector().SelectPage(rpDescriptor);
+ else
+ mrSlideSorter.GetController().GetPageSelector().DeselectPage(rpDescriptor);
+}
+
+
+
+
+void MultiSelectionModeHandler::UpdateModelPosition (const Point& rMouseModelPosition)
{
+ maSecondCorner = rMouseModelPosition;
+ UpdateSelection();
}
-SelectionFunction::SubstitutionHandler::~SubstitutionHandler (void)
+void MultiSelectionModeHandler::UpdateSelection (void)
{
- if (mrSlideSorter.IsValid())
+ view::SlideSorterView::DrawLock aLock (mrSlideSorter);
+
+ model::SlideSorterModel& rModel (mrSlideSorter.GetModel());
+ const sal_Int32 nPageCount (rModel.GetPageCount());
+
+ const sal_Int32 nIndexUnderMouse (
+ mrSlideSorter.GetView().GetLayouter().GetIndexAtPoint (
+ maSecondCorner,
+ false,
+ false));
+ if (nIndexUnderMouse>=0 && nIndexUnderMouse<nPageCount)
{
- view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay());
- rOverlay.GetSubstitutionOverlay().setVisible(false);
- rOverlay.GetSubstitutionOverlay().Clear();
+ if (mnAnchorIndex < 0)
+ mnAnchorIndex = nIndexUnderMouse;
+ mnSecondIndex = nIndexUnderMouse;
+
+ Range aRange (mnAnchorIndex, mnSecondIndex);
+ aRange.Justify();
+
+ for (sal_Int32 nIndex=0; nIndex<nPageCount; ++nIndex)
+ {
+ UpdateSelectionState(rModel.GetPageDescriptor(nIndex), aRange.IsInside(nIndex));
+ }
}
}
-void SelectionFunction::SubstitutionHandler::Start (const Point& rMouseModelPosition)
+//===== DragAndDropModeHandler ================================================
+
+DragAndDropModeHandler::DragAndDropModeHandler (
+ SlideSorter& rSlideSorter,
+ SelectionFunction& rSelectionFunction,
+ const Point& rMousePosition,
+ ::Window* pWindow)
+ : ModeHandler(rSlideSorter, rSelectionFunction, false)
{
- // No Drag-and-Drop for master pages.
- if (mrSlideSorter.GetModel().GetEditMode() != EM_PAGE)
- return;
+ SdTransferable* pDragTransferable = SD_MOD()->pTransferDrag;
+ if (pDragTransferable==NULL && mrSlideSorter.GetViewShell() != NULL)
+ {
+ SlideSorterViewShell* pSlideSorterViewShell
+ = dynamic_cast<SlideSorterViewShell*>(mrSlideSorter.GetViewShell());
+ if (pSlideSorterViewShell != NULL)
+ pSlideSorterViewShell->StartDrag(rMousePosition, pWindow);
+ pDragTransferable = SD_MOD()->pTransferDrag;
+ }
- if (mrSlideSorter.GetController().GetProperties()->IsUIReadOnly())
- return;
+ mpDragAndDropContext.reset(new DragAndDropContext(mrSlideSorter));
+ mrSlideSorter.GetController().GetInsertionIndicatorHandler()->Start(
+ pDragTransferable != NULL
+ && pDragTransferable->GetView()==&mrSlideSorter.GetView());
+}
- view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay());
- if ( ! rOverlay.GetSubstitutionOverlay().isVisible())
+
+
+DragAndDropModeHandler::~DragAndDropModeHandler (void)
+{
+ if (mpDragAndDropContext)
{
- // Show a new substitution for the selected page objects.
- model::PageEnumeration aSelectedPages(
- model::PageEnumerationProvider::CreateSelectedPagesEnumeration(
- mrSlideSorter.GetModel()));
- rOverlay.GetSubstitutionOverlay().Create(aSelectedPages, rMouseModelPosition);
- rOverlay.GetSubstitutionOverlay().setVisible(true);
- mbHasBeenMoved = false;
+ // Disconnect the substitution handler from this selection function.
+ mpDragAndDropContext->SetTargetSlideSorter();
+ mpDragAndDropContext.reset();
}
- else
- UpdatePosition(rMouseModelPosition);
+ mrSlideSorter.GetController().GetInsertionIndicatorHandler()->End(Animator::AM_Animated);
}
-void SelectionFunction::SubstitutionHandler::UpdatePosition (const Point& rMouseModelPosition)
+SelectionFunction::Mode DragAndDropModeHandler::GetMode (void) const
{
- if (mrSlideSorter.GetController().GetProperties()->IsUIReadOnly())
- return;
+ return SelectionFunction::DragAndDropMode;
+}
- view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay());
- // Move the existing substitution to the new position.
- rOverlay.GetSubstitutionOverlay().SetPosition(rMouseModelPosition);
- rOverlay.GetInsertionIndicatorOverlay().SetPosition(rMouseModelPosition);
- rOverlay.GetInsertionIndicatorOverlay().setVisible(true);
- mbHasBeenMoved = true;
+void DragAndDropModeHandler::Abort (void)
+{
+ mrSlideSorter.GetController().GetClipboard().Abort();
+ if (mpDragAndDropContext)
+ mpDragAndDropContext->Dispose();
+ // mrSlideSorter.GetView().RequestRepaint(mrSlideSorter.GetModel().RestoreSelection());
}
-void SelectionFunction::SubstitutionHandler::Process (void)
+bool DragAndDropModeHandler::ProcessButtonUpEvent (
+ SelectionFunction::EventDescriptor& rDescriptor)
{
- if (mrSlideSorter.GetController().GetProperties()->IsUIReadOnly())
- return;
+ if (Match(rDescriptor.mnEventCode, BUTTON_UP | LEFT_BUTTON))
+ {
+ // The following Process() call may lead to the desctruction
+ // of rDescriptor.mpHitDescriptor so release our reference to it.
+ rDescriptor.mpHitDescriptor.reset();
+ mrSelectionFunction.SwitchToNormalMode();
+ return true;
+ }
+ else
+ return false;
+}
- view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay());
- if (IsSubstitutionInsertionNonTrivial())
- {
- // Tell the model to move the selected pages behind the one with the
- // index mnInsertionIndex which first has to transformed into an index
- // understandable by the document.
- sal_Int32 nInsertionIndex = rOverlay.GetInsertionIndicatorOverlay().GetInsertionPageIndex();
- if (nInsertionIndex >= 0)
- {
- USHORT nDocumentIndex = (USHORT)nInsertionIndex-1;
- mrSlideSorter.GetController().GetSelectionManager()->MoveSelectedPages(nDocumentIndex);
- }
- ViewShell* pViewShell = mrSlideSorter.GetViewShell();
- if (pViewShell != NULL)
- pViewShell->GetViewFrame()->GetBindings().Invalidate(SID_STATUS_PAGE);
+
+bool DragAndDropModeHandler::ProcessDragEvent (SelectionFunction::EventDescriptor& rDescriptor)
+{
+ OSL_ASSERT(mpDragAndDropContext);
+
+ if (rDescriptor.mbIsLeaving)
+ {
+ mrSelectionFunction.SwitchToNormalMode();
+ }
+ else if (mpDragAndDropContext)
+ {
+ mpDragAndDropContext->UpdatePosition(
+ rDescriptor.maMousePosition,
+ rDescriptor.meDragMode);
}
+
+ return true;
}
-void SelectionFunction::SubstitutionHandler::End (void)
+//===== ButtonModeHandler =====================================================
+
+ButtonModeHandler::ButtonModeHandler (
+ SlideSorter& rSlideSorter,
+ SelectionFunction& rSelectionFunction)
+ : ModeHandler(rSlideSorter, rSelectionFunction, true)
{
- view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay());
- rOverlay.GetSubstitutionOverlay().setVisible(false);
- rOverlay.GetSubstitutionOverlay().Clear();
- rOverlay.GetInsertionIndicatorOverlay().setVisible(false);
}
-bool SelectionFunction::SubstitutionHandler::HasBeenMoved (void) const
+ButtonModeHandler::~ButtonModeHandler (void)
{
- return mbHasBeenMoved;
}
-bool SelectionFunction::SubstitutionHandler::IsSubstitutionInsertionNonTrivial (void) const
+SelectionFunction::Mode ButtonModeHandler::GetMode (void) const
{
- bool bIsNonTrivial = false;
+ return SelectionFunction::ButtonMode;
+}
+
+
+
- do
+void ButtonModeHandler::Abort (void)
+{
+}
+
+
+
+
+bool ButtonModeHandler::ProcessButtonDownEvent (SelectionFunction::EventDescriptor& rDescriptor)
+{
+ switch (rDescriptor.mnEventCode)
{
- view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay());
+ 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;
+ }
+}
- // Make sure that the substitution and the insertion indicator are visible.
- if ( ! rOverlay.GetSubstitutionOverlay().isVisible())
- break;
- if ( ! rOverlay.GetInsertionIndicatorOverlay().isVisible())
- break;
- // Iterate over all selected pages and check whether there are
- // holes. While we do this we remember the indices of the first and
- // last selected page as preparation for the next step.
- sal_Int32 nCurrentIndex = -1;
- sal_Int32 nFirstIndex = -1;
- sal_Int32 nLastIndex = -1;
- model::PageEnumeration aSelectedPages (
- model::PageEnumerationProvider::CreateSelectedPagesEnumeration(
- mrSlideSorter.GetModel()));
- while (aSelectedPages.HasMoreElements() && ! bIsNonTrivial)
- {
- model::SharedPageDescriptor pDescriptor (aSelectedPages.GetNextElement());
- SdPage* pPage = pDescriptor->GetPage();
- if (pPage != NULL)
- {
- // Get the page number and compare it to the last one.
- sal_Int32 nPageNumber = (pPage->GetPageNum()-1)/2;
- if (nCurrentIndex>=0 && nPageNumber>(nCurrentIndex+1))
- bIsNonTrivial = true;
- else
- nCurrentIndex = nPageNumber;
- // Remember indices of the first and last page of the selection.
- if (nFirstIndex == -1)
- nFirstIndex = nPageNumber;
- nLastIndex = nPageNumber;
- }
- }
- if (bIsNonTrivial)
- break;
- // When we come here then the selection is consecutive. We still
- // have to check that the insertion position is not directly in
- // front or directly behind the selection and thus moving the
- // selection there would not change the model.
- sal_Int32 nInsertionIndex = rOverlay.GetInsertionIndicatorOverlay().GetInsertionPageIndex();
- if (nInsertionIndex<nFirstIndex || nInsertionIndex>(nLastIndex+1))
- bIsNonTrivial = true;
+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;
}
- while (false);
- return bIsNonTrivial;
+ 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
diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx
index f1b4cb6c39be..d9062a4ef2b1 100755
--- a/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx
+++ b/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx
@@ -30,18 +30,22 @@
#include "controller/SlsSelectionManager.hxx"
#include "SlideSorter.hxx"
-#include "SlsSelectionCommand.hxx"
+#include "SlsCommand.hxx"
#include "controller/SlideSorterController.hxx"
#include "controller/SlsAnimator.hxx"
+#include "controller/SlsAnimationFunction.hxx"
#include "controller/SlsCurrentSlideManager.hxx"
#include "controller/SlsFocusManager.hxx"
+#include "controller/SlsPageSelector.hxx"
#include "controller/SlsProperties.hxx"
#include "controller/SlsScrollBarManager.hxx"
#include "controller/SlsSlotManager.hxx"
+#include "controller/SlsSelectionObserver.hxx"
#include "model/SlideSorterModel.hxx"
#include "model/SlsPageEnumerationProvider.hxx"
#include "model/SlsPageDescriptor.hxx"
#include "view/SlideSorterView.hxx"
+#include "view/SlsLayouter.hxx"
#include "drawdoc.hxx"
#include "Window.hxx"
#include <svx/svxids.hrc>
@@ -65,39 +69,24 @@ using namespace ::sd::slidesorter::controller;
namespace sd { namespace slidesorter { namespace controller {
-namespace {
- class VerticalVisibleAreaScroller
- {
- public:
- VerticalVisibleAreaScroller (SlideSorter& rSlideSorter,
- const double nStart, const double nEnd);
- void operator() (const double nValue);
- private:
- SlideSorter& mrSlideSorter;
- double mnStart;
- double mnEnd;
- };
- class HorizontalVisibleAreaScroller
- {
- public:
- HorizontalVisibleAreaScroller (SlideSorter& rSlideSorter,
- const double nStart, const double nEnd);
- void operator() (const double nValue);
- private:
- SlideSorter& mrSlideSorter;
- double mnStart;
- double mnEnd;
- };
-}
-
+class SelectionManager::PageInsertionListener
+ : public SfxListener
+{
+public:
+};
SelectionManager::SelectionManager (SlideSorter& rSlideSorter)
: mrSlideSorter(rSlideSorter),
mrController(rSlideSorter.GetController()),
maSelectionBeforeSwitch(),
- mbIsMakeSelectionVisiblePending(true)
+ mbIsMakeSelectionVisiblePending(true),
+ mnInsertionPosition(-1),
+ mnAnimationId(Animator::NotAnAnimationId),
+ maRequestedTopLeft(),
+ mpPageInsertionListener(),
+ mpSelectionObserver(new SelectionObserver(rSlideSorter))
{
}
@@ -106,14 +95,20 @@ SelectionManager::SelectionManager (SlideSorter& rSlideSorter)
SelectionManager::~SelectionManager (void)
{
+ if (mnAnimationId != Animator::NotAnAnimationId)
+ mrController.GetAnimator()->RemoveAnimation(mnAnimationId);
}
-void SelectionManager::DeleteSelectedPages (void)
+void SelectionManager::DeleteSelectedPages (const bool bSelectFollowingPage)
{
+ // Create some locks to prevent updates of the model, view, selection
+ // state while modifying any of them.
SlideSorterController::ModelChangeLock aLock (mrController);
+ SlideSorterView::DrawLock aDrawLock (mrSlideSorter);
+ PageSelector::UpdateLock aSelectionLock (mrSlideSorter);
// Hide focus.
bool bIsFocusShowing = mrController.GetFocusManager().IsFocusShowing();
@@ -125,8 +120,23 @@ void SelectionManager::DeleteSelectedPages (void)
model::PageEnumeration aPageEnumeration (
PageEnumerationProvider::CreateSelectedPagesEnumeration(mrSlideSorter.GetModel()));
::std::vector<SdPage*> aSelectedPages;
+ sal_Int32 nNewCurrentSlide (-1);
while (aPageEnumeration.HasMoreElements())
- aSelectedPages.push_back (aPageEnumeration.GetNextElement()->GetPage());
+ {
+ SharedPageDescriptor pDescriptor (aPageEnumeration.GetNextElement());
+ aSelectedPages.push_back(pDescriptor->GetPage());
+ if (bSelectFollowingPage || nNewCurrentSlide<0)
+ nNewCurrentSlide = pDescriptor->GetPageIndex();
+ }
+ if (aSelectedPages.empty())
+ return;
+
+ // Determine the slide to select (and thereby make the current slide)
+ // after the deletion.
+ if (bSelectFollowingPage)
+ nNewCurrentSlide -= aSelectedPages.size() - 1;
+ else
+ --nNewCurrentSlide;
// The actual deletion of the selected pages is done in one of two
// helper functions. They are specialized for normal respectively for
@@ -143,8 +153,16 @@ void SelectionManager::DeleteSelectedPages (void)
// Show focus and move it to next valid location.
if (bIsFocusShowing)
- mrController.GetFocusManager().ToggleFocus ();
- mrController.GetFocusManager().MoveFocus (FocusManager::FMD_NONE);
+ mrController.GetFocusManager().ToggleFocus();
+
+ // Set the new current slide.
+ if (nNewCurrentSlide < 0)
+ nNewCurrentSlide = 0;
+ else if (nNewCurrentSlide >= mrSlideSorter.GetModel().GetPageCount())
+ nNewCurrentSlide = mrSlideSorter.GetModel().GetPageCount()-1;
+ mrController.GetPageSelector().CountSelectedPages();
+ mrController.GetPageSelector().SelectPage(nNewCurrentSlide);
+ mrController.GetFocusManager().SetFocusedPage(nNewCurrentSlide);
}
@@ -171,7 +189,7 @@ void SelectionManager::DeleteSelectedNormalPages (const ::std::vector<SdPage*>&
if (xPages->getCount() <= 1)
break;
- USHORT nPage = ((*aI)->GetPageNum()-1) / 2;
+ const USHORT nPage (model::FromCoreIndex((*aI)->GetPageNum()));
Reference< XDrawPage > xPage( xPages->getByIndex( nPage ), UNO_QUERY_THROW );
xPages->remove(xPage);
@@ -207,7 +225,7 @@ void SelectionManager::DeleteSelectedMasterPages (const ::std::vector<SdPage*>&
if (xPages->getCount() <= 1)
break;
- USHORT nPage = ((*aI)->GetPageNum()-1) / 2;
+ const USHORT nPage (model::FromCoreIndex((*aI)->GetPageNum()));
Reference< XDrawPage > xPage( xPages->getByIndex( nPage ), UNO_QUERY_THROW );
xPages->remove(xPage);
@@ -222,60 +240,6 @@ void SelectionManager::DeleteSelectedMasterPages (const ::std::vector<SdPage*>&
-bool SelectionManager::MoveSelectedPages (const sal_Int32 nTargetPageIndex)
-{
- bool bMoved (false);
- PageSelector& rSelector (mrController.GetPageSelector());
-
- mrSlideSorter.GetView().LockRedraw (TRUE);
- SlideSorterController::ModelChangeLock aLock (mrController);
-
- // Transfer selection of the slide sorter to the document.
- mrSlideSorter.GetModel().SynchronizeDocumentSelection ();
-
- // Detect how many pages lie between document start and insertion
- // position.
- sal_Int32 nPageCountBeforeTarget (0);
- ::boost::shared_ptr<PageSelector::PageSelection> pSelection (rSelector.GetPageSelection());
- PageSelector::PageSelection::const_iterator iSelectedPage (pSelection->begin());
- PageSelector::PageSelection::const_iterator iSelectionEnd (pSelection->end());
- for ( ; iSelectedPage!=iSelectionEnd; ++iSelectedPage)
- {
- if (*iSelectedPage==NULL)
- continue;
- if (((*iSelectedPage)->GetPageNum()-1)/2 <= nTargetPageIndex)
- ++nPageCountBeforeTarget;
- else
- break;
- }
-
- // Prepare to select the moved pages.
- SelectionCommand* pCommand = new SelectionCommand(
- rSelector,mrController.GetCurrentSlideManager(),mrSlideSorter.GetModel());
- sal_Int32 nSelectedPageCount (rSelector.GetSelectedPageCount());
- for (sal_Int32 nOffset=0; nOffset<nSelectedPageCount; ++nOffset)
- pCommand->AddSlide(sal::static_int_cast<USHORT>(
- nTargetPageIndex + nOffset - nPageCountBeforeTarget + 1));
-
- // At the moment we can not move master pages.
- if (nTargetPageIndex>=0)
- {
- if (mrSlideSorter.GetModel().GetEditMode() == EM_PAGE)
- bMoved = mrSlideSorter.GetModel().GetDocument()->MovePages(
- sal::static_int_cast<sal_uInt16>(nTargetPageIndex));
- }
- if (bMoved)
- mrController.GetSlotManager()->ExecuteCommandAsynchronously(
- ::std::auto_ptr<controller::Command>(pCommand));
-
- mrSlideSorter.GetView().LockRedraw (FALSE);
-
- return bMoved;
-}
-
-
-
-
void SelectionManager::SelectionHasChanged (const bool bMakeSelectionVisible)
{
if (bMakeSelectionVisible)
@@ -318,166 +282,6 @@ void SelectionManager::SelectionHasChanged (const bool bMakeSelectionVisible)
-bool SelectionManager::IsMakeSelectionVisiblePending (void) const
-{
- return mbIsMakeSelectionVisiblePending;
-}
-
-
-
-
-/** We have to distinguish three cases: 1) the selection is empty, 2) the
- selection fits completely into the visible area, 3) it does not.
- 1) The visible area is not modified.
- 2) When the selection fits completely into the visible area we have to
- decide how to align it. It is done by scrolling it there and thus when
- we scoll up the (towards the end of the document) the bottom of the
- selection is aligned with the bottom of the window. When we scroll
- down (towards the beginning of the document) the top of the selection is
- aligned with the top of the window.
- 3) We have to decide what part of the selection to make visible. Here
- we use the eSelectionHint and concentrate on either the first, the last,
- or the most recently selected page. We then again apply the algorithm
- of a).
-
-*/
-Size SelectionManager::MakeSelectionVisible (const SelectionHint eSelectionHint)
-{
- ::sd::Window* pWindow = mrSlideSorter.GetActiveWindow();
- if (pWindow == NULL)
- return Size(0,0);
-
- mbIsMakeSelectionVisiblePending = false;
-
- // Determine the descriptors of the first and last selected page and the
- // bounding box that encloses their page objects.
- model::SharedPageDescriptor pFirst;
- model::SharedPageDescriptor pLast;
- Rectangle aSelectionBox;
- model::PageEnumeration aSelectedPages (
- PageEnumerationProvider::CreateSelectedPagesEnumeration(mrSlideSorter.GetModel()));
- while (aSelectedPages.HasMoreElements())
- {
- model::SharedPageDescriptor pDescriptor (aSelectedPages.GetNextElement());
-
- if (pFirst.get() == NULL)
- pFirst = pDescriptor;
- pLast = pDescriptor;
-
- aSelectionBox.Union (mrSlideSorter.GetView().GetPageBoundingBox (
- pDescriptor,
- view::SlideSorterView::CS_MODEL,
- view::SlideSorterView::BBT_INFO));
- }
-
- if (pFirst != NULL)
- {
- // Determine scroll direction and the position in model coordinates
- // that will be aligned with the top/left or bottom/right window
- // border.
- if (DoesSelectionExceedVisibleArea(aSelectionBox))
- {
- // We can show only a part of the selection.
- aSelectionBox = ResolveLargeSelection(pFirst,pLast, eSelectionHint);
- }
-
- return MakeRectangleVisible(aSelectionBox);
- }
-
- return Size(0,0);
-}
-
-
-
-
-Size SelectionManager::MakeRectangleVisible (const Rectangle& rBox)
-{
- ::sd::Window* pWindow = mrSlideSorter.GetActiveWindow();
- if (pWindow == NULL)
- return Size(0,0);
-
- Rectangle aVisibleArea (pWindow->PixelToLogic(
- Rectangle(
- Point(0,0),
- pWindow->GetOutputSizePixel())));
-
- if (mrSlideSorter.GetView().GetOrientation() == SlideSorterView::VERTICAL)
- {
- // Scroll the visible area to make aSelectionBox visible.
- sal_Int32 nNewTop (aVisibleArea.Top());
- if (mrSlideSorter.GetController().GetProperties()->IsCenterSelection())
- {
- nNewTop = rBox.Top() - (aVisibleArea.GetHeight() - rBox.GetHeight()) / 2;
- }
- else
- {
- if (rBox.Top() < aVisibleArea.Top())
- nNewTop = rBox.Top();
- else if (rBox.Bottom() > aVisibleArea.Bottom())
- nNewTop = rBox.Bottom() - aVisibleArea.GetHeight();
- // otherwise we do not modify the visible area.
- }
-
- // Make some corrections of the new visible area.
- Rectangle aModelArea (mrSlideSorter.GetView().GetModelArea());
- if (nNewTop + aVisibleArea.GetHeight() > aModelArea.Bottom())
- nNewTop = aModelArea.GetHeight() - aVisibleArea.GetHeight();
- if (nNewTop < aModelArea.Top())
- nNewTop = aModelArea.Top();
-
- // Scroll.
- if (nNewTop != aVisibleArea.Top())
- {
- mrController.GetAnimator()->AddAnimation(
- VerticalVisibleAreaScroller(mrSlideSorter, aVisibleArea.Top(), nNewTop),
- mrSlideSorter.GetController().GetProperties()->IsSmoothSelectionScrolling() ?
- 1000 : 0
- );
- }
-
- return Size(0,aVisibleArea.Top() - nNewTop);
- }
- else
- {
- // Scroll the visible area to make aSelectionBox visible.
- sal_Int32 nNewLeft (aVisibleArea.Left());
- if (mrSlideSorter.GetController().GetProperties()->IsCenterSelection())
- {
- nNewLeft = rBox.Left() - (aVisibleArea.GetWidth() - rBox.GetWidth()) / 2;
- }
- else
- {
- if (rBox.Left() < aVisibleArea.Left())
- nNewLeft = rBox.Left();
- else if (rBox.Right() > aVisibleArea.Right())
- nNewLeft = rBox.Right() - aVisibleArea.GetWidth();
- // otherwise we do not modify the visible area.
- }
-
- // Make some corrections of the new visible area.
- Rectangle aModelArea (mrSlideSorter.GetView().GetModelArea());
- if (nNewLeft + aVisibleArea.GetWidth() > aModelArea.Right())
- nNewLeft = aModelArea.GetWidth() - aVisibleArea.GetWidth();
- if (nNewLeft < aModelArea.Left())
- nNewLeft = aModelArea.Left();
-
- // Scroll.
- if (nNewLeft != aVisibleArea.Left())
- {
- mrController.GetAnimator()->AddAnimation(
- HorizontalVisibleAreaScroller(mrSlideSorter, aVisibleArea.Left(), nNewLeft),
- mrSlideSorter.GetController().GetProperties()->IsSmoothSelectionScrolling() ?
- 1000 : 0
- );
- }
-
- return Size(aVisibleArea.Left() - nNewLeft, 0);
- }
-}
-
-
-
-
void SelectionManager::AddSelectionChangeListener (const Link& rListener)
{
if (::std::find (
@@ -504,70 +308,6 @@ void SelectionManager::RemoveSelectionChangeListener(const Link&rListener)
-bool SelectionManager::DoesSelectionExceedVisibleArea (const Rectangle& rSelectionBox) const
-{
- ::sd::Window* pWindow = mrSlideSorter.GetActiveWindow();
- if (pWindow == NULL)
- return true;
-
- Rectangle aVisibleArea (pWindow->PixelToLogic(
- Rectangle(
- Point(0,0),
- pWindow->GetOutputSizePixel())));
- if (mrSlideSorter.GetView().GetOrientation() == SlideSorterView::VERTICAL)
- return rSelectionBox.GetHeight() > aVisibleArea.GetHeight();
- else
- return rSelectionBox.GetWidth() > aVisibleArea.GetWidth();
-}
-
-
-
-
-Rectangle SelectionManager::ResolveLargeSelection (
- const SharedPageDescriptor& rpFirst,
- const SharedPageDescriptor& rpLast,
- const SelectionHint eSelectionHint)
-{
- OSL_ASSERT(rpFirst.get()!=NULL);
- OSL_ASSERT(rpLast.get()!=NULL);
-
- // The mose recently selected page is assumed to lie in the range
- // between first and last selected page. Therefore the bounding box is
- // not modified.
- model::SharedPageDescriptor pRecent (
- mrController.GetPageSelector().GetMostRecentlySelectedPage());
-
- // Get the bounding box of the page object on which to concentrate.
- model::SharedPageDescriptor pRepresentative;
- switch (eSelectionHint)
- {
- case SH_FIRST:
- pRepresentative = rpFirst;
- break;
-
- case SH_LAST:
- pRepresentative = rpLast;
- break;
-
- case SH_RECENT:
- default:
- if (pRecent.get() == NULL)
- pRepresentative = rpFirst;
- else
- pRepresentative = pRecent;
- break;
- }
- OSL_ASSERT(pRepresentative.get() != NULL);
-
- return mrSlideSorter.GetView().GetPageBoundingBox (
- pRepresentative,
- view::SlideSorterView::CS_MODEL,
- view::SlideSorterView::BBT_INFO);
-}
-
-
-
-
sal_Int32 SelectionManager::GetInsertionPosition (void) const
{
sal_Int32 nInsertionPosition (mnInsertionPosition);
@@ -584,7 +324,7 @@ sal_Int32 SelectionManager::GetInsertionPosition (void) const
const sal_Int32 nPosition (aSelectedPages.GetNextElement()->GetPage()->GetPageNum());
// Convert *2+1 index to straight index (n-1)/2 after the page
// (+1).
- nInsertionPosition = (nPosition-1)/2 + 1;
+ nInsertionPosition = model::FromCoreIndex(nPosition) + 1;
}
}
@@ -611,52 +351,9 @@ void SelectionManager::SetInsertionPosition (const sal_Int32 nInsertionPosition)
-//===== VerticalVisibleAreaScroller ===========================================
-
-namespace {
-
-VerticalVisibleAreaScroller::VerticalVisibleAreaScroller (
- SlideSorter& rSlideSorter,
- const double nStart,
- const double nEnd)
- : mrSlideSorter(rSlideSorter),
- mnStart(nStart),
- mnEnd(nEnd)
+::boost::shared_ptr<SelectionObserver> SelectionManager::GetSelectionObserver (void) const
{
+ return mpSelectionObserver;
}
-
-
-void VerticalVisibleAreaScroller::operator() (const double nValue)
-{
- mrSlideSorter.GetView().InvalidatePageObjectVisibilities();
- mrSlideSorter.GetController().GetScrollBarManager().SetTop(
- int(mnStart * (1.0 - nValue) + mnEnd * nValue));
-}
-
-
-
-
-HorizontalVisibleAreaScroller::HorizontalVisibleAreaScroller (
- SlideSorter& rSlideSorter,
- const double nStart,
- const double nEnd)
- : mrSlideSorter(rSlideSorter),
- mnStart(nStart),
- mnEnd(nEnd)
-{
-}
-
-
-
-
-void HorizontalVisibleAreaScroller::operator() (const double nValue)
-{
- mrSlideSorter.GetView().InvalidatePageObjectVisibilities();
- mrSlideSorter.GetController().GetScrollBarManager().SetLeft(
- int(mnStart * (1.0 - nValue) + mnEnd * nValue));
-}
-
-} // end of anonymous namespace
-
} } } // end of namespace ::sd::slidesorter
diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionObserver.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionObserver.cxx
new file mode 100644
index 000000000000..b40bd667131c
--- /dev/null
+++ b/sd/source/ui/slidesorter/controller/SlsSelectionObserver.cxx
@@ -0,0 +1,173 @@
+/*************************************************************************
+ *
+ * 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 "precompiled_sd.hxx"
+
+#include "SlideSorter.hxx"
+#include "controller/SlideSorterController.hxx"
+#include "controller/SlsSelectionManager.hxx"
+#include "controller/SlsSelectionObserver.hxx"
+#include "controller/SlsPageSelector.hxx"
+#include "controller/SlsFocusManager.hxx"
+#include "model/SlideSorterModel.hxx"
+#include "model/SlsPageDescriptor.hxx"
+#include <svx/svdmodel.hxx>
+#include "drawdoc.hxx"
+
+
+namespace sd { namespace slidesorter { namespace controller {
+
+SelectionObserver::Context::Context (SlideSorter& rSlideSorter)
+ : mpSelectionObserver(
+ rSlideSorter.GetController().GetSelectionManager()->GetSelectionObserver())
+{
+ if (mpSelectionObserver)
+ mpSelectionObserver->StartObservation();
+}
+
+
+
+
+SelectionObserver::Context::~Context(void)
+{
+ if (mpSelectionObserver)
+ mpSelectionObserver->EndObservation();
+}
+
+
+
+
+void SelectionObserver::Context::Abort(void)
+{
+ if (mpSelectionObserver)
+ {
+ mpSelectionObserver->AbortObservation();
+ mpSelectionObserver.reset();
+ }
+}
+
+
+
+
+//===== SelectionObserver =====================================================
+
+SelectionObserver::SelectionObserver (SlideSorter& rSlideSorter)
+ : mrSlideSorter(rSlideSorter),
+ mpDocument(mrSlideSorter.GetModel().GetDocument()),
+ mbIsOvservationActive(false),
+ maInsertedPages(),
+ maDeletedPages()
+{
+}
+
+
+
+
+SelectionObserver::~SelectionObserver (void)
+{
+}
+
+
+
+
+void SelectionObserver::NotifyPageEvent (const SdrPage* pSdrPage)
+{
+ if ( ! mbIsOvservationActive)
+ return;
+
+ const SdPage* pPage = dynamic_cast<const SdPage*>(pSdrPage);
+ if (pPage == NULL)
+ return;
+
+ if (pPage->IsInserted())
+ maInsertedPages.push_back(pPage);
+ else
+ {
+ ::std::vector<const SdPage*>::iterator iPage(
+ ::std::find(maInsertedPages.begin(), maInsertedPages.end(), pPage));
+ if (iPage != maInsertedPages.end())
+ maInsertedPages.erase(iPage);
+
+ maDeletedPages.push_back(pPage->GetPageNum());
+ }
+}
+
+
+
+void SelectionObserver::StartObservation (void)
+{
+ OSL_ASSERT(!mbIsOvservationActive);
+ maInsertedPages.clear();
+ maDeletedPages.clear();
+ mbIsOvservationActive = true;
+}
+
+
+
+
+void SelectionObserver::AbortObservation (void)
+{
+ OSL_ASSERT(mbIsOvservationActive);
+ mbIsOvservationActive = false;
+ maInsertedPages.clear();
+ maDeletedPages.clear();
+}
+
+
+
+
+void SelectionObserver::EndObservation (void)
+{
+ OSL_ASSERT(mbIsOvservationActive);
+ mbIsOvservationActive = false;
+
+ PageSelector& rSelector (mrSlideSorter.GetController().GetPageSelector());
+ PageSelector::UpdateLock aUpdateLock (mrSlideSorter);
+ rSelector.DeselectAllPages();
+ if ( ! maInsertedPages.empty())
+ {
+ // Select the inserted pages.
+ for (::std::vector<const SdPage*>::const_iterator
+ iPage(maInsertedPages.begin()),
+ iEnd(maInsertedPages.end());
+ iPage!=iEnd;
+ ++iPage)
+ {
+ rSelector.SelectPage(*iPage);
+ }
+ maInsertedPages.clear();
+ }
+ maDeletedPages.clear();
+
+ aUpdateLock.Release();
+ mrSlideSorter.GetController().GetFocusManager().SetFocusedPageToCurrentPage();
+
+}
+
+
+
+} } } // end of namespace ::sd::slidesorter::controller
diff --git a/sd/source/ui/slidesorter/controller/SlsSlideFunction.cxx b/sd/source/ui/slidesorter/controller/SlsSlideFunction.cxx
index 7fe090ad5541..1af831c2ad8a 100755
--- a/sd/source/ui/slidesorter/controller/SlsSlideFunction.cxx
+++ b/sd/source/ui/slidesorter/controller/SlsSlideFunction.cxx
@@ -46,7 +46,7 @@ SlideFunction::SlideFunction (
SfxRequest& rRequest)
: FuPoor (
rSlideSorter.GetViewShell(),
- rSlideSorter.GetView().GetWindow(),
+ rSlideSorter.GetContentWindow().get(),
&rSlideSorter.GetView(),
rSlideSorter.GetModel().GetDocument(),
rRequest)
diff --git a/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx b/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx
index e571a765bdad..ded7c2ebfdde 100755..100644
--- a/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx
+++ b/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx
@@ -33,20 +33,20 @@
#include "SlideSorter.hxx"
#include "SlideSorterViewShell.hxx"
#include "controller/SlideSorterController.hxx"
-#include "controller/SlsPageSelector.hxx"
#include "controller/SlsClipboard.hxx"
-#include "controller/SlsSelectionFunction.hxx"
-#include "controller/SlsFocusManager.hxx"
#include "controller/SlsCurrentSlideManager.hxx"
+#include "controller/SlsFocusManager.hxx"
+#include "controller/SlsInsertionIndicatorHandler.hxx"
+#include "controller/SlsPageSelector.hxx"
+#include "controller/SlsSelectionFunction.hxx"
#include "controller/SlsSelectionManager.hxx"
-#include "SlsHideSlideFunction.hxx"
+#include "controller/SlsSelectionObserver.hxx"
#include "SlsCommand.hxx"
#include "model/SlideSorterModel.hxx"
#include "model/SlsPageEnumerationProvider.hxx"
#include "model/SlsPageDescriptor.hxx"
#include "view/SlideSorterView.hxx"
#include "view/SlsLayouter.hxx"
-#include "view/SlsViewOverlay.hxx"
#include "framework/FrameworkHelper.hxx"
#include "Window.hxx"
#include "fupoor.hxx"
@@ -92,12 +92,30 @@
#include <com/sun/star/drawing/XDrawPages.hpp>
#include <vcl/svapp.hxx>
+#include <boost/bind.hpp>
+
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::presentation;
namespace sd { namespace slidesorter { namespace controller {
+namespace {
+
+/** The state of a set of slides with respect to being excluded from the
+ slide show.
+*/
+enum SlideExclusionState {UNDEFINED, EXCLUDED, INCLUDED, MIXED};
+
+/** Return for the given set of slides whether they included are
+ excluded from the slide show.
+*/
+SlideExclusionState GetSlideExclusionState (model::PageEnumeration& rPageSet);
+
+} // end of anonymous namespace
+
+
+
SlotManager::SlotManager (SlideSorter& rSlideSorter)
: mrSlideSorter(rSlideSorter),
maCommandQueue()
@@ -133,8 +151,11 @@ void SlotManager::FuTemporary (SfxRequest& rRequest)
break;
case SID_HIDE_SLIDE:
+ ChangeSlideExclusionState(model::SharedPageDescriptor(), true);
+ break;
+
case SID_SHOW_SLIDE:
- HideSlideFunction::Create(mrSlideSorter, rRequest);
+ ChangeSlideExclusionState(model::SharedPageDescriptor(), false);
break;
case SID_PAGES_PER_ROW:
@@ -145,15 +166,16 @@ void SlotManager::FuTemporary (SfxRequest& rRequest)
if (pPagesPerRow != NULL)
{
sal_Int32 nColumnCount = pPagesPerRow->GetValue();
- // Force the given number of columns by setting the
- // minimal and maximal number of columns to the same
- // value.
+ // Force the given number of columns by setting
+ // the minimal and maximal number of columns to
+ // the same value.
mrSlideSorter.GetView().GetLayouter().SetColumnCount (
nColumnCount, nColumnCount);
// Force a repaint and re-layout.
pShell->ArrangeGUIElements ();
// Rearrange the UI-elements controlled by the
- // controller and force a rearrangement of the view.
+ // controller and force a rearrangement of the
+ // view.
mrSlideSorter.GetController().Rearrange(true);
}
}
@@ -167,11 +189,11 @@ void SlotManager::FuTemporary (SfxRequest& rRequest)
case SID_SLIDE_TRANSITIONS_PANEL:
{
- // Make the slide transition panel visible (expand it) in the
- // tool pane.
+ // Make the slide transition panel visible (expand it)
+ // in the tool pane.
if (mrSlideSorter.GetViewShellBase() != NULL)
- framework::FrameworkHelper::Instance(*mrSlideSorter.GetViewShellBase())
- ->RequestTaskPanel(sd::framework::FrameworkHelper::msSlideTransitionTaskPanelURL);
+ framework::FrameworkHelper::Instance(*mrSlideSorter.GetViewShellBase())
+ ->RequestTaskPanel(sd::framework::FrameworkHelper::msSlideTransitionTaskPanelURL);
rRequest.Ignore ();
break;
}
@@ -179,7 +201,7 @@ void SlotManager::FuTemporary (SfxRequest& rRequest)
case SID_PRESENTATION_DLG:
FuSlideShowDlg::Create (
pShell,
- mrSlideSorter.GetView().GetWindow(),
+ mrSlideSorter.GetContentWindow().get(),
&mrSlideSorter.GetView(),
pDocument,
rRequest);
@@ -188,16 +210,16 @@ void SlotManager::FuTemporary (SfxRequest& rRequest)
case SID_CUSTOMSHOW_DLG:
FuCustomShowDlg::Create (
pShell,
- mrSlideSorter.GetView().GetWindow(),
+ mrSlideSorter.GetContentWindow().get(),
&mrSlideSorter.GetView(),
pDocument,
rRequest);
- break;
+ break;
case SID_EXPAND_PAGE:
FuExpandPage::Create (
pShell,
- mrSlideSorter.GetView().GetWindow(),
+ mrSlideSorter.GetContentWindow().get(),
&mrSlideSorter.GetView(),
pDocument,
rRequest);
@@ -206,7 +228,7 @@ void SlotManager::FuTemporary (SfxRequest& rRequest)
case SID_SUMMARY_PAGE:
FuSummaryPage::Create (
pShell,
- mrSlideSorter.GetView().GetWindow(),
+ mrSlideSorter.GetContentWindow().get(),
&mrSlideSorter.GetView(),
pDocument,
rRequest);
@@ -218,17 +240,22 @@ void SlotManager::FuTemporary (SfxRequest& rRequest)
rRequest.Done();
break;
+ case SID_DUPLICATE_PAGE:
+ DuplicateSelectedSlides(rRequest);
+ rRequest.Done();
+ break;
+
case SID_DELETE_PAGE:
case SID_DELETE_MASTER_PAGE:
case SID_DELETE: // we need SID_CUT to handle the delete key
- // (DEL -> accelerator -> SID_CUT).
- if (mrSlideSorter.GetModel().GetPageCount() > 1)
- {
- mrSlideSorter.GetController().GetSelectionManager()->DeleteSelectedPages();
- }
+ // (DEL -> accelerator -> SID_CUT).
+ if (mrSlideSorter.GetModel().GetPageCount() > 1)
+ {
+ mrSlideSorter.GetController().GetSelectionManager()->DeleteSelectedPages();
+ }
- rRequest.Done();
- break;
+ rRequest.Done();
+ break;
case SID_RENAMEPAGE:
case SID_RENAME_MASTER_PAGE:
@@ -361,21 +388,33 @@ void SlotManager::FuSupport (SfxRequest& rRequest)
break;
}
- case SID_UNDO :
+ case SID_UNDO:
{
SlideSorterViewShell* pViewShell
= dynamic_cast<SlideSorterViewShell*>(mrSlideSorter.GetViewShell());
if (pViewShell != NULL)
+ {
+ view::SlideSorterView::DrawLock aDrawLock (mrSlideSorter);
+ SlideSorterController::ModelChangeLock aModelLock (mrSlideSorter.GetController());
+ PageSelector::UpdateLock aUpdateLock (mrSlideSorter);
+ SelectionObserver::Context aContext (mrSlideSorter);
pViewShell->ImpSidUndo (FALSE, rRequest);
+ }
break;
}
- case SID_REDO :
+ case SID_REDO:
{
SlideSorterViewShell* pViewShell
= dynamic_cast<SlideSorterViewShell*>(mrSlideSorter.GetViewShell());
if (pViewShell != NULL)
+ {
+ view::SlideSorterView::DrawLock aDrawLock (mrSlideSorter);
+ SlideSorterController::ModelChangeLock aModelLock (mrSlideSorter.GetController());
+ PageSelector::UpdateLock aUpdateLock (mrSlideSorter);
+ SelectionObserver::Context aContext (mrSlideSorter);
pViewShell->ImpSidRedo (FALSE, rRequest);
+ }
break;
}
@@ -477,7 +516,7 @@ void SlotManager::GetAttrState (SfxItemSet& rSet)
}
}
-void SlotManager::GetMenuState ( SfxItemSet& rSet)
+void SlotManager::GetMenuState (SfxItemSet& rSet)
{
EditMode eEditMode = mrSlideSorter.GetModel().GetEditMode();
ViewShell* pShell = mrSlideSorter.GetViewShell();
@@ -592,39 +631,48 @@ void SlotManager::GetMenuState ( SfxItemSet& rSet)
model::PageEnumeration aSelectedPages (
model::PageEnumerationProvider::CreateSelectedPagesEnumeration(
mrSlideSorter.GetModel()));
- HideSlideFunction::ExclusionState eState (
- HideSlideFunction::GetExclusionState(aSelectedPages));
+ const SlideExclusionState eState (GetSlideExclusionState(aSelectedPages));
switch (eState)
{
- case HideSlideFunction::MIXED:
+ case MIXED:
// Show both entries.
break;
- case HideSlideFunction::EXCLUDED:
+ case EXCLUDED:
rSet.DisableItem(SID_HIDE_SLIDE);
break;
- case HideSlideFunction::INCLUDED:
+ case INCLUDED:
rSet.DisableItem(SID_SHOW_SLIDE);
break;
- case HideSlideFunction::UNDEFINED:
+ case UNDEFINED:
rSet.DisableItem(SID_HIDE_SLIDE);
rSet.DisableItem(SID_SHOW_SLIDE);
break;
}
}
+
PageKind ePageKind = mrSlideSorter.GetModel().GetPageType();
- if( (eEditMode == EM_MASTERPAGE) && (ePageKind != PK_HANDOUT ) )
+ if ((eEditMode == EM_MASTERPAGE) && (ePageKind != PK_HANDOUT))
{
rSet.DisableItem(SID_ASSIGN_LAYOUT);
}
- if( (eEditMode == EM_MASTERPAGE) || (ePageKind==PK_NOTES) )
+ if ((eEditMode == EM_MASTERPAGE) || (ePageKind==PK_NOTES))
{
rSet.DisableItem(SID_INSERTPAGE);
}
+
+ // Disable some slots when in master page mode.
+ if (eEditMode == EM_MASTERPAGE)
+ {
+ if (rSet.GetItemState(SID_INSERTPAGE) == SFX_ITEM_AVAILABLE)
+ rSet.DisableItem(SID_INSERTPAGE);
+ if (rSet.GetItemState(SID_DUPLICATE_PAGE) == SFX_ITEM_AVAILABLE)
+ rSet.DisableItem(SID_DUPLICATE_PAGE);
+ }
}
@@ -774,18 +822,22 @@ void SlotManager::GetStatusBarState (SfxItemSet& rSet)
model::PageEnumeration aSelectedPages (
model::PageEnumerationProvider::CreateSelectedPagesEnumeration(
mrSlideSorter.GetModel()));
- pPage = aSelectedPages.GetNextElement()->GetPage();
- nFirstPage = pPage->GetPageNum()/2;
- pFirstPage = pPage;
-
- aPageStr += sal_Unicode(' ');
- aPageStr += String::CreateFromInt32( nFirstPage + 1 );
- aPageStr.AppendAscii( RTL_CONSTASCII_STRINGPARAM( " / " ));
- aPageStr += String::CreateFromInt32(
- mrSlideSorter.GetModel().GetPageCount());
-
- aLayoutStr = pFirstPage->GetLayoutName();
- aLayoutStr.Erase( aLayoutStr.SearchAscii( SD_LT_SEPARATOR ) );
+ model::SharedPageDescriptor pDescriptor (aSelectedPages.GetNextElement());
+ if (pDescriptor)
+ {
+ pPage = pDescriptor->GetPage();
+ nFirstPage = pPage->GetPageNum()/2;
+ pFirstPage = pPage;
+
+ aPageStr += sal_Unicode(' ');
+ aPageStr += String::CreateFromInt32( nFirstPage + 1 );
+ aPageStr.AppendAscii( RTL_CONSTASCII_STRINGPARAM( " / " ));
+ aPageStr += String::CreateFromInt32(
+ mrSlideSorter.GetModel().GetPageCount());
+
+ aLayoutStr = pFirstPage->GetLayoutName();
+ aLayoutStr.Erase( aLayoutStr.SearchAscii( SD_LT_SEPARATOR ) );
+ }
}
rSet.Put( SfxStringItem( SID_STATUS_PAGE, aPageStr ) );
@@ -836,7 +888,7 @@ void SlotManager::RenameSlide (void)
SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
DBG_ASSERT(pFact, "Dialogdiet fail!");
AbstractSvxNameDialog* aNameDlg = pFact->CreateSvxNameDialog(
- mrSlideSorter.GetActiveWindow(),
+ mrSlideSorter.GetContentWindow().get(),
aPageName, aDescr);
DBG_ASSERT(aNameDlg, "Dialogdiet fail!");
aNameDlg->SetText( aTitle );
@@ -984,123 +1036,110 @@ bool SlotManager::RenameSlideFromDrawViewShell( USHORT nPageId, const String & r
*/
void SlotManager::InsertSlide (SfxRequest& rRequest)
{
- PageSelector& rSelector (mrSlideSorter.GetController().GetPageSelector());
- // The fallback insertion position is after the last slide.
- sal_Int32 nInsertionIndex (rSelector.GetPageCount() - 1);
- if (rSelector.GetSelectedPageCount() > 0)
+ const sal_Int32 nInsertionIndex (GetInsertionPosition());
+
+ PageSelector::BroadcastLock aBroadcastLock (mrSlideSorter);
+
+ SdPage* pNewPage = NULL;
+ if (mrSlideSorter.GetModel().GetEditMode() == EM_PAGE)
{
- // Deselect all but the last selected slide.
- bool bLastSelectedSlideSeen (false);
- for (int nIndex=rSelector.GetPageCount()-1; nIndex>=0; --nIndex)
+ SlideSorterViewShell* pShell = dynamic_cast<SlideSorterViewShell*>(
+ mrSlideSorter.GetViewShell());
+ if (pShell != NULL)
{
- if (rSelector.IsPageSelected(nIndex))
- {
- if (bLastSelectedSlideSeen)
- rSelector.DeselectPage (nIndex);
- else
- {
- nInsertionIndex = nIndex;
- bLastSelectedSlideSeen = true;
- }
- }
+ pNewPage = pShell->CreateOrDuplicatePage (
+ rRequest,
+ mrSlideSorter.GetModel().GetPageType(),
+ nInsertionIndex>=0
+ ? mrSlideSorter.GetModel().GetPageDescriptor(nInsertionIndex)->GetPage()
+ : NULL);
}
}
-
- // No selection. Is there an insertion indicator?
- else if (mrSlideSorter.GetView().GetOverlay()
- .GetInsertionIndicatorOverlay().isVisible())
- {
- // Select the page before the insertion indicator.
- nInsertionIndex = mrSlideSorter.GetView().GetOverlay()
- .GetInsertionIndicatorOverlay().GetInsertionPageIndex();
- nInsertionIndex --;
- rSelector.SelectPage (nInsertionIndex);
- }
-
- // Is there a stored insertion position?
- else if (mrSlideSorter.GetController().GetSelectionManager()->GetInsertionPosition() >= 0)
+ else
{
- nInsertionIndex
- = mrSlideSorter.GetController().GetSelectionManager()->GetInsertionPosition() - 1;
- rSelector.SelectPage(nInsertionIndex);
- }
+ // Use the API to create a new page.
+ SdDrawDocument* pDocument = mrSlideSorter.GetModel().GetDocument();
+ Reference<drawing::XMasterPagesSupplier> xMasterPagesSupplier (
+ pDocument->getUnoModel(), UNO_QUERY);
+ if (xMasterPagesSupplier.is())
+ {
+ Reference<drawing::XDrawPages> xMasterPages (
+ xMasterPagesSupplier->getMasterPages());
+ if (xMasterPages.is())
+ {
+ xMasterPages->insertNewByIndex (nInsertionIndex+1);
- // Select the last page when there is at least one page.
- else if (rSelector.GetPageCount() > 0)
- {
- nInsertionIndex = rSelector.GetPageCount() - 1;
- rSelector.SelectPage (nInsertionIndex);
+ // Create shapes for the default layout.
+ pNewPage = pDocument->GetMasterSdPage(
+ (USHORT)(nInsertionIndex+1), PK_STANDARD);
+ pNewPage->CreateTitleAndLayout (TRUE,TRUE);
+ }
+ }
}
+ if (pNewPage == NULL)
+ return;
- // Hope for the best that CreateOrDuplicatePage() can cope with an empty
- // selection.
- else
- {
- nInsertionIndex = -1;
- }
+ // When a new page has been inserted then select it, make it the
+ // current page, and focus it.
+ view::SlideSorterView::DrawLock aDrawLock (mrSlideSorter);
+ PageSelector::UpdateLock aUpdateLock (mrSlideSorter);
+ mrSlideSorter.GetController().GetPageSelector().DeselectAllPages();
+ mrSlideSorter.GetController().GetPageSelector().SelectPage(pNewPage);
+}
- USHORT nPageCount ((USHORT)mrSlideSorter.GetModel().GetPageCount());
- rSelector.DisableBroadcasting();
- // In order for SlideSorterController::GetActualPage() to select the
- // selected page as current page we have to turn off the focus
- // temporarily.
- {
- FocusManager::FocusHider aTemporaryFocusHider (
- mrSlideSorter.GetController().GetFocusManager());
- SdPage* pPreviousPage = NULL;
- if (nInsertionIndex >= 0)
- pPreviousPage = mrSlideSorter.GetModel()
- .GetPageDescriptor(nInsertionIndex)->GetPage();
- if (mrSlideSorter.GetModel().GetEditMode() == EM_PAGE)
- {
- SlideSorterViewShell* pShell = dynamic_cast<SlideSorterViewShell*>(
- mrSlideSorter.GetViewShell());
- if (pShell != NULL)
- {
- pShell->CreateOrDuplicatePage (
- rRequest,
- mrSlideSorter.GetModel().GetPageType(),
- pPreviousPage);
- }
- }
- else
+void SlotManager::DuplicateSelectedSlides (SfxRequest& rRequest)
+{
+ // Create a list of the pages that are to be duplicated. The process of
+ // duplication alters the selection.
+ sal_Int32 nInsertPosition (0);
+ ::std::vector<SdPage*> aPagesToDuplicate;
+ model::PageEnumeration aSelectedPages (
+ model::PageEnumerationProvider::CreateSelectedPagesEnumeration(mrSlideSorter.GetModel()));
+ while (aSelectedPages.HasMoreElements())
+ {
+ model::SharedPageDescriptor pDescriptor (aSelectedPages.GetNextElement());
+ if (pDescriptor && pDescriptor->GetPage())
{
- // Use the API to create a new page.
- SdDrawDocument* pDocument = mrSlideSorter.GetModel().GetDocument();
- Reference<drawing::XMasterPagesSupplier> xMasterPagesSupplier (
- pDocument->getUnoModel(), UNO_QUERY);
- if (xMasterPagesSupplier.is())
- {
- Reference<drawing::XDrawPages> xMasterPages (
- xMasterPagesSupplier->getMasterPages());
- if (xMasterPages.is())
- {
- xMasterPages->insertNewByIndex (nInsertionIndex+1);
-
- // Create shapes for the default layout.
- SdPage* pMasterPage = pDocument->GetMasterSdPage(
- (USHORT)(nInsertionIndex+1), PK_STANDARD);
- pMasterPage->CreateTitleAndLayout (TRUE,TRUE);
- }
- }
+ aPagesToDuplicate.push_back(pDescriptor->GetPage());
+ nInsertPosition = pDescriptor->GetPage()->GetPageNum()+2;
}
}
- // When a new page has been inserted then select it and make it the
- // current page.
- mrSlideSorter.GetView().LockRedraw(TRUE);
- if (mrSlideSorter.GetModel().GetPageCount() > nPageCount)
+ // Duplicate the pages in aPagesToDuplicate and collect the newly
+ // created pages in aPagesToSelect.
+ const bool bUndo (aPagesToDuplicate.size()>1 && mrSlideSorter.GetView().IsUndoEnabled());
+ if (bUndo)
+ mrSlideSorter.GetView().BegUndo(String(SdResId(STR_INSERTPAGE)));
+
+ ::std::vector<SdPage*> aPagesToSelect;
+ for(::std::vector<SdPage*>::const_iterator
+ iPage(aPagesToDuplicate.begin()),
+ iEnd(aPagesToDuplicate.end());
+ iPage!=iEnd;
+ ++iPage, nInsertPosition+=2)
{
- nInsertionIndex++;
- model::SharedPageDescriptor pDescriptor = mrSlideSorter.GetModel().GetPageDescriptor(nInsertionIndex);
- if (pDescriptor.get() != NULL)
- mrSlideSorter.GetController().GetCurrentSlideManager()->SwitchCurrentSlide(pDescriptor);
+ aPagesToSelect.push_back(
+ mrSlideSorter.GetViewShell()->CreateOrDuplicatePage(
+ rRequest, PK_STANDARD, *iPage, nInsertPosition));
}
- rSelector.EnableBroadcasting();
- mrSlideSorter.GetView().LockRedraw(FALSE);
+ aPagesToDuplicate.clear();
+
+ if (bUndo)
+ mrSlideSorter.GetView().EndUndo();
+
+ // Set the selection to the pages in aPagesToSelect.
+ PageSelector& rSelector (mrSlideSorter.GetController().GetPageSelector());
+ rSelector.DeselectAllPages();
+ ::std::for_each (
+ aPagesToSelect.begin(),
+ aPagesToSelect.end(),
+ ::boost::bind(
+ static_cast<void (PageSelector::*)(const SdPage*)>(&PageSelector::SelectPage),
+ rSelector,
+ _1));
}
void SlotManager::ExecuteCommandAsynchronously (::std::auto_ptr<Command> pCommand)
@@ -1130,5 +1169,154 @@ IMPL_LINK(SlotManager, UserEventCallback, void*, EMPTYARG)
return 1;
}
+
+
+
+void SlotManager::ChangeSlideExclusionState (
+ const model::SharedPageDescriptor& rpDescriptor,
+ const bool bExcludeSlide)
+{
+ if (rpDescriptor)
+ {
+ mrSlideSorter.GetView().SetState(
+ rpDescriptor,
+ model::PageDescriptor::ST_Excluded,
+ bExcludeSlide);
+ }
+ else
+ {
+ model::PageEnumeration aSelectedPages (
+ model::PageEnumerationProvider::CreateSelectedPagesEnumeration(
+ mrSlideSorter.GetModel()));
+ while (aSelectedPages.HasMoreElements())
+ {
+ model::SharedPageDescriptor pDescriptor (aSelectedPages.GetNextElement());
+ mrSlideSorter.GetView().SetState(
+ pDescriptor,
+ model::PageDescriptor::ST_Excluded,
+ bExcludeSlide);
+ }
+ }
+
+ SfxBindings& rBindings (mrSlideSorter.GetViewShell()->GetViewFrame()->GetBindings());
+ rBindings.Invalidate(SID_PRESENTATION);
+ rBindings.Invalidate(SID_REHEARSE_TIMINGS);
+ rBindings.Invalidate(SID_HIDE_SLIDE);
+ rBindings.Invalidate(SID_SHOW_SLIDE);
+ mrSlideSorter.GetModel().GetDocument()->SetChanged();
+}
+
+
+
+
+sal_Int32 SlotManager::GetInsertionPosition (void)
+{
+ PageSelector& rSelector (mrSlideSorter.GetController().GetPageSelector());
+
+ // The insertion indicator is preferred. After all the user explicitly
+ // used it to define the insertion position.
+ if (mrSlideSorter.GetController().GetInsertionIndicatorHandler()->IsActive())
+ {
+ // Select the page before the insertion indicator.
+ return mrSlideSorter.GetController().GetInsertionIndicatorHandler()->GetInsertionPageIndex()
+ - 1;
+ }
+
+ // Is there a stored insertion position?
+ else if (mrSlideSorter.GetController().GetSelectionManager()->GetInsertionPosition() >= 0)
+ {
+ return mrSlideSorter.GetController().GetSelectionManager()->GetInsertionPosition() - 1;
+ }
+
+ // Use the index of the last selected slide.
+ else if (rSelector.GetSelectedPageCount() > 0)
+ {
+ for (int nIndex=rSelector.GetPageCount()-1; nIndex>=0; --nIndex)
+ if (rSelector.IsPageSelected(nIndex))
+ return nIndex;
+
+ // We should never get here.
+ OSL_ASSERT(false);
+ return rSelector.GetPageCount() - 1;
+ }
+
+ // Select the last page when there is at least one page.
+ else if (rSelector.GetPageCount() > 0)
+ {
+ return rSelector.GetPageCount() - 1;
+ }
+
+ // Hope for the best that CreateOrDuplicatePage() can cope with an empty
+ // selection.
+ else
+ {
+ // We should never get here because there has to be at least one page.
+ OSL_ASSERT(false);
+ return -1;
+ }
+}
+
+
+
+
+void SlotManager::NotifyEditModeChange (void)
+{
+ SfxBindings& rBindings (mrSlideSorter.GetViewShell()->GetViewFrame()->GetBindings());
+ rBindings.Invalidate(SID_PRESENTATION);
+ rBindings.Invalidate(SID_INSERTPAGE);
+ rBindings.Invalidate(SID_DUPLICATE_PAGE);
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+
+namespace {
+
+
+
+SlideExclusionState GetSlideExclusionState (model::PageEnumeration& rPageSet)
+{
+ SlideExclusionState eState (UNDEFINED);
+ BOOL bState;
+
+ // Get toggle state of the selected pages.
+ while (rPageSet.HasMoreElements() && eState!=MIXED)
+ {
+ bState = rPageSet.GetNextElement()->GetPage()->IsExcluded();
+ switch (eState)
+ {
+ case UNDEFINED:
+ // Use the first selected page to set the inital value.
+ eState = bState ? EXCLUDED : INCLUDED;
+ break;
+
+ case EXCLUDED:
+ // The pages before where all not part of the show,
+ // this one is.
+ if ( ! bState)
+ eState = MIXED;
+ break;
+
+ case INCLUDED:
+ // The pages before where all part of the show,
+ // this one is not.
+ if (bState)
+ eState = MIXED;
+ break;
+
+ case MIXED:
+ default:
+ // No need to change anything.
+ break;
+ }
+ }
+
+ return eState;
+}
+
+} // end of anonymous namespace
+
} } } // end of namespace ::sd::slidesorter::controller
diff --git a/sd/source/ui/slidesorter/controller/SlsTransferable.cxx b/sd/source/ui/slidesorter/controller/SlsTransferable.cxx
index 20ddc937469c..efda2eb1e4eb 100644..100755
--- a/sd/source/ui/slidesorter/controller/SlsTransferable.cxx
+++ b/sd/source/ui/slidesorter/controller/SlsTransferable.cxx
@@ -28,7 +28,7 @@
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sd.hxx"
-#include "SlsTransferable.hxx"
+#include "controller/SlsTransferable.hxx"
#include "SlideSorterViewShell.hxx"
#include "View.hxx"
@@ -39,9 +39,11 @@ Transferable::Transferable (
SdDrawDocument* pSrcDoc,
::sd::View* pWorkView,
BOOL bInitOnGetData,
- SlideSorterViewShell* pViewShell)
+ SlideSorterViewShell* pViewShell,
+ const ::std::vector<Representative>& rRepresentatives)
: SdTransferable (pSrcDoc, pWorkView, bInitOnGetData),
- mpViewShell(pViewShell)
+ mpViewShell(pViewShell),
+ maRepresentatives(rRepresentatives)
{
if (mpViewShell != NULL)
StartListening(*mpViewShell);
@@ -49,6 +51,7 @@ Transferable::Transferable (
+
Transferable::~Transferable (void)
{
if (mpViewShell != NULL)
@@ -89,4 +92,10 @@ void Transferable::Notify (SfxBroadcaster& rBroadcaster, const SfxHint& rHint)
+const ::std::vector<Transferable::Representative>& Transferable::GetRepresentatives (void) const
+{
+ return maRepresentatives;
+}
+
+
} } } // end of namespace ::sd::slidesorter::controller
diff --git a/sd/source/ui/slidesorter/controller/SlsTransferable.hxx b/sd/source/ui/slidesorter/controller/SlsTransferable.hxx
deleted file mode 100644
index f527fd4768b9..000000000000
--- a/sd/source/ui/slidesorter/controller/SlsTransferable.hxx
+++ /dev/null
@@ -1,70 +0,0 @@
-/*************************************************************************
- *
- * 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_TRANSFERABLE_HXX
-#define SD_SLIDESORTER_TRANSFERABLE_HXX
-
-#include "sdxfer.hxx"
-
-class SdDrawDocument;
-namespace sd
-{
- class pWorkView;
- namespace slidesorter
- {
- class SlideSorterViewShell;
- }
-}
-
-namespace sd { namespace slidesorter { namespace controller {
-
-/** This class exists to have DragFinished call the correct object: the
- SlideSorterViewShell instead of the old SlideView.
-*/
-class Transferable
- : public SdTransferable
-{
-public:
- Transferable (
- SdDrawDocument* pSrcDoc,
- ::sd::View* pWorkView,
- BOOL bInitOnGetData,
- SlideSorterViewShell* pViewShell);
-
- virtual ~Transferable (void);
-
- virtual void DragFinished (sal_Int8 nDropAction);
-
-private:
- SlideSorterViewShell* mpViewShell;
-
- virtual void Notify (SfxBroadcaster& rBroadcaster, const SfxHint& rHint);
-};
-
-} } } // end of namespace ::sd::slidesorter::controller
-
-#endif
diff --git a/sd/source/ui/slidesorter/controller/SlsVisibleAreaManager.cxx b/sd/source/ui/slidesorter/controller/SlsVisibleAreaManager.cxx
new file mode 100644
index 000000000000..6a85192f8418
--- /dev/null
+++ b/sd/source/ui/slidesorter/controller/SlsVisibleAreaManager.cxx
@@ -0,0 +1,301 @@
+/*************************************************************************
+ *
+ * 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 "precompiled_sd.hxx"
+
+#include "controller/SlsVisibleAreaManager.hxx"
+#include "controller/SlideSorterController.hxx"
+#include "controller/SlsProperties.hxx"
+#include "controller/SlsAnimationFunction.hxx"
+#include "controller/SlsScrollBarManager.hxx"
+#include "controller/SlsCurrentSlideManager.hxx"
+
+
+namespace sd { namespace slidesorter { namespace controller {
+
+namespace {
+ class VisibleAreaScroller
+ {
+ public:
+ VisibleAreaScroller (
+ SlideSorter& rSlideSorter,
+ const Point aStart,
+ const Point aEnd);
+ void operator() (const double nValue);
+ private:
+ SlideSorter& mrSlideSorter;
+ Point maStart;
+ const Point maEnd;
+ const ::boost::function<double(double)> maAccelerationFunction;
+ };
+
+} // end of anonymous namespace
+
+
+
+VisibleAreaManager::VisibleAreaManager (SlideSorter& rSlideSorter)
+ : mrSlideSorter(rSlideSorter),
+ maVisibleRequests(),
+ mnScrollAnimationId(Animator::NotAnAnimationId),
+ maRequestedVisibleTopLeft(),
+ meRequestedAnimationMode(Animator::AM_Immediate),
+ mbIsCurrentSlideTrackingActive(true),
+ mnDisableCount(0)
+{
+}
+
+
+
+
+VisibleAreaManager::~VisibleAreaManager (void)
+{
+}
+
+
+
+
+void VisibleAreaManager::ActivateCurrentSlideTracking (void)
+{
+ mbIsCurrentSlideTrackingActive = true;
+}
+
+
+
+
+void VisibleAreaManager::DeactivateCurrentSlideTracking (void)
+{
+ mbIsCurrentSlideTrackingActive = false;
+}
+
+
+
+
+void VisibleAreaManager::RequestVisible (
+ const model::SharedPageDescriptor& rpDescriptor,
+ const bool bForce)
+{
+ if (rpDescriptor)
+ {
+ if (mnDisableCount == 0)
+ {
+ maVisibleRequests.push_back(
+ mrSlideSorter.GetView().GetLayouter().GetPageObjectBox(
+ rpDescriptor->GetPageIndex(),
+ true));
+ }
+ if (bForce && ! mbIsCurrentSlideTrackingActive)
+ ActivateCurrentSlideTracking();
+ MakeVisible();
+ }
+}
+
+
+
+
+void VisibleAreaManager::RequestCurrentSlideVisible (void)
+{
+ if (mbIsCurrentSlideTrackingActive && mnDisableCount==0)
+ RequestVisible(
+ mrSlideSorter.GetController().GetCurrentSlideManager()->GetCurrentSlide());
+}
+
+
+
+
+void VisibleAreaManager::MakeVisible (void)
+{
+ if (maVisibleRequests.empty())
+ return;
+
+ SharedSdWindow pWindow (mrSlideSorter.GetContentWindow());
+ if ( ! pWindow)
+ return;
+ const Point aCurrentTopLeft (pWindow->PixelToLogic(Point(0,0)));
+
+ const ::boost::optional<Point> aNewVisibleTopLeft (GetRequestedTopLeft());
+ maVisibleRequests.clear();
+ if ( ! aNewVisibleTopLeft)
+ return;
+
+ // We now know what the visible area shall be. Scroll accordingly
+ // unless that is not already the visible area or a running scroll
+ // animation has it as its target area.
+ if (mnScrollAnimationId!=Animator::NotAnAnimationId
+ && maRequestedVisibleTopLeft==aNewVisibleTopLeft)
+ return;
+
+ // Stop a running animation.
+ if (mnScrollAnimationId != Animator::NotAnAnimationId)
+ mrSlideSorter.GetController().GetAnimator()->RemoveAnimation(mnScrollAnimationId);
+
+ maRequestedVisibleTopLeft = aNewVisibleTopLeft.get();
+ VisibleAreaScroller aAnimation(
+ mrSlideSorter,
+ aCurrentTopLeft,
+ maRequestedVisibleTopLeft);
+ if (meRequestedAnimationMode==Animator::AM_Animated
+ && mrSlideSorter.GetProperties()->IsSmoothSelectionScrolling())
+ {
+ mnScrollAnimationId = mrSlideSorter.GetController().GetAnimator()->AddAnimation(
+ aAnimation,
+ 0,
+ 300);
+ }
+ else
+ {
+ // Execute the animation at its final value.
+ aAnimation(1.0);
+ }
+ meRequestedAnimationMode = Animator::AM_Immediate;
+}
+
+
+
+
+::boost::optional<Point> VisibleAreaManager::GetRequestedTopLeft (void) const
+{
+ SharedSdWindow pWindow (mrSlideSorter.GetContentWindow());
+ if ( ! pWindow)
+ return ::boost::optional<Point>();
+
+ // Get the currently visible area and the model area.
+ const Rectangle aVisibleArea (pWindow->PixelToLogic(
+ Rectangle(
+ Point(0,0),
+ pWindow->GetOutputSizePixel())));
+ const Rectangle aModelArea (mrSlideSorter.GetView().GetModelArea());
+
+ sal_Int32 nVisibleTop (aVisibleArea.Top());
+ const sal_Int32 nVisibleWidth (aVisibleArea.GetWidth());
+ sal_Int32 nVisibleLeft (aVisibleArea.Left());
+ const sal_Int32 nVisibleHeight (aVisibleArea.GetHeight());
+
+ // Find the longest run of boxes whose union fits into the visible area.
+ Rectangle aBoundingBox;
+ for (::std::vector<Rectangle>::const_iterator
+ iBox(maVisibleRequests.begin()),
+ iEnd(maVisibleRequests.end());
+ iBox!=iEnd;
+ ++iBox)
+ {
+ if (nVisibleTop+nVisibleHeight <= iBox->Bottom())
+ nVisibleTop = iBox->Bottom()-nVisibleHeight;
+ if (nVisibleTop > iBox->Top())
+ nVisibleTop = iBox->Top();
+
+ if (nVisibleLeft+nVisibleWidth <= iBox->Right())
+ nVisibleLeft = iBox->Right()-nVisibleWidth;
+ if (nVisibleLeft > iBox->Left())
+ nVisibleLeft = iBox->Left();
+
+ // Make sure the visible area does not move outside the model area.
+ if (nVisibleTop + nVisibleHeight > aModelArea.Bottom())
+ nVisibleTop = aModelArea.Bottom() - nVisibleHeight;
+ if (nVisibleTop < aModelArea.Top())
+ nVisibleTop = aModelArea.Top();
+
+ if (nVisibleLeft + nVisibleWidth > aModelArea.Right())
+ nVisibleLeft = aModelArea.Right() - nVisibleWidth;
+ if (nVisibleLeft < aModelArea.Left())
+ nVisibleLeft = aModelArea.Left();
+ }
+
+ const Point aRequestedTopLeft (nVisibleLeft, nVisibleTop);
+ if (aRequestedTopLeft == aVisibleArea.TopLeft())
+ return ::boost::optional<Point>();
+ else
+ return ::boost::optional<Point>(aRequestedTopLeft);
+}
+
+
+
+
+//===== VisibleAreaManager::TemporaryDisabler =================================
+
+VisibleAreaManager::TemporaryDisabler::TemporaryDisabler (SlideSorter& rSlideSorter)
+ : mrVisibleAreaManager(rSlideSorter.GetController().GetVisibleAreaManager())
+{
+ ++mrVisibleAreaManager.mnDisableCount;
+}
+
+
+
+
+VisibleAreaManager::TemporaryDisabler::~TemporaryDisabler (void)
+{
+ --mrVisibleAreaManager.mnDisableCount;
+}
+
+
+
+//===== VerticalVisibleAreaScroller ===========================================
+
+namespace {
+
+const static sal_Int32 gnMaxScrollDistance = 300;
+
+VisibleAreaScroller::VisibleAreaScroller (
+ SlideSorter& rSlideSorter,
+ const Point aStart,
+ const Point aEnd)
+ : mrSlideSorter(rSlideSorter),
+ maStart(aStart),
+ maEnd(aEnd),
+ maAccelerationFunction(
+ controller::AnimationParametricFunction(
+ controller::AnimationBezierFunction (0.1,0.6)))
+{
+ // When the distance to scroll is larger than a threshold then first
+ // jump to within this distance of the final value and start the
+ // animation from there.
+ if (abs(aStart.X()-aEnd.X()) > gnMaxScrollDistance)
+ if (aStart.X() < aEnd.X())
+ maStart.X() = aEnd.X()-gnMaxScrollDistance;
+ else
+ maStart.X() = aEnd.X()+gnMaxScrollDistance;
+ if (abs(aStart.Y()-aEnd.Y()) > gnMaxScrollDistance)
+ if (aStart.Y() < aEnd.Y())
+ maStart.Y() = aEnd.Y()-gnMaxScrollDistance;
+ else
+ maStart.Y() = aEnd.Y()+gnMaxScrollDistance;
+}
+
+
+
+
+void VisibleAreaScroller::operator() (const double nTime)
+{
+ const double nLocalTime (maAccelerationFunction(nTime));
+ mrSlideSorter.GetController().GetScrollBarManager().SetTopLeft(
+ Point(
+ sal_Int32(0.5 + maStart.X() * (1.0 - nLocalTime) + maEnd.X() * nLocalTime),
+ sal_Int32 (0.5 + maStart.Y() * (1.0 - nLocalTime) + maEnd.Y() * nLocalTime)));
+}
+
+} // end of anonymous namespace
+
+} } } // end of namespace ::sd::slidesorter::controller
diff --git a/sd/source/ui/slidesorter/controller/makefile.mk b/sd/source/ui/slidesorter/controller/makefile.mk
index 8ab63ddf776c..460ef16ed3f1 100644..100755
--- a/sd/source/ui/slidesorter/controller/makefile.mk
+++ b/sd/source/ui/slidesorter/controller/makefile.mk
@@ -45,25 +45,23 @@ PRJINC=..$/..
SLOFILES = \
$(SLO)$/SlideSorterController.obj \
$(SLO)$/SlsAnimator.obj \
+ $(SLO)$/SlsAnimationFunction.obj \
$(SLO)$/SlsClipboard.obj \
$(SLO)$/SlsCurrentSlideManager.obj \
+ $(SLO)$/SlsDragAndDropContext.obj \
$(SLO)$/SlsFocusManager.obj \
+ $(SLO)$/SlsInsertionIndicatorHandler.obj\
$(SLO)$/SlsListener.obj \
- $(SLO)$/SlsPageObjectFactory.obj \
$(SLO)$/SlsPageSelector.obj \
$(SLO)$/SlsProperties.obj \
$(SLO)$/SlsScrollBarManager.obj \
$(SLO)$/SlsSelectionCommand.obj \
+ $(SLO)$/SlsSelectionFunction.obj \
$(SLO)$/SlsSelectionManager.obj \
+ $(SLO)$/SlsSelectionObserver.obj \
$(SLO)$/SlsSlotManager.obj \
$(SLO)$/SlsTransferable.obj \
- \
- $(SLO)$/SlsHideSlideFunction.obj \
- $(SLO)$/SlsSelectionFunction.obj \
- $(SLO)$/SlsSlideFunction.obj
-
-EXCEPTIONSFILES= \
- $(SLO)$/SlideSorterController.obj
+ $(SLO)$/SlsVisibleAreaManager.obj
# --- Tagets -------------------------------------------------------