diff options
Diffstat (limited to 'sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx')
-rwxr-xr-x | sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx | 411 |
1 files changed, 54 insertions, 357 deletions
diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx index f1b4cb6c39be..d9062a4ef2b1 100755 --- a/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx @@ -30,18 +30,22 @@ #include "controller/SlsSelectionManager.hxx" #include "SlideSorter.hxx" -#include "SlsSelectionCommand.hxx" +#include "SlsCommand.hxx" #include "controller/SlideSorterController.hxx" #include "controller/SlsAnimator.hxx" +#include "controller/SlsAnimationFunction.hxx" #include "controller/SlsCurrentSlideManager.hxx" #include "controller/SlsFocusManager.hxx" +#include "controller/SlsPageSelector.hxx" #include "controller/SlsProperties.hxx" #include "controller/SlsScrollBarManager.hxx" #include "controller/SlsSlotManager.hxx" +#include "controller/SlsSelectionObserver.hxx" #include "model/SlideSorterModel.hxx" #include "model/SlsPageEnumerationProvider.hxx" #include "model/SlsPageDescriptor.hxx" #include "view/SlideSorterView.hxx" +#include "view/SlsLayouter.hxx" #include "drawdoc.hxx" #include "Window.hxx" #include <svx/svxids.hrc> @@ -65,39 +69,24 @@ using namespace ::sd::slidesorter::controller; namespace sd { namespace slidesorter { namespace controller { -namespace { - class VerticalVisibleAreaScroller - { - public: - VerticalVisibleAreaScroller (SlideSorter& rSlideSorter, - const double nStart, const double nEnd); - void operator() (const double nValue); - private: - SlideSorter& mrSlideSorter; - double mnStart; - double mnEnd; - }; - class HorizontalVisibleAreaScroller - { - public: - HorizontalVisibleAreaScroller (SlideSorter& rSlideSorter, - const double nStart, const double nEnd); - void operator() (const double nValue); - private: - SlideSorter& mrSlideSorter; - double mnStart; - double mnEnd; - }; -} - +class SelectionManager::PageInsertionListener + : public SfxListener +{ +public: +}; SelectionManager::SelectionManager (SlideSorter& rSlideSorter) : mrSlideSorter(rSlideSorter), mrController(rSlideSorter.GetController()), maSelectionBeforeSwitch(), - mbIsMakeSelectionVisiblePending(true) + mbIsMakeSelectionVisiblePending(true), + mnInsertionPosition(-1), + mnAnimationId(Animator::NotAnAnimationId), + maRequestedTopLeft(), + mpPageInsertionListener(), + mpSelectionObserver(new SelectionObserver(rSlideSorter)) { } @@ -106,14 +95,20 @@ SelectionManager::SelectionManager (SlideSorter& rSlideSorter) SelectionManager::~SelectionManager (void) { + if (mnAnimationId != Animator::NotAnAnimationId) + mrController.GetAnimator()->RemoveAnimation(mnAnimationId); } -void SelectionManager::DeleteSelectedPages (void) +void SelectionManager::DeleteSelectedPages (const bool bSelectFollowingPage) { + // Create some locks to prevent updates of the model, view, selection + // state while modifying any of them. SlideSorterController::ModelChangeLock aLock (mrController); + SlideSorterView::DrawLock aDrawLock (mrSlideSorter); + PageSelector::UpdateLock aSelectionLock (mrSlideSorter); // Hide focus. bool bIsFocusShowing = mrController.GetFocusManager().IsFocusShowing(); @@ -125,8 +120,23 @@ void SelectionManager::DeleteSelectedPages (void) model::PageEnumeration aPageEnumeration ( PageEnumerationProvider::CreateSelectedPagesEnumeration(mrSlideSorter.GetModel())); ::std::vector<SdPage*> aSelectedPages; + sal_Int32 nNewCurrentSlide (-1); while (aPageEnumeration.HasMoreElements()) - aSelectedPages.push_back (aPageEnumeration.GetNextElement()->GetPage()); + { + SharedPageDescriptor pDescriptor (aPageEnumeration.GetNextElement()); + aSelectedPages.push_back(pDescriptor->GetPage()); + if (bSelectFollowingPage || nNewCurrentSlide<0) + nNewCurrentSlide = pDescriptor->GetPageIndex(); + } + if (aSelectedPages.empty()) + return; + + // Determine the slide to select (and thereby make the current slide) + // after the deletion. + if (bSelectFollowingPage) + nNewCurrentSlide -= aSelectedPages.size() - 1; + else + --nNewCurrentSlide; // The actual deletion of the selected pages is done in one of two // helper functions. They are specialized for normal respectively for @@ -143,8 +153,16 @@ void SelectionManager::DeleteSelectedPages (void) // Show focus and move it to next valid location. if (bIsFocusShowing) - mrController.GetFocusManager().ToggleFocus (); - mrController.GetFocusManager().MoveFocus (FocusManager::FMD_NONE); + mrController.GetFocusManager().ToggleFocus(); + + // Set the new current slide. + if (nNewCurrentSlide < 0) + nNewCurrentSlide = 0; + else if (nNewCurrentSlide >= mrSlideSorter.GetModel().GetPageCount()) + nNewCurrentSlide = mrSlideSorter.GetModel().GetPageCount()-1; + mrController.GetPageSelector().CountSelectedPages(); + mrController.GetPageSelector().SelectPage(nNewCurrentSlide); + mrController.GetFocusManager().SetFocusedPage(nNewCurrentSlide); } @@ -171,7 +189,7 @@ void SelectionManager::DeleteSelectedNormalPages (const ::std::vector<SdPage*>& if (xPages->getCount() <= 1) break; - USHORT nPage = ((*aI)->GetPageNum()-1) / 2; + const USHORT nPage (model::FromCoreIndex((*aI)->GetPageNum())); Reference< XDrawPage > xPage( xPages->getByIndex( nPage ), UNO_QUERY_THROW ); xPages->remove(xPage); @@ -207,7 +225,7 @@ void SelectionManager::DeleteSelectedMasterPages (const ::std::vector<SdPage*>& if (xPages->getCount() <= 1) break; - USHORT nPage = ((*aI)->GetPageNum()-1) / 2; + const USHORT nPage (model::FromCoreIndex((*aI)->GetPageNum())); Reference< XDrawPage > xPage( xPages->getByIndex( nPage ), UNO_QUERY_THROW ); xPages->remove(xPage); @@ -222,60 +240,6 @@ void SelectionManager::DeleteSelectedMasterPages (const ::std::vector<SdPage*>& -bool SelectionManager::MoveSelectedPages (const sal_Int32 nTargetPageIndex) -{ - bool bMoved (false); - PageSelector& rSelector (mrController.GetPageSelector()); - - mrSlideSorter.GetView().LockRedraw (TRUE); - SlideSorterController::ModelChangeLock aLock (mrController); - - // Transfer selection of the slide sorter to the document. - mrSlideSorter.GetModel().SynchronizeDocumentSelection (); - - // Detect how many pages lie between document start and insertion - // position. - sal_Int32 nPageCountBeforeTarget (0); - ::boost::shared_ptr<PageSelector::PageSelection> pSelection (rSelector.GetPageSelection()); - PageSelector::PageSelection::const_iterator iSelectedPage (pSelection->begin()); - PageSelector::PageSelection::const_iterator iSelectionEnd (pSelection->end()); - for ( ; iSelectedPage!=iSelectionEnd; ++iSelectedPage) - { - if (*iSelectedPage==NULL) - continue; - if (((*iSelectedPage)->GetPageNum()-1)/2 <= nTargetPageIndex) - ++nPageCountBeforeTarget; - else - break; - } - - // Prepare to select the moved pages. - SelectionCommand* pCommand = new SelectionCommand( - rSelector,mrController.GetCurrentSlideManager(),mrSlideSorter.GetModel()); - sal_Int32 nSelectedPageCount (rSelector.GetSelectedPageCount()); - for (sal_Int32 nOffset=0; nOffset<nSelectedPageCount; ++nOffset) - pCommand->AddSlide(sal::static_int_cast<USHORT>( - nTargetPageIndex + nOffset - nPageCountBeforeTarget + 1)); - - // At the moment we can not move master pages. - if (nTargetPageIndex>=0) - { - if (mrSlideSorter.GetModel().GetEditMode() == EM_PAGE) - bMoved = mrSlideSorter.GetModel().GetDocument()->MovePages( - sal::static_int_cast<sal_uInt16>(nTargetPageIndex)); - } - if (bMoved) - mrController.GetSlotManager()->ExecuteCommandAsynchronously( - ::std::auto_ptr<controller::Command>(pCommand)); - - mrSlideSorter.GetView().LockRedraw (FALSE); - - return bMoved; -} - - - - void SelectionManager::SelectionHasChanged (const bool bMakeSelectionVisible) { if (bMakeSelectionVisible) @@ -318,166 +282,6 @@ void SelectionManager::SelectionHasChanged (const bool bMakeSelectionVisible) -bool SelectionManager::IsMakeSelectionVisiblePending (void) const -{ - return mbIsMakeSelectionVisiblePending; -} - - - - -/** We have to distinguish three cases: 1) the selection is empty, 2) the - selection fits completely into the visible area, 3) it does not. - 1) The visible area is not modified. - 2) When the selection fits completely into the visible area we have to - decide how to align it. It is done by scrolling it there and thus when - we scoll up the (towards the end of the document) the bottom of the - selection is aligned with the bottom of the window. When we scroll - down (towards the beginning of the document) the top of the selection is - aligned with the top of the window. - 3) We have to decide what part of the selection to make visible. Here - we use the eSelectionHint and concentrate on either the first, the last, - or the most recently selected page. We then again apply the algorithm - of a). - -*/ -Size SelectionManager::MakeSelectionVisible (const SelectionHint eSelectionHint) -{ - ::sd::Window* pWindow = mrSlideSorter.GetActiveWindow(); - if (pWindow == NULL) - return Size(0,0); - - mbIsMakeSelectionVisiblePending = false; - - // Determine the descriptors of the first and last selected page and the - // bounding box that encloses their page objects. - model::SharedPageDescriptor pFirst; - model::SharedPageDescriptor pLast; - Rectangle aSelectionBox; - model::PageEnumeration aSelectedPages ( - PageEnumerationProvider::CreateSelectedPagesEnumeration(mrSlideSorter.GetModel())); - while (aSelectedPages.HasMoreElements()) - { - model::SharedPageDescriptor pDescriptor (aSelectedPages.GetNextElement()); - - if (pFirst.get() == NULL) - pFirst = pDescriptor; - pLast = pDescriptor; - - aSelectionBox.Union (mrSlideSorter.GetView().GetPageBoundingBox ( - pDescriptor, - view::SlideSorterView::CS_MODEL, - view::SlideSorterView::BBT_INFO)); - } - - if (pFirst != NULL) - { - // Determine scroll direction and the position in model coordinates - // that will be aligned with the top/left or bottom/right window - // border. - if (DoesSelectionExceedVisibleArea(aSelectionBox)) - { - // We can show only a part of the selection. - aSelectionBox = ResolveLargeSelection(pFirst,pLast, eSelectionHint); - } - - return MakeRectangleVisible(aSelectionBox); - } - - return Size(0,0); -} - - - - -Size SelectionManager::MakeRectangleVisible (const Rectangle& rBox) -{ - ::sd::Window* pWindow = mrSlideSorter.GetActiveWindow(); - if (pWindow == NULL) - return Size(0,0); - - Rectangle aVisibleArea (pWindow->PixelToLogic( - Rectangle( - Point(0,0), - pWindow->GetOutputSizePixel()))); - - if (mrSlideSorter.GetView().GetOrientation() == SlideSorterView::VERTICAL) - { - // Scroll the visible area to make aSelectionBox visible. - sal_Int32 nNewTop (aVisibleArea.Top()); - if (mrSlideSorter.GetController().GetProperties()->IsCenterSelection()) - { - nNewTop = rBox.Top() - (aVisibleArea.GetHeight() - rBox.GetHeight()) / 2; - } - else - { - if (rBox.Top() < aVisibleArea.Top()) - nNewTop = rBox.Top(); - else if (rBox.Bottom() > aVisibleArea.Bottom()) - nNewTop = rBox.Bottom() - aVisibleArea.GetHeight(); - // otherwise we do not modify the visible area. - } - - // Make some corrections of the new visible area. - Rectangle aModelArea (mrSlideSorter.GetView().GetModelArea()); - if (nNewTop + aVisibleArea.GetHeight() > aModelArea.Bottom()) - nNewTop = aModelArea.GetHeight() - aVisibleArea.GetHeight(); - if (nNewTop < aModelArea.Top()) - nNewTop = aModelArea.Top(); - - // Scroll. - if (nNewTop != aVisibleArea.Top()) - { - mrController.GetAnimator()->AddAnimation( - VerticalVisibleAreaScroller(mrSlideSorter, aVisibleArea.Top(), nNewTop), - mrSlideSorter.GetController().GetProperties()->IsSmoothSelectionScrolling() ? - 1000 : 0 - ); - } - - return Size(0,aVisibleArea.Top() - nNewTop); - } - else - { - // Scroll the visible area to make aSelectionBox visible. - sal_Int32 nNewLeft (aVisibleArea.Left()); - if (mrSlideSorter.GetController().GetProperties()->IsCenterSelection()) - { - nNewLeft = rBox.Left() - (aVisibleArea.GetWidth() - rBox.GetWidth()) / 2; - } - else - { - if (rBox.Left() < aVisibleArea.Left()) - nNewLeft = rBox.Left(); - else if (rBox.Right() > aVisibleArea.Right()) - nNewLeft = rBox.Right() - aVisibleArea.GetWidth(); - // otherwise we do not modify the visible area. - } - - // Make some corrections of the new visible area. - Rectangle aModelArea (mrSlideSorter.GetView().GetModelArea()); - if (nNewLeft + aVisibleArea.GetWidth() > aModelArea.Right()) - nNewLeft = aModelArea.GetWidth() - aVisibleArea.GetWidth(); - if (nNewLeft < aModelArea.Left()) - nNewLeft = aModelArea.Left(); - - // Scroll. - if (nNewLeft != aVisibleArea.Left()) - { - mrController.GetAnimator()->AddAnimation( - HorizontalVisibleAreaScroller(mrSlideSorter, aVisibleArea.Left(), nNewLeft), - mrSlideSorter.GetController().GetProperties()->IsSmoothSelectionScrolling() ? - 1000 : 0 - ); - } - - return Size(aVisibleArea.Left() - nNewLeft, 0); - } -} - - - - void SelectionManager::AddSelectionChangeListener (const Link& rListener) { if (::std::find ( @@ -504,70 +308,6 @@ void SelectionManager::RemoveSelectionChangeListener(const Link&rListener) -bool SelectionManager::DoesSelectionExceedVisibleArea (const Rectangle& rSelectionBox) const -{ - ::sd::Window* pWindow = mrSlideSorter.GetActiveWindow(); - if (pWindow == NULL) - return true; - - Rectangle aVisibleArea (pWindow->PixelToLogic( - Rectangle( - Point(0,0), - pWindow->GetOutputSizePixel()))); - if (mrSlideSorter.GetView().GetOrientation() == SlideSorterView::VERTICAL) - return rSelectionBox.GetHeight() > aVisibleArea.GetHeight(); - else - return rSelectionBox.GetWidth() > aVisibleArea.GetWidth(); -} - - - - -Rectangle SelectionManager::ResolveLargeSelection ( - const SharedPageDescriptor& rpFirst, - const SharedPageDescriptor& rpLast, - const SelectionHint eSelectionHint) -{ - OSL_ASSERT(rpFirst.get()!=NULL); - OSL_ASSERT(rpLast.get()!=NULL); - - // The mose recently selected page is assumed to lie in the range - // between first and last selected page. Therefore the bounding box is - // not modified. - model::SharedPageDescriptor pRecent ( - mrController.GetPageSelector().GetMostRecentlySelectedPage()); - - // Get the bounding box of the page object on which to concentrate. - model::SharedPageDescriptor pRepresentative; - switch (eSelectionHint) - { - case SH_FIRST: - pRepresentative = rpFirst; - break; - - case SH_LAST: - pRepresentative = rpLast; - break; - - case SH_RECENT: - default: - if (pRecent.get() == NULL) - pRepresentative = rpFirst; - else - pRepresentative = pRecent; - break; - } - OSL_ASSERT(pRepresentative.get() != NULL); - - return mrSlideSorter.GetView().GetPageBoundingBox ( - pRepresentative, - view::SlideSorterView::CS_MODEL, - view::SlideSorterView::BBT_INFO); -} - - - - sal_Int32 SelectionManager::GetInsertionPosition (void) const { sal_Int32 nInsertionPosition (mnInsertionPosition); @@ -584,7 +324,7 @@ sal_Int32 SelectionManager::GetInsertionPosition (void) const const sal_Int32 nPosition (aSelectedPages.GetNextElement()->GetPage()->GetPageNum()); // Convert *2+1 index to straight index (n-1)/2 after the page // (+1). - nInsertionPosition = (nPosition-1)/2 + 1; + nInsertionPosition = model::FromCoreIndex(nPosition) + 1; } } @@ -611,52 +351,9 @@ void SelectionManager::SetInsertionPosition (const sal_Int32 nInsertionPosition) -//===== VerticalVisibleAreaScroller =========================================== - -namespace { - -VerticalVisibleAreaScroller::VerticalVisibleAreaScroller ( - SlideSorter& rSlideSorter, - const double nStart, - const double nEnd) - : mrSlideSorter(rSlideSorter), - mnStart(nStart), - mnEnd(nEnd) +::boost::shared_ptr<SelectionObserver> SelectionManager::GetSelectionObserver (void) const { + return mpSelectionObserver; } - - -void VerticalVisibleAreaScroller::operator() (const double nValue) -{ - mrSlideSorter.GetView().InvalidatePageObjectVisibilities(); - mrSlideSorter.GetController().GetScrollBarManager().SetTop( - int(mnStart * (1.0 - nValue) + mnEnd * nValue)); -} - - - - -HorizontalVisibleAreaScroller::HorizontalVisibleAreaScroller ( - SlideSorter& rSlideSorter, - const double nStart, - const double nEnd) - : mrSlideSorter(rSlideSorter), - mnStart(nStart), - mnEnd(nEnd) -{ -} - - - - -void HorizontalVisibleAreaScroller::operator() (const double nValue) -{ - mrSlideSorter.GetView().InvalidatePageObjectVisibilities(); - mrSlideSorter.GetController().GetScrollBarManager().SetLeft( - int(mnStart * (1.0 - nValue) + mnEnd * nValue)); -} - -} // end of anonymous namespace - } } } // end of namespace ::sd::slidesorter |