summaryrefslogtreecommitdiff
path: root/sd/source/ui/slidesorter/controller
diff options
context:
space:
mode:
Diffstat (limited to 'sd/source/ui/slidesorter/controller')
-rwxr-xr-xsd/source/ui/slidesorter/controller/SlideSorterController.cxx1000
-rw-r--r--sd/source/ui/slidesorter/controller/SlsAnimator.cxx232
-rw-r--r--sd/source/ui/slidesorter/controller/SlsClipboard.cxx778
-rw-r--r--sd/source/ui/slidesorter/controller/SlsCommand.hxx45
-rwxr-xr-xsd/source/ui/slidesorter/controller/SlsCurrentSlideManager.cxx256
-rwxr-xr-xsd/source/ui/slidesorter/controller/SlsFocusManager.cxx362
-rw-r--r--sd/source/ui/slidesorter/controller/SlsHideSlideFunction.cxx169
-rw-r--r--sd/source/ui/slidesorter/controller/SlsHideSlideFunction.hxx73
-rwxr-xr-xsd/source/ui/slidesorter/controller/SlsListener.cxx599
-rw-r--r--sd/source/ui/slidesorter/controller/SlsListener.hxx185
-rw-r--r--sd/source/ui/slidesorter/controller/SlsPageObjectFactory.cxx100
-rwxr-xr-xsd/source/ui/slidesorter/controller/SlsPageSelector.cxx324
-rw-r--r--sd/source/ui/slidesorter/controller/SlsProperties.cxx233
-rwxr-xr-xsd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx631
-rwxr-xr-xsd/source/ui/slidesorter/controller/SlsSelectionCommand.cxx85
-rwxr-xr-xsd/source/ui/slidesorter/controller/SlsSelectionCommand.hxx95
-rwxr-xr-xsd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx1317
-rwxr-xr-xsd/source/ui/slidesorter/controller/SlsSelectionManager.cxx662
-rwxr-xr-xsd/source/ui/slidesorter/controller/SlsSlideFunction.cxx80
-rwxr-xr-xsd/source/ui/slidesorter/controller/SlsSlotManager.cxx1134
-rw-r--r--sd/source/ui/slidesorter/controller/SlsTransferable.cxx92
-rw-r--r--sd/source/ui/slidesorter/controller/SlsTransferable.hxx70
-rw-r--r--sd/source/ui/slidesorter/controller/makefile.mk71
23 files changed, 8593 insertions, 0 deletions
diff --git a/sd/source/ui/slidesorter/controller/SlideSorterController.cxx b/sd/source/ui/slidesorter/controller/SlideSorterController.cxx
new file mode 100755
index 000000000000..69c2a02ddc24
--- /dev/null
+++ b/sd/source/ui/slidesorter/controller/SlideSorterController.cxx
@@ -0,0 +1,1000 @@
+/*************************************************************************
+ *
+ * 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/SlideSorterController.hxx"
+
+#include "SlideSorter.hxx"
+#include "controller/SlsPageSelector.hxx"
+#include "controller/SlsSelectionFunction.hxx"
+#include "controller/SlsProperties.hxx"
+#include "controller/SlsCurrentSlideManager.hxx"
+#include "SlsListener.hxx"
+#include "controller/SlsFocusManager.hxx"
+#include "SlsSelectionCommand.hxx"
+#include "controller/SlsAnimator.hxx"
+#include "controller/SlsClipboard.hxx"
+#include "controller/SlsScrollBarManager.hxx"
+#include "controller/SlsPageObjectFactory.hxx"
+#include "controller/SlsSelectionManager.hxx"
+#include "controller/SlsSlotManager.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 "cache/SlsPageCache.hxx"
+#include "cache/SlsPageCacheManager.hxx"
+
+#include "drawdoc.hxx"
+#include "DrawViewShell.hxx"
+#include "TextLogger.hxx"
+#include "ViewShellBase.hxx"
+#include "Window.hxx"
+#include "FrameView.hxx"
+#include "DrawDocShell.hxx"
+#include "sdpage.hxx"
+#include "res_bmp.hrc"
+#include "sdresid.hxx"
+#include "strings.hrc"
+#include "app.hrc"
+#include "glob.hrc"
+#include "sdmod.hxx"
+#include "sdxfer.hxx"
+#include "FrameView.hxx"
+#include "ViewShellHint.hxx"
+#include "AccessibleSlideSorterView.hxx"
+#include "AccessibleSlideSorterObject.hxx"
+
+#include <vcl/window.hxx>
+#include <svx/svdopage.hxx>
+#include <svx/svxids.hrc>
+#include <svx/ruler.hxx>
+#include <svx/zoomitem.hxx>
+#include <svtools/tabbar.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/dispatch.hxx>
+#include <tools/link.hxx>
+#include <vcl/svapp.hxx>
+
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/drawing/XMasterPagesSupplier.hpp>
+#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
+#include <com/sun/star/drawing/XDrawPages.hpp>
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::sd::slidesorter::model;
+using namespace ::sd::slidesorter::view;
+using namespace ::sd::slidesorter::controller;
+
+namespace sd { namespace slidesorter { namespace controller {
+
+
+SlideSorterController::SlideSorterController (SlideSorter& rSlideSorter)
+ : mrSlideSorter(rSlideSorter),
+ mrModel(mrSlideSorter.GetModel()),
+ mrView(mrSlideSorter.GetView()),
+ mpPageSelector(),
+ mpFocusManager(),
+ mpSlotManager(),
+ mpClipboard(),
+ mpScrollBarManager(),
+ mpCurrentSlideManager(),
+ mpSelectionManager(),
+ mpAnimator(new Animator(rSlideSorter)),
+ mpListener(),
+ mnModelChangeLockCount(0),
+ mbPreModelChangeDone(false),
+ mbPostModelChangePending(false),
+ maSelectionBeforeSwitch(),
+ mnCurrentPageBeforeSwitch(0),
+ mpEditModeChangeMasterPage(NULL),
+ maTotalWindowArea(),
+ mnPaintEntranceCount(0),
+ mbIsContextMenuOpen(false),
+ mpProperties(new Properties())
+{
+ ::sd::Window* pWindow = mrSlideSorter.GetActiveWindow();
+ OSL_ASSERT(pWindow!=NULL);
+ if (pWindow != NULL)
+ {
+ // The whole background is painted by the view and controls.
+ ::Window* pParentWindow = pWindow->GetParent();
+ OSL_ASSERT(pParentWindow!=NULL);
+ pParentWindow->SetBackground (Wallpaper());
+
+ // Connect the view with the window that has been created by our base
+ // class.
+ pWindow->SetBackground (Wallpaper());
+ 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());
+ }
+}
+
+
+
+
+void SlideSorterController::Init (void)
+{
+ mrView.HandleModelChange();
+
+ mpCurrentSlideManager.reset(new CurrentSlideManager(mrSlideSorter));
+ mpPageSelector.reset(new PageSelector(mrSlideSorter));
+ mpFocusManager.reset(new FocusManager(mrSlideSorter));
+ mpSlotManager.reset(new SlotManager(mrSlideSorter));
+ mpClipboard.reset(new Clipboard(mrSlideSorter));
+ mpScrollBarManager.reset(new ScrollBarManager(mrSlideSorter));
+ mpSelectionManager.reset(new SelectionManager(mrSlideSorter));
+
+ mpScrollBarManager->LateInitialization();
+
+ // Create the selection function.
+ SfxRequest aRequest (
+ SID_OBJECT_SELECT,
+ 0,
+ mrModel.GetDocument()->GetItemPool());
+ mrSlideSorter.SetCurrentFunction(CreateSelectionFunction(aRequest));
+
+ mpListener = new Listener(mrSlideSorter);
+
+ mpPageSelector->UpdateAllPages();
+ GetSelectionManager()->SelectionHasChanged();
+}
+
+
+
+
+SlideSorterController::~SlideSorterController (void)
+{
+ try
+ {
+ uno::Reference<lang::XComponent> xComponent (
+ static_cast<XWeak*>(mpListener.get()), uno::UNO_QUERY);
+ if (xComponent.is())
+ xComponent->dispose();
+ }
+ catch( uno::Exception& e )
+ {
+ (void)e;
+ DBG_ERROR( "sd::SlideSorterController::~SlideSorterController(), exception caught!" );
+ }
+
+ // dispose should have been called by now so that nothing is to be done
+ // to shut down cleanly.
+}
+
+
+
+
+model::SharedPageDescriptor SlideSorterController::GetPageAt (
+ const Point& aPixelPosition)
+{
+ sal_Int32 nHitPageIndex (mrView.GetPageIndexAtPoint(aPixelPosition));
+ model::SharedPageDescriptor pDescriptorAtPoint;
+ if (nHitPageIndex >= 0)
+ pDescriptorAtPoint = mrModel.GetPageDescriptor(nHitPageIndex);
+
+ return pDescriptorAtPoint;
+}
+
+PageSelector& SlideSorterController::GetPageSelector (void)
+{
+ OSL_ASSERT(mpPageSelector.get()!=NULL);
+ return *mpPageSelector.get();
+}
+
+
+
+
+FocusManager& SlideSorterController::GetFocusManager (void)
+{
+ OSL_ASSERT(mpFocusManager.get()!=NULL);
+ return *mpFocusManager.get();
+}
+
+
+
+
+Clipboard& SlideSorterController::GetClipboard (void)
+{
+ OSL_ASSERT(mpClipboard.get()!=NULL);
+ return *mpClipboard.get();
+}
+
+
+
+
+ScrollBarManager& SlideSorterController::GetScrollBarManager (void)
+{
+ OSL_ASSERT(mpScrollBarManager.get()!=NULL);
+ return *mpScrollBarManager.get();
+}
+
+
+
+
+::boost::shared_ptr<CurrentSlideManager> SlideSorterController::GetCurrentSlideManager (void) const
+{
+ OSL_ASSERT(mpCurrentSlideManager.get()!=NULL);
+ return mpCurrentSlideManager;
+}
+
+
+
+
+::boost::shared_ptr<SlotManager> SlideSorterController::GetSlotManager (void) const
+{
+ OSL_ASSERT(mpSlotManager.get()!=NULL);
+ return mpSlotManager;
+}
+
+
+
+
+::boost::shared_ptr<SelectionManager> SlideSorterController::GetSelectionManager (void) const
+{
+ OSL_ASSERT(mpSelectionManager.get()!=NULL);
+ return mpSelectionManager;
+}
+
+
+
+
+void SlideSorterController::PrePaint()
+{
+ // forward VCLs PrePaint window event to DrawingLayer
+ mrView.PrePaint();
+}
+
+
+
+
+void SlideSorterController::Paint (
+ const Rectangle& rBBox,
+ ::Window* pWindow)
+{
+ // if (mnPaintEntranceCount == 0)
+ {
+ ++mnPaintEntranceCount;
+
+ try
+ {
+ if (GetSelectionManager()->IsMakeSelectionVisiblePending())
+ GetSelectionManager()->MakeSelectionVisible();
+
+ mrView.SetApplicationDocumentColor(GetProperties()->GetBackgroundColor());
+ mrView.CompleteRedraw(pWindow, Region(rBBox), 0);
+ }
+ catch (const Exception&)
+ {
+ // Ignore all exceptions.
+ }
+
+ --mnPaintEntranceCount;
+ }
+}
+
+
+
+
+void SlideSorterController::FuTemporary (SfxRequest& rRequest)
+{
+ mpSlotManager->FuTemporary (rRequest);
+}
+
+
+
+
+void SlideSorterController::FuPermanent (SfxRequest &rRequest)
+{
+ mpSlotManager->FuPermanent (rRequest);
+}
+
+
+
+
+void SlideSorterController::FuSupport (SfxRequest &rRequest)
+{
+ mpSlotManager->FuSupport (rRequest);
+}
+
+
+
+
+bool SlideSorterController::Command (
+ const CommandEvent& rEvent,
+ ::sd::Window* pWindow)
+{
+ bool bEventHasBeenHandled = false;
+
+ ViewShell* pViewShell = mrSlideSorter.GetViewShell();
+
+ switch (rEvent.GetCommand())
+ {
+ case COMMAND_CONTEXTMENU:
+ {
+ SdPage* pPage = NULL;
+ USHORT nPopupId;
+
+ model::PageEnumeration aSelectedPages (
+ PageEnumerationProvider::CreateSelectedPagesEnumeration(mrModel));
+ if (aSelectedPages.HasMoreElements())
+ pPage = aSelectedPages.GetNextElement()->GetPage();
+
+ // Choose the popup menu depending on a) the type of the main
+ // view shell, b) the edit mode, and c) on whether the selection
+ // is empty or not.
+ ViewShell::ShellType eMainViewShellType (ViewShell::ST_NONE);
+ ::boost::shared_ptr<ViewShell> pMainViewShell (
+ pViewShell->GetViewShellBase().GetMainViewShell());
+ if (pMainViewShell.get() != NULL)
+ eMainViewShellType = pMainViewShell->GetShellType();
+ switch (eMainViewShellType)
+ {
+ case ViewShell::ST_DRAW:
+ if (pPage != NULL)
+ nPopupId = RID_SLIDE_SORTER_DRAW_SEL_POPUP;
+ else
+ nPopupId = RID_SLIDE_SORTER_DRAW_NOSEL_POPUP;
+ break;
+
+ default:
+ if (mrModel.GetEditMode() == EM_PAGE)
+ if (pPage != NULL)
+ nPopupId = RID_SLIDE_SORTER_IMPRESS_SEL_POPUP;
+ else
+ nPopupId = RID_SLIDE_SORTER_IMPRESS_NOSEL_POPUP;
+ else
+ if (pPage != NULL)
+ nPopupId = RID_SLIDE_SORTER_MASTER_SEL_POPUP;
+ else
+ nPopupId = RID_SLIDE_SORTER_MASTER_NOSEL_POPUP;
+ }
+
+ 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);
+ }
+
+ pWindow->ReleaseMouse();
+ if (rEvent.IsMouseEvent())
+ {
+ mbIsContextMenuOpen = true;
+ if (pViewShell != NULL)
+ {
+ SfxDispatcher* pDispatcher = pViewShell->GetDispatcher();
+ if (pDispatcher != NULL)
+ pDispatcher->ExecutePopup(SdResId(nPopupId));
+ }
+ }
+ 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)
+ {
+ Rectangle aBBox (mrView.GetPageBoundingBox (
+ 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);
+ }
+ }
+ }
+ mbIsContextMenuOpen = false;
+ if (pPage == NULL)
+ {
+ // Remember the position of the insertion indicator before
+ // it is hidden, so that a pending slide insertion slot call
+ // finds the right place to insert a new slide.
+ GetSelectionManager()->SetInsertionPosition(
+ mrView.GetOverlay().GetInsertionIndicatorOverlay().GetInsertionPageIndex());
+ mrView.GetOverlay().GetInsertionIndicatorOverlay().setVisible(false);
+ }
+ 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;
+ }
+ break;
+ }
+
+ return bEventHasBeenHandled;
+}
+
+
+
+
+void SlideSorterController::LockModelChange (void)
+{
+ mnModelChangeLockCount += 1;
+}
+
+
+
+
+void SlideSorterController::UnlockModelChange (void)
+{
+ mnModelChangeLockCount -= 1;
+ if (mnModelChangeLockCount==0 && mbPostModelChangePending)
+ PostModelChange();
+}
+
+
+
+
+void SlideSorterController::PreModelChange (void)
+{
+ // Prevent PreModelChange to execute more than once per model lock.
+ if (mbPostModelChangePending)
+ return;
+ mbPreModelChangeDone = true;
+
+ if (mrSlideSorter.GetViewShell() != NULL)
+ mrSlideSorter.GetViewShell()->Broadcast(
+ ViewShellHint(ViewShellHint::HINT_COMPLEX_MODEL_CHANGE_START));
+
+ mpPageSelector->PrepareModelChange();
+ GetCurrentSlideManager()->PrepareModelChange();
+
+ ::sd::Window* pWindow = mrSlideSorter.GetActiveWindow();
+ if (pWindow != NULL)
+ mrView.PreModelChange();
+
+ mbPostModelChangePending = true;
+}
+
+
+
+
+void SlideSorterController::PostModelChange (void)
+{
+ mbPostModelChangePending = false;
+ mrModel.Resync();
+
+ ::sd::Window* pWindow = mrSlideSorter.GetActiveWindow();
+ if (pWindow != NULL)
+ {
+ GetCurrentSlideManager()->HandleModelChange();
+
+ mrView.PostModelChange ();
+
+ pWindow->SetViewOrigin (Point (0,0));
+ pWindow->SetViewSize (mrView.GetModelArea().GetSize());
+
+ // The visibility of the scroll bars may have to be changed. Then
+ // the size of the view has to change, too. Let Rearrange() handle
+ // that.
+ Rearrange();
+ }
+
+ mpPageSelector->HandleModelChange ();
+
+ if (mrSlideSorter.GetViewShell() != NULL)
+ mrSlideSorter.GetViewShell()->Broadcast(
+ ViewShellHint(ViewShellHint::HINT_COMPLEX_MODEL_CHANGE_END));
+}
+
+
+
+
+void SlideSorterController::HandleModelChange (void)
+{
+ // Ignore this call when the document is not in a valid state, i.e. has
+ // not the same number of regular and notes pages.
+ bool bIsDocumentValid = (mrModel.GetDocument()->GetPageCount() % 2 == 1);
+
+ if (bIsDocumentValid)
+ {
+ ModelChangeLock aLock (*this);
+ PreModelChange();
+ }
+}
+
+
+
+
+IMPL_LINK(SlideSorterController, WindowEventHandler, VclWindowEvent*, pEvent)
+{
+ if (pEvent != NULL)
+ {
+ ::Window* pWindow = pEvent->GetWindow();
+ ::sd::Window* pActiveWindow = mrSlideSorter.GetActiveWindow();
+ switch (pEvent->GetId())
+ {
+ case VCLEVENT_WINDOW_ACTIVATE:
+ case VCLEVENT_WINDOW_SHOW:
+ if (pActiveWindow != NULL && pWindow == pActiveWindow->GetParent())
+ mrView.RequestRepaint();
+ break;
+
+ case VCLEVENT_WINDOW_GETFOCUS:
+ if (pActiveWindow != NULL && pWindow == pActiveWindow)
+ GetFocusManager().ShowFocus(false);
+ break;
+
+ case VCLEVENT_WINDOW_LOSEFOCUS:
+ if (pActiveWindow != NULL && pWindow == pActiveWindow)
+ GetFocusManager().HideFocus();
+ break;
+
+ case VCLEVENT_APPLICATION_DATACHANGED:
+ {
+ // Invalidate the preview cache.
+ cache::PageCacheManager::Instance()->InvalidateAllCaches();
+
+ // Update the draw mode.
+ ULONG nDrawMode (Application::GetSettings().GetStyleSettings().GetHighContrastMode()
+ ? ViewShell::OUTPUT_DRAWMODE_CONTRAST
+ : ViewShell::OUTPUT_DRAWMODE_COLOR);
+ if (mrSlideSorter.GetViewShell() != NULL)
+ mrSlideSorter.GetViewShell()->GetFrameView()->SetDrawMode(nDrawMode);
+ if (pActiveWindow != NULL)
+ pActiveWindow->SetDrawMode(nDrawMode);
+ mrView.HandleDrawModeChange();
+
+ // When the system font has changed a layout has to be done.
+ mrView.Resize();
+ FontProvider::Instance().Invalidate();
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+
+
+
+void SlideSorterController::GetCtrlState (SfxItemSet& rSet)
+{
+ if (rSet.GetItemState(SID_RELOAD) != SFX_ITEM_UNKNOWN)
+ {
+ // "Letzte Version" vom SFx en/disablen lassen
+ SfxViewFrame* pSlideViewFrame = SfxViewFrame::Current();
+ DBG_ASSERT(pSlideViewFrame!=NULL,
+ "SlideSorterController::GetCtrlState: ViewFrame not found");
+ if (pSlideViewFrame)
+ {
+ pSlideViewFrame->GetSlotState (SID_RELOAD, NULL, &rSet);
+ }
+ else // MI sagt: kein MDIFrame --> disablen
+ {
+ rSet.DisableItem(SID_RELOAD);
+ }
+ }
+
+ // Output quality.
+ if (rSet.GetItemState(SID_OUTPUT_QUALITY_COLOR)==SFX_ITEM_AVAILABLE
+ ||rSet.GetItemState(SID_OUTPUT_QUALITY_GRAYSCALE)==SFX_ITEM_AVAILABLE
+ ||rSet.GetItemState(SID_OUTPUT_QUALITY_BLACKWHITE)==SFX_ITEM_AVAILABLE
+ ||rSet.GetItemState(SID_OUTPUT_QUALITY_CONTRAST)==SFX_ITEM_AVAILABLE)
+ {
+ ::sd::Window* pWindow = mrSlideSorter.GetActiveWindow();
+ if (pWindow != NULL)
+ {
+ ULONG nMode = pWindow->GetDrawMode();
+ UINT16 nQuality = 0;
+
+ switch (nMode)
+ {
+ case ViewShell::OUTPUT_DRAWMODE_COLOR:
+ nQuality = 0;
+ break;
+ case ViewShell::OUTPUT_DRAWMODE_GRAYSCALE:
+ nQuality = 1;
+ break;
+ case ViewShell::OUTPUT_DRAWMODE_BLACKWHITE:
+ nQuality = 2;
+ break;
+ case ViewShell::OUTPUT_DRAWMODE_CONTRAST:
+ nQuality = 3;
+ break;
+ }
+
+ rSet.Put (SfxBoolItem (SID_OUTPUT_QUALITY_COLOR,
+ (BOOL)(nQuality==0)));
+ rSet.Put (SfxBoolItem (SID_OUTPUT_QUALITY_GRAYSCALE,
+ (BOOL)(nQuality==1)));
+ rSet.Put (SfxBoolItem (SID_OUTPUT_QUALITY_BLACKWHITE,
+ (BOOL)(nQuality==2)));
+ rSet.Put (SfxBoolItem (SID_OUTPUT_QUALITY_CONTRAST,
+ (BOOL)(nQuality==3)));
+ }
+ }
+
+ if (rSet.GetItemState(SID_MAIL_SCROLLBODY_PAGEDOWN) == SFX_ITEM_AVAILABLE)
+ {
+ rSet.Put (SfxBoolItem( SID_MAIL_SCROLLBODY_PAGEDOWN, TRUE));
+ }
+}
+
+
+
+
+void SlideSorterController::GetStatusBarState (SfxItemSet& rSet)
+{
+ mpSlotManager->GetStatusBarState (rSet);
+}
+
+
+
+
+void SlideSorterController::ExecCtrl (SfxRequest& rRequest)
+{
+ mpSlotManager->ExecCtrl (rRequest);
+}
+
+
+
+
+void SlideSorterController::GetAttrState (SfxItemSet& rSet)
+{
+ mpSlotManager->GetAttrState (rSet);
+}
+
+
+
+
+void SlideSorterController::ExecStatusBar (SfxRequest& )
+{
+}
+
+
+
+
+void SlideSorterController::UpdateAllPages (void)
+{
+ // Do a redraw.
+ mrView.InvalidateAllWin();
+}
+
+
+
+
+Rectangle SlideSorterController::Resize (const Rectangle& rAvailableSpace)
+{
+ Rectangle aContentArea (rAvailableSpace);
+
+ if (maTotalWindowArea != rAvailableSpace)
+ {
+ maTotalWindowArea = rAvailableSpace;
+ aContentArea = Rearrange(true);
+ }
+
+ return aContentArea;
+}
+
+
+
+
+Rectangle SlideSorterController::Rearrange (bool bForce)
+{
+ Rectangle aNewContentArea (maTotalWindowArea);
+
+ ::boost::shared_ptr<sd::Window> pWindow = mrSlideSorter.GetContentWindow();
+ if (pWindow.get() != NULL)
+ {
+ // Place the scroll bars.
+ aNewContentArea = GetScrollBarManager().PlaceScrollBars(maTotalWindowArea);
+
+ bool bSizeHasChanged (false);
+ // Only when bForce is not true we have to test for a size change in
+ // order to determine whether the window and the view have to be resized.
+ if ( ! bForce)
+ {
+ Rectangle aCurrentContentArea (
+ pWindow->GetPosPixel(),
+ pWindow->GetOutputSizePixel());
+ bSizeHasChanged = (aNewContentArea != aCurrentContentArea);
+ }
+ if (bForce || bSizeHasChanged)
+ {
+ // The browser window gets the remaining space.
+ pWindow->SetPosSizePixel (aNewContentArea.TopLeft(), aNewContentArea.GetSize());
+ mrView.Resize();
+ }
+
+ // Adapt the scroll bars to the new zoom factor of the browser
+ // window and the arrangement of the page objects.
+ GetScrollBarManager().UpdateScrollBars(false, !bForce);
+ }
+
+ return aNewContentArea;
+}
+
+
+
+
+FunctionReference SlideSorterController::CreateSelectionFunction (SfxRequest& rRequest)
+{
+ FunctionReference xFunc( SelectionFunction::Create(mrSlideSorter, rRequest) );
+ return xFunc;
+}
+
+
+
+
+void SlideSorterController::PrepareEditModeChange (void)
+{
+ // Before we throw away the page descriptors we prepare for selecting
+ // descriptors in the other mode and for restoring the current
+ // selection when switching back to the current mode.
+ if (mrModel.GetEditMode() == EM_PAGE)
+ {
+ maSelectionBeforeSwitch.clear();
+
+ // Search for the first selected page and determine the master page
+ // used by its page object. It will be selected after the switch.
+ // In the same loop the current selection is stored.
+ PageEnumeration aSelectedPages (
+ PageEnumerationProvider::CreateSelectedPagesEnumeration(mrModel));
+ while (aSelectedPages.HasMoreElements())
+ {
+ SharedPageDescriptor pDescriptor (aSelectedPages.GetNextElement());
+ SdPage* pPage = pDescriptor->GetPage();
+ // Remember the master page of the first selected descriptor.
+ if (pPage!=NULL && mpEditModeChangeMasterPage==NULL)
+ mpEditModeChangeMasterPage = &static_cast<SdPage&>(
+ pPage->TRG_GetMasterPage());
+
+ maSelectionBeforeSwitch.push_back(pPage);
+ }
+
+ // Remember the current page.
+ if (mrSlideSorter.GetViewShell() != NULL)
+ mnCurrentPageBeforeSwitch = (mrSlideSorter.GetViewShell()->GetViewShellBase()
+ .GetMainViewShell()->GetActualPage()->GetPageNum()-1)/2;
+ }
+}
+
+
+
+
+bool SlideSorterController::ChangeEditMode (EditMode eEditMode)
+{
+ bool bResult (false);
+ if (mrModel.GetEditMode() != eEditMode)
+ {
+ ModelChangeLock aLock (*this);
+ PreModelChange();
+ // Do the actual edit mode switching.
+ bResult = mrModel.SetEditMode(eEditMode);
+ if (bResult)
+ HandleModelChange();
+ }
+ return bResult;
+}
+
+
+
+
+void SlideSorterController::FinishEditModeChange (void)
+{
+ if (mrModel.GetEditMode() == EM_MASTERPAGE)
+ {
+ // Search for the master page that was determined in
+ // PrepareEditModeChange() and make it the current page.
+ PageEnumeration aAllPages (PageEnumerationProvider::CreateAllPagesEnumeration(mrModel));
+ while (aAllPages.HasMoreElements())
+ {
+ SharedPageDescriptor pDescriptor (aAllPages.GetNextElement());
+ if (pDescriptor->GetPage() == mpEditModeChangeMasterPage)
+ {
+ GetCurrentSlideManager()->SwitchCurrentSlide(pDescriptor);
+ break;
+ }
+ }
+ }
+ else
+ {
+ SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(mnCurrentPageBeforeSwitch));
+ GetCurrentSlideManager()->SwitchCurrentSlide(pDescriptor);
+
+ // Restore the selection.
+ ::std::vector<SdPage*>::iterator iPage;
+ for (iPage=maSelectionBeforeSwitch.begin();
+ iPage!=maSelectionBeforeSwitch.end();
+ ++iPage)
+ {
+ mpPageSelector->SelectPage(*iPage);
+ }
+ maSelectionBeforeSwitch.clear( );
+ }
+ mpEditModeChangeMasterPage = NULL;
+}
+
+
+
+
+void SlideSorterController::PageNameHasChanged (int nPageIndex, const String& rsOldName)
+{
+ // Request a repaint for the page object whose name has changed.
+ model::SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nPageIndex));
+ if (pDescriptor.get() != NULL)
+ mrView.RequestRepaint(pDescriptor);
+
+ // Get a pointer to the corresponding accessible object and notify
+ // that of the name change.
+ do
+ {
+ ::sd::Window* pWindow = mrSlideSorter.GetActiveWindow();
+ if (pWindow == NULL)
+ break;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
+ xAccessible (pWindow->GetAccessible(FALSE));
+ if ( ! xAccessible.is())
+ break;
+
+ // Now comes a small hack. We assume that the accessible object is
+ // an instantiation of AccessibleSlideSorterView and cast it to that
+ // class. The cleaner alternative to this cast would be a new member
+ // in which we would store the last AccessibleSlideSorterView object
+ // created by SlideSorterViewShell::CreateAccessibleDocumentView().
+ // But then there is no guaranty that the accessible object obtained
+ // from the window really is that instance last created by
+ // CreateAccessibleDocumentView().
+ // However, the dynamic cast together with the check of the result
+ // being NULL should be safe enough.
+ ::accessibility::AccessibleSlideSorterView* pAccessibleView
+ = dynamic_cast< ::accessibility::AccessibleSlideSorterView*>(xAccessible.get());
+ if (pAccessibleView == NULL)
+ break;
+
+ ::accessibility::AccessibleSlideSorterObject* pChild
+ = pAccessibleView->GetAccessibleChildImplementation(nPageIndex);
+ if (pChild == NULL || pChild->GetPage() == NULL)
+ break;
+
+ ::rtl::OUString sOldName (rsOldName);
+ ::rtl::OUString sNewName (pChild->GetPage()->GetName());
+ pChild->FireAccessibleEvent(
+ ::com::sun::star::accessibility::AccessibleEventId::NAME_CHANGED,
+ makeAny(sOldName),
+ makeAny(sNewName));
+ }
+ while (false);
+}
+
+
+
+
+bool SlideSorterController::IsContextMenuOpen (void) const
+{
+ return mbIsContextMenuOpen;
+}
+
+
+
+
+::boost::shared_ptr<Properties> SlideSorterController::GetProperties (void) const
+{
+ return mpProperties;
+}
+
+
+
+
+void SlideSorterController::SetDocumentSlides (const Reference<container::XIndexAccess>& rxSlides)
+{
+ if (mrModel.GetDocumentSlides() != rxSlides)
+ {
+ ModelChangeLock aLock (*this);
+ PreModelChange();
+
+ mrModel.SetDocumentSlides(rxSlides);
+ mrView.Layout();
+ }
+}
+
+
+
+
+::boost::shared_ptr<Animator> SlideSorterController::GetAnimator (void) const
+{
+ return mpAnimator;
+}
+
+
+
+
+//===== SlideSorterController::ModelChangeLock ================================
+
+SlideSorterController::ModelChangeLock::ModelChangeLock (
+ SlideSorterController& rController)
+ : mpController(&rController)
+{
+ mpController->LockModelChange();
+}
+
+
+
+
+SlideSorterController::ModelChangeLock::~ModelChangeLock (void)
+{
+ Release();
+}
+
+
+
+
+void SlideSorterController::ModelChangeLock::Release (void)
+{
+ if (mpController != NULL)
+ {
+ mpController->UnlockModelChange();
+ mpController = NULL;
+ }
+}
+
+} } } // end of namespace ::sd::slidesorter
diff --git a/sd/source/ui/slidesorter/controller/SlsAnimator.cxx b/sd/source/ui/slidesorter/controller/SlsAnimator.cxx
new file mode 100644
index 000000000000..56505d9756e6
--- /dev/null
+++ b/sd/source/ui/slidesorter/controller/SlsAnimator.cxx
@@ -0,0 +1,232 @@
+/*************************************************************************
+ *
+ * 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/SlsAnimator.hxx"
+#include "view/SlideSorterView.hxx"
+#include "View.hxx"
+
+namespace sd { namespace slidesorter { namespace controller {
+
+namespace {
+ static const sal_Int32 gnResolution = 25;
+}
+/** Handle one animation function by using a timer for frequent calls to
+ the animations operator().
+*/
+class Animator::Animation
+{
+public:
+ Animation (
+ const Animator::AnimationFunction& rAnimation,
+ const double nDelta);
+ ~Animation (void);
+ bool Run (void);
+ bool IsExpired (void);
+ Animator::AnimationFunction maAnimation;
+ double mnValue;
+ double mnDelta;
+};
+
+
+
+
+class Animator::DrawLock
+{
+public:
+ DrawLock (View& rView);
+ ~DrawLock (void);
+
+private:
+ View& mrView;
+};
+
+
+
+
+Animator::Animator (SlideSorter& rSlideSorter)
+ : mrSlideSorter(rSlideSorter),
+ maTimer(),
+ maAnimations(),
+ mpDrawLock()
+{
+ maTimer.SetTimeout(gnResolution);
+ maTimer.SetTimeoutHdl(LINK(this,Animator,TimeoutHandler));
+}
+
+
+
+
+Animator::~Animator (void)
+{
+ maTimer.Stop();
+ mpDrawLock.reset();
+}
+
+
+
+
+void Animator::AddAnimation (
+ const AnimationFunction& rAnimation,
+ const sal_Int32 nDuration)
+{
+ const double nDelta = double(gnResolution) / double(nDuration);
+ maAnimations.push_back(boost::shared_ptr<Animation>(new Animation(rAnimation, nDelta)));
+
+ // 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();
+}
+
+
+
+
+bool Animator::ServeAnimations (void)
+{
+ bool bExpired (false);
+
+ AnimationList aCopy (maAnimations);
+ AnimationList::const_iterator iAnimation;
+ for (iAnimation=aCopy.begin(); iAnimation!=aCopy.end(); ++iAnimation)
+ {
+ bExpired |= (*iAnimation)->Run();
+ }
+
+ return bExpired;
+}
+
+
+
+
+void Animator::CleanUpAnimationList (void)
+{
+ AnimationList aActiveAnimations;
+
+ AnimationList::const_iterator iAnimation;
+ for (iAnimation=maAnimations.begin(); iAnimation!=maAnimations.end(); ++iAnimation)
+ {
+ if ( ! (*iAnimation)->IsExpired())
+ aActiveAnimations.push_back(*iAnimation);
+ }
+
+ maAnimations.swap(aActiveAnimations);
+}
+
+
+
+
+IMPL_LINK(Animator, TimeoutHandler, Timer*, EMPTYARG)
+{
+ if (ServeAnimations())
+ 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();
+ }
+
+ return 0;
+}
+
+
+
+
+//===== Animator::Animation ===================================================
+
+Animator::Animation::Animation (
+ const Animator::AnimationFunction& rAnimation,
+ const double nDelta)
+ : maAnimation(rAnimation),
+ mnValue(0),
+ mnDelta(nDelta)
+{
+
+ maAnimation(mnValue);
+ mnValue = mnDelta;
+
+}
+
+
+
+
+Animator::Animation::~Animation (void)
+{
+}
+
+
+
+
+bool Animator::Animation::Run (void)
+{
+ if (mnValue < 1.0)
+ {
+ maAnimation(mnValue);
+ mnValue += mnDelta;
+ return false;
+ }
+ else
+ {
+ maAnimation(1.0);
+ return true;
+ }
+}
+
+
+
+
+bool Animator::Animation::IsExpired (void)
+{
+ return mnValue >= 1.0;
+}
+
+
+
+
+//===== Animator::DrawLock ====================================================
+
+Animator::DrawLock::DrawLock (View& rView)
+ : mrView(rView)
+{
+ mrView.LockRedraw(TRUE);
+}
+
+
+
+
+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
new file mode 100644
index 000000000000..d226a8c2e294
--- /dev/null
+++ b/sd/source/ui/slidesorter/controller/SlsClipboard.cxx
@@ -0,0 +1,778 @@
+/*************************************************************************
+ *
+ * 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/SlsClipboard.hxx"
+
+#include "SlideSorterViewShell.hxx"
+#include "SlideSorter.hxx"
+#include "model/SlideSorterModel.hxx"
+#include "model/SlsPageDescriptor.hxx"
+#include "model/SlsPageEnumerationProvider.hxx"
+#include "view/SlideSorterView.hxx"
+#include "view/SlsViewOverlay.hxx"
+#include "view/SlsPageObject.hxx"
+#include "controller/SlideSorterController.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 "ViewShellBase.hxx"
+#include "DrawViewShell.hxx"
+#include "Window.hxx"
+#include "fupoor.hxx"
+#include "fuslhide.hxx"
+#include "fuzoom.hxx"
+#include "fucushow.hxx"
+#include "fusldlg.hxx"
+#include "fuexpand.hxx"
+#include "fusumry.hxx"
+#include "app.hrc"
+#include "glob.hrc"
+#include "strings.hrc"
+#include "sdresid.hxx"
+#include "sdxfer.hxx"
+#include "sdmod.hxx"
+#include "sddll.hxx"
+#include "ins_paste.hxx"
+#include "drawdoc.hxx"
+#include "DrawDocShell.hxx"
+#include "sdpage.hxx"
+
+#include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
+#include <sfx2/request.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/docfile.hxx>
+#include <svx/svxids.hrc>
+#include <vcl/msgbox.hxx>
+#include <tools/urlobj.hxx>
+#include <rtl/ustring.hxx>
+#include <vos/mutex.hxx>
+#include <vcl/svapp.hxx>
+
+namespace sd { namespace slidesorter { namespace controller {
+
+
+Clipboard::Clipboard (SlideSorter& rSlideSorter)
+ : ViewClipboard(rSlideSorter.GetView()),
+ mrSlideSorter(rSlideSorter),
+ mrController(mrSlideSorter.GetController()),
+ maPagesToRemove(),
+ maPagesToSelect(),
+ mbUpdateSelectionPending(false)
+{
+}
+
+
+
+
+Clipboard::~Clipboard (void)
+{
+}
+
+
+
+
+/** With the current implementation the forwarded calls to the current
+ function will come back eventually to call the local Do(Cut|Copy|Paste)
+ methods. A shortcut is possible but would be an unclean hack.
+*/
+void Clipboard::HandleSlotCall (SfxRequest& rRequest)
+{
+ ViewShell* pViewShell = mrSlideSorter.GetViewShell();
+ FunctionReference xFunc;
+ if (pViewShell != NULL)
+ xFunc = pViewShell->GetCurrentFunction();
+ switch (rRequest.GetSlot())
+ {
+ case SID_CUT:
+ if (mrSlideSorter.GetModel().GetEditMode() != EM_MASTERPAGE)
+ {
+ if(xFunc.is())
+ xFunc->DoCut();
+ else
+ DoCut();
+ }
+ rRequest.Done();
+ break;
+
+ case SID_COPY:
+ if (mrSlideSorter.GetModel().GetEditMode() != EM_MASTERPAGE)
+ {
+ if(xFunc.is())
+ xFunc->DoCopy();
+ else
+ DoCopy();
+ }
+ rRequest.Done();
+ break;
+
+ case SID_PASTE:
+ // Prevent redraws while inserting pages from the clipboard
+ // because the intermediate inconsistent state might lead to
+ // a crash.
+ if (mrSlideSorter.GetModel().GetEditMode() != EM_MASTERPAGE)
+ {
+ mrSlideSorter.GetView().LockRedraw (TRUE);
+ if(xFunc.is())
+ xFunc->DoPaste();
+ else
+ DoPaste();
+ mrController.GetSelectionManager()->MakeSelectionVisible();
+ mrSlideSorter.GetView().LockRedraw(FALSE);
+ }
+ rRequest.Done();
+ break;
+
+ case SID_DELETE:
+ DoDelete();
+ rRequest.Done();
+ break;
+ }
+}
+
+
+
+
+void Clipboard::DoCut (::Window* pWindow)
+{
+ if (mrSlideSorter.GetModel().GetPageCount() > 1)
+ {
+ DoCopy(pWindow);
+ DoDelete(pWindow);
+ }
+}
+
+
+
+
+void Clipboard::DoDelete (::Window* )
+{
+ if (mrSlideSorter.GetModel().GetPageCount() > 1)
+ {
+ mrController.GetSelectionManager()->DeleteSelectedPages();
+ }
+}
+
+
+
+
+void Clipboard::DoCopy (::Window* pWindow )
+{
+ CreateSlideTransferable( pWindow, FALSE );
+}
+
+
+
+
+void Clipboard::DoPaste (::Window* pWindow)
+{
+ SdTransferable* pClipTransferable = SD_MOD()->pTransferClip;
+
+ if (pClipTransferable!=NULL && pClipTransferable->IsPageTransferable())
+ {
+ sal_Int32 nInsertPosition = GetInsertionPosition(pWindow);
+
+ if (nInsertPosition >= 0)
+ {
+ // Paste the pages from the clipboard.
+ sal_Int32 nInsertPageCount = PasteTransferable(nInsertPosition);
+ // Select the pasted pages and make the first of them the
+ // current page.
+ mrSlideSorter.GetView().GetWindow()->GrabFocus();
+ SelectPageRange(nInsertPosition, nInsertPageCount);
+ }
+ }
+}
+
+
+
+
+sal_Int32 Clipboard::GetInsertionPosition (::Window* pWindow)
+{
+ sal_Int32 nInsertPosition = -1;
+
+ // Determine the insertion position:
+ // a) When the insertion indicator is visible, then at that position.
+ // b) When the focus indicator is visible, then before or after the
+ // focused page, depending on user input to a dialog.
+ // c) When there is a selection but no focus, then after the
+ // selection.
+ // d) After the last page when there is no selection and no focus.
+
+ view::InsertionIndicatorOverlay& rInsertionIndicatorOverlay (
+ mrSlideSorter.GetView().GetOverlay().GetInsertionIndicatorOverlay());
+ if (rInsertionIndicatorOverlay.isVisible())
+ {
+ nInsertPosition = rInsertionIndicatorOverlay.GetInsertionPageIndex();
+ }
+ else if (mrController.GetFocusManager().IsFocusShowing())
+ {
+ SdInsertPasteDlg aDialog (pWindow);
+ if (aDialog.Execute() == RET_OK)
+ {
+ nInsertPosition = mrController.GetFocusManager().GetFocusedPageIndex();
+ if ( ! aDialog.IsInsertBefore())
+ nInsertPosition ++;
+ }
+ }
+ else
+ {
+ nInsertPosition = mrController.GetSelectionManager()->GetInsertionPosition();
+ }
+
+ return nInsertPosition;
+}
+
+
+
+
+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));
+ sal_Int32 nInsertPageCount (0);
+ if (pClipTransferable->HasPageBookmarks())
+ {
+ const List& rBookmarkList = pClipTransferable->GetPageBookmarks();
+ const ::vos::OGuard aGuard (Application::GetSolarMutex());
+
+ nInsertPageCount = (USHORT) rBookmarkList.Count();
+ mrSlideSorter.GetModel().GetDocument()->InsertBookmarkAsPage(
+ const_cast<List*>(&rBookmarkList),
+ NULL,
+ FALSE,
+ FALSE,
+ nInsertIndex,
+ FALSE,
+ pClipTransferable->GetPageDocShell(),
+ TRUE,
+ bMergeMasterPages,
+ FALSE);
+ }
+ else
+ {
+ SfxObjectShell* pShell = pClipTransferable->GetDocShell();
+ DrawDocShell* pDataDocSh = (DrawDocShell*)pShell;
+ SdDrawDocument* pDataDoc = pDataDocSh->GetDoc();
+
+ if (pDataDoc!=NULL
+ && pDataDoc->GetSdPageCount(PK_STANDARD))
+ {
+ const ::vos::OGuard aGuard (Application::GetSolarMutex());
+
+ bMergeMasterPages = (pDataDoc != mrSlideSorter.GetModel().GetDocument());
+ nInsertPageCount = pDataDoc->GetSdPageCount( PK_STANDARD );
+ mrSlideSorter.GetModel().GetDocument()->InsertBookmarkAsPage(
+ NULL,
+ NULL,
+ FALSE,
+ FALSE,
+ nInsertIndex,
+ FALSE,
+ pDataDocSh,
+ TRUE,
+ bMergeMasterPages,
+ FALSE);
+ }
+ }
+ mrController.HandleModelChange();
+ return nInsertPageCount;
+}
+
+
+
+
+void Clipboard::SelectPageRange (sal_Int32 nFirstIndex, sal_Int32 nPageCount)
+{
+ // Select the newly inserted pages. That are the nInsertPageCount pages
+ // after the nInsertIndex position.
+ PageSelector& rSelector (mrController.GetPageSelector());
+ rSelector.DeselectAllPages();
+ for (USHORT i=0; i<nPageCount; i++)
+ {
+ model::SharedPageDescriptor pDescriptor (
+ mrSlideSorter.GetModel().GetPageDescriptor(nFirstIndex + i));
+ if (pDescriptor.get() != NULL)
+ {
+ rSelector.SelectPage(pDescriptor);
+ // The first page of the new selection is made the current page.
+ if (i == 0)
+ {
+ mrController.GetCurrentSlideManager()->SwitchCurrentSlide(pDescriptor);
+ mrController.GetFocusManager().SetFocusedPage(pDescriptor);
+ }
+ }
+ }
+}
+
+
+
+
+void Clipboard::CreateSlideTransferable (
+ ::Window* pWindow,
+ bool bDrag)
+{
+ List aBookmarkList;
+
+ // Insert all selected pages into a bookmark list and remember them in
+ // maPagesToRemove for possible later removal.
+ model::PageEnumeration aSelectedPages
+ (model::PageEnumerationProvider::CreateSelectedPagesEnumeration(
+ mrSlideSorter.GetModel()));
+ while (aSelectedPages.HasMoreElements())
+ {
+ model::SharedPageDescriptor pDescriptor (aSelectedPages.GetNextElement());
+ aBookmarkList.Insert (
+ new String(pDescriptor->GetPage()->GetName()),
+ LIST_APPEND);
+ maPagesToRemove.push_back (pDescriptor->GetPage());
+ }
+
+ if (aBookmarkList.Count() > 0)
+ {
+ mrSlideSorter.GetView().BrkAction();
+ SdDrawDocument* pDocument = mrSlideSorter.GetModel().GetDocument();
+ SdTransferable* pTransferable = new Transferable (
+ pDocument,
+ NULL,
+ FALSE,
+ dynamic_cast<SlideSorterViewShell*>(mrSlideSorter.GetViewShell()));
+
+ if (bDrag)
+ SD_MOD()->pTransferDrag = pTransferable;
+ else
+ SD_MOD()->pTransferClip = pTransferable;
+
+ pDocument->CreatingDataObj (pTransferable);
+ pTransferable->SetWorkDocument( dynamic_cast<SdDrawDocument*>(pDocument->AllocModel()) );
+ pDocument->CreatingDataObj (NULL);
+ TransferableObjectDescriptor aObjDesc;
+ pTransferable->GetWorkDocument()->GetDocSh()
+ ->FillTransferableObjectDescriptor (aObjDesc);
+
+ if (pDocument->GetDocSh() != NULL)
+ aObjDesc.maDisplayName = pDocument->GetDocSh()
+ ->GetMedium()->GetURLObject().GetURLNoPass();
+
+ ::Window* pActionWindow = pWindow;
+ if (pActionWindow == NULL)
+ {
+ ViewShell* pViewShell = mrSlideSorter.GetViewShell();
+ if (pViewShell != NULL)
+ pActionWindow = pViewShell->GetActiveWindow();
+ }
+
+ pTransferable->SetStartPos (pActionWindow->PixelToLogic(
+ pActionWindow->GetPointerPosPixel()));
+ pTransferable->SetObjectDescriptor (aObjDesc);
+ pTransferable->SetPageBookmarks (aBookmarkList, !bDrag);
+
+ for (void* p=aBookmarkList.First(); p!=NULL; p=aBookmarkList.Next())
+ delete static_cast<String*>(p);
+
+ if (bDrag)
+ {
+ pTransferable->SetView (&mrSlideSorter.GetView());
+ sal_Int8 nDragSourceActions (DND_ACTION_COPY);
+ // The move action is available only when not all pages would be
+ // moved. Otherwise an empty document would remain. Crash.
+ sal_Int32 nRemainingPages = mrSlideSorter.GetModel().GetPageCount() - aBookmarkList.Count();
+ if (nRemainingPages > 0)
+ nDragSourceActions |= DND_ACTION_MOVE;
+ pTransferable->StartDrag (pActionWindow, nDragSourceActions);
+ }
+ else
+ pTransferable->CopyToClipboard (pActionWindow);
+ }
+}
+
+
+
+
+void Clipboard::StartDrag (
+ const Point&,
+ ::Window* pWindow)
+{
+ maPagesToRemove.clear();
+ maPagesToSelect.clear();
+ mbUpdateSelectionPending = false;
+ CreateSlideTransferable (pWindow, TRUE);
+}
+
+
+
+
+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);
+
+ PageSelector& rSelector (mrController.GetPageSelector());
+ if ((nDropAction & DND_ACTION_MOVE) != 0
+ && ! maPagesToRemove.empty())
+ {
+ // Remove the pages that have been moved to another place (possibly
+ // in the same document.)
+ rSelector.DeselectAllPages();
+ PageList::iterator aDraggedPage;
+ for (aDraggedPage=maPagesToRemove.begin();
+ aDraggedPage!=maPagesToRemove.end();
+ aDraggedPage++)
+ {
+ rSelector.SelectPage (*aDraggedPage);
+ }
+ mrController.GetSelectionManager()->DeleteSelectedPages ();
+ }
+
+ SelectPages();
+}
+
+
+
+
+void Clipboard::SelectPages (void)
+{
+ PageSelector& rSelector (mrController.GetPageSelector());
+
+ // Select the dropped pages.
+ PageList::iterator iPage;
+ rSelector.DeselectAllPages();
+ for (iPage=maPagesToSelect.begin(); iPage!=maPagesToSelect.end(); ++iPage)
+ {
+ rSelector.SelectPage(*iPage);
+ }
+}
+
+
+
+
+sal_Int8 Clipboard::AcceptDrop (
+ const AcceptDropEvent& rEvent,
+ DropTargetHelper& rTargetHelper,
+ ::sd::Window* pTargetWindow,
+ USHORT nPage,
+ USHORT nLayer)
+{
+ sal_Int8 nResult = DND_ACTION_NONE;
+
+ switch (IsDropAccepted())
+ {
+ case DT_PAGE:
+ {
+ // Accept a drop.
+ nResult = 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
+ // target models are not the same.
+ const SdTransferable* pDragTransferable = SD_MOD()->pTransferDrag;
+ if (pDragTransferable != NULL
+ && pDragTransferable->IsPageTransferable()
+ && ((rEvent.maDragEvent.DropAction
+ & ::com::sun::star::datatransfer::dnd::DNDConstants::ACTION_DEFAULT) != 0)
+ && (mrSlideSorter.GetModel().GetDocument()->GetDocSh()
+ != pDragTransferable->GetPageDocShell()))
+ {
+ nResult = DND_ACTION_COPY;
+ }
+
+ // 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);
+
+ // Scroll the window when the mouse reaches the window border.
+ mrController.GetScrollBarManager().AutoScroll (rEvent.maPosPixel);
+ }
+ break;
+
+ case DT_SHAPE:
+ nResult = ExecuteOrAcceptShapeDrop(
+ DC_ACCEPT,
+ rEvent.maPosPixel,
+ &rEvent,
+ rTargetHelper,
+ pTargetWindow,
+ nPage,
+ nLayer);
+ break;
+ default:
+ break;
+ }
+
+ return nResult;
+}
+
+
+
+
+sal_Int8 Clipboard::ExecuteDrop (
+ const ExecuteDropEvent& rEvent,
+ DropTargetHelper& rTargetHelper,
+ ::sd::Window* pTargetWindow,
+ USHORT nPage,
+ USHORT nLayer)
+{
+ sal_Int8 nResult = DND_ACTION_NONE;
+
+ switch (IsDropAccepted())
+ {
+ case DT_PAGE:
+ {
+ 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 =
+ ( pDragTransferable->GetView() != &mrSlideSorter.GetView() )
+ || ( nXOffset >= 2 && nYOffset >= 2 );
+
+ // 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);
+
+ 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;
+ }
+ }
+ }
+ break;
+
+ case DT_SHAPE:
+ nResult = ExecuteOrAcceptShapeDrop(
+ DC_EXECUTE,
+ rEvent.maPosPixel,
+ &rEvent,
+ rTargetHelper,
+ pTargetWindow,
+ nPage,
+ nLayer);
+ break;
+ default:
+ break;
+ }
+
+ return nResult;
+}
+
+
+
+
+USHORT Clipboard::DetermineInsertPosition (const SdTransferable& )
+{
+ USHORT nInsertPosition = SDRPAGE_NOTFOUND;
+
+ // 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());
+
+ // 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.
+ if (nInsertionIndex >= 0)
+ nInsertPosition = (USHORT)nInsertionIndex * 2 + 1;
+
+ return nInsertPosition;
+}
+
+
+
+
+USHORT Clipboard::InsertSlides (
+ const SdTransferable& rTransferable,
+ USHORT nInsertPosition)
+{
+ USHORT nInsertedPageCount = ViewClipboard::InsertSlides (
+ rTransferable,
+ nInsertPosition);
+
+ // 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());
+ }
+
+ mbUpdateSelectionPending |= (nInsertedPageCount>0);
+
+ return nInsertedPageCount;
+}
+
+
+
+
+Clipboard::DropType Clipboard::IsDropAccepted (void) const
+{
+ DropType eResult (DT_NONE);
+
+ const SdTransferable* pDragTransferable = SD_MOD()->pTransferDrag;
+ if (pDragTransferable != NULL)
+ {
+ if (pDragTransferable->IsPageTransferable())
+ {
+ if (mrSlideSorter.GetModel().GetEditMode() != EM_MASTERPAGE)
+ eResult = DT_PAGE;
+ }
+ else
+ {
+ eResult = DT_SHAPE;
+ }
+ }
+
+ return eResult;
+}
+
+
+
+
+sal_Int8 Clipboard::ExecuteOrAcceptShapeDrop (
+ DropCommand eCommand,
+ const Point& rPosition,
+ const void* pDropEvent,
+ DropTargetHelper& rTargetHelper,
+ ::sd::Window* pTargetWindow,
+ USHORT nPage,
+ USHORT nLayer)
+{
+ sal_Int8 nResult = 0;
+
+ // The dropping of a shape is accepted or executed only when there is
+ // DrawViewShell available to which we can forward this call. This has
+ // technical reasons: The actual code to accept or execute a shape drop
+ // is implemented in the ViewShell class and uses the page view of the
+ // main edit view. This is not possible without a DrawViewShell.
+ ::boost::shared_ptr<DrawViewShell> pDrawViewShell;
+ if (mrSlideSorter.GetViewShell() != NULL)
+ pDrawViewShell = ::boost::dynamic_pointer_cast<DrawViewShell>(
+ mrSlideSorter.GetViewShell()->GetViewShellBase().GetMainViewShell());
+ if (pDrawViewShell.get() != NULL
+ && (pDrawViewShell->GetShellType() == ViewShell::ST_IMPRESS
+ || pDrawViewShell->GetShellType() == ViewShell::ST_DRAW))
+ {
+ // The drop is only accepted or executed when it takes place over a
+ // page object. Therefore we replace a missing page number by the
+ // number of the page under the mouse.
+ if (nPage == SDRPAGE_NOTFOUND)
+ {
+ model::SharedPageDescriptor pDescriptor (
+ mrSlideSorter.GetModel().GetPageDescriptor(
+ mrSlideSorter.GetView().GetPageIndexAtPoint(rPosition)));
+ if (pDescriptor.get() != NULL && pDescriptor->GetPage()!=NULL)
+ nPage = (pDescriptor->GetPage()->GetPageNum() - 1) / 2;
+ }
+
+ // Now comes the code that is different for the Execute and Accept:
+ // We simply forward the call to the AcceptDrop() or ExecuteDrop()
+ // methods of the DrawViewShell in the center pane.
+ if (nPage != SDRPAGE_NOTFOUND)
+ switch (eCommand)
+ {
+ case DC_ACCEPT:
+ nResult = pDrawViewShell->AcceptDrop(
+ *reinterpret_cast<const AcceptDropEvent*>(pDropEvent),
+ rTargetHelper,
+ pTargetWindow,
+ nPage,
+ nLayer);
+ break;
+
+ case DC_EXECUTE:
+ nResult = pDrawViewShell->ExecuteDrop(
+ *reinterpret_cast<const ExecuteDropEvent*>(pDropEvent),
+ rTargetHelper,
+ pTargetWindow,
+ nPage,
+ nLayer);
+ break;
+ }
+ }
+
+ return nResult;
+}
+
+
+
+} } } // end of namespace ::sd::slidesorter::controller
+
diff --git a/sd/source/ui/slidesorter/controller/SlsCommand.hxx b/sd/source/ui/slidesorter/controller/SlsCommand.hxx
new file mode 100644
index 000000000000..26980dc51f11
--- /dev/null
+++ b/sd/source/ui/slidesorter/controller/SlsCommand.hxx
@@ -0,0 +1,45 @@
+/*************************************************************************
+ *
+ * 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_COMMAND_HXX
+#define SD_SLIDESORTER_COMMAND_HXX
+
+namespace sd { namespace slidesorter { namespace controller {
+
+/** Base class for command objects. It specifies the interface for commands
+ whose execution can be scheduled via the SlotManager.
+*/
+class Command
+{
+public:
+ virtual ~Command (void) {};
+ virtual void operator() (void) = 0;
+};
+
+} } } // end of namespace sd::slidesorter::controller
+
+#endif
diff --git a/sd/source/ui/slidesorter/controller/SlsCurrentSlideManager.cxx b/sd/source/ui/slidesorter/controller/SlsCurrentSlideManager.cxx
new file mode 100755
index 000000000000..f5864c3307a1
--- /dev/null
+++ b/sd/source/ui/slidesorter/controller/SlsCurrentSlideManager.cxx
@@ -0,0 +1,256 @@
+/*************************************************************************
+ *
+ * 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 "model/SlideSorterModel.hxx"
+#include "model/SlsPageDescriptor.hxx"
+#include "controller/SlsPageSelector.hxx"
+#include "controller/SlideSorterController.hxx"
+#include "controller/SlsCurrentSlideManager.hxx"
+#include "view/SlideSorterView.hxx"
+#include "view/SlsPageObjectViewObjectContact.hxx"
+#include "ViewShellBase.hxx"
+#include "ViewShell.hxx"
+#include "DrawViewShell.hxx"
+#include "sdpage.hxx"
+#include "FrameView.hxx"
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+using namespace ::com::sun::star;
+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()
+{
+}
+
+
+
+
+CurrentSlideManager::~CurrentSlideManager (void)
+{
+}
+
+
+
+
+void CurrentSlideManager::CurrentSlideHasChanged (const sal_Int32 nSlideIndex)
+{
+ if (mnCurrentSlideIndex != nSlideIndex)
+ {
+ ReleaseCurrentSlide();
+ AcquireCurrentSlide(nSlideIndex);
+
+ // Update the selection.
+ mrSlideSorter.GetController().GetPageSelector().DeselectAllPages();
+ if (mpCurrentSlide.get() != NULL)
+ mrSlideSorter.GetController().GetPageSelector().SelectPage(mpCurrentSlide);
+ }
+}
+
+
+
+
+void CurrentSlideManager::ReleaseCurrentSlide (void)
+{
+ if (mpCurrentSlide.get() != NULL)
+ {
+ mpCurrentSlide->SetIsCurrentPage(false);
+ mrSlideSorter.GetView().RequestRepaint(mpCurrentSlide);
+ }
+
+ mpCurrentSlide.reset();
+ mnCurrentSlideIndex = -1;
+}
+
+
+
+
+bool CurrentSlideManager::IsCurrentSlideIsValid (void)
+{
+ return mnCurrentSlideIndex >= 0 && mnCurrentSlideIndex<mrSlideSorter.GetModel().GetPageCount();
+}
+
+
+
+
+void CurrentSlideManager::AcquireCurrentSlide (const sal_Int32 nSlideIndex)
+{
+ mnCurrentSlideIndex = nSlideIndex;
+
+ if (IsCurrentSlideIsValid())
+ {
+ // Get a descriptor for the XDrawPage reference. Note that the
+ // given XDrawPage may or may not be member of the slide sorter
+ // document.
+ mpCurrentSlide = mrSlideSorter.GetModel().GetPageDescriptor(mnCurrentSlideIndex);
+ if (mpCurrentSlide.get() != NULL)
+ {
+ mpCurrentSlide->SetIsCurrentPage(true);
+ mrSlideSorter.GetView().RequestRepaint(mpCurrentSlide);
+ }
+ }
+}
+
+
+
+
+void CurrentSlideManager::SwitchCurrentSlide (const sal_Int32 nSlideIndex)
+{
+ SwitchCurrentSlide(mrSlideSorter.GetModel().GetPageDescriptor(nSlideIndex));
+}
+
+
+
+
+void CurrentSlideManager::SwitchCurrentSlide (const SharedPageDescriptor& rpDescriptor)
+{
+ if (rpDescriptor.get() != NULL)
+ {
+ mpCurrentSlide = rpDescriptor;
+ mnCurrentSlideIndex = (rpDescriptor->GetPage()->GetPageNum()-1)/2;
+
+ ViewShell* pViewShell = mrSlideSorter.GetViewShell();
+ if (pViewShell != NULL && pViewShell->IsMainViewShell())
+ {
+ FrameView* pFrameView = pViewShell->GetFrameView();
+ if (pFrameView != NULL)
+ pFrameView->SetSelectedPage(sal::static_int_cast<USHORT>(mnCurrentSlideIndex));
+ }
+ else
+ {
+ // 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);
+ }
+ }
+}
+
+
+
+
+void CurrentSlideManager::SetCurrentSlideAtViewShellBase (const SharedPageDescriptor& rpDescriptor)
+{
+ OSL_ASSERT(rpDescriptor.get() != NULL);
+
+ ViewShellBase* pBase = mrSlideSorter.GetViewShellBase();
+ if (pBase != NULL)
+ {
+ DrawViewShell* pDrawViewShell = dynamic_cast<DrawViewShell*>(
+ pBase->GetMainViewShell().get());
+ if (pDrawViewShell != NULL)
+ {
+ USHORT nPageNumber = (rpDescriptor->GetPage()->GetPageNum()-1)/2;
+ pDrawViewShell->SwitchPage(nPageNumber);
+ pDrawViewShell->GetPageTabControl()->SetCurPageId(nPageNumber+1);
+ }
+ /*
+ else
+ {
+ presenter::PresenterViewShell* pPresenterViewShell
+ = dynamic_cast<presenter::PresenterViewShell*>(pBase->GetMainViewShell());
+ if (pPresenterViewShell != NULL)
+ {
+ pPresenterViewShell->SetCurrentSlide(
+ Reference<drawing::XDrawPage>(
+ rpDescriptor->GetPage()->getUnoPage(), UNO_QUERY));
+ }
+ }
+ */
+ }
+}
+
+
+
+
+void CurrentSlideManager::SetCurrentSlideAtXController (const SharedPageDescriptor& rpDescriptor)
+{
+ OSL_ASSERT(rpDescriptor.get() != NULL);
+
+ try
+ {
+ Reference<beans::XPropertySet> xSet (mrSlideSorter.GetXController(), UNO_QUERY);
+ if (xSet.is())
+ {
+ Any aPage;
+ aPage <<= rpDescriptor->GetPage()->getUnoPage();
+ xSet->setPropertyValue (
+ String::CreateFromAscii("CurrentPage"),
+ aPage);
+ }
+ }
+ catch (beans::UnknownPropertyException 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,
+ // this exception is silently ignored.
+ }
+}
+
+
+
+
+SharedPageDescriptor CurrentSlideManager::GetCurrentSlide (void)
+{
+ return mpCurrentSlide;
+}
+
+
+
+
+void CurrentSlideManager::PrepareModelChange (void)
+{
+ mpCurrentSlide.reset();
+}
+
+
+
+
+void CurrentSlideManager::HandleModelChange (void)
+{
+ if (mnCurrentSlideIndex >= 0)
+ {
+ mpCurrentSlide = mrSlideSorter.GetModel().GetPageDescriptor(
+ mnCurrentSlideIndex);
+ if (mpCurrentSlide.get() != NULL)
+ mpCurrentSlide->SetIsCurrentPage(true);
+ }
+}
+
+} } } // end of namespace ::sd::slidesorter::controller
diff --git a/sd/source/ui/slidesorter/controller/SlsFocusManager.cxx b/sd/source/ui/slidesorter/controller/SlsFocusManager.cxx
new file mode 100755
index 000000000000..dcda73d38dba
--- /dev/null
+++ b/sd/source/ui/slidesorter/controller/SlsFocusManager.cxx
@@ -0,0 +1,362 @@
+/*************************************************************************
+ *
+ * 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/SlsFocusManager.hxx"
+
+#include "SlideSorter.hxx"
+#include "PaneDockingWindow.hxx"
+#include "controller/SlideSorterController.hxx"
+#include "controller/SlsSelectionManager.hxx"
+#include "model/SlideSorterModel.hxx"
+#include "model/SlsPageDescriptor.hxx"
+#include "view/SlideSorterView.hxx"
+#include "view/SlsLayouter.hxx"
+#include <vcl/toolbox.hxx>
+
+#include "Window.hxx"
+#include "sdpage.hxx"
+
+namespace sd { namespace slidesorter { namespace controller {
+
+FocusManager::FocusManager (SlideSorter& rSlideSorter)
+ : mrSlideSorter(rSlideSorter),
+ mnPageIndex(0),
+ mbPageIsFocused(false)
+{
+ if (mrSlideSorter.GetModel().GetPageCount() > 0)
+ mnPageIndex = 0;
+}
+
+
+
+
+FocusManager::~FocusManager (void)
+{
+}
+
+
+
+
+void FocusManager::MoveFocus (FocusMoveDirection eDirection)
+{
+ if (mnPageIndex >= 0 && mbPageIsFocused)
+ {
+ HideFocusIndicator (GetFocusedPageDescriptor());
+
+ int nColumnCount (mrSlideSorter.GetView().GetLayouter().GetColumnCount());
+ switch (eDirection)
+ {
+ case FMD_NONE:
+ if (mnPageIndex >= mrSlideSorter.GetModel().GetPageCount())
+ mnPageIndex = mrSlideSorter.GetModel().GetPageCount() - 1;
+ break;
+
+ case FMD_LEFT:
+ mnPageIndex -= 1;
+ if (mnPageIndex < 0)
+ {
+ mnPageIndex = mrSlideSorter.GetModel().GetPageCount() - 1;
+ SetFocusToToolBox();
+ }
+ break;
+
+ case FMD_RIGHT:
+ mnPageIndex += 1;
+ if (mnPageIndex >= mrSlideSorter.GetModel().GetPageCount())
+ {
+ mnPageIndex = 0;
+ SetFocusToToolBox();
+ }
+ break;
+
+ case FMD_UP:
+ {
+ int nColumn = mnPageIndex % nColumnCount;
+ mnPageIndex -= nColumnCount;
+ if (mnPageIndex < 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;
+ }
+ }
+ break;
+
+ case FMD_DOWN:
+ {
+ int nColumn = mnPageIndex % nColumnCount;
+ mnPageIndex += nColumnCount;
+ if (mnPageIndex >= mrSlideSorter.GetModel().GetPageCount())
+ {
+ // Wrap arround to the correct column.
+ mnPageIndex = nColumn;
+ }
+ }
+ break;
+ }
+
+ if (mbPageIsFocused)
+ ShowFocusIndicator(GetFocusedPageDescriptor(), true);
+ }
+}
+
+
+
+
+void FocusManager::ShowFocus (const bool bScrollToFocus)
+{
+ mbPageIsFocused = true;
+ ShowFocusIndicator(GetFocusedPageDescriptor(), bScrollToFocus);
+}
+
+
+
+
+void FocusManager::HideFocus (void)
+{
+ mbPageIsFocused = false;
+ HideFocusIndicator(GetFocusedPageDescriptor());
+}
+
+
+
+
+bool FocusManager::ToggleFocus (void)
+{
+ if (mnPageIndex >= 0)
+ {
+ if (mbPageIsFocused)
+ HideFocus ();
+ else
+ ShowFocus ();
+ }
+ return mbPageIsFocused;
+}
+
+
+
+
+bool FocusManager::HasFocus (void) const
+{
+ return mrSlideSorter.GetView().GetWindow()->HasFocus();
+}
+
+
+
+
+model::SharedPageDescriptor FocusManager::GetFocusedPageDescriptor (void) const
+{
+ return mrSlideSorter.GetModel().GetPageDescriptor(mnPageIndex);
+}
+
+
+
+
+sal_Int32 FocusManager::GetFocusedPageIndex (void) const
+{
+ return mnPageIndex;
+}
+
+
+
+
+void FocusManager::FocusPage (sal_Int32 nPageIndex)
+{
+ if (nPageIndex != mnPageIndex)
+ {
+ // Hide the focus while switching it to the specified page.
+ FocusHider aHider (*this);
+ mnPageIndex = nPageIndex;
+ }
+
+ if (HasFocus() && !IsFocusShowing())
+ ShowFocus();
+}
+
+
+
+
+void FocusManager::SetFocusedPage (const model::SharedPageDescriptor& rpDescriptor)
+{
+ if (rpDescriptor.get() != NULL)
+ {
+ FocusHider aFocusHider (*this);
+ mnPageIndex = (rpDescriptor->GetPage()->GetPageNum()-1)/2;
+ }
+}
+
+
+
+
+void FocusManager::SetFocusedPage (sal_Int32 nPageIndex)
+{
+ FocusHider aFocusHider (*this);
+ mnPageIndex = nPageIndex;
+}
+
+
+
+
+bool FocusManager::IsFocusShowing (void) const
+{
+ return HasFocus() && mbPageIsFocused;
+}
+
+
+
+
+void FocusManager::HideFocusIndicator (const model::SharedPageDescriptor& rpDescriptor)
+{
+ if (rpDescriptor.get() != NULL)
+ {
+ rpDescriptor->RemoveFocus();
+ mrSlideSorter.GetView().RequestRepaint(rpDescriptor);
+ }
+}
+
+
+
+
+void FocusManager::ShowFocusIndicator (
+ const model::SharedPageDescriptor& rpDescriptor,
+ const bool bScrollToFocus)
+{
+ if (rpDescriptor.get() != NULL)
+ {
+ rpDescriptor->SetFocus ();
+
+ 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.GetView().RequestRepaint (rpDescriptor);
+ NotifyFocusChangeListeners();
+ }
+}
+
+
+
+
+void FocusManager::AddFocusChangeListener (const Link& rListener)
+{
+ if (::std::find (maFocusChangeListeners.begin(), maFocusChangeListeners.end(), rListener)
+ == maFocusChangeListeners.end())
+ {
+ maFocusChangeListeners.push_back (rListener);
+ }
+}
+
+
+
+
+void FocusManager::RemoveFocusChangeListener (const Link& rListener)
+{
+ maFocusChangeListeners.erase (
+ ::std::find (maFocusChangeListeners.begin(), maFocusChangeListeners.end(), rListener));
+}
+
+
+
+
+void FocusManager::SetFocusToToolBox (void)
+{
+ HideFocus();
+
+ if (mrSlideSorter.GetViewShell() != NULL)
+ {
+ ::Window* pParentWindow = mrSlideSorter.GetViewShell()->GetParentWindow();
+ DockingWindow* pDockingWindow = NULL;
+ while (pParentWindow!=NULL && pDockingWindow==NULL)
+ {
+ pDockingWindow = dynamic_cast<DockingWindow*>(pParentWindow);
+ pParentWindow = pParentWindow->GetParent();
+ }
+ if (pDockingWindow)
+ {
+ PaneDockingWindow* pPaneDockingWindow = dynamic_cast<PaneDockingWindow*>(pDockingWindow);
+ if (pPaneDockingWindow != NULL)
+ pPaneDockingWindow->GetToolBox().GrabFocus();
+ }
+ }
+}
+
+
+
+
+void FocusManager::NotifyFocusChangeListeners (void) const
+{
+ // Create a copy of the listener list to be safe when that is modified.
+ ::std::vector<Link> aListeners (maFocusChangeListeners);
+
+ // Tell the slection change listeners that the selection has changed.
+ ::std::vector<Link>::iterator iListener (aListeners.begin());
+ ::std::vector<Link>::iterator iEnd (aListeners.end());
+ for (; iListener!=iEnd; ++iListener)
+ {
+ iListener->Call(NULL);
+ }
+}
+
+
+
+
+FocusManager::FocusHider::FocusHider (FocusManager& rManager)
+: mbFocusVisible(rManager.IsFocusShowing())
+, mrManager(rManager)
+{
+ mrManager.HideFocus();
+}
+
+
+
+
+FocusManager::FocusHider::~FocusHider (void)
+{
+ if (mbFocusVisible)
+ mrManager.ShowFocus();
+}
+
+} } } // end of namespace ::sd::slidesorter::controller
+
diff --git a/sd/source/ui/slidesorter/controller/SlsHideSlideFunction.cxx b/sd/source/ui/slidesorter/controller/SlsHideSlideFunction.cxx
new file mode 100644
index 000000000000..666d4b017302
--- /dev/null
+++ b/sd/source/ui/slidesorter/controller/SlsHideSlideFunction.cxx
@@ -0,0 +1,169 @@
+/*************************************************************************
+ *
+ * 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 "SlsHideSlideFunction.hxx"
+
+#include "SlideSorter.hxx"
+#include "model/SlsPageEnumerationProvider.hxx"
+#include "model/SlsPageDescriptor.hxx"
+#include "view/SlideSorterView.hxx"
+
+#include "app.hrc"
+#include "drawdoc.hxx"
+#include "sdpage.hxx"
+#include "ViewShell.hxx"
+
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/request.hxx>
+#include <svx/svxids.hrc>
+
+namespace sd { namespace slidesorter { namespace controller {
+
+TYPEINIT1(HideSlideFunction, SlideFunction);
+
+HideSlideFunction::HideSlideFunction (
+ SlideSorter& rSlideSorter,
+ SfxRequest& rRequest)
+ : SlideFunction( rSlideSorter, rRequest),
+ mrSlideSorter(rSlideSorter)
+{
+}
+
+
+
+
+HideSlideFunction::~HideSlideFunction (void)
+{
+}
+
+
+
+
+FunctionReference HideSlideFunction::Create (
+ SlideSorter& rSlideSorter,
+ SfxRequest& rRequest )
+{
+ FunctionReference xFunc( new HideSlideFunction( rSlideSorter, rRequest ) );
+ xFunc->DoExecute(rRequest);
+ return xFunc;
+}
+
+
+
+
+void HideSlideFunction::DoExecute (SfxRequest& rRequest)
+{
+ SlideFunction::DoExecute(rRequest);
+
+ model::PageEnumeration aSelectedPages (
+ model::PageEnumerationProvider::CreateSelectedPagesEnumeration(mrSlideSorter.GetModel()));
+
+ ExclusionState eState (UNDEFINED);
+
+ switch (rRequest.GetSlot())
+ {
+ case SID_HIDE_SLIDE:
+ eState = EXCLUDED;
+ break;
+
+ case SID_SHOW_SLIDE:
+ eState = INCLUDED;
+ break;
+
+ default:
+ eState = UNDEFINED;
+ break;
+ }
+
+ if (eState != UNDEFINED)
+ {
+ // Set status at the selected pages.
+ aSelectedPages.Rewind ();
+ while (aSelectedPages.HasMoreElements())
+ {
+ model::SharedPageDescriptor pDescriptor (aSelectedPages.GetNextElement());
+ pDescriptor->GetPage()->SetExcluded (eState==EXCLUDED);
+ static_cast<view::SlideSorterView*>(mpView)->RequestRepaint(pDescriptor);
+ }
+ }
+
+ SfxBindings& rBindings = mpViewShell->GetViewFrame()->GetBindings();
+ rBindings.Invalidate (SID_PRESENTATION);
+ rBindings.Invalidate (SID_REHEARSE_TIMINGS);
+ rBindings.Invalidate (SID_HIDE_SLIDE);
+ rBindings.Invalidate (SID_SHOW_SLIDE);
+ mpDoc->SetChanged();
+}
+
+
+
+
+HideSlideFunction::ExclusionState HideSlideFunction::GetExclusionState (
+ model::PageEnumeration& rPageSet)
+{
+ ExclusionState 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 namespace ::sd::slidesorter::controller
diff --git a/sd/source/ui/slidesorter/controller/SlsHideSlideFunction.hxx b/sd/source/ui/slidesorter/controller/SlsHideSlideFunction.hxx
new file mode 100644
index 000000000000..8cef9455619f
--- /dev/null
+++ b/sd/source/ui/slidesorter/controller/SlsHideSlideFunction.hxx
@@ -0,0 +1,73 @@
+/*************************************************************************
+ *
+ * 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_HIDE_SLIDE_FUNCTION_HXX
+#define SD_SLIDESORTER_HIDE_SLIDE_FUNCTION_HXX
+
+#include "controller/SlsSlideFunction.hxx"
+#include "model/SlsPageEnumeration.hxx"
+
+
+namespace sd { namespace slidesorter { namespace controller {
+
+/** Toggle the hidden flag of the selected slides.
+ When the selected pages have not all the same state they will all set to
+ hidden. When all selected pages have the same state this state is
+ toggled for all of them
+*/
+class HideSlideFunction
+ : public SlideFunction
+{
+public:
+ TYPEINFO();
+
+ virtual ~HideSlideFunction (void);
+
+ static FunctionReference Create( SlideSorter& rSlideSorter, SfxRequest& rRequest );
+ virtual void DoExecute( SfxRequest& rReq );
+
+ // The state of a set of slides with respect to being excluded from the
+ // slide show.
+ enum ExclusionState {UNDEFINED, EXCLUDED, INCLUDED, MIXED};
+
+ /** Return for the given set of slides whether they included are
+ excluded from the slide show.
+ */
+ static ExclusionState GetExclusionState (model::PageEnumeration& rPageSet);
+
+protected:
+ HideSlideFunction (
+ SlideSorter& rSlideSorter,
+ SfxRequest& rRequest);
+
+ SlideSorter& mrSlideSorter;
+};
+
+} } } // end of namespace ::sd::slidesorter::controller
+
+#endif
+
diff --git a/sd/source/ui/slidesorter/controller/SlsListener.cxx b/sd/source/ui/slidesorter/controller/SlsListener.cxx
new file mode 100755
index 000000000000..94b3b4afe717
--- /dev/null
+++ b/sd/source/ui/slidesorter/controller/SlsListener.cxx
@@ -0,0 +1,599 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sd.hxx"
+#include "SlsListener.hxx"
+
+#include "SlideSorter.hxx"
+#include "SlideSorterViewShell.hxx"
+#include "ViewShellHint.hxx"
+#include "controller/SlideSorterController.hxx"
+#include "controller/SlsPageSelector.hxx"
+#include "controller/SlsCurrentSlideManager.hxx"
+#include "model/SlideSorterModel.hxx"
+#include "view/SlideSorterView.hxx"
+#include "drawdoc.hxx"
+
+#include "glob.hrc"
+#include "ViewShellBase.hxx"
+#include "ViewShellManager.hxx"
+#include "FrameView.hxx"
+#include "EventMultiplexer.hxx"
+#include <com/sun/star/document/XEventBroadcaster.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/frame/FrameActionEvent.hpp>
+#include <com/sun/star/frame/FrameAction.hpp>
+#include <sfx2/viewfrm.hxx>
+#include <tools/diagnose_ex.h>
+
+
+using namespace ::com::sun::star::accessibility;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star;
+
+namespace sd { namespace slidesorter { namespace controller {
+
+
+Listener::Listener (
+ SlideSorter& rSlideSorter)
+ : ListenerInterfaceBase(maMutex),
+ mrSlideSorter(rSlideSorter),
+ mrController(mrSlideSorter.GetController()),
+ mpBase(mrSlideSorter.GetViewShellBase()),
+ mbListeningToDocument (false),
+ mbListeningToUNODocument (false),
+ mbListeningToController (false),
+ mbListeningToFrame (false),
+ mbIsMainViewChangePending(false),
+ mxControllerWeak(),
+ mxFrameWeak(),
+ mpModelChangeLock()
+{
+ StartListening (*mrSlideSorter.GetModel().GetDocument());
+ mbListeningToDocument = true;
+
+ // Connect to the UNO document.
+ Reference<document::XEventBroadcaster> xBroadcaster (
+ mrSlideSorter.GetModel().GetDocument()->getUnoModel(), uno::UNO_QUERY);
+ if (xBroadcaster.is())
+ {
+ xBroadcaster->addEventListener (this);
+ mbListeningToUNODocument = true;
+ }
+
+ // Listen for disposing events from the document.
+ Reference<XComponent> xComponent (xBroadcaster, UNO_QUERY);
+ if (xComponent.is())
+ xComponent->addEventListener (
+ Reference<lang::XEventListener>(
+ static_cast<XWeak*>(this), UNO_QUERY));
+
+ // Connect to the frame to listen for controllers being exchanged.
+ bool bIsMainViewShell (false);
+ ViewShell* pViewShell = mrSlideSorter.GetViewShell();
+ if (pViewShell != NULL)
+ bIsMainViewShell = pViewShell->IsMainViewShell();
+ if ( ! bIsMainViewShell)
+ {
+ // Listen to changes of certain properties.
+ Reference<frame::XFrame> xFrame;
+ Reference<frame::XController> xController (mrSlideSorter.GetXController());
+ if (xController.is())
+ xFrame = xController->getFrame();
+ mxFrameWeak = xFrame;
+ if (xFrame.is())
+ {
+ xFrame->addFrameActionListener (
+ Reference<frame::XFrameActionListener>(
+ static_cast<XWeak*>(this), UNO_QUERY));
+ mbListeningToFrame = true;
+ }
+
+ // Connect to the current controller.
+ ConnectToController ();
+ }
+
+ // Listen for hints of the MainViewShell as well. If that is not yet
+ // present then the EventMultiplexer will tell us when it is available.
+ if (mpBase != NULL)
+ {
+ ViewShell* pMainViewShell = mpBase->GetMainViewShell().get();
+ if (pMainViewShell != NULL
+ && pMainViewShell!=pViewShell)
+ {
+ StartListening (*pMainViewShell);
+ }
+
+ Link aLink (LINK(this, Listener, EventMultiplexerCallback));
+ mpBase->GetEventMultiplexer()->AddEventListener(
+ aLink,
+ tools::EventMultiplexerEvent::EID_MAIN_VIEW_REMOVED
+ | tools::EventMultiplexerEvent::EID_MAIN_VIEW_ADDED
+ | tools::EventMultiplexerEvent::EID_CONTROLLER_ATTACHED
+ | tools::EventMultiplexerEvent::EID_CONTROLLER_DETACHED
+ | tools::EventMultiplexerEvent::EID_CONFIGURATION_UPDATED);
+ }
+}
+
+
+
+
+Listener::~Listener (void)
+{
+ DBG_ASSERT( !mbListeningToDocument && !mbListeningToUNODocument && !mbListeningToFrame,
+ "sd::Listener::~Listener(), disposing() was not called, ask DBO!" );
+}
+
+
+
+
+void Listener::ReleaseListeners (void)
+{
+ if (mbListeningToDocument)
+ {
+ EndListening (*mrSlideSorter.GetModel().GetDocument());
+ mbListeningToDocument = false;
+ }
+
+ if (mbListeningToUNODocument)
+ {
+ Reference<document::XEventBroadcaster> xBroadcaster (
+ mrSlideSorter.GetModel().GetDocument()->getUnoModel(), UNO_QUERY);
+ if (xBroadcaster.is())
+ xBroadcaster->removeEventListener (this);
+
+ // Remove the dispose listener.
+ Reference<XComponent> xComponent (xBroadcaster, UNO_QUERY);
+ if (xComponent.is())
+ xComponent->removeEventListener (
+ Reference<lang::XEventListener>(
+ static_cast<XWeak*>(this), UNO_QUERY));
+
+ mbListeningToUNODocument = false;
+ }
+
+ if (mbListeningToFrame)
+ {
+ // Listen to changes of certain properties.
+ Reference<frame::XFrame> xFrame (mxFrameWeak);
+ if (xFrame.is())
+ {
+ xFrame->removeFrameActionListener (
+ Reference<frame::XFrameActionListener>(
+ static_cast<XWeak*>(this), UNO_QUERY));
+ mbListeningToFrame = false;
+ }
+ }
+
+ DisconnectFromController ();
+
+ if (mpBase != NULL)
+ {
+ Link aLink (LINK(this, Listener, EventMultiplexerCallback));
+ mpBase->GetEventMultiplexer()->RemoveEventListener(
+ aLink,
+ tools::EventMultiplexerEvent::EID_MAIN_VIEW_REMOVED
+ | tools::EventMultiplexerEvent::EID_MAIN_VIEW_ADDED
+ | tools::EventMultiplexerEvent::EID_CONTROLLER_ATTACHED
+ | tools::EventMultiplexerEvent::EID_CONTROLLER_DETACHED
+ | tools::EventMultiplexerEvent::EID_CONFIGURATION_UPDATED);
+ }
+}
+
+
+
+
+void Listener::ConnectToController (void)
+{
+ ViewShell* pShell = mrSlideSorter.GetViewShell();
+
+ // Register at the controller of the main view shell (if we are that not
+ // ourself).
+ if (pShell==NULL || ! pShell->IsMainViewShell())
+ {
+ Reference<frame::XController> xController (mrSlideSorter.GetXController());
+
+ // Listen to changes of certain properties.
+ Reference<beans::XPropertySet> xSet (xController, UNO_QUERY);
+ if (xSet.is())
+ {
+ try
+ {
+ xSet->addPropertyChangeListener(String::CreateFromAscii("CurrentPage"), this);
+ }
+ catch (beans::UnknownPropertyException aEvent)
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ try
+ {
+ xSet->addPropertyChangeListener(String::CreateFromAscii("IsMasterPageMode"), this);
+ }
+ catch (beans::UnknownPropertyException aEvent)
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+
+ // Listen for disposing events.
+ Reference<XComponent> xComponent (xController, UNO_QUERY);
+ if (xComponent.is())
+ {
+ xComponent->addEventListener (
+ Reference<lang::XEventListener>(static_cast<XWeak*>(this), UNO_QUERY));
+
+ mxControllerWeak = xController;
+ mbListeningToController = true;
+ }
+ }
+}
+
+
+
+
+void Listener::DisconnectFromController (void)
+{
+ if (mbListeningToController)
+ {
+ Reference<frame::XController> xController = mxControllerWeak;
+ Reference<beans::XPropertySet> xSet (xController, UNO_QUERY);
+ try
+ {
+ // Remove the property listener.
+ if (xSet.is())
+ {
+ xSet->removePropertyChangeListener (
+ String::CreateFromAscii("CurrentPage"),
+ this);
+ xSet->removePropertyChangeListener (
+ String::CreateFromAscii("IsMasterPageMode"),
+ this);
+ }
+
+ // Remove the dispose listener.
+ Reference<XComponent> xComponent (xController, UNO_QUERY);
+ if (xComponent.is())
+ xComponent->removeEventListener (
+ Reference<lang::XEventListener>(
+ static_cast<XWeak*>(this), UNO_QUERY));
+ }
+ catch (beans::UnknownPropertyException aEvent)
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+
+ mbListeningToController = false;
+ mxControllerWeak = Reference<frame::XController>();
+ }
+}
+
+
+
+
+void Listener::Notify (
+ SfxBroadcaster& rBroadcaster,
+ const SfxHint& rHint)
+{
+ if (rHint.ISA(SdrHint))
+ {
+ SdrHint& rSdrHint (*PTR_CAST(SdrHint,&rHint));
+ if(rSdrHint.GetKind() == HINT_PAGEORDERCHG )
+ {
+ if (rBroadcaster.ISA(SdDrawDocument))
+ {
+ SdDrawDocument& rDocument (
+ static_cast<SdDrawDocument&>(rBroadcaster));
+ if (rDocument.GetMasterSdPageCount(PK_STANDARD)
+ == rDocument.GetMasterSdPageCount(PK_NOTES))
+ {
+ mrController.HandleModelChange();
+ }
+ }
+ }
+ }
+ else if (rHint.ISA(ViewShellHint))
+ {
+ ViewShellHint& rViewShellHint (*PTR_CAST(ViewShellHint,&rHint));
+ switch (rViewShellHint.GetHintId())
+ {
+ case ViewShellHint::HINT_PAGE_RESIZE_START:
+ // Initiate a model change but do nothing (well, not much)
+ // until we are told that all slides have been resized.
+ mpModelChangeLock.reset(new SlideSorterController::ModelChangeLock(mrController));
+ mrController.HandleModelChange();
+ break;
+
+ case ViewShellHint::HINT_PAGE_RESIZE_END:
+ // All slides have been resized. The model has to be updated.
+ mpModelChangeLock.reset();
+ break;
+
+ case ViewShellHint::HINT_CHANGE_EDIT_MODE_START:
+ mrController.PrepareEditModeChange();
+ break;
+
+ case ViewShellHint::HINT_CHANGE_EDIT_MODE_END:
+ mrController.FinishEditModeChange();
+ break;
+
+ case ViewShellHint::HINT_COMPLEX_MODEL_CHANGE_START:
+ mpModelChangeLock.reset(new SlideSorterController::ModelChangeLock(mrController));
+ break;
+
+ case ViewShellHint::HINT_COMPLEX_MODEL_CHANGE_END:
+ mpModelChangeLock.reset();
+ break;
+ }
+ }
+}
+
+
+
+
+IMPL_LINK(Listener, EventMultiplexerCallback, ::sd::tools::EventMultiplexerEvent*, pEvent)
+{
+ switch (pEvent->meEventId)
+ {
+ case tools::EventMultiplexerEvent::EID_MAIN_VIEW_REMOVED:
+ {
+ if (mpBase != NULL)
+ {
+ ViewShell* pMainViewShell = mpBase->GetMainViewShell().get();
+ if (pMainViewShell != NULL)
+ EndListening(*pMainViewShell);
+ }
+ }
+ break;
+
+
+ case tools::EventMultiplexerEvent::EID_MAIN_VIEW_ADDED:
+ mbIsMainViewChangePending = true;
+ break;
+
+ case tools::EventMultiplexerEvent::EID_CONFIGURATION_UPDATED:
+ if (mbIsMainViewChangePending && mpBase != NULL)
+ {
+ mbIsMainViewChangePending = false;
+ ViewShell* pMainViewShell = mpBase->GetMainViewShell().get();
+ if (pMainViewShell != NULL
+ && pMainViewShell!=mrSlideSorter.GetViewShell())
+ {
+ StartListening (*pMainViewShell);
+ }
+ }
+ break;
+
+ case tools::EventMultiplexerEvent::EID_CONTROLLER_ATTACHED:
+ {
+ ConnectToController();
+ mrController.GetPageSelector().UpdateAllPages();
+ UpdateEditMode();
+ }
+ break;
+
+
+ case tools::EventMultiplexerEvent::EID_CONTROLLER_DETACHED:
+ DisconnectFromController();
+ break;
+
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+
+
+
+//===== lang::XEventListener ================================================
+
+void SAL_CALL Listener::disposing (
+ const lang::EventObject& rEventObject)
+ throw (RuntimeException)
+{
+ if ((mbListeningToDocument || mbListeningToUNODocument)
+ && mrSlideSorter.GetModel().GetDocument()!=NULL
+ && rEventObject.Source
+ == mrSlideSorter.GetModel().GetDocument()->getUnoModel())
+ {
+ mbListeningToDocument = false;
+ mbListeningToUNODocument = false;
+ }
+ else if (mbListeningToController)
+ {
+ Reference<frame::XController> xController (mxControllerWeak);
+ if (rEventObject.Source == xController)
+ {
+ mbListeningToController = false;
+ }
+ }
+}
+
+
+
+
+//===== document::XEventListener ============================================
+
+void SAL_CALL Listener::notifyEvent (
+ const document::EventObject& )
+ throw (RuntimeException)
+{
+}
+
+
+
+
+//===== beans::XPropertySetListener =========================================
+
+void SAL_CALL Listener::propertyChange (
+ const PropertyChangeEvent& rEvent)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+
+ static const ::rtl::OUString sCurrentPagePropertyName (
+ RTL_CONSTASCII_USTRINGPARAM("CurrentPage"));
+ static const ::rtl::OUString sEditModePropertyName (
+ RTL_CONSTASCII_USTRINGPARAM("IsMasterPageMode"));
+
+ if (rEvent.PropertyName.equals (sCurrentPagePropertyName))
+ {
+ Any aCurrentPage = rEvent.NewValue;
+ Reference<beans::XPropertySet> xPageSet (aCurrentPage, UNO_QUERY);
+ if (xPageSet.is())
+ {
+ try
+ {
+ Any aPageNumber = xPageSet->getPropertyValue (
+ String(RTL_CONSTASCII_USTRINGPARAM("Number")));
+ sal_Int32 nCurrentPage = 0;
+ aPageNumber >>= nCurrentPage;
+ mrController.GetPageSelector().UpdateAllPages ();
+ // 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);
+ }
+ catch (beans::UnknownPropertyException aEvent)
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ catch (lang::DisposedException&)
+ {
+ // Something is already disposed. There is not much we can
+ // do, except not to crash.
+ }
+ }
+ }
+ else if (rEvent.PropertyName.equals (sEditModePropertyName))
+ {
+ sal_Bool bIsMasterPageMode = sal_False;
+ rEvent.NewValue >>= bIsMasterPageMode;
+ mrController.ChangeEditMode (
+ bIsMasterPageMode ? EM_MASTERPAGE : EM_PAGE);
+ }
+}
+
+
+
+
+//===== frame::XFrameActionListener ==========================================
+
+void SAL_CALL Listener::frameAction (const frame::FrameActionEvent& rEvent)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ switch (rEvent.Action)
+ {
+ case frame::FrameAction_COMPONENT_DETACHING:
+ DisconnectFromController();
+ break;
+
+ case frame::FrameAction_COMPONENT_REATTACHED:
+ {
+ ConnectToController();
+ mrController.GetPageSelector().UpdateAllPages();
+ UpdateEditMode();
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+
+
+//===== accessibility::XAccessibleEventListener ==============================
+
+void SAL_CALL Listener::notifyEvent (
+ const AccessibleEventObject& )
+ throw (RuntimeException)
+{
+}
+
+
+
+
+void SAL_CALL Listener::disposing (void)
+{
+ ReleaseListeners();
+}
+
+
+
+
+void Listener::UpdateEditMode (void)
+{
+ // When there is a new controller then the edit mode may have changed at
+ // the same time.
+ Reference<frame::XController> xController (mxControllerWeak);
+ Reference<beans::XPropertySet> xSet (xController, UNO_QUERY);
+ bool bIsMasterPageMode = false;
+ if (xSet != NULL)
+ {
+ try
+ {
+ Any aValue (xSet->getPropertyValue(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("IsMasterPageMode"))));
+ aValue >>= bIsMasterPageMode;
+ }
+ catch (beans::UnknownPropertyException e)
+ {
+ // When the property is not supported then the master page mode
+ // is not supported, too.
+ bIsMasterPageMode = false;
+ }
+ }
+ mrController.ChangeEditMode (
+ bIsMasterPageMode ? EM_MASTERPAGE : EM_PAGE);
+}
+
+
+
+
+void Listener::ThrowIfDisposed (void)
+ throw (::com::sun::star::lang::DisposedException)
+{
+ if (rBHelper.bDisposed || rBHelper.bInDispose)
+ {
+ throw lang::DisposedException (
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "SlideSorterController object has already been disposed")),
+ static_cast<uno::XWeak*>(this));
+ }
+}
+
+
+
+
+} } } // end of namespace ::sd::slidesorter::controller
diff --git a/sd/source/ui/slidesorter/controller/SlsListener.hxx b/sd/source/ui/slidesorter/controller/SlsListener.hxx
new file mode 100644
index 000000000000..5613452a1b59
--- /dev/null
+++ b/sd/source/ui/slidesorter/controller/SlsListener.hxx
@@ -0,0 +1,185 @@
+/*************************************************************************
+ *
+ * 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_SLIDE_SORTER_LISTENER_HXX
+#define SD_SLIDESORTER_SLIDE_SORTER_LISTENER_HXX
+
+#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>
+#include <com/sun/star/frame/XFrameActionListener.hpp>
+#include <cppuhelper/compbase4.hxx>
+
+#include <svl/lstner.hxx>
+#include <tools/link.hxx>
+#include <boost/shared_ptr.hpp>
+
+namespace sd {
+class ViewShellBase;
+}
+
+namespace sd { namespace tools {
+class EventMultiplexerEvent;
+} }
+
+namespace sd { namespace slidesorter {
+class SlideSorter;
+} }
+
+
+namespace sd { namespace slidesorter { namespace controller {
+
+typedef cppu::WeakComponentImplHelper4<
+ ::com::sun::star::document::XEventListener,
+ ::com::sun::star::beans::XPropertyChangeListener,
+ ::com::sun::star::accessibility::XAccessibleEventListener,
+ ::com::sun::star::frame::XFrameActionListener
+ > ListenerInterfaceBase;
+
+class SlideSorterController;
+
+/** Listen for events of various types and sources and react to them. This
+ class is a part of the controller.
+
+ When the view shell in the center pane is replaced by another the
+ associated controller is replaced as well. Therefore we have to
+ register at the frame and on certain FrameActionEvents to stop listening
+ to the old controller and register as listener at the new one.
+*/
+class Listener
+ : protected MutexOwner,
+ public ListenerInterfaceBase,
+ public SfxListener
+{
+public:
+ Listener (SlideSorter& rSlideSorter);
+ virtual ~Listener (void);
+
+ /** Connect to the current controller of the view shell as listener.
+ This method is called once during initialization and every time a
+ FrameActionEvent signals the current controller being exchanged.
+ When the connection is successfull then the flag
+ mbListeningToController is set to <TRUE/>.
+ */
+ void ConnectToController (void);
+
+ /** Disconnect from the current controller of the view shell as
+ listener. This method is called once during initialization and
+ every time a FrameActionEvent signals the current controller being
+ exchanged. When this method terminates then mbListeningToController
+ is <FALSE/>.
+ */
+ void DisconnectFromController (void);
+
+ virtual void Notify (
+ SfxBroadcaster& rBroadcaster,
+ const SfxHint& rHint);
+
+ //===== lang::XEventListener ============================================
+ virtual void SAL_CALL
+ disposing (const ::com::sun::star::lang::EventObject& rEventObject)
+ throw (::com::sun::star::uno::RuntimeException);
+
+
+ //===== document::XEventListener ========================================
+ virtual void SAL_CALL
+ notifyEvent (
+ const ::com::sun::star::document::EventObject& rEventObject)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ //===== beans::XPropertySetListener =====================================
+ virtual void SAL_CALL
+ propertyChange (
+ const com::sun::star::beans::PropertyChangeEvent& rEvent)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ //===== accessibility::XAccessibleEventListener ==========================
+ virtual void SAL_CALL
+ notifyEvent (
+ const ::com::sun::star::accessibility::AccessibleEventObject&
+ rEvent)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ //===== frame::XFrameActionListener ======================================
+ /** For certain actions the listener connects to a new controller of the
+ frame it is listening to. This usually happens when the view shell
+ in the center pane is replaced by another view shell.
+ */
+ virtual void SAL_CALL
+ frameAction (const ::com::sun::star::frame::FrameActionEvent& rEvent)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL disposing (void);
+
+private:
+ SlideSorter& mrSlideSorter;
+ SlideSorterController& mrController;
+ ViewShellBase* mpBase;
+
+ /// Remember whether we are listening to the document.
+ bool mbListeningToDocument;
+ /// Remember whether we are listening to the UNO document.
+ bool mbListeningToUNODocument;
+ /// Remember whether we are listening to the UNO controller.
+ bool mbListeningToController;
+ /// Remember whether we are listening to the frame.
+ bool mbListeningToFrame;
+ bool mbIsMainViewChangePending;
+
+ ::com::sun::star::uno::WeakReference< ::com::sun::star::frame::XController> mxControllerWeak;
+ ::com::sun::star::uno::WeakReference< ::com::sun::star::frame::XFrame> mxFrameWeak;
+
+ /** This object is used to lock the model between some
+ events. It is refernce counted in order to cope with events that
+ are expected but never sent.
+ */
+ ::boost::shared_ptr<SlideSorterController::ModelChangeLock> mpModelChangeLock;
+
+ void ReleaseListeners (void);
+
+ /** Called when the edit mode has changed. Update model accordingly.
+ */
+ void UpdateEditMode (void);
+
+ /** This method throws a DisposedException when the object has already been
+ disposed.
+ */
+ void ThrowIfDisposed (void)
+ throw (::com::sun::star::lang::DisposedException);
+
+ DECL_LINK(EventMultiplexerCallback, tools::EventMultiplexerEvent*);
+};
+
+} } } // end of namespace ::sd::slidesorter::controller
+
+#endif
diff --git a/sd/source/ui/slidesorter/controller/SlsPageObjectFactory.cxx b/sd/source/ui/slidesorter/controller/SlsPageObjectFactory.cxx
new file mode 100644
index 000000000000..5ac41849a674
--- /dev/null
+++ b/sd/source/ui/slidesorter/controller/SlsPageObjectFactory.cxx
@@ -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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sd.hxx"
+
+#include "controller/SlsPageObjectFactory.hxx"
+
+#include "view/SlsPageObject.hxx"
+#include "view/SlsPageObjectViewContact.hxx"
+#include "view/SlsPageObjectViewObjectContact.hxx"
+
+#include "sdpage.hxx"
+
+
+namespace sd { namespace slidesorter { namespace controller {
+
+
+PageObjectFactory::PageObjectFactory (
+ const ::boost::shared_ptr<cache::PageCache>& rpCache,
+ const ::boost::shared_ptr<controller::Properties>& rpProperties)
+ : mpPageCache(rpCache),
+ mpProperties(rpProperties)
+{
+}
+
+
+
+
+PageObjectFactory::~PageObjectFactory (void)
+{
+}
+
+
+
+
+view::PageObject* PageObjectFactory::CreatePageObject (
+ SdPage* pPage,
+ const model::SharedPageDescriptor& rpDescriptor) const
+{
+ return new view::PageObject(
+ Rectangle (Point(0,0), pPage->GetSize()),
+ pPage,
+ rpDescriptor);
+}
+
+
+
+
+::sdr::contact::ViewContact*
+ PageObjectFactory::CreateViewContact (
+ view::PageObject* pPageObject,
+ const model::SharedPageDescriptor& rpDescriptor) const
+{
+ return new view::PageObjectViewContact (
+ *pPageObject,
+ rpDescriptor);
+}
+
+
+
+
+::sdr::contact::ViewObjectContact*
+ PageObjectFactory::CreateViewObjectContact (
+ ::sdr::contact::ObjectContact& rObjectContact,
+ ::sdr::contact::ViewContact& rViewContact) const
+{
+ return new view::PageObjectViewObjectContact (
+ rObjectContact,
+ rViewContact,
+ mpPageCache,
+ mpProperties);
+}
+
+
+} } } // end of namespace ::sd::slidesorter::controller
diff --git a/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx b/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx
new file mode 100755
index 000000000000..0e8f5e100d1c
--- /dev/null
+++ b/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx
@@ -0,0 +1,324 @@
+/*************************************************************************
+ *
+ * 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/SlsPageSelector.hxx"
+
+#include "SlideSorter.hxx"
+#include "SlideSorterViewShell.hxx"
+#include "controller/SlideSorterController.hxx"
+#include "controller/SlsSelectionManager.hxx"
+#include "model/SlsPageDescriptor.hxx"
+#include "model/SlsPageEnumerationProvider.hxx"
+#include "model/SlideSorterModel.hxx"
+#include "view/SlideSorterView.hxx"
+
+#include "sdpage.hxx"
+#include "ViewShell.hxx"
+#include "DrawViewShell.hxx"
+#include "ViewShellBase.hxx"
+#include <com/sun/star/drawing/XDrawView.hpp>
+#include <com/sun/star/beans/XPropertySet.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 {
+
+
+PageSelector::PageSelector (SlideSorter& rSlideSorter)
+ : mrModel(rSlideSorter.GetModel()),
+ mrSlideSorter(rSlideSorter),
+ mrController(mrSlideSorter.GetController()),
+ mnSelectedPageCount(0),
+ mnBroadcastDisableLevel(0),
+ mbSelectionChangeBroadcastPending(false),
+ mpMostRecentlySelectedPage(),
+ mpSelectionAnchor()
+{
+ CountSelectedPages ();
+}
+
+
+
+
+void PageSelector::SelectAllPages (void)
+{
+ int nPageCount = mrModel.GetPageCount();
+ for (int nPageIndex=0; nPageIndex<nPageCount; nPageIndex++)
+ SelectPage (nPageIndex);
+}
+
+
+
+
+void PageSelector::DeselectAllPages (void)
+{
+ int nPageCount = mrModel.GetPageCount();
+ for (int nPageIndex=0; nPageIndex<nPageCount; 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)
+{
+ bool bSelectionHasChanged (true);
+ mnSelectedPageCount = 0;
+ model::PageEnumeration aAllPages (
+ model::PageEnumerationProvider::CreateAllPagesEnumeration(mrModel));
+ while (aAllPages.HasMoreElements())
+ {
+ model::SharedPageDescriptor pDescriptor (aAllPages.GetNextElement());
+ if (pDescriptor->UpdateSelection())
+ {
+ mrSlideSorter.GetView().RequestRepaint(pDescriptor);
+ bSelectionHasChanged = true;
+ }
+
+ if (pDescriptor->IsSelected())
+ mnSelectedPageCount++;
+ }
+
+ if (bSelectionHasChanged)
+ {
+ if (mnBroadcastDisableLevel > 0)
+ mbSelectionChangeBroadcastPending = true;
+ else
+ mrController.GetSelectionManager()->SelectionHasChanged();
+ }
+}
+
+
+
+
+void PageSelector::SelectPage (int nPageIndex)
+{
+ SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nPageIndex));
+ if (pDescriptor.get() != NULL)
+ SelectPage(pDescriptor);
+}
+
+
+
+
+void PageSelector::SelectPage (const SdPage* pPage)
+{
+ int nPageIndex = (pPage->GetPageNum()-1) / 2;
+ SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nPageIndex));
+ if (pDescriptor.get()!=NULL && pDescriptor->GetPage()==pPage)
+ SelectPage(pDescriptor);
+}
+
+
+
+
+void PageSelector::SelectPage (const SharedPageDescriptor& rpDescriptor)
+{
+ if (rpDescriptor.get()!=NULL && rpDescriptor->Select())
+ {
+ mnSelectedPageCount ++;
+ mrSlideSorter.GetView().RequestRepaint(rpDescriptor);
+
+ mpMostRecentlySelectedPage = rpDescriptor;
+ if (mpSelectionAnchor == NULL)
+ mpSelectionAnchor = rpDescriptor;
+
+ if (mnBroadcastDisableLevel > 0)
+ mbSelectionChangeBroadcastPending = true;
+ else
+ mrController.GetSelectionManager()->SelectionHasChanged();
+ }
+}
+
+
+
+
+void PageSelector::DeselectPage (int nPageIndex)
+{
+ model::SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nPageIndex));
+ if (pDescriptor.get() != NULL)
+ DeselectPage(pDescriptor);
+}
+
+
+
+
+void PageSelector::DeselectPage (const SharedPageDescriptor& rpDescriptor)
+{
+ if (rpDescriptor.get()!=NULL && rpDescriptor->Deselect())
+ {
+ mnSelectedPageCount --;
+ mrSlideSorter.GetView().RequestRepaint(rpDescriptor);
+ if (mpMostRecentlySelectedPage == rpDescriptor)
+ mpMostRecentlySelectedPage.reset();
+ if (mnBroadcastDisableLevel > 0)
+ mbSelectionChangeBroadcastPending = true;
+ else
+ mrController.GetSelectionManager()->SelectionHasChanged();
+ }
+}
+
+
+
+
+bool PageSelector::IsPageSelected (int nPageIndex)
+{
+ SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nPageIndex));
+ if (pDescriptor.get() != NULL)
+ return pDescriptor->IsSelected();
+ else
+ return false;
+}
+
+
+
+
+int PageSelector::GetPageCount (void) const
+{
+ return mrModel.GetPageCount();
+}
+
+
+
+
+int PageSelector::GetSelectedPageCount (void) const
+{
+ return mnSelectedPageCount;
+}
+
+
+
+
+void PageSelector::PrepareModelChange (void)
+{
+ DeselectAllPages ();
+}
+
+
+
+
+void PageSelector::HandleModelChange (void)
+{
+ UpdateAllPages();
+}
+
+
+
+
+SharedPageDescriptor PageSelector::GetMostRecentlySelectedPage (void) const
+{
+ return mpMostRecentlySelectedPage;
+}
+
+
+
+
+SharedPageDescriptor PageSelector::GetSelectionAnchor (void) const
+{
+ return mpSelectionAnchor;
+}
+
+
+
+
+void PageSelector::CountSelectedPages (void)
+{
+ mnSelectedPageCount = 0;
+ model::PageEnumeration aSelectedPages (
+ model::PageEnumerationProvider::CreateSelectedPagesEnumeration(mrModel));
+ while (aSelectedPages.HasMoreElements())
+ {
+ mnSelectedPageCount++;
+ aSelectedPages.GetNextElement();
+ }
+}
+
+
+
+
+void PageSelector::EnableBroadcasting (bool bMakeSelectionVisible)
+{
+ if (mnBroadcastDisableLevel > 0)
+ mnBroadcastDisableLevel --;
+ if (mnBroadcastDisableLevel==0 && mbSelectionChangeBroadcastPending)
+ {
+ mrController.GetSelectionManager()->SelectionHasChanged(bMakeSelectionVisible);
+ mbSelectionChangeBroadcastPending = false;
+ }
+}
+
+
+
+
+void PageSelector::DisableBroadcasting (void)
+{
+ mnBroadcastDisableLevel ++;
+}
+
+
+
+
+::boost::shared_ptr<PageSelector::PageSelection> PageSelector::GetPageSelection (void) const
+{
+ ::boost::shared_ptr<PageSelection> pSelection (new PageSelection());
+ pSelection->reserve(GetSelectedPageCount());
+
+ int nPageCount = GetPageCount();
+ for (int nIndex=0; nIndex<nPageCount; nIndex++)
+ {
+ SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nIndex));
+ if (pDescriptor.get()!=NULL && pDescriptor->IsSelected())
+ pSelection->push_back(pDescriptor->GetPage());
+ }
+
+ return pSelection;
+}
+
+
+
+
+void PageSelector::SetPageSelection (const ::boost::shared_ptr<PageSelection>& rpSelection)
+{
+ PageSelection::const_iterator iPage;
+ for (iPage=rpSelection->begin(); iPage!=rpSelection->end(); ++iPage)
+ SelectPage(*iPage);
+}
+
+
+
+
+} } } // end of namespace ::sd::slidesorter::controller
diff --git a/sd/source/ui/slidesorter/controller/SlsProperties.cxx b/sd/source/ui/slidesorter/controller/SlsProperties.cxx
new file mode 100644
index 000000000000..7382d769bbe2
--- /dev/null
+++ b/sd/source/ui/slidesorter/controller/SlsProperties.cxx
@@ -0,0 +1,233 @@
+/*************************************************************************
+ *
+ * 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/SlsProperties.hxx"
+#include <vcl/svapp.hxx>
+
+namespace sd { namespace slidesorter { namespace controller {
+
+Properties::Properties (void)
+ : mbIsHighlightCurrentSlide(false),
+ mbIsShowSelection(true),
+ mbIsShowFocus(true),
+ mbIsCenterSelection(false),
+ mbIsSmoothSelectionScrolling(false),
+ mbIsSuspendPreviewUpdatesDuringFullScreenPresentation(true),
+ maBackgroundColor(Application::GetSettings().GetStyleSettings().GetWindowColor()),
+ maTextColor(Application::GetSettings().GetStyleSettings().GetActiveTextColor()),
+ maSelectionColor(Application::GetSettings().GetStyleSettings().GetMenuHighlightColor()),
+ maHighlightColor(Application::GetSettings().GetStyleSettings().GetMenuHighlightColor()),
+ mbIsUIReadOnly(false)
+{
+}
+
+
+
+
+Properties::~Properties (void)
+{
+}
+
+
+
+
+bool Properties::IsHighlightCurrentSlide (void) const
+{
+ return mbIsHighlightCurrentSlide;
+}
+
+
+
+
+void Properties::SetHighlightCurrentSlide (const bool bIsHighlightCurrentSlide)
+{
+ mbIsHighlightCurrentSlide = bIsHighlightCurrentSlide;
+}
+
+
+
+
+bool Properties::IsShowSelection (void) const
+{
+ return mbIsShowSelection;
+}
+
+
+
+
+void Properties::SetShowSelection (const bool bIsShowSelection)
+{
+ mbIsShowSelection = bIsShowSelection;
+}
+
+
+
+
+bool Properties::IsShowFocus (void) const
+{
+ return mbIsShowFocus;
+}
+
+
+
+
+void Properties::SetShowFocus (const bool bIsShowFocus)
+{
+ mbIsShowFocus = bIsShowFocus;
+}
+
+
+
+
+bool Properties::IsCenterSelection (void) const
+{
+ return mbIsCenterSelection;
+}
+
+
+
+
+void Properties::SetCenterSelection (const bool bIsCenterSelection)
+{
+ mbIsCenterSelection = bIsCenterSelection;
+}
+
+
+
+
+bool Properties::IsSmoothSelectionScrolling (void) const
+{
+ return mbIsSmoothSelectionScrolling;
+}
+
+
+
+
+void Properties::SetSmoothSelectionScrolling (const bool bIsSmoothSelectionScrolling)
+{
+ mbIsSmoothSelectionScrolling = bIsSmoothSelectionScrolling;
+}
+
+
+
+
+bool Properties::IsSuspendPreviewUpdatesDuringFullScreenPresentation (void) const
+{
+ return mbIsSuspendPreviewUpdatesDuringFullScreenPresentation;
+}
+
+
+
+
+void Properties::SetSuspendPreviewUpdatesDuringFullScreenPresentation (const bool bFlag)
+{
+ mbIsSuspendPreviewUpdatesDuringFullScreenPresentation = bFlag;
+}
+
+
+
+
+Color Properties::GetBackgroundColor (void) const
+{
+ return maBackgroundColor;
+}
+
+
+
+
+void Properties::SetBackgroundColor (const Color& rColor)
+{
+ maBackgroundColor = rColor;
+}
+
+
+
+Color Properties::GetTextColor (void) const
+{
+ return maTextColor;
+}
+
+
+
+
+void Properties::SetTextColor (const Color& rColor)
+{
+ maTextColor = rColor;
+}
+
+
+
+
+Color Properties::GetSelectionColor (void) const
+{
+ return maSelectionColor;
+}
+
+
+
+
+void Properties::SetSelectionColor (const Color& rColor)
+{
+ maSelectionColor = rColor;
+}
+
+
+
+
+Color Properties::GetHighlightColor (void) const
+{
+ return maHighlightColor;
+}
+
+
+
+
+void Properties::SetHighlightColor (const Color& rColor)
+{
+ maHighlightColor = rColor;
+}
+
+
+
+
+bool Properties::IsUIReadOnly (void) const
+{
+ return mbIsUIReadOnly;
+}
+
+
+
+
+void Properties::SetUIReadOnly (const bool bIsUIReadOnly)
+{
+ mbIsUIReadOnly = bIsUIReadOnly;
+}
+
+
+} } } // end of namespace ::sd::slidesorter::controller
diff --git a/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx b/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx
new file mode 100755
index 000000000000..5ee7f6f58b82
--- /dev/null
+++ b/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx
@@ -0,0 +1,631 @@
+/*************************************************************************
+ *
+ * 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/SlsScrollBarManager.hxx"
+
+#include "SlideSorter.hxx"
+#include "controller/SlideSorterController.hxx"
+#include "model/SlideSorterModel.hxx"
+#include "model/SlsPageDescriptor.hxx"
+#include "view/SlideSorterView.hxx"
+#include "view/SlsLayouter.hxx"
+#include "view/SlsViewOverlay.hxx"
+#include "Window.hxx"
+#include "sdpage.hxx"
+
+#include <boost/limits.hpp>
+
+#include <vcl/scrbar.hxx>
+
+namespace sd { namespace slidesorter { namespace controller {
+
+ScrollBarManager::ScrollBarManager (SlideSorter& rSlideSorter)
+ : mrSlideSorter(rSlideSorter),
+ mpHorizontalScrollBar(mrSlideSorter.GetHorizontalScrollBar()),
+ mpVerticalScrollBar(mrSlideSorter.GetVerticalScrollBar()),
+ mnHorizontalPosition (0),
+ mnVerticalPosition (0),
+ maScrollBorder (10,10),
+ mnHorizontalScrollFactor (0.1),
+ mnVerticalScrollFactor (0.1),
+ mpScrollBarFiller(mrSlideSorter.GetScrollBarFiller()),
+ mpContentWindow(mrSlideSorter.GetContentWindow())
+{
+ // Hide the scroll bars by default to prevent display errors while
+ // switching between view shells: In the short time between initiating
+ // such a switch and the final rearrangement of UI controls the scroll
+ // bars and the filler where displayed in the upper left corner of the
+ // ViewTabBar.
+ mpHorizontalScrollBar->Hide();
+ mpVerticalScrollBar->Hide();
+ mpScrollBarFiller->Hide();
+
+ maAutoScrollTimer.SetTimeout(50);
+ maAutoScrollTimer.SetTimeoutHdl (
+ LINK(this, ScrollBarManager, AutoScrollTimeoutHandler));
+}
+
+
+
+
+ScrollBarManager::~ScrollBarManager (void)
+{
+}
+
+
+
+
+void ScrollBarManager::LateInitialization (void)
+{
+}
+
+
+
+
+void ScrollBarManager::Connect (void)
+{
+ if (mpVerticalScrollBar != NULL)
+ mpVerticalScrollBar->SetScrollHdl (
+ LINK(
+ this,
+ ScrollBarManager,
+ VerticalScrollBarHandler));
+ if (mpHorizontalScrollBar != NULL)
+ mpHorizontalScrollBar->SetScrollHdl (
+ LINK(
+ this,
+ ScrollBarManager,
+ HorizontalScrollBarHandler));
+}
+
+
+
+
+void ScrollBarManager::Disconnect (void)
+{
+ if (mpVerticalScrollBar != NULL)
+ mpVerticalScrollBar->SetScrollHdl (Link());
+ if (mpHorizontalScrollBar != NULL)
+ mpHorizontalScrollBar->SetScrollHdl (Link());
+}
+
+
+
+
+/** Placing the scroll bars is an iterative process. The visibility of one
+ scroll bar affects the remaining size and thus may lead to the other
+ scroll bar becoming visible.
+
+ First we determine the visibility of the horizontal scroll bar. After
+ that we do the same for the vertical scroll bar. To have an initial
+ value for the required size we call the layouter before that. When one
+ of the two scroll bars is made visible then the size of the browser
+ 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 aRemainingSpace (DetermineScrollBarVisibilities(rAvailableArea));
+ PlaceHorizontalScrollBar (rAvailableArea);
+ PlaceVerticalScrollBar (rAvailableArea);
+ PlaceFiller (rAvailableArea);
+
+ return aRemainingSpace;
+}
+
+
+
+
+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()));
+ }
+}
+
+
+
+
+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());
+ }
+}
+
+
+
+
+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();
+}
+
+
+
+
+void ScrollBarManager::UpdateScrollBars (bool bResetThumbPosition, bool bUseScrolling)
+{
+ Rectangle aModelArea (mrSlideSorter.GetView().GetModelArea());
+ ::sd::Window* pWindow = mrSlideSorter.GetView().GetWindow();
+ Size aWindowModelSize (pWindow->PixelToLogic(pWindow->GetSizePixel()));
+
+ // The horizontal scroll bar is only shown when the window is
+ // horizontally smaller than the view.
+ if (mpHorizontalScrollBar != NULL && mpHorizontalScrollBar->IsVisible())
+ {
+ mpHorizontalScrollBar->Show();
+ mpHorizontalScrollBar->SetRange (
+ Range(aModelArea.Left(), aModelArea.Right()));
+ if (bResetThumbPosition)
+ {
+ mpHorizontalScrollBar->SetThumbPos (0);
+ mnHorizontalPosition = 0;
+ }
+ else
+ mnHorizontalPosition =
+ double(mpHorizontalScrollBar->GetThumbPos())
+ / double(mpHorizontalScrollBar->GetRange().Len());
+
+ mpHorizontalScrollBar->SetVisibleSize (aWindowModelSize.Width());
+
+ const long nWidth (mpContentWindow->PixelToLogic(
+ mpContentWindow->GetSizePixel()).Width());
+ // Make the line size about 10% of the visible width.
+ mpHorizontalScrollBar->SetLineSize (nWidth / 10);
+ // Make the page size about 90% of the visible width.
+ mpHorizontalScrollBar->SetPageSize ((nWidth * 9) / 10);
+ }
+ else
+ {
+ mnHorizontalPosition = 0;
+ }
+
+ // The vertical scroll bar is always shown.
+ if (mpVerticalScrollBar != NULL && mpVerticalScrollBar->IsVisible())
+ {
+ mpVerticalScrollBar->SetRange (
+ Range(aModelArea.Top(), aModelArea.Bottom()));
+ if (bResetThumbPosition)
+ {
+ mpVerticalScrollBar->SetThumbPos (0);
+ mnVerticalPosition = 0;
+ }
+ else
+ mnVerticalPosition =
+ double(mpVerticalScrollBar->GetThumbPos())
+ / double(mpVerticalScrollBar->GetRange().Len());
+
+ mpVerticalScrollBar->SetVisibleSize (aWindowModelSize.Height());
+
+ const long nHeight (mpContentWindow->PixelToLogic(
+ mpContentWindow->GetSizePixel()).Height());
+ // Make the line size about 10% of the visible height.
+ mpVerticalScrollBar->SetLineSize (nHeight / 10);
+ // Make the page size about 90% of the visible height.
+ mpVerticalScrollBar->SetPageSize ((nHeight * 9) / 10);
+ }
+ else
+ {
+ mnVerticalPosition = 0;
+ }
+
+
+ double nEps (::std::numeric_limits<double>::epsilon());
+ if (fabs(mnHorizontalPosition-pWindow->GetVisibleX()) > nEps
+ || fabs(mnVerticalPosition-pWindow->GetVisibleY()) > nEps)
+ {
+ mrSlideSorter.GetView().InvalidatePageObjectVisibilities();
+ if (bUseScrolling)
+ pWindow->SetVisibleXY(mnHorizontalPosition, mnVerticalPosition);
+ else
+ SetWindowOrigin(mnHorizontalPosition, mnVerticalPosition);
+ }
+}
+
+
+
+
+IMPL_LINK(ScrollBarManager, VerticalScrollBarHandler, ScrollBar*, pScrollBar)
+{
+ if (pScrollBar!=NULL
+ && pScrollBar==mpVerticalScrollBar.get()
+ && pScrollBar->IsVisible()
+ && mrSlideSorter.GetView().GetWindow()!=NULL)
+ {
+ double nRelativePosition = double(pScrollBar->GetThumbPos())
+ / double(pScrollBar->GetRange().Len());
+ mrSlideSorter.GetView().InvalidatePageObjectVisibilities();
+ mrSlideSorter.GetView().GetWindow()->SetVisibleXY (
+ -1,
+ nRelativePosition);
+ }
+ return TRUE;
+}
+
+
+
+
+IMPL_LINK(ScrollBarManager, HorizontalScrollBarHandler, ScrollBar*, pScrollBar)
+{
+ if (pScrollBar!=NULL
+ && pScrollBar==mpHorizontalScrollBar.get()
+ && pScrollBar->IsVisible()
+ && mrSlideSorter.GetView().GetWindow()!=NULL)
+ {
+ double nRelativePosition = double(pScrollBar->GetThumbPos())
+ / double(pScrollBar->GetRange().Len());
+ mrSlideSorter.GetView().InvalidatePageObjectVisibilities();
+ mrSlideSorter.GetView().GetWindow()->SetVisibleXY (nRelativePosition, -1);
+ }
+ return TRUE;
+}
+
+
+
+
+void ScrollBarManager::SetWindowOrigin (
+ double nHorizontalPosition,
+ double nVerticalPosition)
+{
+ mnHorizontalPosition = nHorizontalPosition;
+ mnVerticalPosition = nVerticalPosition;
+
+ ::sd::Window* pWindow = mrSlideSorter.GetView().GetWindow();
+ Size aViewSize (pWindow->GetViewSize());
+ Point aOrigin (
+ (long int) (mnHorizontalPosition * aViewSize.Width()),
+ (long int) (mnVerticalPosition * aViewSize.Height()));
+
+ pWindow->SetWinViewPos (aOrigin);
+ pWindow->UpdateMapMode ();
+ pWindow->Invalidate ();
+}
+
+
+
+
+/** Determining the visibility of the scroll bars is quite complicated. The
+ visibility of one influences that of the other because showing a scroll
+ bar makes the available space smaller and may lead to the need of
+ displaying the other.
+ To solve this we test all four combinations of showing or hiding each
+ scroll bar and use the best one. The best one is that combination that
+ a) shows the least number of scroll bars with preference of showing the
+ vertical over showing the horizontal and
+ 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)
+{
+ // Test which combination of scroll bars is the best.
+ bool bShowHorizontal = false;
+ bool bShowVertical = false;
+ do
+ {
+ 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;
+ }
+ while (false);
+
+ // Make the visibility of the scroll bars permanent.
+ mpVerticalScrollBar->Show(bShowVertical);
+ mpHorizontalScrollBar->Show(bShowHorizontal);
+
+ // Adapt the remaining space accordingly.
+ Rectangle aRemainingSpace (rAvailableArea);
+ if (bShowVertical)
+ aRemainingSpace.Right() -= mpVerticalScrollBar->GetSizePixel().Width();
+ if (bShowHorizontal)
+ aRemainingSpace.Bottom() -= mpHorizontalScrollBar->GetSizePixel().Height();
+
+ return aRemainingSpace;
+}
+
+
+
+
+bool ScrollBarManager::TestScrollBarVisibilities (
+ bool bHorizontalScrollBarVisible,
+ bool bVerticalScrollBarVisible,
+ const Rectangle& rAvailableArea)
+{
+ bool bAreVisibilitiesOK = true;
+
+ // Adapt the available size by subtracting the sizes of the scroll bars
+ // visible in this combination.
+ Size aBrowserSize (rAvailableArea.GetSize());
+ if (bHorizontalScrollBarVisible)
+ aBrowserSize.Height() -= mpHorizontalScrollBar->GetSizePixel().Height();
+ if (bVerticalScrollBarVisible)
+ aBrowserSize.Width() -= mpVerticalScrollBar->GetSizePixel().Width();
+
+ // 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());
+ }
+
+ if (bRearrangeSuccess)
+ {
+ Size aPageSize = mrSlideSorter.GetView().GetLayouter().GetPageBox (
+ mrSlideSorter.GetModel().GetPageCount()).GetSize();
+ Size aWindowModelSize = mpContentWindow->PixelToLogic(aBrowserSize);
+
+ bool bHorizontallyClipped = (aPageSize.Width() > aWindowModelSize.Width());
+ bool bVerticallyClipped = (aPageSize.Height() > aWindowModelSize.Height());
+ bAreVisibilitiesOK = (bHorizontallyClipped == bHorizontalScrollBarVisible)
+ && (bVerticallyClipped == bVerticalScrollBarVisible);
+ }
+ else
+ bAreVisibilitiesOK = false;
+
+ return bAreVisibilitiesOK;
+}
+
+
+
+
+void ScrollBarManager::SetTop (const sal_Int32 nNewTop)
+{
+ if (mpVerticalScrollBar != NULL
+ && mpVerticalScrollBar->GetThumbPos() != nNewTop)
+ {
+ // Flush pending repaints before scrolling to avoid temporary artifacts.
+ mrSlideSorter.GetView().GetWindow()->Update();
+
+ mpVerticalScrollBar->SetThumbPos(nNewTop);
+ mnVerticalPosition = double(nNewTop) / double(mpVerticalScrollBar->GetRange().Len());
+ mrSlideSorter.GetView().GetWindow()->SetVisibleXY (
+ mnHorizontalPosition, mnVerticalPosition);
+ }
+}
+
+
+
+
+void ScrollBarManager::SetLeft (const sal_Int32 nNewLeft)
+{
+ if (mpHorizontalScrollBar != NULL
+ && mpHorizontalScrollBar->GetThumbPos() != nNewLeft)
+ {
+ // Flush pending repaints before scrolling to avoid temporary artifacts.
+ mrSlideSorter.GetView().GetWindow()->Update();
+
+ mpHorizontalScrollBar->SetThumbPos(nNewLeft);
+ mnHorizontalPosition = double(nNewLeft) / double(mpHorizontalScrollBar->GetRange().Len());
+ mrSlideSorter.GetView().GetWindow()->SetVisibleXY (
+ mnHorizontalPosition, mnVerticalPosition);
+ }
+}
+
+
+
+
+int ScrollBarManager::GetVerticalScrollBarWidth (void) const
+{
+ if (mpVerticalScrollBar != NULL && mpVerticalScrollBar->IsVisible())
+ return mpVerticalScrollBar->GetSizePixel().Width();
+ else
+ return 0;
+}
+
+
+
+
+int ScrollBarManager::GetHorizontalScrollBarHeight (void) const
+{
+ if (mpHorizontalScrollBar != NULL && mpHorizontalScrollBar->IsVisible())
+ return mpHorizontalScrollBar->GetSizePixel().Height();
+ else
+ return 0;
+}
+
+
+
+
+void ScrollBarManager::CalcAutoScrollOffset (const Point& rMouseWindowPosition)
+{
+ ::sd::Window* pWindow = mrSlideSorter.GetView().GetWindow();
+
+ int nDx = 0;
+ int nDy = 0;
+
+ Size aWindowSize = pWindow->GetOutputSizePixel();
+ Rectangle aWindowArea (pWindow->GetPosPixel(), aWindowSize);
+ Rectangle aViewPixelArea (
+ pWindow->LogicToPixel(mrSlideSorter.GetView().GetModelArea()));
+
+ if (aWindowSize.Width() > maScrollBorder.Width() * 3
+ && mpHorizontalScrollBar != NULL
+ && mpHorizontalScrollBar->IsVisible())
+ {
+ if (rMouseWindowPosition.X() < maScrollBorder.Width()
+ && aWindowArea.Left() > aViewPixelArea.Left())
+ {
+ nDx = -1 + (int)(mnHorizontalScrollFactor
+ * (rMouseWindowPosition.X() - maScrollBorder.Width()));
+ }
+
+ if (rMouseWindowPosition.X() >= (aWindowSize.Width() - maScrollBorder.Width())
+ && aWindowArea.Right() < aViewPixelArea.Right())
+ {
+ nDx = 1 + (int)(mnHorizontalScrollFactor
+ * (rMouseWindowPosition.X() - aWindowSize.Width()
+ + maScrollBorder.Width()));
+ }
+ }
+
+ if (aWindowSize.Height() > maScrollBorder.Height() * 3
+ && aWindowSize.Height() < aViewPixelArea.GetHeight())
+ {
+ if (rMouseWindowPosition.Y() < maScrollBorder.Height()
+ && aWindowArea.Top() > aViewPixelArea.Top())
+ {
+ nDy = -1 + (int)(mnVerticalScrollFactor
+ * (rMouseWindowPosition.Y() - maScrollBorder.Height()));
+ }
+
+ if (rMouseWindowPosition.Y() >= (aWindowSize.Height() - maScrollBorder.Height())
+ && aWindowArea.Bottom() < aViewPixelArea.Bottom())
+ {
+ nDy = 1 + (int)(mnVerticalScrollFactor
+ * (rMouseWindowPosition.Y() - aWindowSize.Height()
+ + maScrollBorder.Height()));
+ }
+ }
+
+ maAutoScrollOffset = Size(nDx,nDy);
+}
+
+
+
+
+bool ScrollBarManager::AutoScroll (const Point& rMouseWindowPosition)
+{
+ CalcAutoScrollOffset (rMouseWindowPosition);
+ bool bResult = RepeatAutoScroll();
+ if (bResult)
+ {
+ maAutoScrollTimer.Start();
+ }
+ return bResult;
+}
+
+
+
+
+void ScrollBarManager::StopAutoScroll (void)
+{
+ maAutoScrollTimer.Stop();
+}
+
+
+
+
+bool ScrollBarManager::RepeatAutoScroll (void)
+{
+ if (maAutoScrollOffset != Size(0,0))
+ {
+ if (mrSlideSorter.GetViewShell() != NULL)
+ {
+ mrSlideSorter.GetViewShell()->ScrollLines(
+ maAutoScrollOffset.Width(),
+ maAutoScrollOffset.Height());
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+
+
+IMPL_LINK(ScrollBarManager, AutoScrollTimeoutHandler, Timer *, EMPTYARG)
+{
+ RepeatAutoScroll();
+
+ return 0;
+}
+
+
+} } } // end of namespace ::sd::slidesorter::controller
diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionCommand.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionCommand.cxx
new file mode 100755
index 000000000000..687019954feb
--- /dev/null
+++ b/sd/source/ui/slidesorter/controller/SlsSelectionCommand.cxx
@@ -0,0 +1,85 @@
+/*************************************************************************
+ *
+ * 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 "SlsSelectionCommand.hxx"
+
+#include "controller/SlsCurrentSlideManager.hxx"
+#include "model/SlideSorterModel.hxx"
+#include "model/SlsPageDescriptor.hxx"
+
+#include "sdpage.hxx"
+
+namespace sd { namespace slidesorter { namespace controller {
+
+
+
+SelectionCommand::SelectionCommand (
+ PageSelector& rSelector,
+ const ::boost::shared_ptr<CurrentSlideManager>& rpCurrentSlideManager,
+ const model::SlideSorterModel& rModel)
+ : mrPageSelector(rSelector),
+ mpCurrentSlideManager(rpCurrentSlideManager),
+ mrModel(rModel),
+ maPagesToSelect(),
+ mnCurrentPageIndex(-1)
+{
+}
+
+
+
+
+void SelectionCommand::AddSlide (USHORT nPageIndex)
+{
+ maPagesToSelect.push_back(nPageIndex);
+}
+
+
+
+
+void SelectionCommand::operator() (void)
+{
+ OSL_ASSERT(mpCurrentSlideManager.get()!=NULL);
+
+ mrPageSelector.DeselectAllPages();
+
+ if (mnCurrentPageIndex >= 0)
+ mpCurrentSlideManager->SwitchCurrentSlide(mnCurrentPageIndex);
+
+ PageList::iterator iPage = maPagesToSelect.begin();
+ PageList::iterator iEnd = maPagesToSelect.end();
+ for (; iPage!=iEnd; ++iPage)
+ {
+ sal_Int32 nIndex (*iPage);
+ if (nIndex >= 0)
+ mrPageSelector.SelectPage(mrModel.GetPageDescriptor(nIndex));
+ }
+}
+
+
+} } } // end of namespace sd::slidesorter::controller
diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionCommand.hxx b/sd/source/ui/slidesorter/controller/SlsSelectionCommand.hxx
new file mode 100755
index 000000000000..7a9d0f27369e
--- /dev/null
+++ b/sd/source/ui/slidesorter/controller/SlsSelectionCommand.hxx
@@ -0,0 +1,95 @@
+/*************************************************************************
+ *
+ * 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_SELECTION_COMMAND_HXX
+#define SD_SLIDESORTER_SELECTION_COMMAND_HXX
+
+#include "controller/SlsPageSelector.hxx"
+#include "SlsCommand.hxx"
+#include <tools/solar.h>
+#include <com/sun/star/drawing/XDrawPage.hpp>
+
+#include <boost/shared_ptr.hpp>
+#include <vector>
+
+namespace sd { namespace slidesorter { namespace model {
+class SlideSorterModel;
+} } }
+
+
+namespace sd { namespace slidesorter { namespace controller {
+
+class CurrentSlideManager;
+class PageSelector;
+
+/** The SelectionCommand stores a list of pages that it will select on its
+ execution. Furthermore it will make a page the current page. Note that
+ internally pages are stored with pointers because this command is designed
+ to be executed after model changes where page indices may change but
+ page object identities remain.
+*/
+class SelectionCommand
+ : public Command
+{
+public:
+ /** Create a new command object that will on its exection use the given
+ PageSelector to select a set of pages.
+ */
+ SelectionCommand (
+ PageSelector& rSelector,
+ const ::boost::shared_ptr<controller::CurrentSlideManager>& rpCurrentSlideManager,
+ const model::SlideSorterModel& rModel);
+
+ /** Remember the specified page to be selected when this command is
+ executed.
+ */
+ void AddSlide (USHORT nPageIndex);
+
+ /** Execute the command and select the pages added by previous calls to
+ AddPages() and AddPage().
+ */
+ virtual void operator() (void);
+
+private:
+ /// The page selector is used to select pages and set the current page.
+ PageSelector& mrPageSelector;
+ /// Used for setting the current slide.
+ ::boost::shared_ptr<controller::CurrentSlideManager> mpCurrentSlideManager;
+ /// The model is used to translate page indices into page pointers.
+ const model::SlideSorterModel& mrModel;
+ /// The list of pages to be selected when the command is executed.
+ typedef ::std::vector<sal_Int32> PageList;
+ PageList maPagesToSelect;
+ /** The page that will be made the current page when the command is
+ executed.
+ */
+ sal_Int32 mnCurrentPageIndex;
+};
+
+} } } // end of namespace sd::slidesorter::controller
+
+#endif
diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx
new file mode 100755
index 000000000000..c1d742ce7158
--- /dev/null
+++ b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx
@@ -0,0 +1,1317 @@
+/*************************************************************************
+ *
+ * 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/SlsSelectionFunction.hxx"
+
+#include "SlideSorter.hxx"
+#include "SlideSorterViewShell.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/SlsSelectionManager.hxx"
+#include "controller/SlsProperties.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 "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 "ViewShell.hxx"
+#include "ViewShellBase.hxx"
+#include "FrameView.hxx"
+#include "app.hrc"
+#include "sdresid.hxx"
+#include "strings.hrc"
+
+namespace {
+static const sal_uInt32 SINGLE_CLICK (0x00000001);
+static const sal_uInt32 DOUBLE_CLICK (0x00000002);
+static const sal_uInt32 LEFT_BUTTON (0x00000010);
+static const sal_uInt32 RIGHT_BUTTON (0x00000020);
+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);
+// 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 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);
+
+
+} // end of anonymous namespace
+
+
+namespace sd { namespace slidesorter { namespace controller {
+
+class SelectionFunction::SubstitutionHandler
+{
+public:
+ SubstitutionHandler (SlideSorter& rSlideSorter);
+ ~SubstitutionHandler (void);
+
+ /** Create a substitution display of the currently selected pages and
+ use the given position as the anchor point.
+ */
+ void Start (const Point& rMouseModelPosition);
+
+ /** 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& rMouseModelPosition);
+
+ /** Move the substitution display of the currently selected pages.
+ */
+ void Process (void);
+
+ void End (void);
+
+ bool HasBeenMoved (void) const;
+
+private:
+ SlideSorter& mrSlideSorter;
+
+ bool mbHasBeenMoved;
+
+ /** 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.
+ */
+ bool IsSubstitutionInsertionNonTrivial (void) const;
+};
+
+
+class SelectionFunction::EventDescriptor
+{
+public:
+
+ Point maMousePosition;
+ Point maMouseModelPosition;
+ ::boost::weak_ptr<model::PageDescriptor> mpHitDescriptor;
+ SdrPage* mpHitPage;
+ sal_uInt32 mnEventCode;
+
+ EventDescriptor (
+ sal_uInt32 nEventType,
+ const MouseEvent& rEvent,
+ SlideSorter& rSlideSorter);
+ EventDescriptor (
+ const KeyEvent& rEvent,
+ SlideSorter& rSlideSorter);
+};
+
+
+TYPEINIT1(SelectionFunction, FuPoor);
+
+
+SelectionFunction::SelectionFunction (
+ SlideSorter& rSlideSorter,
+ SfxRequest& rRequest)
+ : SlideFunction (rSlideSorter, rRequest),
+ mrSlideSorter(rSlideSorter),
+ mrController(mrSlideSorter.GetController()),
+ mbDragSelection(false),
+ maInsertionMarkerBox(),
+ mbProcessingMouseButtonDown(false),
+ mpSubstitutionHandler(new SubstitutionHandler(mrSlideSorter))
+{
+ //af aDelayToScrollTimer.SetTimeout(50);
+ aDragTimer.SetTimeoutHdl( LINK( this, SelectionFunction, DragSlideHdl ) );
+}
+
+SelectionFunction::~SelectionFunction (void)
+{
+ aDragTimer.Stop();
+}
+
+
+
+
+FunctionReference SelectionFunction::Create(
+ SlideSorter& rSlideSorter,
+ SfxRequest& rRequest)
+{
+ FunctionReference xFunc( new SelectionFunction( rSlideSorter, rRequest ) );
+ return xFunc;
+}
+
+
+
+
+BOOL SelectionFunction::MouseButtonDown (const MouseEvent& rEvent)
+{
+ // #95491# remember button state for creation of own MouseEvents
+ SetMouseButtonCode (rEvent.GetButtons());
+ mbProcessingMouseButtonDown = true;
+
+ mpWindow->CaptureMouse();
+
+ ProcessMouseEvent(BUTTON_DOWN, rEvent);
+
+ return TRUE;
+}
+
+
+
+
+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);
+ }
+ }
+
+ return TRUE;
+}
+
+
+
+
+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();
+
+ return TRUE;
+}
+
+
+
+
+BOOL SelectionFunction::KeyInput (const KeyEvent& rEvent)
+{
+ FocusManager& rFocusManager (mrController.GetFocusManager());
+ BOOL bResult = FALSE;
+
+ switch (rEvent.GetKeyCode().GetCode())
+ {
+ case KEY_RETURN:
+ if (rFocusManager.HasFocus())
+ {
+ model::SharedPageDescriptor pDescriptor (rFocusManager.GetFocusedPageDescriptor());
+ if (pDescriptor.get() != NULL)
+ {
+ SetCurrentPage(pDescriptor);
+ SwitchView(pDescriptor);
+ }
+ 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;
+ break;
+
+ case KEY_ESCAPE:
+ rFocusManager.SetFocusToToolBox();
+ bResult = TRUE;
+ break;
+
+ case KEY_SPACE:
+ {
+ // Toggle the selection state.
+ model::SharedPageDescriptor pDescriptor (rFocusManager.GetFocusedPageDescriptor());
+ if (pDescriptor.get() != NULL)
+ {
+ // 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);
+ else
+ mrController.GetPageSelector().SelectPage(pDescriptor);
+ }
+ bResult = TRUE;
+ }
+ break;
+
+
+ // Move the focus indicator left.
+ case KEY_LEFT:
+ rFocusManager.MoveFocus (FocusManager::FMD_LEFT);
+ bResult = TRUE;
+ break;
+
+ // Move the focus indicator right.
+ case KEY_RIGHT:
+ rFocusManager.MoveFocus (FocusManager::FMD_RIGHT);
+ bResult = TRUE;
+ break;
+
+ // Move the focus indicator up.
+ case KEY_UP:
+ rFocusManager.MoveFocus (FocusManager::FMD_UP);
+ bResult = TRUE;
+ break;
+
+ // Move the focus indicator down.
+ case KEY_DOWN:
+ rFocusManager.MoveFocus (FocusManager::FMD_DOWN);
+ bResult = TRUE;
+ break;
+
+ // Go to previous page. No wrap around.
+ case KEY_PAGEUP:
+ GotoNextPage(-1);
+ bResult = TRUE;
+ break;
+
+ // Go to next page. No wrap around..
+ case KEY_PAGEDOWN:
+ GotoNextPage(+1);
+ bResult = TRUE;
+ break;
+
+ case KEY_DELETE:
+ case KEY_BACKSPACE:
+ {
+ if (mrController.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();
+
+ bResult = TRUE;
+ }
+ break;
+
+ case KEY_F10:
+ if (rEvent.GetKeyCode().IsShift())
+ ProcessKeyEvent(rEvent);
+ break;
+
+ default:
+ break;
+ }
+
+ if ( ! bResult)
+ bResult = SlideFunction::KeyInput (rEvent);
+
+ return bResult;
+}
+
+
+
+
+void SelectionFunction::Activate()
+{
+ FuPoor::Activate();
+}
+
+
+
+
+void SelectionFunction::Deactivate()
+{
+ FuPoor::Deactivate();
+}
+
+
+
+void SelectionFunction::ScrollStart (void)
+{
+}
+
+
+
+
+void SelectionFunction::ScrollEnd (void)
+{
+}
+
+
+
+
+void SelectionFunction::DoCut (void)
+{
+ if ( ! mrController.GetProperties()->IsUIReadOnly())
+ {
+ mrController.GetClipboard().DoCut();
+ }
+}
+
+
+
+
+void SelectionFunction::DoCopy (void)
+{
+ mrController.GetClipboard().DoCopy();
+}
+
+
+
+
+void SelectionFunction::DoPaste (void)
+{
+ if ( ! mrController.GetProperties()->IsUIReadOnly())
+ {
+ mrController.GetClipboard().DoPaste();
+ }
+}
+
+
+
+
+void SelectionFunction::Paint (const Rectangle&, ::sd::Window* )
+{
+}
+
+
+
+
+IMPL_LINK( SelectionFunction, DragSlideHdl, Timer*, EMPTYARG )
+{
+ StartDrag();
+ return 0;
+}
+
+
+
+
+void SelectionFunction::StartDrag (void)
+{
+ if (mbPageHit
+ && ! mrController.GetProperties()->IsUIReadOnly())
+ {
+ 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);
+ }
+ }
+}
+
+
+
+
+bool SelectionFunction::cancel (void)
+{
+ mrController.GetFocusManager().ToggleFocus();
+ return true;
+}
+
+
+
+
+void SelectionFunction::SelectHitPage (const model::SharedPageDescriptor& rpDescriptor)
+{
+ mrController.GetPageSelector().SelectPage(rpDescriptor);
+}
+
+
+
+
+void SelectionFunction::DeselectHitPage (const model::SharedPageDescriptor& rpDescriptor)
+{
+ mrController.GetPageSelector().DeselectPage(rpDescriptor);
+}
+
+
+
+
+void SelectionFunction::DeselectAllPages (void)
+{
+ mrController.GetPageSelector().DeselectAllPages();
+}
+
+
+
+
+void SelectionFunction::StartRectangleSelection (const Point& rMouseModelPosition)
+{
+ if (mrController.GetProperties()->IsShowSelection())
+ {
+ mrSlideSorter.GetView().GetOverlay().GetSelectionRectangleOverlay().Start(
+ rMouseModelPosition);
+ }
+}
+
+
+
+
+void SelectionFunction::UpdateRectangleSelection (const Point& rMouseModelPosition)
+{
+ if (mrController.GetProperties()->IsShowSelection())
+ {
+ mrSlideSorter.GetView().GetOverlay().GetSelectionRectangleOverlay().Update(
+ rMouseModelPosition);
+ }
+}
+
+
+
+
+void SelectionFunction::ProcessRectangleSelection (bool bToggleSelection)
+{
+ if ( ! mrController.GetProperties()->IsShowSelection())
+ return;
+
+ view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay());
+ if (rOverlay.GetSelectionRectangleOverlay().isVisible())
+ {
+ 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);
+ }
+ }
+ }
+}
+
+
+
+
+void SelectionFunction::PrepareMouseMotion (const Point& )
+{
+ if ( ! mrController.GetProperties()->IsUIReadOnly())
+ {
+ bFirstMouseMove = TRUE;
+ aDragTimer.Start();
+ }
+}
+
+
+
+
+void SelectionFunction::RangeSelect (const model::SharedPageDescriptor& rpDescriptor)
+{
+ PageSelector& rSelector (mrController.GetPageSelector());
+
+ 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::GotoNextPage (int nOffset)
+{
+ 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;
+ 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);
+ }
+ }
+}
+
+
+
+
+void SelectionFunction::ProcessMouseEvent (sal_uInt32 nEventType, const MouseEvent& rEvent)
+{
+ // #95491# remember button state for creation of own MouseEvents
+ SetMouseButtonCode (rEvent.GetButtons());
+
+ // 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))
+ {
+ OSL_TRACE ("can not handle event code %x", pEventDescriptor->mnEventCode);
+ }
+ EventPostprocessing(*pEventDescriptor);
+
+ if (nEventType == BUTTON_UP)
+ mbPageHit = false;
+}
+
+
+
+
+sal_uInt32 SelectionFunction::EncodeMouseEvent (
+ const EventDescriptor& rDescriptor,
+ const MouseEvent& rEvent) const
+{
+ // Initialize with the type of mouse event.
+ sal_uInt32 nEventCode (rDescriptor.mnEventCode & (BUTTON_DOWN | BUTTON_UP | MOUSE_MOTION));
+
+ // Detect the affected button.
+ switch (rEvent.GetButtons())
+ {
+ case MOUSE_LEFT: nEventCode |= LEFT_BUTTON; break;
+ case MOUSE_RIGHT: nEventCode |= RIGHT_BUTTON; break;
+ case MOUSE_MIDDLE: nEventCode |= MIDDLE_BUTTON; break;
+ }
+
+ // Detect the number of clicks.
+ switch (rEvent.GetClicks())
+ {
+ case 1: nEventCode |= SINGLE_CLICK; break;
+ 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;
+
+ return nEventCode;
+}
+
+
+
+
+void SelectionFunction::ProcessKeyEvent (const KeyEvent& rEvent)
+{
+ // 1. Compute some frequently used values relating to the event.
+ ::std::auto_ptr<EventDescriptor> pEventDescriptor (
+ new EventDescriptor(rEvent, mrSlideSorter));
+
+ // 2. Encode the event.
+ pEventDescriptor->mnEventCode = EncodeKeyEvent(*pEventDescriptor, rEvent);
+
+ // 3. Process the event.
+ EventPreprocessing(*pEventDescriptor);
+ if ( ! EventProcessing(*pEventDescriptor))
+ OSL_TRACE ("can not handle event code %x", pEventDescriptor->mnEventCode);
+ EventPostprocessing(*pEventDescriptor);
+}
+
+
+
+
+sal_uInt32 SelectionFunction::EncodeKeyEvent (
+ const EventDescriptor& rDescriptor,
+ const KeyEvent& rEvent) 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;
+
+ // 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 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;
+
+ return nEventCode;
+}
+
+
+
+void SelectionFunction::EventPreprocessing (const EventDescriptor& rDescriptor)
+{
+ // 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);
+}
+
+
+
+
+bool SelectionFunction::EventProcessing (const 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)
+
+
+ bool bResult (true);
+ bool bMakeSelectionVisible (true);
+
+ 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);
+
+ 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();
+ 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));
+
+ 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);
+ break;
+
+ // Was: Preview of the page transition effect.
+ case BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | OVER_FADE_INDICATOR:
+ // No action.
+ break;
+
+ // 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;
+ 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;
+ 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:
+ 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);
+ 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);
+ 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();
+ break;
+
+ // Rectangle selection.
+ case BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | NOT_OVER_PAGE | NO_MODIFIER:
+ DeselectAllPages();
+ StartRectangleSelection(rDescriptor.maMouseModelPosition);
+ 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);
+ break;
+
+ case ANY_MODIFIER(MOUSE_MOTION | LEFT_BUTTON | SINGLE_CLICK | NOT_OVER_PAGE):
+ 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;
+
+ case ANY_PAGE(BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK | RECTANGLE_VISIBLE | NO_MODIFIER):
+ ProcessRectangleSelection(false);
+ 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);
+ break;
+
+ default:
+ bResult = false;
+ break;
+ }
+ mrController.GetPageSelector().EnableBroadcasting(bMakeSelectionVisible);
+
+ return bResult;
+}
+
+
+
+
+void SelectionFunction::EventPostprocessing (const EventDescriptor& rDescriptor)
+{
+ if (rDescriptor.mnEventCode & BUTTON_UP)
+ {
+ 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);
+ }
+}
+
+
+
+
+void SelectionFunction::SetCurrentPage (const model::SharedPageDescriptor& rpDescriptor)
+{
+ PageSelector& rSelector (mrController.GetPageSelector());
+ rSelector.DeselectAllPages ();
+ rSelector.SelectPage(rpDescriptor);
+
+ mrController.GetCurrentSlideManager()->SwitchCurrentSlide(rpDescriptor);
+}
+
+
+
+
+void SelectionFunction::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);
+ mpViewShell->GetFrameView()->SetSelectedPage(
+ (rpDescriptor->GetPage()->GetPageNum()-1)/2);
+ }
+ if (mrSlideSorter.GetViewShellBase() != NULL)
+ framework::FrameworkHelper::Instance(*mrSlideSorter.GetViewShellBase())->RequestView(
+ framework::FrameworkHelper::msImpressViewURL,
+ framework::FrameworkHelper::msCenterPaneURL);
+ }
+}
+
+
+
+
+//===== EventDescriptor =======================================================
+
+SelectionFunction::EventDescriptor::EventDescriptor (
+ sal_uInt32 nEventType,
+ const MouseEvent& rEvent,
+ SlideSorter& rSlideSorter)
+ : maMousePosition(),
+ maMouseModelPosition(),
+ mpHitDescriptor(),
+ mpHitPage(),
+ mnEventCode(nEventType)
+{
+ ::Window* pWindow = rSlideSorter.GetActiveWindow();
+
+ maMousePosition = rEvent.GetPosPixel();
+ maMouseModelPosition = pWindow->PixelToLogic(maMousePosition);
+ model::SharedPageDescriptor pHitDescriptor (
+ rSlideSorter.GetController().GetPageAt(maMousePosition));
+ if (pHitDescriptor.get() != NULL)
+ {
+ mpHitDescriptor = pHitDescriptor;
+ mpHitPage = pHitDescriptor->GetPage();
+ }
+}
+
+
+
+
+
+SelectionFunction::EventDescriptor::EventDescriptor (
+ const KeyEvent&,
+ SlideSorter& rSlideSorter)
+ : maMousePosition(),
+ maMouseModelPosition(),
+ mpHitDescriptor(),
+ mpHitPage(),
+ mnEventCode(0)
+{
+ mpHitDescriptor = rSlideSorter.GetController().GetFocusManager().GetFocusedPageDescriptor();
+ model::SharedPageDescriptor pHitDescriptor (
+ rSlideSorter.GetController().GetFocusManager().GetFocusedPageDescriptor());
+ if (pHitDescriptor.get() != NULL)
+ {
+ mpHitPage = pHitDescriptor->GetPage();
+ mpHitDescriptor = pHitDescriptor;
+ }
+}
+
+
+
+
+
+//===== SubstitutionHandler ===================================================
+
+SelectionFunction::SubstitutionHandler::SubstitutionHandler (SlideSorter& rSlideSorter)
+ : mrSlideSorter(rSlideSorter),
+ mbHasBeenMoved(false)
+{
+}
+
+
+
+
+SelectionFunction::SubstitutionHandler::~SubstitutionHandler (void)
+{
+ if (mrSlideSorter.IsValid())
+ {
+ view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay());
+ rOverlay.GetSubstitutionOverlay().setVisible(false);
+ rOverlay.GetSubstitutionOverlay().Clear();
+ }
+}
+
+
+
+
+void SelectionFunction::SubstitutionHandler::Start (const Point& rMouseModelPosition)
+{
+ // No Drag-and-Drop for master pages.
+ if (mrSlideSorter.GetModel().GetEditMode() != EM_PAGE)
+ return;
+
+ if (mrSlideSorter.GetController().GetProperties()->IsUIReadOnly())
+ return;
+
+ view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay());
+
+ if ( ! rOverlay.GetSubstitutionOverlay().isVisible())
+ {
+ // 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;
+ }
+ else
+ UpdatePosition(rMouseModelPosition);
+}
+
+
+
+
+void SelectionFunction::SubstitutionHandler::UpdatePosition (const Point& rMouseModelPosition)
+{
+ if (mrSlideSorter.GetController().GetProperties()->IsUIReadOnly())
+ return;
+
+ 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 SelectionFunction::SubstitutionHandler::Process (void)
+{
+ if (mrSlideSorter.GetController().GetProperties()->IsUIReadOnly())
+ return;
+
+ 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);
+ }
+}
+
+
+
+
+void SelectionFunction::SubstitutionHandler::End (void)
+{
+ view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay());
+ rOverlay.GetSubstitutionOverlay().setVisible(false);
+ rOverlay.GetSubstitutionOverlay().Clear();
+ rOverlay.GetInsertionIndicatorOverlay().setVisible(false);
+}
+
+
+
+
+bool SelectionFunction::SubstitutionHandler::HasBeenMoved (void) const
+{
+ return mbHasBeenMoved;
+}
+
+
+
+
+bool SelectionFunction::SubstitutionHandler::IsSubstitutionInsertionNonTrivial (void) const
+{
+ bool bIsNonTrivial = false;
+
+ do
+ {
+ view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay());
+
+ // 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;
+ }
+ while (false);
+
+ return bIsNonTrivial;
+}
+
+} } } // end of namespace ::sd::slidesorter::controller
diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx
new file mode 100755
index 000000000000..f1b4cb6c39be
--- /dev/null
+++ b/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx
@@ -0,0 +1,662 @@
+/*************************************************************************
+ *
+ * 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/SlsSelectionManager.hxx"
+
+#include "SlideSorter.hxx"
+#include "SlsSelectionCommand.hxx"
+#include "controller/SlideSorterController.hxx"
+#include "controller/SlsAnimator.hxx"
+#include "controller/SlsCurrentSlideManager.hxx"
+#include "controller/SlsFocusManager.hxx"
+#include "controller/SlsProperties.hxx"
+#include "controller/SlsScrollBarManager.hxx"
+#include "controller/SlsSlotManager.hxx"
+#include "model/SlideSorterModel.hxx"
+#include "model/SlsPageEnumerationProvider.hxx"
+#include "model/SlsPageDescriptor.hxx"
+#include "view/SlideSorterView.hxx"
+#include "drawdoc.hxx"
+#include "Window.hxx"
+#include <svx/svxids.hrc>
+#include <com/sun/star/drawing/XMasterPagesSupplier.hpp>
+#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
+
+#include "res_bmp.hrc"
+#include "sdresid.hxx"
+#include "strings.hrc"
+#include "app.hrc"
+#include "glob.hrc"
+
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::uno;
+using namespace ::sd::slidesorter::model;
+using namespace ::sd::slidesorter::view;
+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;
+ };
+}
+
+
+
+
+SelectionManager::SelectionManager (SlideSorter& rSlideSorter)
+ : mrSlideSorter(rSlideSorter),
+ mrController(rSlideSorter.GetController()),
+ maSelectionBeforeSwitch(),
+ mbIsMakeSelectionVisiblePending(true)
+{
+}
+
+
+
+
+SelectionManager::~SelectionManager (void)
+{
+}
+
+
+
+
+void SelectionManager::DeleteSelectedPages (void)
+{
+ SlideSorterController::ModelChangeLock aLock (mrController);
+
+ // Hide focus.
+ bool bIsFocusShowing = mrController.GetFocusManager().IsFocusShowing();
+ if (bIsFocusShowing)
+ mrController.GetFocusManager().ToggleFocus();
+
+ // Store pointers to all selected page descriptors. This is necessary
+ // because the pages get deselected when the first one is deleted.
+ model::PageEnumeration aPageEnumeration (
+ PageEnumerationProvider::CreateSelectedPagesEnumeration(mrSlideSorter.GetModel()));
+ ::std::vector<SdPage*> aSelectedPages;
+ while (aPageEnumeration.HasMoreElements())
+ aSelectedPages.push_back (aPageEnumeration.GetNextElement()->GetPage());
+
+ // The actual deletion of the selected pages is done in one of two
+ // helper functions. They are specialized for normal respectively for
+ // master pages.
+ mrSlideSorter.GetView().BegUndo (SdResId(STR_UNDO_DELETEPAGES));
+ if (mrSlideSorter.GetModel().GetEditMode() == EM_PAGE)
+ DeleteSelectedNormalPages(aSelectedPages);
+ else
+ DeleteSelectedMasterPages(aSelectedPages);
+ mrSlideSorter.GetView().EndUndo ();
+
+ mrController.HandleModelChange();
+ aLock.Release();
+
+ // Show focus and move it to next valid location.
+ if (bIsFocusShowing)
+ mrController.GetFocusManager().ToggleFocus ();
+ mrController.GetFocusManager().MoveFocus (FocusManager::FMD_NONE);
+}
+
+
+
+
+void SelectionManager::DeleteSelectedNormalPages (const ::std::vector<SdPage*>& rSelectedPages)
+{
+ // Prepare the deletion via the UNO API.
+ OSL_ASSERT(mrSlideSorter.GetModel().GetEditMode() == EM_PAGE);
+
+ try
+ {
+ Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier( mrSlideSorter.GetModel().GetDocument()->getUnoModel(), UNO_QUERY_THROW );
+ Reference<drawing::XDrawPages> xPages( xDrawPagesSupplier->getDrawPages(), UNO_QUERY_THROW );
+
+ // Iterate over all pages that where seleted when this method was called
+ // and delete the draw page the notes page. The iteration is done in
+ // reverse order so that when one slide is not deleted (to avoid an
+ // empty document) the remaining slide is the first one.
+ ::std::vector<SdPage*>::const_reverse_iterator aI;
+ for (aI=rSelectedPages.rbegin(); aI!=rSelectedPages.rend(); aI++)
+ {
+ // Do not delete the last slide in the document.
+ if (xPages->getCount() <= 1)
+ break;
+
+ USHORT nPage = ((*aI)->GetPageNum()-1) / 2;
+
+ Reference< XDrawPage > xPage( xPages->getByIndex( nPage ), UNO_QUERY_THROW );
+ xPages->remove(xPage);
+ }
+ }
+ catch( Exception& )
+ {
+ DBG_ERROR("SelectionManager::DeleteSelectedNormalPages(), exception caught!");
+ }
+}
+
+
+
+
+void SelectionManager::DeleteSelectedMasterPages (const ::std::vector<SdPage*>& rSelectedPages)
+{
+ // Prepare the deletion via the UNO API.
+ OSL_ASSERT(mrSlideSorter.GetModel().GetEditMode() == EM_MASTERPAGE);
+
+ try
+ {
+ Reference<drawing::XMasterPagesSupplier> xDrawPagesSupplier( mrSlideSorter.GetModel().GetDocument()->getUnoModel(), UNO_QUERY_THROW );
+ Reference<drawing::XDrawPages> xPages( xDrawPagesSupplier->getMasterPages(), UNO_QUERY_THROW );
+
+ // Iterate over all pages that where seleted when this method was called
+ // and delete the draw page the notes page. The iteration is done in
+ // reverse order so that when one slide is not deleted (to avoid an
+ // empty document) the remaining slide is the first one.
+ ::std::vector<SdPage*>::const_reverse_iterator aI;
+ for (aI=rSelectedPages.rbegin(); aI!=rSelectedPages.rend(); aI++)
+ {
+ // Do not delete the last slide in the document.
+ if (xPages->getCount() <= 1)
+ break;
+
+ USHORT nPage = ((*aI)->GetPageNum()-1) / 2;
+
+ Reference< XDrawPage > xPage( xPages->getByIndex( nPage ), UNO_QUERY_THROW );
+ xPages->remove(xPage);
+ }
+ }
+ catch( Exception& )
+ {
+ DBG_ERROR("SelectionManager::DeleteSelectedMasterPages(), exception caught!");
+ }
+}
+
+
+
+
+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)
+ mbIsMakeSelectionVisiblePending = true;
+
+ ViewShell* pViewShell = mrSlideSorter.GetViewShell();
+ if (pViewShell != NULL)
+ {
+ pViewShell->Invalidate (SID_EXPAND_PAGE);
+ pViewShell->Invalidate (SID_SUMMARY_PAGE);
+ pViewShell->Invalidate(SID_SHOW_SLIDE);
+ pViewShell->Invalidate(SID_HIDE_SLIDE);
+ pViewShell->Invalidate(SID_DELETE_PAGE);
+ pViewShell->Invalidate(SID_DELETE_MASTER_PAGE);
+ pViewShell->Invalidate(SID_ASSIGN_LAYOUT);
+
+ // StatusBar
+ pViewShell->Invalidate (SID_STATUS_PAGE);
+ pViewShell->Invalidate (SID_STATUS_LAYOUT);
+
+ OSL_ASSERT(mrController.GetCurrentSlideManager());
+ SharedPageDescriptor pDescriptor(mrController.GetCurrentSlideManager()->GetCurrentSlide());
+ if (pDescriptor.get() != NULL)
+ pViewShell->UpdatePreview(pDescriptor->GetPage());
+
+ // Tell the slection change listeners that the selection has changed.
+ ::std::vector<Link>::iterator iListener (maSelectionChangeListeners.begin());
+ ::std::vector<Link>::iterator iEnd (maSelectionChangeListeners.end());
+ for (; iListener!=iEnd; ++iListener)
+ {
+ iListener->Call(NULL);
+ }
+
+ // Reset the insertion position: until set again it is calculated from
+ // the current selection.
+ mnInsertionPosition = -1;
+ }
+}
+
+
+
+
+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 (
+ maSelectionChangeListeners.begin(),
+ maSelectionChangeListeners.end(),
+ rListener) == maSelectionChangeListeners.end())
+ {
+ maSelectionChangeListeners.push_back (rListener);
+ }
+}
+
+
+
+
+void SelectionManager::RemoveSelectionChangeListener(const Link&rListener)
+{
+ maSelectionChangeListeners.erase (
+ ::std::find (
+ maSelectionChangeListeners.begin(),
+ maSelectionChangeListeners.end(),
+ 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);
+ if (nInsertionPosition < 0)
+ {
+ model::PageEnumeration aSelectedPages
+ (model::PageEnumerationProvider::CreateSelectedPagesEnumeration(
+ mrSlideSorter.GetModel()));
+ // Initialize (for the case of an empty selection) with the position
+ // at the end of the document.
+ nInsertionPosition = mrSlideSorter.GetModel().GetPageCount();
+ while (aSelectedPages.HasMoreElements())
+ {
+ 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;
+ }
+
+ }
+ return nInsertionPosition;
+}
+
+
+
+
+void SelectionManager::SetInsertionPosition (const sal_Int32 nInsertionPosition)
+{
+ if (nInsertionPosition < 0)
+ mnInsertionPosition = -1;
+ else if (nInsertionPosition > mrSlideSorter.GetModel().GetPageCount())
+ {
+ // Assert but then ignore invalid values.
+ OSL_ASSERT(nInsertionPosition<=mrSlideSorter.GetModel().GetPageCount());
+ return;
+ }
+ else
+ mnInsertionPosition = nInsertionPosition;
+}
+
+
+
+
+//===== VerticalVisibleAreaScroller ===========================================
+
+namespace {
+
+VerticalVisibleAreaScroller::VerticalVisibleAreaScroller (
+ SlideSorter& rSlideSorter,
+ const double nStart,
+ const double nEnd)
+ : mrSlideSorter(rSlideSorter),
+ mnStart(nStart),
+ mnEnd(nEnd)
+{
+}
+
+
+
+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/SlsSlideFunction.cxx b/sd/source/ui/slidesorter/controller/SlsSlideFunction.cxx
new file mode 100755
index 000000000000..7fe090ad5541
--- /dev/null
+++ b/sd/source/ui/slidesorter/controller/SlsSlideFunction.cxx
@@ -0,0 +1,80 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sd.hxx"
+
+#include "controller/SlsSlideFunction.hxx"
+
+#include "SlideSorter.hxx"
+#include "controller/SlideSorterController.hxx"
+#include "view/SlideSorterView.hxx"
+#include "model/SlideSorterModel.hxx"
+
+
+namespace sd { namespace slidesorter { namespace controller {
+
+TYPEINIT1(SlideFunction, FuPoor);
+
+
+SlideFunction::SlideFunction (
+ SlideSorter& rSlideSorter,
+ SfxRequest& rRequest)
+ : FuPoor (
+ rSlideSorter.GetViewShell(),
+ rSlideSorter.GetView().GetWindow(),
+ &rSlideSorter.GetView(),
+ rSlideSorter.GetModel().GetDocument(),
+ rRequest)
+{
+}
+
+void SlideFunction::ScrollStart (void)
+{
+}
+
+void SlideFunction::ScrollEnd (void)
+{
+}
+
+BOOL SlideFunction::MouseMove(const MouseEvent& )
+{
+ return FALSE;
+}
+
+BOOL SlideFunction::MouseButtonUp(const MouseEvent& )
+{
+ return FALSE;
+
+}
+
+BOOL SlideFunction::MouseButtonDown(const MouseEvent& )
+{
+ return FALSE;
+}
+
+} } } // end of namespace ::sd::slidesorter::controller
diff --git a/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx b/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx
new file mode 100755
index 000000000000..e571a765bdad
--- /dev/null
+++ b/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx
@@ -0,0 +1,1134 @@
+/*************************************************************************
+ *
+ * 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 <com/sun/star/presentation/XPresentation2.hpp>
+
+#include "controller/SlsSlotManager.hxx"
+#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/SlsSelectionManager.hxx"
+#include "SlsHideSlideFunction.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"
+#include "fuzoom.hxx"
+#include "fucushow.hxx"
+#include "fusldlg.hxx"
+#include "fuexpand.hxx"
+#include "fusumry.hxx"
+#include "fuscale.hxx"
+#include "slideshow.hxx"
+#include "app.hrc"
+#include "strings.hrc"
+#include "sdresid.hxx"
+#include "drawdoc.hxx"
+#include "DrawDocShell.hxx"
+#include "ViewShellBase.hxx"
+#include "ViewShellImplementation.hxx"
+#include "sdattr.hxx"
+#include "FrameView.hxx"
+#include "zoomlist.hxx"
+#include "sdpage.hxx"
+#include "sdxfer.hxx"
+#include "helpids.h"
+#include "glob.hrc"
+#include "unmodpg.hxx"
+#include "DrawViewShell.hxx"
+
+#include <sfx2/request.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/dispatch.hxx>
+#include <svx/svxids.hrc>
+#include <svx/zoomitem.hxx>
+#include <svx/svxdlg.hxx>
+#include <svx/dialogs.hrc>
+#include <vcl/msgbox.hxx>
+#include <svl/intitem.hxx>
+#include <svl/whiter.hxx>
+#include <svl/itempool.hxx>
+#include <svl/aeitem.hxx>
+#include <com/sun/star/presentation/FadeEffect.hpp>
+#include <com/sun/star/drawing/XMasterPagesSupplier.hpp>
+#include <com/sun/star/drawing/XDrawPages.hpp>
+#include <vcl/svapp.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::presentation;
+
+namespace sd { namespace slidesorter { namespace controller {
+
+SlotManager::SlotManager (SlideSorter& rSlideSorter)
+ : mrSlideSorter(rSlideSorter),
+ maCommandQueue()
+{
+}
+
+
+
+
+SlotManager::~SlotManager (void)
+{
+}
+
+
+
+
+void SlotManager::FuTemporary (SfxRequest& rRequest)
+{
+ SdDrawDocument* pDocument = mrSlideSorter.GetModel().GetDocument();
+
+ SlideSorterViewShell* pShell
+ = dynamic_cast<SlideSorterViewShell*>(mrSlideSorter.GetViewShell());
+ if (pShell == NULL)
+ return;
+
+ switch (rRequest.GetSlot())
+ {
+ case SID_PRESENTATION:
+ case SID_REHEARSE_TIMINGS:
+ ShowSlideShow (rRequest);
+ pShell->Cancel();
+ rRequest.Done();
+ break;
+
+ case SID_HIDE_SLIDE:
+ case SID_SHOW_SLIDE:
+ HideSlideFunction::Create(mrSlideSorter, rRequest);
+ break;
+
+ case SID_PAGES_PER_ROW:
+ if (rRequest.GetArgs() != NULL)
+ {
+ SFX_REQUEST_ARG(rRequest, pPagesPerRow, SfxUInt16Item,
+ SID_PAGES_PER_ROW, FALSE);
+ 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.
+ 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.
+ mrSlideSorter.GetController().Rearrange(true);
+ }
+ }
+ rRequest.Done();
+ break;
+
+ case SID_SELECTALL:
+ mrSlideSorter.GetController().GetPageSelector().SelectAllPages();
+ rRequest.Done();
+ break;
+
+ case SID_SLIDE_TRANSITIONS_PANEL:
+ {
+ // 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);
+ rRequest.Ignore ();
+ break;
+ }
+
+ case SID_PRESENTATION_DLG:
+ FuSlideShowDlg::Create (
+ pShell,
+ mrSlideSorter.GetView().GetWindow(),
+ &mrSlideSorter.GetView(),
+ pDocument,
+ rRequest);
+ break;
+
+ case SID_CUSTOMSHOW_DLG:
+ FuCustomShowDlg::Create (
+ pShell,
+ mrSlideSorter.GetView().GetWindow(),
+ &mrSlideSorter.GetView(),
+ pDocument,
+ rRequest);
+ break;
+
+ case SID_EXPAND_PAGE:
+ FuExpandPage::Create (
+ pShell,
+ mrSlideSorter.GetView().GetWindow(),
+ &mrSlideSorter.GetView(),
+ pDocument,
+ rRequest);
+ break;
+
+ case SID_SUMMARY_PAGE:
+ FuSummaryPage::Create (
+ pShell,
+ mrSlideSorter.GetView().GetWindow(),
+ &mrSlideSorter.GetView(),
+ pDocument,
+ rRequest);
+ break;
+
+ case SID_INSERTPAGE:
+ case SID_INSERT_MASTER_PAGE:
+ InsertSlide(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();
+ }
+
+ rRequest.Done();
+ break;
+
+ case SID_RENAMEPAGE:
+ case SID_RENAME_MASTER_PAGE:
+ RenameSlide ();
+ rRequest.Done ();
+ break;
+
+ case SID_ASSIGN_LAYOUT:
+ {
+ pShell->mpImpl->AssignLayout( rRequest, mrSlideSorter.GetModel().GetPageType() );
+ rRequest.Done ();
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+
+
+void SlotManager::FuPermanent (SfxRequest& rRequest)
+{
+ ViewShell* pShell = mrSlideSorter.GetViewShell();
+ if (pShell == NULL)
+ return;
+
+ if(pShell->GetCurrentFunction().is())
+ {
+ FunctionReference xEmpty;
+ if (pShell->GetOldFunction() == pShell->GetCurrentFunction())
+ pShell->SetOldFunction(xEmpty);
+
+ pShell->GetCurrentFunction()->Deactivate();
+ pShell->SetCurrentFunction(xEmpty);
+ }
+
+ switch(rRequest.GetSlot())
+ {
+ case SID_OBJECT_SELECT:
+ pShell->SetCurrentFunction( SelectionFunction::Create(mrSlideSorter, rRequest) );
+ rRequest.Done();
+ break;
+
+ default:
+ break;
+ }
+
+ if(pShell->GetOldFunction().is())
+ {
+ pShell->GetOldFunction()->Deactivate();
+ FunctionReference xEmpty;
+ pShell->SetOldFunction(xEmpty);
+ }
+
+ if(pShell->GetCurrentFunction().is())
+ {
+ pShell->GetCurrentFunction()->Activate();
+ pShell->SetOldFunction(pShell->GetCurrentFunction());
+ }
+
+ //! das ist nur bis das ENUM-Slots sind
+ // Invalidate( SID_OBJECT_SELECT );
+}
+
+void SlotManager::FuSupport (SfxRequest& rRequest)
+{
+ switch (rRequest.GetSlot())
+ {
+ case SID_STYLE_FAMILY:
+ if (rRequest.GetArgs() != NULL)
+ {
+ SdDrawDocument* pDocument
+ = mrSlideSorter.GetModel().GetDocument();
+ if (pDocument != NULL)
+ {
+ const SfxPoolItem& rItem (
+ rRequest.GetArgs()->Get(SID_STYLE_FAMILY));
+ pDocument->GetDocSh()->SetStyleFamily(
+ static_cast<const SfxUInt16Item&>(rItem).GetValue());
+ }
+ }
+ break;
+
+ case SID_PASTE:
+ {
+ SdTransferable* pTransferClip = SD_MOD()->pTransferClip;
+ if( pTransferClip )
+ {
+ SfxObjectShell* pTransferDocShell = pTransferClip->GetDocShell();
+
+ DrawDocShell* pDocShell = dynamic_cast<DrawDocShell*>(pTransferDocShell);
+ if (pDocShell && pDocShell->GetDoc()->GetPageCount() > 1)
+ {
+ mrSlideSorter.GetController().GetClipboard().HandleSlotCall(rRequest);
+ break;
+ }
+ }
+ ViewShellBase* pBase = mrSlideSorter.GetViewShellBase();
+ if (pBase != NULL)
+ {
+ ::boost::shared_ptr<DrawViewShell> pDrawViewShell (
+ ::boost::dynamic_pointer_cast<DrawViewShell>(pBase->GetMainViewShell()));
+ if (pDrawViewShell.get() != NULL)
+ pDrawViewShell->FuSupport(rRequest);
+ }
+ }
+ break;
+
+ case SID_CUT:
+ case SID_COPY:
+ case SID_DELETE:
+ mrSlideSorter.GetController().GetClipboard().HandleSlotCall(rRequest);
+ break;
+
+ case SID_DRAWINGMODE:
+ case SID_NOTESMODE:
+ case SID_HANDOUTMODE:
+ case SID_DIAMODE:
+ case SID_OUTLINEMODE:
+ {
+ ViewShellBase* pBase = mrSlideSorter.GetViewShellBase();
+ if (pBase != NULL)
+ {
+ framework::FrameworkHelper::Instance(*pBase)->HandleModeChangeSlot(
+ rRequest.GetSlot(), rRequest);
+ rRequest.Done();
+ }
+ break;
+ }
+
+ case SID_UNDO :
+ {
+ SlideSorterViewShell* pViewShell
+ = dynamic_cast<SlideSorterViewShell*>(mrSlideSorter.GetViewShell());
+ if (pViewShell != NULL)
+ pViewShell->ImpSidUndo (FALSE, rRequest);
+ break;
+ }
+
+ case SID_REDO :
+ {
+ SlideSorterViewShell* pViewShell
+ = dynamic_cast<SlideSorterViewShell*>(mrSlideSorter.GetViewShell());
+ if (pViewShell != NULL)
+ pViewShell->ImpSidRedo (FALSE, rRequest);
+ break;
+ }
+
+ default:
+ break;
+ }
+}
+
+
+
+
+void SlotManager::ExecCtrl (SfxRequest& rRequest)
+{
+ ViewShell* pViewShell = mrSlideSorter.GetViewShell();
+ USHORT nSlot = rRequest.GetSlot();
+ switch (nSlot)
+ {
+ case SID_RELOAD:
+ {
+ // Undo-Manager leeren
+ mrSlideSorter.GetModel().GetDocument()->GetDocSh()->ClearUndoBuffer();
+
+ // Normale Weiterleitung an ViewFrame zur Ausfuehrung
+ if (pViewShell != NULL)
+ pViewShell->GetViewFrame()->ExecuteSlot(rRequest);
+
+ // Muss sofort beendet werden
+ return;
+ }
+
+ case SID_OUTPUT_QUALITY_COLOR:
+ case SID_OUTPUT_QUALITY_GRAYSCALE:
+ case SID_OUTPUT_QUALITY_BLACKWHITE:
+ case SID_OUTPUT_QUALITY_CONTRAST:
+ {
+ // flush page cache
+ if (pViewShell != NULL)
+ pViewShell->ExecReq (rRequest);
+ break;
+ }
+
+ case SID_MAIL_SCROLLBODY_PAGEDOWN:
+ {
+ if (pViewShell != NULL)
+ pViewShell->ExecReq (rRequest);
+ break;
+ }
+
+ case SID_OPT_LOCALE_CHANGED:
+ {
+ mrSlideSorter.GetController().UpdateAllPages();
+ if (pViewShell != NULL)
+ pViewShell->UpdatePreview (pViewShell->GetActualPage());
+ rRequest.Done();
+ break;
+ }
+
+ case SID_SEARCH_DLG:
+ // We have to handle the SID_SEARCH_DLG slot explicitly because
+ // in some cases (when the slide sorter is displayed in the
+ // center pane) we want to disable the search dialog. Therefore
+ // we have to handle the execution of that slot as well.
+ // We try to do that by forwarding the request to the view frame
+ // of the view shell.
+ if (pViewShell != NULL)
+ pViewShell->GetViewFrame()->ExecuteSlot(rRequest);
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+
+
+void SlotManager::GetAttrState (SfxItemSet& rSet)
+{
+ // Iteratate over all items.
+ SfxWhichIter aIter (rSet);
+ USHORT nWhich = aIter.FirstWhich();
+ while (nWhich)
+ {
+ USHORT nSlotId (nWhich);
+ if (SfxItemPool::IsWhich(nWhich) && mrSlideSorter.GetViewShell()!=NULL)
+ nSlotId = mrSlideSorter.GetViewShell()->GetPool().GetSlotId(nWhich);
+ switch (nSlotId)
+ {
+ case SID_PAGES_PER_ROW:
+ rSet.Put (
+ SfxUInt16Item (
+ nSlotId,
+ (USHORT)mrSlideSorter.GetView().GetLayouter().GetColumnCount()
+ )
+ );
+ break;
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+void SlotManager::GetMenuState ( SfxItemSet& rSet)
+{
+ EditMode eEditMode = mrSlideSorter.GetModel().GetEditMode();
+ ViewShell* pShell = mrSlideSorter.GetViewShell();
+ DrawDocShell* pDocShell = mrSlideSorter.GetModel().GetDocument()->GetDocSh();
+
+ if (pShell!=NULL && pShell->GetCurrentFunction().is())
+ {
+ USHORT nSId = pShell->GetCurrentFunction()->GetSlotID();
+
+ rSet.Put( SfxBoolItem( nSId, TRUE ) );
+ }
+ rSet.Put( SfxBoolItem( SID_DRAWINGMODE, FALSE ) );
+ rSet.Put( SfxBoolItem( SID_DIAMODE, TRUE ) );
+ rSet.Put( SfxBoolItem( SID_OUTLINEMODE, FALSE ) );
+ rSet.Put( SfxBoolItem( SID_NOTESMODE, FALSE ) );
+ rSet.Put( SfxBoolItem( SID_HANDOUTMODE, FALSE ) );
+
+ // Vorlagenkatalog darf nicht aufgerufen werden
+ rSet.DisableItem(SID_STYLE_CATALOG);
+
+ if (pShell!=NULL && pShell->IsMainViewShell())
+ {
+ rSet.DisableItem(SID_SPELL_DIALOG);
+ rSet.DisableItem(SID_SEARCH_DLG);
+ }
+
+ if (SFX_ITEM_AVAILABLE == rSet.GetItemState(SID_EXPAND_PAGE))
+ {
+ bool bDisable = true;
+ if (eEditMode == EM_PAGE)
+ {
+ // At least one of the selected pages has to contain an outline
+ // presentation objects in order to enable the expand page menu
+ // entry.
+ model::PageEnumeration aSelectedPages (
+ model::PageEnumerationProvider::CreateSelectedPagesEnumeration(
+ mrSlideSorter.GetModel()));
+ while (aSelectedPages.HasMoreElements())
+ {
+ SdPage* pPage = aSelectedPages.GetNextElement()->GetPage();
+ SdrObject* pObj = pPage->GetPresObj(PRESOBJ_OUTLINE);
+ if (pObj!=NULL && !pObj->IsEmptyPresObj())
+ bDisable = false;
+ }
+ }
+
+ if (bDisable)
+ rSet.DisableItem (SID_EXPAND_PAGE);
+ }
+
+ if (SFX_ITEM_AVAILABLE == rSet.GetItemState(SID_SUMMARY_PAGE))
+ {
+ bool bDisable = true;
+ if (eEditMode == EM_PAGE)
+ {
+ // At least one of the selected pages has to contain a title
+ // presentation objects in order to enable the summary page menu
+ // entry.
+ model::PageEnumeration aSelectedPages (
+ model::PageEnumerationProvider::CreateSelectedPagesEnumeration(
+ mrSlideSorter.GetModel()));
+ while (aSelectedPages.HasMoreElements())
+ {
+ SdPage* pPage = aSelectedPages.GetNextElement()->GetPage();
+ SdrObject* pObj = pPage->GetPresObj(PRESOBJ_TITLE);
+
+ if (pObj!=NULL && !pObj->IsEmptyPresObj())
+ bDisable = false;
+ }
+ }
+ if (bDisable)
+ rSet.DisableItem (SID_SUMMARY_PAGE);
+ }
+
+ // Starten der Praesentation moeglich?
+ if( SFX_ITEM_AVAILABLE == rSet.GetItemState( SID_PRESENTATION ) ||
+ SFX_ITEM_AVAILABLE == rSet.GetItemState( SID_REHEARSE_TIMINGS ) )
+ {
+ BOOL bDisable = TRUE;
+ model::PageEnumeration aAllPages (
+ model::PageEnumerationProvider::CreateAllPagesEnumeration(mrSlideSorter.GetModel()));
+ while (aAllPages.HasMoreElements())
+ {
+ SdPage* pPage = aAllPages.GetNextElement()->GetPage();
+
+ if( !pPage->IsExcluded() )
+ bDisable = FALSE;
+ }
+ if( bDisable || pDocShell->IsPreview())
+ {
+ rSet.DisableItem( SID_PRESENTATION );
+ rSet.DisableItem( SID_REHEARSE_TIMINGS );
+ }
+ }
+
+
+ // Disable the rename slots when there are no or more than one slides/master
+ // pages selected.
+ if (rSet.GetItemState(SID_RENAMEPAGE) == SFX_ITEM_AVAILABLE
+ || rSet.GetItemState(SID_RENAME_MASTER_PAGE) == SFX_ITEM_AVAILABLE)
+ {
+ if (mrSlideSorter.GetController().GetPageSelector().GetSelectedPageCount() != 1)
+ {
+ rSet.DisableItem(SID_RENAMEPAGE);
+ rSet.DisableItem(SID_RENAME_MASTER_PAGE);
+ }
+ }
+
+ if (rSet.GetItemState(SID_HIDE_SLIDE) == SFX_ITEM_AVAILABLE
+ || rSet.GetItemState(SID_SHOW_SLIDE) == SFX_ITEM_AVAILABLE)
+ {
+ model::PageEnumeration aSelectedPages (
+ model::PageEnumerationProvider::CreateSelectedPagesEnumeration(
+ mrSlideSorter.GetModel()));
+ HideSlideFunction::ExclusionState eState (
+ HideSlideFunction::GetExclusionState(aSelectedPages));
+ switch (eState)
+ {
+ case HideSlideFunction::MIXED:
+ // Show both entries.
+ break;
+
+ case HideSlideFunction::EXCLUDED:
+ rSet.DisableItem(SID_HIDE_SLIDE);
+ break;
+
+ case HideSlideFunction::INCLUDED:
+ rSet.DisableItem(SID_SHOW_SLIDE);
+ break;
+
+ case HideSlideFunction::UNDEFINED:
+ rSet.DisableItem(SID_HIDE_SLIDE);
+ rSet.DisableItem(SID_SHOW_SLIDE);
+ break;
+ }
+ }
+
+ PageKind ePageKind = mrSlideSorter.GetModel().GetPageType();
+ if( (eEditMode == EM_MASTERPAGE) && (ePageKind != PK_HANDOUT ) )
+ {
+ rSet.DisableItem(SID_ASSIGN_LAYOUT);
+ }
+
+ if( (eEditMode == EM_MASTERPAGE) || (ePageKind==PK_NOTES) )
+ {
+ rSet.DisableItem(SID_INSERTPAGE);
+ }
+}
+
+
+
+
+void SlotManager::GetClipboardState ( SfxItemSet& rSet)
+{
+ SdTransferable* pTransferClip = SD_MOD()->pTransferClip;
+
+ if (rSet.GetItemState(SID_PASTE) == SFX_ITEM_AVAILABLE
+ || rSet.GetItemState(SID_PASTE_SPECIAL) == SFX_ITEM_AVAILABLE)
+ {
+ // Keine eigenen Clipboard-Daten?
+ if ( !pTransferClip || !pTransferClip->GetDocShell() )
+ {
+ rSet.DisableItem(SID_PASTE);
+ rSet.DisableItem(SID_PASTE_SPECIAL);
+ }
+ else
+ {
+ SfxObjectShell* pTransferDocShell = pTransferClip->GetDocShell();
+
+ if( !pTransferDocShell || ( (DrawDocShell*) pTransferDocShell)->GetDoc()->GetPageCount() <= 1 )
+ {
+ bool bIsPastingSupported (false);
+
+ // No or just one page. Check if there is anything that can be
+ // pasted via a DrawViewShell.
+ ViewShellBase* pBase = mrSlideSorter.GetViewShellBase();
+ if (pBase != NULL)
+ {
+ ::boost::shared_ptr<DrawViewShell> pDrawViewShell (
+ ::boost::dynamic_pointer_cast<DrawViewShell>(pBase->GetMainViewShell()));
+ if (pDrawViewShell.get() != NULL)
+ {
+ TransferableDataHelper aDataHelper (
+ TransferableDataHelper::CreateFromSystemClipboard(
+ pDrawViewShell->GetActiveWindow()));
+ if (aDataHelper.GetFormatCount() > 0)
+ bIsPastingSupported = true;
+ }
+ }
+
+ if ( ! bIsPastingSupported)
+ {
+ rSet.DisableItem(SID_PASTE);
+ rSet.DisableItem(SID_PASTE_SPECIAL);
+ }
+ }
+ }
+ }
+
+ // Cut, copy and paste of master pages is not yet implemented properly
+ if (rSet.GetItemState(SID_COPY) == SFX_ITEM_AVAILABLE
+ || rSet.GetItemState(SID_PASTE) == SFX_ITEM_AVAILABLE
+ || rSet.GetItemState(SID_PASTE_SPECIAL) == SFX_ITEM_AVAILABLE
+ || rSet.GetItemState(SID_CUT) == SFX_ITEM_AVAILABLE)
+ {
+ if (mrSlideSorter.GetModel().GetEditMode() == EM_MASTERPAGE)
+ {
+ if (rSet.GetItemState(SID_CUT) == SFX_ITEM_AVAILABLE)
+ rSet.DisableItem(SID_CUT);
+ if (rSet.GetItemState(SID_COPY) == SFX_ITEM_AVAILABLE)
+ rSet.DisableItem(SID_COPY);
+ if (rSet.GetItemState(SID_PASTE) == SFX_ITEM_AVAILABLE)
+ rSet.DisableItem(SID_PASTE);
+ if (rSet.GetItemState(SID_PASTE_SPECIAL) == SFX_ITEM_AVAILABLE)
+ rSet.DisableItem(SID_PASTE_SPECIAL);
+ }
+ }
+
+ // Cut, copy, and delete page are disabled when there is no selection.
+ if (rSet.GetItemState(SID_CUT) == SFX_ITEM_AVAILABLE
+ || rSet.GetItemState(SID_COPY) == SFX_ITEM_AVAILABLE
+ || rSet.GetItemState(SID_DELETE) == SFX_ITEM_AVAILABLE
+ || rSet.GetItemState(SID_DELETE_PAGE) == SFX_ITEM_AVAILABLE
+ || rSet.GetItemState(SID_DELETE_MASTER_PAGE) == SFX_ITEM_AVAILABLE)
+ {
+ model::PageEnumeration aSelectedPages (
+ model::PageEnumerationProvider::CreateSelectedPagesEnumeration(
+ mrSlideSorter.GetModel()));
+
+ // For copy to work we have to have at least one selected page.
+ if ( ! aSelectedPages.HasMoreElements())
+ rSet.DisableItem(SID_COPY);
+
+ bool bDisable = false;
+ // The operations that lead to the deletion of a page are valid if
+ // a) there is at least one selected page
+ // b) deleting the selected pages leaves at least one page in the
+ // document
+ // c) selected master pages must not be used by slides.
+
+ // Test a).
+ if ( ! aSelectedPages.HasMoreElements())
+ bDisable = true;
+ // Test b): Count the number of selected pages. It has to be less
+ // than the number of all pages.
+ else if (mrSlideSorter.GetController().GetPageSelector().GetSelectedPageCount()
+ >= mrSlideSorter.GetController().GetPageSelector().GetPageCount())
+ bDisable = true;
+ // Test c): Iterate over the selected pages and look for a master
+ // page that is used by at least one page.
+ else while (aSelectedPages.HasMoreElements())
+ {
+ SdPage* pPage = aSelectedPages.GetNextElement()->GetPage();
+ int nUseCount (mrSlideSorter.GetModel().GetDocument()
+ ->GetMasterPageUserCount(pPage));
+ if (nUseCount > 0)
+ {
+ bDisable = true;
+ break;
+ }
+ }
+
+ if (bDisable)
+ {
+ rSet.DisableItem(SID_CUT);
+ rSet.DisableItem(SID_DELETE_PAGE);
+ rSet.DisableItem(SID_DELETE_MASTER_PAGE);
+ }
+ }
+}
+
+
+
+
+void SlotManager::GetStatusBarState (SfxItemSet& rSet)
+{
+ // Seitenanzeige und Layout
+ /*
+ if( SFX_ITEM_AVAILABLE == rSet.GetItemState( SID_STATUS_PAGE ) ||
+ SFX_ITEM_AVAILABLE == rSet.GetItemState( SID_STATUS_LAYOUT ) )
+ */
+ SdPage* pPage = NULL;
+ SdPage* pFirstPage = NULL;
+ USHORT nFirstPage;
+ USHORT nSelectedPages = (USHORT)mrSlideSorter.GetController().GetPageSelector().GetSelectedPageCount();
+ String aPageStr;
+ String aLayoutStr;
+
+ if (nSelectedPages > 0)
+ aPageStr = String(SdResId(STR_SD_PAGE));
+
+ if (nSelectedPages == 1)
+ {
+ 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 ) );
+ }
+
+ rSet.Put( SfxStringItem( SID_STATUS_PAGE, aPageStr ) );
+ rSet.Put( SfxStringItem( SID_STATUS_LAYOUT, aLayoutStr ) );
+
+ if( SFX_ITEM_AVAILABLE == rSet.GetItemState( SID_ATTR_ZOOMSLIDER ) )
+ {
+ rSet.Put( SfxVoidItem( SID_ATTR_ZOOMSLIDER ) );
+ }
+}
+
+void SlotManager::ShowSlideShow( SfxRequest& rReq)
+{
+ Reference< XPresentation2 > xPresentation( mrSlideSorter.GetModel().GetDocument()->getPresentation() );
+ if( xPresentation.is() )
+ {
+ if( ( SID_REHEARSE_TIMINGS != rReq.GetSlot() ) )
+ xPresentation->start();
+ else
+ xPresentation->rehearseTimings();
+ }
+}
+
+void SlotManager::RenameSlide (void)
+{
+ PageKind ePageKind = mrSlideSorter.GetModel().GetPageType();
+ View* pDrView = &mrSlideSorter.GetView();
+
+ if (ePageKind==PK_STANDARD || ePageKind==PK_NOTES)
+ {
+ if ( pDrView->IsTextEdit() )
+ {
+ pDrView->SdrEndTextEdit();
+ }
+
+ SdPage* pSelectedPage = NULL;
+ model::PageEnumeration aSelectedPages (
+ model::PageEnumerationProvider::CreateSelectedPagesEnumeration(
+ mrSlideSorter.GetModel()));
+ if (aSelectedPages.HasMoreElements())
+ pSelectedPage = aSelectedPages.GetNextElement()->GetPage();
+ if (pSelectedPage != NULL)
+ {
+ String aTitle( SdResId( STR_TITLE_RENAMESLIDE ) );
+ String aDescr( SdResId( STR_DESC_RENAMESLIDE ) );
+ String aPageName = pSelectedPage->GetName();
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "Dialogdiet fail!");
+ AbstractSvxNameDialog* aNameDlg = pFact->CreateSvxNameDialog(
+ mrSlideSorter.GetActiveWindow(),
+ aPageName, aDescr);
+ DBG_ASSERT(aNameDlg, "Dialogdiet fail!");
+ aNameDlg->SetText( aTitle );
+ aNameDlg->SetCheckNameHdl( LINK( this, SlotManager, RenameSlideHdl ), true );
+ aNameDlg->SetEditHelpId( HID_SD_NAMEDIALOG_PAGE );
+
+ if( aNameDlg->Execute() == RET_OK )
+ {
+ String aNewName;
+ aNameDlg->GetName( aNewName );
+ if( ! aNewName.Equals( aPageName ) )
+ {
+#ifdef DBG_UTIL
+ bool bResult =
+#endif
+ RenameSlideFromDrawViewShell(
+ pSelectedPage->GetPageNum()/2, aNewName );
+ DBG_ASSERT( bResult, "Couldn't rename slide" );
+ }
+ }
+ delete aNameDlg;
+
+ // Tell the slide sorter about the name change (necessary for
+ // accessibility.)
+ mrSlideSorter.GetController().PageNameHasChanged(
+ (pSelectedPage->GetPageNum()-1)/2, aPageName);
+ }
+ }
+}
+
+IMPL_LINK(SlotManager, RenameSlideHdl, AbstractSvxNameDialog*, pDialog)
+{
+ if( ! pDialog )
+ return 0;
+
+ String aNewName;
+ pDialog->GetName( aNewName );
+
+ model::SharedPageDescriptor pDescriptor (
+ mrSlideSorter.GetController().GetCurrentSlideManager()->GetCurrentSlide());
+ SdPage* pCurrentPage = NULL;
+ if (pDescriptor.get() != NULL)
+ pCurrentPage = pDescriptor->GetPage();
+
+ return ( (pCurrentPage!=NULL && aNewName.Equals( pCurrentPage->GetName() ))
+ || (mrSlideSorter.GetViewShell()
+ && mrSlideSorter.GetViewShell()->GetDocSh()->IsNewPageNameValid( aNewName ) ));
+}
+
+bool SlotManager::RenameSlideFromDrawViewShell( USHORT nPageId, const String & rName )
+{
+ BOOL bOutDummy;
+ SdDrawDocument* pDocument = mrSlideSorter.GetModel().GetDocument();
+ if( pDocument->GetPageByName( rName, bOutDummy ) != SDRPAGE_NOTFOUND )
+ return false;
+
+ SdPage* pPageToRename = NULL;
+ PageKind ePageKind = mrSlideSorter.GetModel().GetPageType();
+
+ SfxUndoManager* pManager = pDocument->GetDocSh()->GetUndoManager();
+
+ if( mrSlideSorter.GetModel().GetEditMode() == EM_PAGE )
+ {
+ model::SharedPageDescriptor pDescriptor (
+ mrSlideSorter.GetController().GetCurrentSlideManager()->GetCurrentSlide());
+ if (pDescriptor.get() != NULL)
+ pPageToRename = pDescriptor->GetPage();
+
+ if (pPageToRename != NULL)
+ {
+ // Undo
+ SdPage* pUndoPage = pPageToRename;
+ SdrLayerAdmin & rLayerAdmin = pDocument->GetLayerAdmin();
+ BYTE nBackground = rLayerAdmin.GetLayerID( String( SdResId( STR_LAYER_BCKGRND )), FALSE );
+ BYTE nBgObj = rLayerAdmin.GetLayerID( String( SdResId( STR_LAYER_BCKGRNDOBJ )), FALSE );
+ SetOfByte aVisibleLayers = pPageToRename->TRG_GetMasterPageVisibleLayers();
+
+ // (#67720#)
+ ModifyPageUndoAction* pAction = new ModifyPageUndoAction(
+ pManager, pDocument, pUndoPage, rName, pUndoPage->GetAutoLayout(),
+ aVisibleLayers.IsSet( nBackground ),
+ aVisibleLayers.IsSet( nBgObj ));
+ pManager->AddUndoAction( pAction );
+
+ // rename
+ pPageToRename->SetName( rName );
+
+ if( ePageKind == PK_STANDARD )
+ {
+ // also rename notes-page
+ SdPage* pNotesPage = pDocument->GetSdPage( nPageId, PK_NOTES );
+ if (pNotesPage != NULL)
+ pNotesPage->SetName (rName);
+ }
+ }
+ }
+ else
+ {
+ // rename MasterPage -> rename LayoutTemplate
+ pPageToRename = pDocument->GetMasterSdPage( nPageId, ePageKind );
+ if (pPageToRename != NULL)
+ {
+ const String aOldLayoutName( pPageToRename->GetLayoutName() );
+ pManager->AddUndoAction( new RenameLayoutTemplateUndoAction( pDocument, aOldLayoutName, rName ) );
+ pDocument->RenameLayoutTemplate( aOldLayoutName, rName );
+ }
+ }
+
+ bool bSuccess = pPageToRename!=NULL && ( FALSE != rName.Equals( pPageToRename->GetName()));
+
+ if( bSuccess )
+ {
+ // user edited page names may be changed by the page so update control
+ // aTabControl.SetPageText( nPageId, rName );
+
+ // set document to modified state
+ pDocument->SetChanged( TRUE );
+
+ // inform navigator about change
+ SfxBoolItem aItem( SID_NAVIGATOR_INIT, TRUE );
+ if (mrSlideSorter.GetViewShell() != NULL)
+ mrSlideSorter.GetViewShell()->GetDispatcher()->Execute(
+ SID_NAVIGATOR_INIT, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD, &aItem, 0L );
+ }
+
+ return bSuccess;
+}
+
+
+
+
+/** Insert a slide. The insertion position depends on a) the selection and
+ b) the mouse position when there is no selection.
+
+ When there is a selection then insertion takes place after the last
+ slide of the selection. For this to work all but the last selected
+ slide are deselected first.
+
+ Otherwise, when there is no selection but the insertion marker is visible
+ the slide is inserted at that position. The slide before that marker is
+ selected first.
+
+ When both the selection and the insertion marker are not visible--can
+ that happen?--the new slide is inserted after the last slide.
+*/
+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)
+ {
+ // Deselect all but the last selected slide.
+ bool bLastSelectedSlideSeen (false);
+ for (int nIndex=rSelector.GetPageCount()-1; nIndex>=0; --nIndex)
+ {
+ if (rSelector.IsPageSelected(nIndex))
+ {
+ if (bLastSelectedSlideSeen)
+ rSelector.DeselectPage (nIndex);
+ else
+ {
+ nInsertionIndex = nIndex;
+ bLastSelectedSlideSeen = true;
+ }
+ }
+ }
+ }
+
+ // 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)
+ {
+ nInsertionIndex
+ = mrSlideSorter.GetController().GetSelectionManager()->GetInsertionPosition() - 1;
+ rSelector.SelectPage(nInsertionIndex);
+ }
+
+ // Select the last page when there is at least one page.
+ else if (rSelector.GetPageCount() > 0)
+ {
+ nInsertionIndex = rSelector.GetPageCount() - 1;
+ rSelector.SelectPage (nInsertionIndex);
+ }
+
+ // Hope for the best that CreateOrDuplicatePage() can cope with an empty
+ // selection.
+ else
+ {
+ nInsertionIndex = -1;
+ }
+
+ 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
+ {
+ // 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);
+ }
+ }
+ }
+ }
+
+ // 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)
+ {
+ nInsertionIndex++;
+ model::SharedPageDescriptor pDescriptor = mrSlideSorter.GetModel().GetPageDescriptor(nInsertionIndex);
+ if (pDescriptor.get() != NULL)
+ mrSlideSorter.GetController().GetCurrentSlideManager()->SwitchCurrentSlide(pDescriptor);
+ }
+ rSelector.EnableBroadcasting();
+ mrSlideSorter.GetView().LockRedraw(FALSE);
+}
+
+void SlotManager::ExecuteCommandAsynchronously (::std::auto_ptr<Command> pCommand)
+{
+ // Ownership of command is (implicitely) transferred to the queue.
+ maCommandQueue.push(pCommand.get());
+ pCommand.release();
+ Application::PostUserEvent(LINK(this,SlotManager,UserEventCallback));
+}
+
+IMPL_LINK(SlotManager, UserEventCallback, void*, EMPTYARG)
+{
+ if ( ! maCommandQueue.empty())
+ {
+ Command* pCommand = maCommandQueue.front();
+ maCommandQueue.pop();
+
+ if (pCommand != NULL)
+ {
+ // The queue ownes the command that has just been removed from
+ // it. Therefore it is deleted after it has been executed.
+ (*pCommand)();
+ delete pCommand;
+ }
+ }
+
+ return 1;
+}
+
+} } } // end of namespace ::sd::slidesorter::controller
+
diff --git a/sd/source/ui/slidesorter/controller/SlsTransferable.cxx b/sd/source/ui/slidesorter/controller/SlsTransferable.cxx
new file mode 100644
index 000000000000..20ddc937469c
--- /dev/null
+++ b/sd/source/ui/slidesorter/controller/SlsTransferable.cxx
@@ -0,0 +1,92 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sd.hxx"
+
+#include "SlsTransferable.hxx"
+
+#include "SlideSorterViewShell.hxx"
+#include "View.hxx"
+
+namespace sd { namespace slidesorter { namespace controller {
+
+Transferable::Transferable (
+ SdDrawDocument* pSrcDoc,
+ ::sd::View* pWorkView,
+ BOOL bInitOnGetData,
+ SlideSorterViewShell* pViewShell)
+ : SdTransferable (pSrcDoc, pWorkView, bInitOnGetData),
+ mpViewShell(pViewShell)
+{
+ if (mpViewShell != NULL)
+ StartListening(*mpViewShell);
+}
+
+
+
+Transferable::~Transferable (void)
+{
+ if (mpViewShell != NULL)
+ EndListening(*mpViewShell);
+}
+
+
+
+
+void Transferable::DragFinished (sal_Int8 nDropAction)
+{
+ if (mpViewShell != NULL)
+ mpViewShell->DragFinished(nDropAction);
+}
+
+
+
+
+void Transferable::Notify (SfxBroadcaster& rBroadcaster, const SfxHint& rHint)
+{
+ if (rHint.ISA(SfxSimpleHint) && mpViewShell!=NULL)
+ {
+ SfxSimpleHint& rSimpleHint (*PTR_CAST(SfxSimpleHint, &rHint));
+ if (rSimpleHint.GetId() == SFX_HINT_DYING)
+ {
+ // This hint may come either from the ViewShell or from the
+ // document (registered by SdTransferable). We do not know
+ // which but both are sufficient to disconnect from the
+ // ViewShell.
+ EndListening(*mpViewShell);
+ mpViewShell = NULL;
+ }
+ }
+
+ SdTransferable::Notify(rBroadcaster, rHint);
+}
+
+
+
+
+} } } // end of namespace ::sd::slidesorter::controller
diff --git a/sd/source/ui/slidesorter/controller/SlsTransferable.hxx b/sd/source/ui/slidesorter/controller/SlsTransferable.hxx
new file mode 100644
index 000000000000..f527fd4768b9
--- /dev/null
+++ b/sd/source/ui/slidesorter/controller/SlsTransferable.hxx
@@ -0,0 +1,70 @@
+/*************************************************************************
+ *
+ * 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/makefile.mk b/sd/source/ui/slidesorter/controller/makefile.mk
new file mode 100644
index 000000000000..8ab63ddf776c
--- /dev/null
+++ b/sd/source/ui/slidesorter/controller/makefile.mk
@@ -0,0 +1,71 @@
+#*************************************************************************
+#
+# 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.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..$/..
+
+PROJECTPCH=sd
+PROJECTPCHSOURCE=$(PRJ)$/util$/sd
+PRJNAME=sd
+TARGET=slscontroller
+ENABLE_EXCEPTIONS=TRUE
+AUTOSEG=true
+PRJINC=..$/..
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/SlideSorterController.obj \
+ $(SLO)$/SlsAnimator.obj \
+ $(SLO)$/SlsClipboard.obj \
+ $(SLO)$/SlsCurrentSlideManager.obj \
+ $(SLO)$/SlsFocusManager.obj \
+ $(SLO)$/SlsListener.obj \
+ $(SLO)$/SlsPageObjectFactory.obj \
+ $(SLO)$/SlsPageSelector.obj \
+ $(SLO)$/SlsProperties.obj \
+ $(SLO)$/SlsScrollBarManager.obj \
+ $(SLO)$/SlsSelectionCommand.obj \
+ $(SLO)$/SlsSelectionManager.obj \
+ $(SLO)$/SlsSlotManager.obj \
+ $(SLO)$/SlsTransferable.obj \
+ \
+ $(SLO)$/SlsHideSlideFunction.obj \
+ $(SLO)$/SlsSelectionFunction.obj \
+ $(SLO)$/SlsSlideFunction.obj
+
+EXCEPTIONSFILES= \
+ $(SLO)$/SlideSorterController.obj
+
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE : target.mk
+