diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
commit | ed5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch) | |
tree | 7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /sd/source/ui/slidesorter/controller/SlsPageSelector.cxx | |
parent | Initial commit. (diff) | |
download | libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.tar.xz libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.zip |
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sd/source/ui/slidesorter/controller/SlsPageSelector.cxx')
-rw-r--r-- | sd/source/ui/slidesorter/controller/SlsPageSelector.cxx | 386 |
1 files changed, 386 insertions, 0 deletions
diff --git a/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx b/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx new file mode 100644 index 000000000..21affcf2f --- /dev/null +++ b/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx @@ -0,0 +1,386 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#include <controller/SlsPageSelector.hxx> + +#include <SlideSorter.hxx> +#include <controller/SlideSorterController.hxx> +#include <controller/SlsSelectionManager.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 <osl/diagnose.h> + +#include <sdpage.hxx> +#include <tools/debug.hxx> +#include <memory> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::sd::slidesorter::model; +using namespace ::sd::slidesorter::view; + +namespace sd::slidesorter::controller { + +PageSelector::PageSelector (SlideSorter& rSlideSorter) + : mrModel(rSlideSorter.GetModel()), + mrSlideSorter(rSlideSorter), + mrController(mrSlideSorter.GetController()), + mnSelectedPageCount(0), + mnBroadcastDisableLevel(0), + mbSelectionChangeBroadcastPending(false), + mnUpdateLockCount(0), + mbIsUpdateCurrentPagePending(true) +{ + CountSelectedPages (); +} + +void PageSelector::SelectAllPages() +{ + VisibleAreaManager::TemporaryDisabler aDisabler (mrSlideSorter); + PageSelector::UpdateLock aLock (*this); + + int nPageCount = mrModel.GetPageCount(); + for (int nPageIndex=0; nPageIndex<nPageCount; nPageIndex++) + SelectPage(nPageIndex); +} + +void PageSelector::DeselectAllPages() +{ + 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() +{ + 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() +{ + 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) + SelectPage(pDescriptor); +} + +void PageSelector::SelectPage (const SdPage* pPage) +{ + const sal_Int32 nPageIndex (mrModel.GetIndex(pPage)); + SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nPageIndex)); + if (pDescriptor && pDescriptor->GetPage()==pPage) + SelectPage(pDescriptor); +} + +void PageSelector::SelectPage (const SharedPageDescriptor& rpDescriptor) +{ + if (!rpDescriptor + || !mrSlideSorter.GetView().SetState(rpDescriptor, PageDescriptor::ST_Selected, true)) + return; + + ++mnSelectedPageCount; + mrSlideSorter.GetController().GetVisibleAreaManager().RequestVisible(rpDescriptor,true); + mrSlideSorter.GetView().RequestRepaint(rpDescriptor); + + mpMostRecentlySelectedPage = rpDescriptor; + if (mpSelectionAnchor == nullptr) + mpSelectionAnchor = rpDescriptor; + + if (mnBroadcastDisableLevel > 0) + mbSelectionChangeBroadcastPending = true; + else + mrController.GetSelectionManager()->SelectionHasChanged(); + UpdateCurrentPage(); + + CheckConsistency(); +} + +void PageSelector::DeselectPage (int nPageIndex) +{ + model::SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nPageIndex)); + if (pDescriptor) + DeselectPage(pDescriptor); +} + +void PageSelector::DeselectPage ( + const SharedPageDescriptor& rpDescriptor, + const bool bUpdateCurrentPage) +{ + if (!rpDescriptor + || !mrSlideSorter.GetView().SetState(rpDescriptor, PageDescriptor::ST_Selected, false)) + return; + + --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() 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) + { + // #i120020# 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) + return pDescriptor->HasState(PageDescriptor::ST_Selected); + else + return false; +} + +bool PageSelector::IsPageVisible(int nPageIndex) +{ + SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nPageIndex)); + if (pDescriptor) + return pDescriptor->HasState(PageDescriptor::ST_Visible); + else + return false; +} + +int PageSelector::GetPageCount() const +{ + return mrModel.GetPageCount(); +} + +void PageSelector::CountSelectedPages() +{ + mnSelectedPageCount = 0; + model::PageEnumeration aSelectedPages ( + model::PageEnumerationProvider::CreateSelectedPagesEnumeration(mrModel)); + while (aSelectedPages.HasMoreElements()) + { + mnSelectedPageCount++; + aSelectedPages.GetNextElement(); + } +} + +void PageSelector::EnableBroadcasting() +{ + if (mnBroadcastDisableLevel > 0) + mnBroadcastDisableLevel --; + if (mnBroadcastDisableLevel==0 && mbSelectionChangeBroadcastPending) + { + mrController.GetSelectionManager()->SelectionHasChanged(); + mbSelectionChangeBroadcastPending = false; + } +} + +void PageSelector::DisableBroadcasting() +{ + mnBroadcastDisableLevel ++; +} + +std::shared_ptr<PageSelector::PageSelection> PageSelector::GetPageSelection() const +{ + auto pSelection = std::make_shared<PageSelection>(); + pSelection->reserve(GetSelectedPageCount()); + + int nPageCount = GetPageCount(); + for (int nIndex=0; nIndex<nPageCount; nIndex++) + { + SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nIndex)); + if (pDescriptor && pDescriptor->HasState(PageDescriptor::ST_Selected)) + pSelection->push_back(pDescriptor->GetPage()); + } + + return pSelection; +} + +void PageSelector::SetPageSelection ( + const std::shared_ptr<PageSelection>& rpSelection, + const bool bUpdateCurrentPage) +{ + for (const auto& rpPage : *rpSelection) + SelectPage(rpPage); + 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) + return; + + // 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. + std::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 const & rSlideSorter) + : mpSelector(&rSlideSorter.GetController().GetPageSelector()) +{ + ++mpSelector->mnUpdateLockCount; +} + +PageSelector::UpdateLock::UpdateLock (PageSelector& rSelector) + : mpSelector(&rSelector) +{ + ++mpSelector->mnUpdateLockCount; +} + +PageSelector::UpdateLock::~UpdateLock() +{ + Release(); +} + +void PageSelector::UpdateLock::Release() +{ + if (mpSelector != nullptr) + { + --mpSelector->mnUpdateLockCount; + OSL_ASSERT(mpSelector->mnUpdateLockCount >= 0); + if (mpSelector->mnUpdateLockCount == 0) + mpSelector->UpdateCurrentPage(true); + + mpSelector = nullptr; + } +} + +//===== PageSelector::BroadcastLock ============================================== + +PageSelector::BroadcastLock::BroadcastLock (SlideSorter const & rSlideSorter) + : mrSelector(rSlideSorter.GetController().GetPageSelector()) +{ + mrSelector.DisableBroadcasting(); +} + +PageSelector::BroadcastLock::BroadcastLock (PageSelector& rSelector) + : mrSelector(rSelector) +{ + mrSelector.DisableBroadcasting(); +} + +PageSelector::BroadcastLock::~BroadcastLock() +{ + mrSelector.EnableBroadcasting(); +} + +} // end of namespace ::sd::slidesorter::controller + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |