bump product version to 5.0.4.1
[LibreOffice.git] / sd / source / ui / slidesorter / controller / SlsPageSelector.cxx
blobb9563ae7b814a18c2058e41ddae5391a05ba3fa6
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 <boost/shared_ptr.hpp>
42 using namespace ::com::sun::star;
43 using namespace ::com::sun::star::uno;
44 using namespace ::sd::slidesorter::model;
45 using namespace ::sd::slidesorter::view;
47 namespace sd { namespace slidesorter { namespace controller {
49 PageSelector::PageSelector (SlideSorter& rSlideSorter)
50 : mrModel(rSlideSorter.GetModel()),
51 mrSlideSorter(rSlideSorter),
52 mrController(mrSlideSorter.GetController()),
53 mnSelectedPageCount(0),
54 mnBroadcastDisableLevel(0),
55 mbSelectionChangeBroadcastPending(false),
56 mpMostRecentlySelectedPage(),
57 mpSelectionAnchor(),
58 mpCurrentPage(),
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() != NULL)
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()!=NULL && pDescriptor->GetPage()==pPage)
144 SelectPage(pDescriptor);
147 void PageSelector::SelectPage (const SharedPageDescriptor& rpDescriptor)
149 if (rpDescriptor.get()!=NULL
150 && mrSlideSorter.GetView().SetState(rpDescriptor, PageDescriptor::ST_Selected, true))
152 ++mnSelectedPageCount;
153 mrSlideSorter.GetController().GetVisibleAreaManager().RequestVisible(rpDescriptor,true);
154 mrSlideSorter.GetView().RequestRepaint(rpDescriptor);
156 mpMostRecentlySelectedPage = rpDescriptor;
157 if (mpSelectionAnchor == 0)
158 mpSelectionAnchor = rpDescriptor;
160 if (mnBroadcastDisableLevel > 0)
161 mbSelectionChangeBroadcastPending = true;
162 else
163 mrController.GetSelectionManager()->SelectionHasChanged();
164 UpdateCurrentPage();
166 CheckConsistency();
170 void PageSelector::DeselectPage (
171 int nPageIndex,
172 const bool bUpdateCurrentPage)
174 model::SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nPageIndex));
175 if (pDescriptor.get() != NULL)
176 DeselectPage(pDescriptor, bUpdateCurrentPage);
179 void PageSelector::DeselectPage (
180 const SharedPageDescriptor& rpDescriptor,
181 const bool bUpdateCurrentPage)
183 if (rpDescriptor.get()!=NULL
184 && mrSlideSorter.GetView().SetState(rpDescriptor, PageDescriptor::ST_Selected, false))
186 --mnSelectedPageCount;
187 mrSlideSorter.GetController().GetVisibleAreaManager().RequestVisible(rpDescriptor);
188 mrSlideSorter.GetView().RequestRepaint(rpDescriptor);
189 if (mpMostRecentlySelectedPage == rpDescriptor)
190 mpMostRecentlySelectedPage.reset();
191 if (mnBroadcastDisableLevel > 0)
192 mbSelectionChangeBroadcastPending = true;
193 else
194 mrController.GetSelectionManager()->SelectionHasChanged();
195 if (bUpdateCurrentPage)
196 UpdateCurrentPage();
198 CheckConsistency();
202 void PageSelector::CheckConsistency() const
204 int nSelectionCount (0);
205 for (int nPageIndex=0,nPageCount=mrModel.GetPageCount(); nPageIndex<nPageCount; nPageIndex++)
207 SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nPageIndex));
208 assert(pDescriptor);
209 if (pDescriptor->HasState(PageDescriptor::ST_Selected))
210 ++nSelectionCount;
212 if (nSelectionCount!=mnSelectedPageCount)
214 // #i120020# The former call to assert(..) internally calls
215 // SlideSorterModel::GetPageDescriptor which will crash in this situation
216 // (only in non-pro code). All what is wanted there is to assert it (the
217 // error is already detected), so do this directly.
218 OSL_ENSURE(false, "PageSelector: Consistency error (!)");
222 bool PageSelector::IsPageSelected (int nPageIndex)
224 SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nPageIndex));
225 if (pDescriptor.get() != NULL)
226 return pDescriptor->HasState(PageDescriptor::ST_Selected);
227 else
228 return false;
231 int PageSelector::GetPageCount() const
233 return mrModel.GetPageCount();
236 void PageSelector::CountSelectedPages()
238 mnSelectedPageCount = 0;
239 model::PageEnumeration aSelectedPages (
240 model::PageEnumerationProvider::CreateSelectedPagesEnumeration(mrModel));
241 while (aSelectedPages.HasMoreElements())
243 mnSelectedPageCount++;
244 aSelectedPages.GetNextElement();
248 void PageSelector::EnableBroadcasting()
250 if (mnBroadcastDisableLevel > 0)
251 mnBroadcastDisableLevel --;
252 if (mnBroadcastDisableLevel==0 && mbSelectionChangeBroadcastPending)
254 mrController.GetSelectionManager()->SelectionHasChanged();
255 mbSelectionChangeBroadcastPending = false;
259 void PageSelector::DisableBroadcasting()
261 mnBroadcastDisableLevel ++;
264 ::boost::shared_ptr<PageSelector::PageSelection> PageSelector::GetPageSelection() const
266 ::boost::shared_ptr<PageSelection> pSelection (new PageSelection());
267 pSelection->reserve(GetSelectedPageCount());
269 int nPageCount = GetPageCount();
270 for (int nIndex=0; nIndex<nPageCount; nIndex++)
272 SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nIndex));
273 if (pDescriptor.get()!=NULL && pDescriptor->HasState(PageDescriptor::ST_Selected))
274 pSelection->push_back(pDescriptor->GetPage());
277 return pSelection;
280 void PageSelector::SetPageSelection (
281 const ::boost::shared_ptr<PageSelection>& rpSelection,
282 const bool bUpdateCurrentPage)
284 PageSelection::const_iterator iPage;
285 for (iPage=rpSelection->begin(); iPage!=rpSelection->end(); ++iPage)
286 SelectPage(*iPage);
287 if (bUpdateCurrentPage)
288 UpdateCurrentPage();
291 void PageSelector::UpdateCurrentPage (const bool bUpdateOnlyWhenPending)
293 if (mnUpdateLockCount > 0)
295 mbIsUpdateCurrentPagePending = true;
296 return;
299 if ( ! mbIsUpdateCurrentPagePending && bUpdateOnlyWhenPending)
300 return;
302 mbIsUpdateCurrentPagePending = false;
304 // Make the first selected page the current page.
305 SharedPageDescriptor pCurrentPageDescriptor;
306 const sal_Int32 nPageCount (GetPageCount());
307 for (sal_Int32 nIndex=0; nIndex<nPageCount; ++nIndex)
309 SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nIndex));
310 if ( ! pDescriptor)
311 continue;
312 if (pDescriptor->HasState(PageDescriptor::ST_Selected))
314 pCurrentPageDescriptor = pDescriptor;
315 break;
319 if (pCurrentPageDescriptor)
321 // Switching the current slide normally sets also the
322 // selection to just the new current slide. To prevent that,
323 // we store (and at the end of this scope restore) the current
324 // selection.
325 ::boost::shared_ptr<PageSelection> pSelection (GetPageSelection());
327 mrController.GetCurrentSlideManager()->SwitchCurrentSlide(pCurrentPageDescriptor);
329 // Restore the selection and prevent a recursive call to
330 // UpdateCurrentPage().
331 SetPageSelection(pSelection, false);
335 //===== PageSelector::UpdateLock ==============================================
337 PageSelector::UpdateLock::UpdateLock (SlideSorter& rSlideSorter)
338 : mpSelector(&rSlideSorter.GetController().GetPageSelector())
340 ++mpSelector->mnUpdateLockCount;
343 PageSelector::UpdateLock::UpdateLock (PageSelector& rSelector)
344 : mpSelector(&rSelector)
346 ++mpSelector->mnUpdateLockCount;
349 PageSelector::UpdateLock::~UpdateLock()
351 Release();
354 void PageSelector::UpdateLock::Release()
356 if (mpSelector != NULL)
358 --mpSelector->mnUpdateLockCount;
359 OSL_ASSERT(mpSelector->mnUpdateLockCount >= 0);
360 if (mpSelector->mnUpdateLockCount == 0)
361 mpSelector->UpdateCurrentPage(true);
363 mpSelector = NULL;
367 //===== PageSelector::BroadcastLock ==============================================
369 PageSelector::BroadcastLock::BroadcastLock (SlideSorter& rSlideSorter)
370 : mrSelector(rSlideSorter.GetController().GetPageSelector())
372 mrSelector.DisableBroadcasting();
375 PageSelector::BroadcastLock::BroadcastLock (PageSelector& rSelector)
376 : mrSelector(rSelector)
378 mrSelector.DisableBroadcasting();
381 PageSelector::BroadcastLock::~BroadcastLock()
383 mrSelector.EnableBroadcasting();
386 } } } // end of namespace ::sd::slidesorter::controller
388 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */