android: Update app-specific/MIME type icons
[LibreOffice.git] / sd / source / ui / slidesorter / controller / SlsPageSelector.cxx
blob21affcf2f5dac52c8c8bc337d5d6cabb11717b21
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 <controller/SlideSorterController.hxx>
24 #include <controller/SlsSelectionManager.hxx>
25 #include <controller/SlsCurrentSlideManager.hxx>
26 #include <controller/SlsVisibleAreaManager.hxx>
27 #include <model/SlsPageDescriptor.hxx>
28 #include <model/SlsPageEnumerationProvider.hxx>
29 #include <model/SlideSorterModel.hxx>
30 #include <view/SlideSorterView.hxx>
31 #include <osl/diagnose.h>
33 #include <sdpage.hxx>
34 #include <tools/debug.hxx>
35 #include <memory>
37 using namespace ::com::sun::star;
38 using namespace ::com::sun::star::uno;
39 using namespace ::sd::slidesorter::model;
40 using namespace ::sd::slidesorter::view;
42 namespace sd::slidesorter::controller {
44 PageSelector::PageSelector (SlideSorter& rSlideSorter)
45 : mrModel(rSlideSorter.GetModel()),
46 mrSlideSorter(rSlideSorter),
47 mrController(mrSlideSorter.GetController()),
48 mnSelectedPageCount(0),
49 mnBroadcastDisableLevel(0),
50 mbSelectionChangeBroadcastPending(false),
51 mnUpdateLockCount(0),
52 mbIsUpdateCurrentPagePending(true)
54 CountSelectedPages ();
57 void PageSelector::SelectAllPages()
59 VisibleAreaManager::TemporaryDisabler aDisabler (mrSlideSorter);
60 PageSelector::UpdateLock aLock (*this);
62 int nPageCount = mrModel.GetPageCount();
63 for (int nPageIndex=0; nPageIndex<nPageCount; nPageIndex++)
64 SelectPage(nPageIndex);
67 void PageSelector::DeselectAllPages()
69 VisibleAreaManager::TemporaryDisabler aDisabler (mrSlideSorter);
70 PageSelector::UpdateLock aLock (*this);
72 int nPageCount = mrModel.GetPageCount();
73 for (int nPageIndex=0; nPageIndex<nPageCount; nPageIndex++)
74 DeselectPage(nPageIndex);
76 DBG_ASSERT (mnSelectedPageCount==0,
77 "PageSelector::DeselectAllPages: the selected pages counter is not 0");
78 mnSelectedPageCount = 0;
79 mpSelectionAnchor.reset();
82 void PageSelector::GetCoreSelection()
84 PageSelector::UpdateLock aLock (*this);
86 bool bSelectionHasChanged (true);
87 mnSelectedPageCount = 0;
88 model::PageEnumeration aAllPages (
89 model::PageEnumerationProvider::CreateAllPagesEnumeration(mrModel));
90 while (aAllPages.HasMoreElements())
92 model::SharedPageDescriptor pDescriptor (aAllPages.GetNextElement());
93 if (pDescriptor->GetCoreSelection())
95 mrSlideSorter.GetController().GetVisibleAreaManager().RequestVisible(pDescriptor);
96 mrSlideSorter.GetView().RequestRepaint(pDescriptor);
97 bSelectionHasChanged = true;
100 if (pDescriptor->HasState(PageDescriptor::ST_Selected))
101 mnSelectedPageCount++;
104 if (bSelectionHasChanged)
106 if (mnBroadcastDisableLevel > 0)
107 mbSelectionChangeBroadcastPending = true;
108 else
109 mrController.GetSelectionManager()->SelectionHasChanged();
113 void PageSelector::SetCoreSelection()
115 model::PageEnumeration aAllPages (
116 model::PageEnumerationProvider::CreateAllPagesEnumeration(mrModel));
117 while (aAllPages.HasMoreElements())
119 model::SharedPageDescriptor pDescriptor (aAllPages.GetNextElement());
120 pDescriptor->SetCoreSelection();
124 void PageSelector::SelectPage (int nPageIndex)
126 SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nPageIndex));
127 if (pDescriptor)
128 SelectPage(pDescriptor);
131 void PageSelector::SelectPage (const SdPage* pPage)
133 const sal_Int32 nPageIndex (mrModel.GetIndex(pPage));
134 SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nPageIndex));
135 if (pDescriptor && pDescriptor->GetPage()==pPage)
136 SelectPage(pDescriptor);
139 void PageSelector::SelectPage (const SharedPageDescriptor& rpDescriptor)
141 if (!rpDescriptor
142 || !mrSlideSorter.GetView().SetState(rpDescriptor, PageDescriptor::ST_Selected, true))
143 return;
145 ++mnSelectedPageCount;
146 mrSlideSorter.GetController().GetVisibleAreaManager().RequestVisible(rpDescriptor,true);
147 mrSlideSorter.GetView().RequestRepaint(rpDescriptor);
149 mpMostRecentlySelectedPage = rpDescriptor;
150 if (mpSelectionAnchor == nullptr)
151 mpSelectionAnchor = rpDescriptor;
153 if (mnBroadcastDisableLevel > 0)
154 mbSelectionChangeBroadcastPending = true;
155 else
156 mrController.GetSelectionManager()->SelectionHasChanged();
157 UpdateCurrentPage();
159 CheckConsistency();
162 void PageSelector::DeselectPage (int nPageIndex)
164 model::SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nPageIndex));
165 if (pDescriptor)
166 DeselectPage(pDescriptor);
169 void PageSelector::DeselectPage (
170 const SharedPageDescriptor& rpDescriptor,
171 const bool bUpdateCurrentPage)
173 if (!rpDescriptor
174 || !mrSlideSorter.GetView().SetState(rpDescriptor, PageDescriptor::ST_Selected, false))
175 return;
177 --mnSelectedPageCount;
178 mrSlideSorter.GetController().GetVisibleAreaManager().RequestVisible(rpDescriptor);
179 mrSlideSorter.GetView().RequestRepaint(rpDescriptor);
180 if (mpMostRecentlySelectedPage == rpDescriptor)
181 mpMostRecentlySelectedPage.reset();
182 if (mnBroadcastDisableLevel > 0)
183 mbSelectionChangeBroadcastPending = true;
184 else
185 mrController.GetSelectionManager()->SelectionHasChanged();
186 if (bUpdateCurrentPage)
187 UpdateCurrentPage();
189 CheckConsistency();
192 void PageSelector::CheckConsistency() const
194 int nSelectionCount (0);
195 for (int nPageIndex=0,nPageCount=mrModel.GetPageCount(); nPageIndex<nPageCount; nPageIndex++)
197 SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nPageIndex));
198 assert(pDescriptor);
199 if (pDescriptor->HasState(PageDescriptor::ST_Selected))
200 ++nSelectionCount;
202 if (nSelectionCount!=mnSelectedPageCount)
204 // #i120020# The former call to assert(..) internally calls
205 // SlideSorterModel::GetPageDescriptor which will crash in this situation
206 // (only in non-pro code). All what is wanted there is to assert it (the
207 // error is already detected), so do this directly.
208 OSL_ENSURE(false, "PageSelector: Consistency error (!)");
212 bool PageSelector::IsPageSelected(int nPageIndex)
214 SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nPageIndex));
215 if (pDescriptor)
216 return pDescriptor->HasState(PageDescriptor::ST_Selected);
217 else
218 return false;
221 bool PageSelector::IsPageVisible(int nPageIndex)
223 SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nPageIndex));
224 if (pDescriptor)
225 return pDescriptor->HasState(PageDescriptor::ST_Visible);
226 else
227 return false;
230 int PageSelector::GetPageCount() const
232 return mrModel.GetPageCount();
235 void PageSelector::CountSelectedPages()
237 mnSelectedPageCount = 0;
238 model::PageEnumeration aSelectedPages (
239 model::PageEnumerationProvider::CreateSelectedPagesEnumeration(mrModel));
240 while (aSelectedPages.HasMoreElements())
242 mnSelectedPageCount++;
243 aSelectedPages.GetNextElement();
247 void PageSelector::EnableBroadcasting()
249 if (mnBroadcastDisableLevel > 0)
250 mnBroadcastDisableLevel --;
251 if (mnBroadcastDisableLevel==0 && mbSelectionChangeBroadcastPending)
253 mrController.GetSelectionManager()->SelectionHasChanged();
254 mbSelectionChangeBroadcastPending = false;
258 void PageSelector::DisableBroadcasting()
260 mnBroadcastDisableLevel ++;
263 std::shared_ptr<PageSelector::PageSelection> PageSelector::GetPageSelection() const
265 auto pSelection = std::make_shared<PageSelection>();
266 pSelection->reserve(GetSelectedPageCount());
268 int nPageCount = GetPageCount();
269 for (int nIndex=0; nIndex<nPageCount; nIndex++)
271 SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nIndex));
272 if (pDescriptor && pDescriptor->HasState(PageDescriptor::ST_Selected))
273 pSelection->push_back(pDescriptor->GetPage());
276 return pSelection;
279 void PageSelector::SetPageSelection (
280 const std::shared_ptr<PageSelection>& rpSelection,
281 const bool bUpdateCurrentPage)
283 for (const auto& rpPage : *rpSelection)
284 SelectPage(rpPage);
285 if (bUpdateCurrentPage)
286 UpdateCurrentPage();
289 void PageSelector::UpdateCurrentPage (const bool bUpdateOnlyWhenPending)
291 if (mnUpdateLockCount > 0)
293 mbIsUpdateCurrentPagePending = true;
294 return;
297 if ( ! mbIsUpdateCurrentPagePending && bUpdateOnlyWhenPending)
298 return;
300 mbIsUpdateCurrentPagePending = false;
302 // Make the first selected page the current page.
303 SharedPageDescriptor pCurrentPageDescriptor;
304 const sal_Int32 nPageCount (GetPageCount());
305 for (sal_Int32 nIndex=0; nIndex<nPageCount; ++nIndex)
307 SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nIndex));
308 if ( ! pDescriptor)
309 continue;
310 if (pDescriptor->HasState(PageDescriptor::ST_Selected))
312 pCurrentPageDescriptor = pDescriptor;
313 break;
317 if (!pCurrentPageDescriptor)
318 return;
320 // Switching the current slide normally sets also the
321 // selection to just the new current slide. To prevent that,
322 // we store (and at the end of this scope restore) the current
323 // selection.
324 std::shared_ptr<PageSelection> pSelection (GetPageSelection());
326 mrController.GetCurrentSlideManager()->SwitchCurrentSlide(pCurrentPageDescriptor);
328 // Restore the selection and prevent a recursive call to
329 // UpdateCurrentPage().
330 SetPageSelection(pSelection, false);
333 //===== PageSelector::UpdateLock ==============================================
335 PageSelector::UpdateLock::UpdateLock (SlideSorter const & rSlideSorter)
336 : mpSelector(&rSlideSorter.GetController().GetPageSelector())
338 ++mpSelector->mnUpdateLockCount;
341 PageSelector::UpdateLock::UpdateLock (PageSelector& rSelector)
342 : mpSelector(&rSelector)
344 ++mpSelector->mnUpdateLockCount;
347 PageSelector::UpdateLock::~UpdateLock()
349 Release();
352 void PageSelector::UpdateLock::Release()
354 if (mpSelector != nullptr)
356 --mpSelector->mnUpdateLockCount;
357 OSL_ASSERT(mpSelector->mnUpdateLockCount >= 0);
358 if (mpSelector->mnUpdateLockCount == 0)
359 mpSelector->UpdateCurrentPage(true);
361 mpSelector = nullptr;
365 //===== PageSelector::BroadcastLock ==============================================
367 PageSelector::BroadcastLock::BroadcastLock (SlideSorter const & rSlideSorter)
368 : mrSelector(rSlideSorter.GetController().GetPageSelector())
370 mrSelector.DisableBroadcasting();
373 PageSelector::BroadcastLock::BroadcastLock (PageSelector& rSelector)
374 : mrSelector(rSelector)
376 mrSelector.DisableBroadcasting();
379 PageSelector::BroadcastLock::~BroadcastLock()
381 mrSelector.EnableBroadcasting();
384 } // end of namespace ::sd::slidesorter::controller
386 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */