bump product version to 6.3.0.0.beta1
[LibreOffice.git] / sd / source / ui / slidesorter / controller / SlsPageSelector.cxx
blob327acbb0e16ee9bff251fc6f3e5346e279125dfd
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <controller/SlsPageSelector.hxx>
22 #include <SlideSorter.hxx>
23 #include <SlideSorterViewShell.hxx>
24 #include <controller/SlideSorterController.hxx>
25 #include <controller/SlsSelectionManager.hxx>
26 #include <controller/SlsAnimator.hxx>
27 #include <controller/SlsCurrentSlideManager.hxx>
28 #include <controller/SlsVisibleAreaManager.hxx>
29 #include <model/SlsPageDescriptor.hxx>
30 #include <model/SlsPageEnumerationProvider.hxx>
31 #include <model/SlideSorterModel.hxx>
32 #include <view/SlideSorterView.hxx>
34 #include <sdpage.hxx>
35 #include <ViewShell.hxx>
36 #include <DrawViewShell.hxx>
37 #include <ViewShellBase.hxx>
38 #include <com/sun/star/drawing/XDrawView.hpp>
39 #include <com/sun/star/beans/XPropertySet.hpp>
40 #include <tools/debug.hxx>
41 #include <memory>
43 using namespace ::com::sun::star;
44 using namespace ::com::sun::star::uno;
45 using namespace ::sd::slidesorter::model;
46 using namespace ::sd::slidesorter::view;
48 namespace sd { namespace slidesorter { namespace controller {
50 PageSelector::PageSelector (SlideSorter& rSlideSorter)
51 : mrModel(rSlideSorter.GetModel()),
52 mrSlideSorter(rSlideSorter),
53 mrController(mrSlideSorter.GetController()),
54 mnSelectedPageCount(0),
55 mnBroadcastDisableLevel(0),
56 mbSelectionChangeBroadcastPending(false),
57 mpMostRecentlySelectedPage(),
58 mpSelectionAnchor(),
59 mnUpdateLockCount(0),
60 mbIsUpdateCurrentPagePending(true)
62 CountSelectedPages ();
65 void PageSelector::SelectAllPages()
67 VisibleAreaManager::TemporaryDisabler aDisabler (mrSlideSorter);
68 PageSelector::UpdateLock aLock (*this);
70 int nPageCount = mrModel.GetPageCount();
71 for (int nPageIndex=0; nPageIndex<nPageCount; nPageIndex++)
72 SelectPage(nPageIndex);
75 void PageSelector::DeselectAllPages()
77 VisibleAreaManager::TemporaryDisabler aDisabler (mrSlideSorter);
78 PageSelector::UpdateLock aLock (*this);
80 int nPageCount = mrModel.GetPageCount();
81 for (int nPageIndex=0; nPageIndex<nPageCount; nPageIndex++)
82 DeselectPage(nPageIndex);
84 DBG_ASSERT (mnSelectedPageCount==0,
85 "PageSelector::DeselectAllPages: the selected pages counter is not 0");
86 mnSelectedPageCount = 0;
87 mpSelectionAnchor.reset();
90 void PageSelector::GetCoreSelection()
92 PageSelector::UpdateLock aLock (*this);
94 bool bSelectionHasChanged (true);
95 mnSelectedPageCount = 0;
96 model::PageEnumeration aAllPages (
97 model::PageEnumerationProvider::CreateAllPagesEnumeration(mrModel));
98 while (aAllPages.HasMoreElements())
100 model::SharedPageDescriptor pDescriptor (aAllPages.GetNextElement());
101 if (pDescriptor->GetCoreSelection())
103 mrSlideSorter.GetController().GetVisibleAreaManager().RequestVisible(pDescriptor);
104 mrSlideSorter.GetView().RequestRepaint(pDescriptor);
105 bSelectionHasChanged = true;
108 if (pDescriptor->HasState(PageDescriptor::ST_Selected))
109 mnSelectedPageCount++;
112 if (bSelectionHasChanged)
114 if (mnBroadcastDisableLevel > 0)
115 mbSelectionChangeBroadcastPending = true;
116 else
117 mrController.GetSelectionManager()->SelectionHasChanged();
121 void PageSelector::SetCoreSelection()
123 model::PageEnumeration aAllPages (
124 model::PageEnumerationProvider::CreateAllPagesEnumeration(mrModel));
125 while (aAllPages.HasMoreElements())
127 model::SharedPageDescriptor pDescriptor (aAllPages.GetNextElement());
128 pDescriptor->SetCoreSelection();
132 void PageSelector::SelectPage (int nPageIndex)
134 SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nPageIndex));
135 if (pDescriptor.get() != nullptr)
136 SelectPage(pDescriptor);
139 void PageSelector::SelectPage (const SdPage* pPage)
141 const sal_Int32 nPageIndex (mrModel.GetIndex(pPage));
142 SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nPageIndex));
143 if (pDescriptor.get()!=nullptr && pDescriptor->GetPage()==pPage)
144 SelectPage(pDescriptor);
147 void PageSelector::SelectPage (const SharedPageDescriptor& rpDescriptor)
149 if (rpDescriptor.get()==nullptr
150 || !mrSlideSorter.GetView().SetState(rpDescriptor, PageDescriptor::ST_Selected, true))
151 return;
153 ++mnSelectedPageCount;
154 mrSlideSorter.GetController().GetVisibleAreaManager().RequestVisible(rpDescriptor,true);
155 mrSlideSorter.GetView().RequestRepaint(rpDescriptor);
157 mpMostRecentlySelectedPage = rpDescriptor;
158 if (mpSelectionAnchor == nullptr)
159 mpSelectionAnchor = rpDescriptor;
161 if (mnBroadcastDisableLevel > 0)
162 mbSelectionChangeBroadcastPending = true;
163 else
164 mrController.GetSelectionManager()->SelectionHasChanged();
165 UpdateCurrentPage();
167 CheckConsistency();
170 void PageSelector::DeselectPage (int nPageIndex)
172 model::SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nPageIndex));
173 if (pDescriptor.get() != nullptr)
174 DeselectPage(pDescriptor);
177 void PageSelector::DeselectPage (
178 const SharedPageDescriptor& rpDescriptor,
179 const bool bUpdateCurrentPage)
181 if (rpDescriptor.get()==nullptr
182 || !mrSlideSorter.GetView().SetState(rpDescriptor, PageDescriptor::ST_Selected, false))
183 return;
185 --mnSelectedPageCount;
186 mrSlideSorter.GetController().GetVisibleAreaManager().RequestVisible(rpDescriptor);
187 mrSlideSorter.GetView().RequestRepaint(rpDescriptor);
188 if (mpMostRecentlySelectedPage == rpDescriptor)
189 mpMostRecentlySelectedPage.reset();
190 if (mnBroadcastDisableLevel > 0)
191 mbSelectionChangeBroadcastPending = true;
192 else
193 mrController.GetSelectionManager()->SelectionHasChanged();
194 if (bUpdateCurrentPage)
195 UpdateCurrentPage();
197 CheckConsistency();
200 void PageSelector::CheckConsistency() const
202 int nSelectionCount (0);
203 for (int nPageIndex=0,nPageCount=mrModel.GetPageCount(); nPageIndex<nPageCount; nPageIndex++)
205 SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nPageIndex));
206 assert(pDescriptor);
207 if (pDescriptor->HasState(PageDescriptor::ST_Selected))
208 ++nSelectionCount;
210 if (nSelectionCount!=mnSelectedPageCount)
212 // #i120020# The former call to assert(..) internally calls
213 // SlideSorterModel::GetPageDescriptor which will crash in this situation
214 // (only in non-pro code). All what is wanted there is to assert it (the
215 // error is already detected), so do this directly.
216 OSL_ENSURE(false, "PageSelector: Consistency error (!)");
220 bool PageSelector::IsPageSelected (int nPageIndex)
222 SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nPageIndex));
223 if (pDescriptor.get() != nullptr)
224 return pDescriptor->HasState(PageDescriptor::ST_Selected);
225 else
226 return false;
229 int PageSelector::GetPageCount() const
231 return mrModel.GetPageCount();
234 void PageSelector::CountSelectedPages()
236 mnSelectedPageCount = 0;
237 model::PageEnumeration aSelectedPages (
238 model::PageEnumerationProvider::CreateSelectedPagesEnumeration(mrModel));
239 while (aSelectedPages.HasMoreElements())
241 mnSelectedPageCount++;
242 aSelectedPages.GetNextElement();
246 void PageSelector::EnableBroadcasting()
248 if (mnBroadcastDisableLevel > 0)
249 mnBroadcastDisableLevel --;
250 if (mnBroadcastDisableLevel==0 && mbSelectionChangeBroadcastPending)
252 mrController.GetSelectionManager()->SelectionHasChanged();
253 mbSelectionChangeBroadcastPending = false;
257 void PageSelector::DisableBroadcasting()
259 mnBroadcastDisableLevel ++;
262 std::shared_ptr<PageSelector::PageSelection> PageSelector::GetPageSelection() const
264 std::shared_ptr<PageSelection> pSelection (new PageSelection);
265 pSelection->reserve(GetSelectedPageCount());
267 int nPageCount = GetPageCount();
268 for (int nIndex=0; nIndex<nPageCount; nIndex++)
270 SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nIndex));
271 if (pDescriptor.get()!=nullptr && pDescriptor->HasState(PageDescriptor::ST_Selected))
272 pSelection->push_back(pDescriptor->GetPage());
275 return pSelection;
278 void PageSelector::SetPageSelection (
279 const std::shared_ptr<PageSelection>& rpSelection,
280 const bool bUpdateCurrentPage)
282 for (const auto& rpPage : *rpSelection)
283 SelectPage(rpPage);
284 if (bUpdateCurrentPage)
285 UpdateCurrentPage();
288 void PageSelector::UpdateCurrentPage (const bool bUpdateOnlyWhenPending)
290 if (mnUpdateLockCount > 0)
292 mbIsUpdateCurrentPagePending = true;
293 return;
296 if ( ! mbIsUpdateCurrentPagePending && bUpdateOnlyWhenPending)
297 return;
299 mbIsUpdateCurrentPagePending = false;
301 // Make the first selected page the current page.
302 SharedPageDescriptor pCurrentPageDescriptor;
303 const sal_Int32 nPageCount (GetPageCount());
304 for (sal_Int32 nIndex=0; nIndex<nPageCount; ++nIndex)
306 SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nIndex));
307 if ( ! pDescriptor)
308 continue;
309 if (pDescriptor->HasState(PageDescriptor::ST_Selected))
311 pCurrentPageDescriptor = pDescriptor;
312 break;
316 if (!pCurrentPageDescriptor)
317 return;
319 // Switching the current slide normally sets also the
320 // selection to just the new current slide. To prevent that,
321 // we store (and at the end of this scope restore) the current
322 // selection.
323 std::shared_ptr<PageSelection> pSelection (GetPageSelection());
325 mrController.GetCurrentSlideManager()->SwitchCurrentSlide(pCurrentPageDescriptor);
327 // Restore the selection and prevent a recursive call to
328 // UpdateCurrentPage().
329 SetPageSelection(pSelection, false);
332 //===== PageSelector::UpdateLock ==============================================
334 PageSelector::UpdateLock::UpdateLock (SlideSorter const & rSlideSorter)
335 : mpSelector(&rSlideSorter.GetController().GetPageSelector())
337 ++mpSelector->mnUpdateLockCount;
340 PageSelector::UpdateLock::UpdateLock (PageSelector& rSelector)
341 : mpSelector(&rSelector)
343 ++mpSelector->mnUpdateLockCount;
346 PageSelector::UpdateLock::~UpdateLock()
348 Release();
351 void PageSelector::UpdateLock::Release()
353 if (mpSelector != nullptr)
355 --mpSelector->mnUpdateLockCount;
356 OSL_ASSERT(mpSelector->mnUpdateLockCount >= 0);
357 if (mpSelector->mnUpdateLockCount == 0)
358 mpSelector->UpdateCurrentPage(true);
360 mpSelector = nullptr;
364 //===== PageSelector::BroadcastLock ==============================================
366 PageSelector::BroadcastLock::BroadcastLock (SlideSorter const & rSlideSorter)
367 : mrSelector(rSlideSorter.GetController().GetPageSelector())
369 mrSelector.DisableBroadcasting();
372 PageSelector::BroadcastLock::BroadcastLock (PageSelector& rSelector)
373 : mrSelector(rSelector)
375 mrSelector.DisableBroadcasting();
378 PageSelector::BroadcastLock::~BroadcastLock()
380 mrSelector.EnableBroadcasting();
383 } } } // end of namespace ::sd::slidesorter::controller
385 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */