LibreOffice Module sd (master) 1
SlsSelectionManager.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
21
22#include <SlideSorter.hxx>
33#include <drawdoc.hxx>
34#include <sdpage.hxx>
35#include <drawview.hxx>
36#include <DrawViewShell.hxx>
37#include <ViewShellBase.hxx>
38#include <svx/svxids.hrc>
39#include <com/sun/star/drawing/XMasterPagesSupplier.hpp>
40#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
41
42
43#include <sdresid.hxx>
44#include <strings.hrc>
45#include <app.hrc>
46
47using namespace ::com::sun::star;
48using namespace ::com::sun::star::drawing;
49using namespace ::com::sun::star::uno;
50using namespace ::sd::slidesorter::model;
51using namespace ::sd::slidesorter::view;
52using namespace ::sd::slidesorter::controller;
53
55
57 : mrSlideSorter(rSlideSorter),
58 mrController(rSlideSorter.GetController()),
59 mnInsertionPosition(-1),
60 mpSelectionObserver(std::make_shared<SelectionObserver>(rSlideSorter))
61{
62}
63
65{
66}
67
68void SelectionManager::DeleteSelectedPages (const bool bSelectFollowingPage)
69{
70 // Create some locks to prevent updates of the model, view, selection
71 // state while modifying any of them.
73 SlideSorterView::DrawLock aDrawLock (mrSlideSorter);
75
76 // Hide focus.
77 bool bIsFocusShowing = mrController.GetFocusManager().IsFocusShowing();
78 if (bIsFocusShowing)
80
81 // Store pointers to all selected page descriptors. This is necessary
82 // because the pages get deselected when the first one is deleted.
83 model::PageEnumeration aPageEnumeration (
84 PageEnumerationProvider::CreateSelectedPagesEnumeration(mrSlideSorter.GetModel()));
85 ::std::vector<SdPage*> aSelectedPages;
86 sal_Int32 nNewCurrentSlide (-1);
87 while (aPageEnumeration.HasMoreElements())
88 {
89 SharedPageDescriptor pDescriptor (aPageEnumeration.GetNextElement());
90 aSelectedPages.push_back(pDescriptor->GetPage());
91 if (bSelectFollowingPage || nNewCurrentSlide<0)
92 nNewCurrentSlide = pDescriptor->GetPageIndex();
93 }
94 if (aSelectedPages.empty())
95 return;
96
97 // Determine the slide to select (and thereby make the current slide)
98 // after the deletion.
99 if (bSelectFollowingPage)
100 nNewCurrentSlide -= aSelectedPages.size() - 1;
101 else
102 --nNewCurrentSlide;
103
104 const auto pViewShell = mrSlideSorter.GetViewShell();
105 const auto pDrawViewShell = pViewShell ? std::dynamic_pointer_cast<sd::DrawViewShell>(pViewShell->GetViewShellBase().GetMainViewShell()) : nullptr;
106 const auto pDrawView = pDrawViewShell ? pDrawViewShell->GetDrawView() : nullptr;
107
108 if (pDrawView)
109 pDrawView->BlockPageOrderChangedHint(true);
110
111 // Proper naming for the undo action
112 OUString sUndoComment(SdResId(STR_UNDO_DELETEPAGES));
114 sUndoComment = SdResId(STR_UNDO_DELETEPAGES_DRAW);
115
116 // The actual deletion of the selected pages is done in one of two
117 // helper functions. They are specialized for normal respectively for
118 // master pages.
119 mrSlideSorter.GetView().BegUndo (sUndoComment);
121 DeleteSelectedNormalPages(aSelectedPages);
122 else
123 DeleteSelectedMasterPages(aSelectedPages);
125
127 aLock.Release();
128 if (pDrawView)
129 {
130 assert(pDrawViewShell);
131 pDrawView->BlockPageOrderChangedHint(false);
132 pDrawViewShell->ResetActualPage();
133 }
134
135 // Show focus and move it to next valid location.
136 if (bIsFocusShowing)
138
139 // Set the new current slide.
140 if (nNewCurrentSlide < 0)
141 nNewCurrentSlide = 0;
142 else if (nNewCurrentSlide >= mrSlideSorter.GetModel().GetPageCount())
143 nNewCurrentSlide = mrSlideSorter.GetModel().GetPageCount()-1;
145 mrController.GetPageSelector().SelectPage(nNewCurrentSlide);
146 mrController.GetFocusManager().SetFocusedPage(nNewCurrentSlide);
147}
148
149void SelectionManager::DeleteSelectedNormalPages (const ::std::vector<SdPage*>& rSelectedPages)
150{
151 // Prepare the deletion via the UNO API.
153
154 try
155 {
156 Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier( mrSlideSorter.GetModel().GetDocument()->getUnoModel(), UNO_QUERY_THROW );
157 Reference<drawing::XDrawPages> xPages( xDrawPagesSupplier->getDrawPages(), UNO_SET_THROW );
158
159 // Iterate over all pages that were selected when this method was called
160 // and delete the draw page the notes page. The iteration is done in
161 // reverse order so that when one slide is not deleted (to avoid an
162 // empty document) the remaining slide is the first one.
163 ::std::vector<SdPage*>::const_reverse_iterator aI;
164 for (aI=rSelectedPages.rbegin(); aI!=rSelectedPages.rend(); ++aI)
165 {
166 // Do not delete the last slide in the document.
167 if (xPages->getCount() <= 1)
168 break;
169
170 const sal_uInt16 nPage (model::FromCoreIndex((*aI)->GetPageNum()));
171
172 Reference< XDrawPage > xPage( xPages->getByIndex( nPage ), UNO_QUERY_THROW );
173 xPages->remove(xPage);
174 }
175 }
176 catch( Exception& )
177 {
178 TOOLS_WARN_EXCEPTION( "sd", "SelectionManager::DeleteSelectedNormalPages()");
179 }
180}
181
182void SelectionManager::DeleteSelectedMasterPages (const ::std::vector<SdPage*>& rSelectedPages)
183{
184 // Prepare the deletion via the UNO API.
186
187 try
188 {
189 Reference<drawing::XMasterPagesSupplier> xDrawPagesSupplier( mrSlideSorter.GetModel().GetDocument()->getUnoModel(), UNO_QUERY_THROW );
190 Reference<drawing::XDrawPages> xPages( xDrawPagesSupplier->getMasterPages(), UNO_SET_THROW );
191
192 // Iterate over all pages that were selected when this method was called
193 // and delete the draw page the notes page. The iteration is done in
194 // reverse order so that when one slide is not deleted (to avoid an
195 // empty document) the remaining slide is the first one.
196 ::std::vector<SdPage*>::const_reverse_iterator aI;
197 for (aI=rSelectedPages.rbegin(); aI!=rSelectedPages.rend(); ++aI)
198 {
199 // Do not delete the last slide in the document.
200 if (xPages->getCount() <= 1)
201 break;
202
203 const sal_uInt16 nPage (model::FromCoreIndex((*aI)->GetPageNum()));
204
205 Reference< XDrawPage > xPage( xPages->getByIndex( nPage ), UNO_QUERY_THROW );
206 xPages->remove(xPage);
207 }
208 }
209 catch( Exception& )
210 {
211 TOOLS_WARN_EXCEPTION( "sd", "SelectionManager::DeleteSelectedMasterPages()");
212 }
213}
214
216{
217 ViewShell* pViewShell = mrSlideSorter.GetViewShell();
218 if (pViewShell == nullptr)
219 return;
220
221 pViewShell->Invalidate (SID_EXPAND_PAGE);
222 pViewShell->Invalidate (SID_SUMMARY_PAGE);
223 pViewShell->Invalidate(SID_SHOW_SLIDE);
224 pViewShell->Invalidate(SID_HIDE_SLIDE);
225 pViewShell->Invalidate(SID_DELETE_PAGE);
226 pViewShell->Invalidate(SID_DELETE_MASTER_PAGE);
227 pViewShell->Invalidate(SID_ASSIGN_LAYOUT);
228
229 // StatusBar
230 pViewShell->Invalidate (SID_STATUS_PAGE);
231 pViewShell->Invalidate (SID_STATUS_LAYOUT);
232 pViewShell->Invalidate (SID_SCALE);
233
235 SharedPageDescriptor pDescriptor(mrController.GetCurrentSlideManager()->GetCurrentSlide());
236 if (pDescriptor)
237 pViewShell->UpdatePreview(pDescriptor->GetPage());
238
239 // Tell the selection change listeners that the selection has changed.
240 for (const auto& rLink : maSelectionChangeListeners)
241 {
242 rLink.Call(nullptr);
243 }
244
245 // Reset the insertion position: until set again it is calculated from
246 // the current selection.
248}
249
251{
252 if (::std::find (
255 rListener) == maSelectionChangeListeners.end())
256 {
257 maSelectionChangeListeners.push_back (rListener);
258 }
259}
260
262{
264 ::std::find (
267 rListener));
268}
269
271{
272 sal_Int32 nInsertionPosition (mnInsertionPosition);
273 if (nInsertionPosition < 0)
274 {
275 model::PageEnumeration aSelectedPages
278 // Initialize (for the case of an empty selection) with the position
279 // at the end of the document.
280 nInsertionPosition = mrSlideSorter.GetModel().GetPageCount();
281 while (aSelectedPages.HasMoreElements())
282 {
283 const sal_Int32 nPosition (aSelectedPages.GetNextElement()->GetPage()->GetPageNum());
284 // Convert *2+1 index to straight index (n-1)/2 after the page
285 // (+1).
286 nInsertionPosition = model::FromCoreIndex(nPosition) + 1;
287 }
288
289 }
290 return nInsertionPosition;
291}
292
293void SelectionManager::SetInsertionPosition (const sal_Int32 nInsertionPosition)
294{
295 if (nInsertionPosition < 0)
297 else if (nInsertionPosition > mrSlideSorter.GetModel().GetPageCount())
298 {
299 // Assert but then ignore invalid values.
300 OSL_ASSERT(nInsertionPosition<=mrSlideSorter.GetModel().GetPageCount());
301 return;
302 }
303 else
304 mnInsertionPosition = nInsertionPosition;
305}
306
307} // end of namespace ::sd::slidesorter::controller
308
309/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SlideSorterController & mrController
SlideSorter & mrSlideSorter
SAL_DLLPRIVATE DocumentType GetDocumentType() const
Definition: drawdoc.hxx:251
void BegUndo()
void EndUndo()
css::uno::Reference< css::uno::XInterface > const & getUnoModel()
virtual void Invalidate(sal_uInt16 nId=0)
Base class of the stacked shell hierarchy.
Definition: ViewShell.hxx:92
virtual void UpdatePreview(SdPage *pPage)
This method is still used by the OutlineViewShell to update the model according to the content of the...
Definition: viewshel.cxx:1087
SdDrawDocument & GetDoc() const
Definition: View.hxx:293
Show previews for all the slides in a document and allow the user to insert or delete slides and modi...
Definition: SlideSorter.hxx:62
ViewShell * GetViewShell() const
Return the view shell that was given at construction.
model::SlideSorterModel & GetModel() const
view::SlideSorterView & GetView() const
bool ToggleFocus()
Toggle the focused state of the current slide.
bool SetFocusedPage(const model::SharedPageDescriptor &rDescriptor)
Set the focused page to the one described by the given page descriptor.
bool IsFocusShowing() const
Return <TRUE> when the focus indicator is currently shown.
Use the UpdateLock whenever you do a complex selection, i.e.
void CountSelectedPages()
Call this method after the model has changed to set the number of selected pages.
void SelectPage(int nPageIndex)
Select the specified descriptor.
void SetInsertionPosition(const sal_Int32 nInsertionPosition)
Store an insertion position temporarily.
void AddSelectionChangeListener(const Link< LinkParamNone *, void > &rListener)
Add a listener that is called when the selection of the slide sorter changes.
sal_Int32 mnInsertionPosition
The insertion position is only temporarily valid.
sal_Int32 GetInsertionPosition() const
Return the position where to insert pasted slides based on the current selection.
void DeleteSelectedMasterPages(const ::std::vector< SdPage * > &rSelectedMasterPages)
Delete the given list of master pages.
void DeleteSelectedPages(const bool bSelectFollowingPage=true)
Delete the currently selected slides.
void SelectionHasChanged()
Call this method after the selection has changed (possible several calls to the PageSelector) to inva...
void RemoveSelectionChangeListener(const Link< LinkParamNone *, void > &rListener)
Remove a listener that was called when the selection of the slide sorter changes.
::std::vector< Link< LinkParamNone *, void > > maSelectionChangeListeners
SelectionManager(SlideSorter &rSlideSorter)
Create a new SelectionManager for the given slide sorter.
void DeleteSelectedNormalPages(const ::std::vector< SdPage * > &rSelectedNormalPages)
Delete the given list of normal pages.
Observe insertions and deletions of pages between calls to StartObservation() and EndObservation().
Create an object of this inner class to prevent updates due to model changes.
void HandleModelChange()
Handle a change of the model, that is, handle the removal and insertion of whole pages or a change of...
std::shared_ptr< CurrentSlideManager > const & GetCurrentSlideManager() const
static PageEnumeration CreateSelectedPagesEnumeration(const SlideSorterModel &rModel)
The returned enumeration of slides iterates over the currently selected slides of the given model.
Public class of page enumerations that delegates its calls to an implementation object that can filte...
virtual SharedPageDescriptor GetNextElement() override
Return the next element of the enumeration.
virtual bool HasMoreElements() const override
Return <TRUE> when the enumeration has more elements, i.e.
SdDrawDocument * GetDocument()
This method is present to let the view create a ShowView for displaying slides.
sal_Int32 GetPageCount() const
Return the number of slides in the document regardless of whether they are visible or not or whether ...
#define TOOLS_WARN_EXCEPTION(area, stream)
virtual std::shared_ptr< SfxDialogController > GetController() override
@ Exception
std::shared_ptr< T > make_shared(Args &&... args)
sal_Int32 FromCoreIndex(const sal_uInt16 nCoreIndex)
std::shared_ptr< PageDescriptor > SharedPageDescriptor
OUString SdResId(TranslateId aId)
Definition: sdmod.cxx:83