| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| #include "precompiled_sd.hxx" |
| |
| #include "controller/SlsPageSelector.hxx" |
| |
| #include "SlideSorter.hxx" |
| #include "SlideSorterViewShell.hxx" |
| #include "controller/SlideSorterController.hxx" |
| #include "controller/SlsSelectionManager.hxx" |
| #include "controller/SlsAnimator.hxx" |
| #include "controller/SlsCurrentSlideManager.hxx" |
| #include "controller/SlsVisibleAreaManager.hxx" |
| #include "model/SlsPageDescriptor.hxx" |
| #include "model/SlsPageEnumerationProvider.hxx" |
| #include "model/SlideSorterModel.hxx" |
| #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> |
| #include <boost/bind.hpp> |
| |
| |
| using namespace ::com::sun::star; |
| using namespace ::com::sun::star::uno; |
| using namespace ::sd::slidesorter::model; |
| using namespace ::sd::slidesorter::view; |
| |
| |
| namespace sd { namespace slidesorter { namespace controller { |
| |
| PageSelector::PageSelector (SlideSorter& rSlideSorter) |
| : mrModel(rSlideSorter.GetModel()), |
| mrSlideSorter(rSlideSorter), |
| mrController(mrSlideSorter.GetController()), |
| mnSelectedPageCount(0), |
| mnBroadcastDisableLevel(0), |
| mbSelectionChangeBroadcastPending(false), |
| mpMostRecentlySelectedPage(), |
| mpSelectionAnchor(), |
| mpCurrentPage(), |
| mnUpdateLockCount(0), |
| mbIsUpdateCurrentPagePending(true) |
| { |
| CountSelectedPages (); |
| } |
| |
| |
| |
| |
| void PageSelector::SelectAllPages (void) |
| { |
| VisibleAreaManager::TemporaryDisabler aDisabler (mrSlideSorter); |
| PageSelector::UpdateLock aLock (*this); |
| |
| int nPageCount = mrModel.GetPageCount(); |
| for (int nPageIndex=0; nPageIndex<nPageCount; nPageIndex++) |
| SelectPage(nPageIndex); |
| } |
| |
| |
| |
| |
| void PageSelector::DeselectAllPages (void) |
| { |
| VisibleAreaManager::TemporaryDisabler aDisabler (mrSlideSorter); |
| PageSelector::UpdateLock aLock (*this); |
| |
| int nPageCount = mrModel.GetPageCount(); |
| for (int nPageIndex=0; nPageIndex<nPageCount; nPageIndex++) |
| DeselectPage(nPageIndex); |
| |
| DBG_ASSERT (mnSelectedPageCount==0, |
| "PageSelector::DeselectAllPages: the selected pages counter is not 0"); |
| mnSelectedPageCount = 0; |
| mpSelectionAnchor.reset(); |
| } |
| |
| |
| |
| |
| void PageSelector::GetCoreSelection (void) |
| { |
| PageSelector::UpdateLock aLock (*this); |
| |
| bool bSelectionHasChanged (true); |
| mnSelectedPageCount = 0; |
| model::PageEnumeration aAllPages ( |
| model::PageEnumerationProvider::CreateAllPagesEnumeration(mrModel)); |
| while (aAllPages.HasMoreElements()) |
| { |
| model::SharedPageDescriptor pDescriptor (aAllPages.GetNextElement()); |
| if (pDescriptor->GetCoreSelection()) |
| { |
| mrSlideSorter.GetController().GetVisibleAreaManager().RequestVisible(pDescriptor); |
| mrSlideSorter.GetView().RequestRepaint(pDescriptor); |
| bSelectionHasChanged = true; |
| } |
| |
| if (pDescriptor->HasState(PageDescriptor::ST_Selected)) |
| mnSelectedPageCount++; |
| } |
| |
| if (bSelectionHasChanged) |
| { |
| if (mnBroadcastDisableLevel > 0) |
| mbSelectionChangeBroadcastPending = true; |
| else |
| mrController.GetSelectionManager()->SelectionHasChanged(); |
| } |
| } |
| |
| |
| |
| |
| void PageSelector::SetCoreSelection (void) |
| { |
| model::PageEnumeration aAllPages ( |
| model::PageEnumerationProvider::CreateAllPagesEnumeration(mrModel)); |
| while (aAllPages.HasMoreElements()) |
| { |
| model::SharedPageDescriptor pDescriptor (aAllPages.GetNextElement()); |
| pDescriptor->SetCoreSelection(); |
| } |
| } |
| |
| |
| |
| |
| void PageSelector::SelectPage (int nPageIndex) |
| { |
| SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nPageIndex)); |
| if (pDescriptor.get() != NULL) |
| SelectPage(pDescriptor); |
| } |
| |
| |
| |
| |
| void PageSelector::SelectPage (const SdPage* pPage) |
| { |
| const sal_Int32 nPageIndex (mrModel.GetIndex(pPage)); |
| SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nPageIndex)); |
| if (pDescriptor.get()!=NULL && pDescriptor->GetPage()==pPage) |
| SelectPage(pDescriptor); |
| } |
| |
| |
| |
| |
| void PageSelector::SelectPage (const SharedPageDescriptor& rpDescriptor) |
| { |
| if (rpDescriptor.get()!=NULL |
| && mrSlideSorter.GetView().SetState(rpDescriptor, PageDescriptor::ST_Selected, true)) |
| { |
| ++mnSelectedPageCount; |
| mrSlideSorter.GetController().GetVisibleAreaManager().RequestVisible(rpDescriptor,true); |
| mrSlideSorter.GetView().RequestRepaint(rpDescriptor); |
| |
| mpMostRecentlySelectedPage = rpDescriptor; |
| if( !bool(mpSelectionAnchor) ) |
| mpSelectionAnchor = rpDescriptor; |
| |
| if (mnBroadcastDisableLevel > 0) |
| mbSelectionChangeBroadcastPending = true; |
| else |
| mrController.GetSelectionManager()->SelectionHasChanged(); |
| UpdateCurrentPage(); |
| |
| CheckConsistency(); |
| } |
| } |
| |
| |
| |
| |
| void PageSelector::DeselectPage ( |
| int nPageIndex, |
| const bool bUpdateCurrentPage) |
| { |
| model::SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nPageIndex)); |
| if (pDescriptor.get() != NULL) |
| DeselectPage(pDescriptor, bUpdateCurrentPage); |
| } |
| |
| |
| |
| |
| void PageSelector::DeselectPage ( |
| const SdPage* pPage, |
| const bool bUpdateCurrentPage) |
| { |
| const sal_Int32 nPageIndex (mrModel.GetIndex(pPage)); |
| SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nPageIndex)); |
| if (pDescriptor.get()!=NULL && pDescriptor->GetPage()==pPage) |
| DeselectPage(pDescriptor, bUpdateCurrentPage); |
| } |
| |
| |
| |
| |
| void PageSelector::DeselectPage ( |
| const SharedPageDescriptor& rpDescriptor, |
| const bool bUpdateCurrentPage) |
| { |
| if (rpDescriptor.get()!=NULL |
| && mrSlideSorter.GetView().SetState(rpDescriptor, PageDescriptor::ST_Selected, false)) |
| { |
| --mnSelectedPageCount; |
| mrSlideSorter.GetController().GetVisibleAreaManager().RequestVisible(rpDescriptor); |
| mrSlideSorter.GetView().RequestRepaint(rpDescriptor); |
| if (mpMostRecentlySelectedPage == rpDescriptor) |
| mpMostRecentlySelectedPage.reset(); |
| if (mnBroadcastDisableLevel > 0) |
| mbSelectionChangeBroadcastPending = true; |
| else |
| mrController.GetSelectionManager()->SelectionHasChanged(); |
| if (bUpdateCurrentPage) |
| UpdateCurrentPage(); |
| |
| CheckConsistency(); |
| } |
| } |
| |
| |
| |
| |
| void PageSelector::CheckConsistency (void) const |
| { |
| int nSelectionCount (0); |
| for (int nPageIndex=0,nPageCount=mrModel.GetPageCount(); nPageIndex<nPageCount; nPageIndex++) |
| { |
| SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nPageIndex)); |
| assert(pDescriptor); |
| if (pDescriptor->HasState(PageDescriptor::ST_Selected)) |
| ++nSelectionCount; |
| } |
| if (nSelectionCount!=mnSelectedPageCount) |
| { |
| // #120020# The former call to assert(..) internally calls |
| // SlideSorterModel::GetPageDescriptor which will crash in this situation |
| // (only in non-pro code). All what is wanted there is to assert it (the |
| // error is already detected), so do this directly. |
| OSL_ENSURE(false, "PageSelector: Consistency error (!)"); |
| } |
| } |
| |
| |
| |
| |
| bool PageSelector::IsPageSelected (int nPageIndex) |
| { |
| SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nPageIndex)); |
| if (pDescriptor.get() != NULL) |
| return pDescriptor->HasState(PageDescriptor::ST_Selected); |
| else |
| return false; |
| } |
| |
| |
| |
| |
| int PageSelector::GetPageCount (void) const |
| { |
| return mrModel.GetPageCount(); |
| } |
| |
| |
| |
| |
| int PageSelector::GetSelectedPageCount (void) const |
| { |
| return mnSelectedPageCount; |
| } |
| |
| |
| |
| |
| 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 (void) |
| { |
| if (mnBroadcastDisableLevel > 0) |
| mnBroadcastDisableLevel --; |
| if (mnBroadcastDisableLevel==0 && mbSelectionChangeBroadcastPending) |
| { |
| mrController.GetSelectionManager()->SelectionHasChanged(); |
| 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->HasState(PageDescriptor::ST_Selected)) |
| pSelection->push_back(pDescriptor->GetPage()); |
| } |
| |
| return pSelection; |
| } |
| |
| |
| |
| |
| void PageSelector::SetPageSelection ( |
| const ::boost::shared_ptr<PageSelection>& rpSelection, |
| const bool bUpdateCurrentPage) |
| { |
| PageSelection::const_iterator iPage; |
| for (iPage=rpSelection->begin(); iPage!=rpSelection->end(); ++iPage) |
| SelectPage(*iPage); |
| if (bUpdateCurrentPage) |
| UpdateCurrentPage(); |
| } |
| |
| |
| |
| |
| void PageSelector::UpdateCurrentPage (const bool bUpdateOnlyWhenPending) |
| { |
| if (mnUpdateLockCount > 0) |
| { |
| mbIsUpdateCurrentPagePending = true; |
| return; |
| } |
| |
| if ( ! mbIsUpdateCurrentPagePending && bUpdateOnlyWhenPending) |
| return; |
| |
| mbIsUpdateCurrentPagePending = false; |
| |
| // Make the first selected page the current page. |
| SharedPageDescriptor pCurrentPageDescriptor; |
| const sal_Int32 nPageCount (GetPageCount()); |
| for (sal_Int32 nIndex=0; nIndex<nPageCount; ++nIndex) |
| { |
| SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nIndex)); |
| if ( ! pDescriptor) |
| continue; |
| if (pDescriptor->HasState(PageDescriptor::ST_Selected)) |
| { |
| pCurrentPageDescriptor = pDescriptor; |
| break; |
| } |
| } |
| if ( ! pCurrentPageDescriptor && nPageCount>0) |
| { |
| // No page is selected. Make the first slide the current page. |
| pCurrentPageDescriptor = mrModel.GetPageDescriptor(0); |
| } |
| |
| if (pCurrentPageDescriptor) |
| { |
| // Switching the current slide normally sets also the |
| // selection to just the new current slide. To prevent that, |
| // we store (and at the end of this scope restore) the current |
| // selection. |
| ::boost::shared_ptr<PageSelection> pSelection (GetPageSelection()); |
| |
| mrController.GetCurrentSlideManager()->SwitchCurrentSlide(pCurrentPageDescriptor); |
| |
| // Restore the selection and prevent a recursive call to |
| // UpdateCurrentPage(). |
| SetPageSelection(pSelection, false); |
| } |
| } |
| |
| |
| |
| |
| //===== PageSelector::UpdateLock ============================================== |
| |
| PageSelector::UpdateLock::UpdateLock (SlideSorter& rSlideSorter) |
| : mpSelector(&rSlideSorter.GetController().GetPageSelector()) |
| { |
| ++mpSelector->mnUpdateLockCount; |
| } |
| |
| |
| |
| |
| PageSelector::UpdateLock::UpdateLock (PageSelector& rSelector) |
| : mpSelector(&rSelector) |
| { |
| ++mpSelector->mnUpdateLockCount; |
| } |
| |
| |
| |
| |
| PageSelector::UpdateLock::~UpdateLock (void) |
| { |
| Release(); |
| } |
| |
| void PageSelector::UpdateLock::Release (void) |
| { |
| if (mpSelector != NULL) |
| { |
| --mpSelector->mnUpdateLockCount; |
| OSL_ASSERT(mpSelector->mnUpdateLockCount >= 0); |
| if (mpSelector->mnUpdateLockCount == 0) |
| mpSelector->UpdateCurrentPage(true); |
| |
| mpSelector = NULL; |
| } |
| } |
| |
| |
| |
| |
| //===== PageSelector::BroadcastLock ============================================== |
| |
| PageSelector::BroadcastLock::BroadcastLock (SlideSorter& rSlideSorter) |
| : mrSelector(rSlideSorter.GetController().GetPageSelector()) |
| { |
| mrSelector.DisableBroadcasting(); |
| } |
| |
| |
| |
| |
| PageSelector::BroadcastLock::BroadcastLock (PageSelector& rSelector) |
| : mrSelector(rSelector) |
| { |
| mrSelector.DisableBroadcasting(); |
| } |
| |
| |
| |
| |
| PageSelector::BroadcastLock::~BroadcastLock (void) |
| { |
| mrSelector.EnableBroadcasting(); |
| } |
| |
| } } } // end of namespace ::sd::slidesorter::controller |