Bug Summary

File:home/maarten/src/libreoffice/core/include/rtl/ref.hxx
Warning:line 192, column 9
Use of memory after it is freed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name SlsSlotManager.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -isystem /usr/include/libxml2 -isystem /usr/include/dbus-1.0 -isystem /usr/lib64/dbus-1.0/include -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D SD_DLLIMPLEMENTATION -D SDUI_DLL_NAME="libsduilo.so" -D SYSTEM_LIBXML -D ENABLE_SDREMOTE -D ENABLE_SDREMOTE_BLUETOOTH -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/i18n -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/common -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/external/bluez_bluetooth/inc -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/sd/inc -I /home/maarten/src/libreoffice/core/sd/source/ui/inc -I /home/maarten/src/libreoffice/core/sd/source/ui/slidesorter/inc -I /home/maarten/src/libreoffice/core/workdir/SdiTarget/sd/sdi -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/officecfg/registry -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/oox/generated -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx

/home/maarten/src/libreoffice/core/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx

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
20#include <editeng/outlobj.hxx>
21
22#include <controller/SlsSlotManager.hxx>
23#include <SlideSorter.hxx>
24#include <SlideSorterViewShell.hxx>
25#include <controller/SlideSorterController.hxx>
26#include <controller/SlsClipboard.hxx>
27#include <controller/SlsCurrentSlideManager.hxx>
28#include <controller/SlsInsertionIndicatorHandler.hxx>
29#include <controller/SlsPageSelector.hxx>
30#include <controller/SlsSelectionFunction.hxx>
31#include <controller/SlsSelectionManager.hxx>
32#include <model/SlideSorterModel.hxx>
33#include <model/SlsPageEnumerationProvider.hxx>
34#include <model/SlsPageDescriptor.hxx>
35#include <view/SlideSorterView.hxx>
36#include <view/SlsLayouter.hxx>
37#include <framework/FrameworkHelper.hxx>
38#include <Window.hxx>
39#include <fupoor.hxx>
40#include <fucushow.hxx>
41#include <fusldlg.hxx>
42#include <fuexpand.hxx>
43#include <fusumry.hxx>
44#include <slideshow.hxx>
45#include <app.hrc>
46#include <strings.hrc>
47#include <sdresid.hxx>
48#include <unokywds.hxx>
49#include <drawdoc.hxx>
50#include <DrawDocShell.hxx>
51#include <ViewShellBase.hxx>
52#include <ViewShellImplementation.hxx>
53#include <sdpage.hxx>
54#include <sdxfer.hxx>
55#include <helpids.h>
56#include <unmodpg.hxx>
57#include <DrawViewShell.hxx>
58#include <sdabstdlg.hxx>
59#include <sdmod.hxx>
60
61#include <vcl/uitest/logger.hxx>
62#include <vcl/uitest/eventdescription.hxx>
63
64#include <sfx2/request.hxx>
65#include <sfx2/viewfrm.hxx>
66#include <sfx2/bindings.hxx>
67#include <sfx2/dispatch.hxx>
68#include <sfx2/sidebar/Sidebar.hxx>
69#include <svx/svxids.hrc>
70#include <svx/svxdlg.hxx>
71#include <svl/intitem.hxx>
72#include <svl/stritem.hxx>
73#include <svl/whiter.hxx>
74#include <svl/itempool.hxx>
75#include <com/sun/star/drawing/XMasterPagesSupplier.hpp>
76#include <com/sun/star/drawing/XDrawPages.hpp>
77
78
79#include <memory>
80
81using namespace ::com::sun::star;
82using namespace ::com::sun::star::uno;
83using namespace ::com::sun::star::beans;
84
85namespace sd::slidesorter::controller {
86
87namespace {
88
89/** The state of a set of slides with respect to being excluded from the
90 slide show.
91*/
92enum SlideExclusionState {UNDEFINED, EXCLUDED, INCLUDED, MIXED};
93
94/** Return for the given set of slides whether they included are
95 excluded from the slide show.
96*/
97SlideExclusionState GetSlideExclusionState (model::PageEnumeration& rPageSet);
98
99} // end of anonymous namespace
100
101
102namespace {
103
104void collectUIInformation(const std::map<OUString, OUString>& aParameters, const OUString& rAction)
105{
106 EventDescription aDescription;
107 aDescription.aID = "impress_win_or_draw_win";
108 aDescription.aParameters = aParameters;
109 aDescription.aAction = rAction;
110 aDescription.aKeyWord = "ImpressWindowUIObject";
111 aDescription.aParent = "MainWindow";
112
113 UITestLogger::getInstance().logEvent(aDescription);
114}
115
116}
117
118SlotManager::SlotManager (SlideSorter& rSlideSorter)
119 : mrSlideSorter(rSlideSorter)
120{
121}
122
123SlotManager::~SlotManager()
124{
125}
126
127void SlotManager::FuTemporary (SfxRequest& rRequest)
128{
129 SdDrawDocument* pDocument = mrSlideSorter.GetModel().GetDocument();
130
131 SlideSorterViewShell* pShell
132 = dynamic_cast<SlideSorterViewShell*>(mrSlideSorter.GetViewShell());
133 if (pShell == nullptr)
1
Assuming the condition is false
2
Taking false branch
134 return;
135
136 switch (rRequest.GetSlot())
3
Control jumps to 'case 27337:' at line 289
137 {
138 case SID_PRESENTATION( 10000 + 157 ):
139 case SID_PRESENTATION_CURRENT_SLIDE( 10000 + 158 ):
140 case SID_REHEARSE_TIMINGS( 10000 + 159 ):
141 slideshowhelp::ShowSlideShow(rRequest, *mrSlideSorter.GetModel().GetDocument());
142 pShell->Cancel();
143 rRequest.Done();
144 break;
145
146 case SID_HIDE_SLIDE( 10000 + 161 ):
147 ChangeSlideExclusionState(model::SharedPageDescriptor(), true);
148 break;
149
150 case SID_SHOW_SLIDE(27000 +441):
151 ChangeSlideExclusionState(model::SharedPageDescriptor(), false);
152 break;
153
154 case SID_PAGES_PER_ROW(27000 +284):
155 if (rRequest.GetArgs() != nullptr)
156 {
157 const SfxUInt16Item* pPagesPerRow = rRequest.GetArg<SfxUInt16Item>(SID_PAGES_PER_ROW(27000 +284));
158 if (pPagesPerRow != nullptr)
159 {
160 sal_Int32 nColumnCount = pPagesPerRow->GetValue();
161 // Force the given number of columns by setting
162 // the minimal and maximal number of columns to
163 // the same value.
164 mrSlideSorter.GetView().GetLayouter().SetColumnCount (
165 nColumnCount, nColumnCount);
166 // Force a repaint and re-layout.
167 pShell->ArrangeGUIElements ();
168 // Rearrange the UI-elements controlled by the
169 // controller and force a rearrangement of the
170 // view.
171 mrSlideSorter.GetController().Rearrange(true);
172 }
173 }
174 rRequest.Done();
175 break;
176
177 case SID_SELECTALL(5000 + 723):
178 mrSlideSorter.GetController().GetPageSelector().SelectAllPages();
179 rRequest.Done();
180 break;
181
182 case SID_SLIDE_TRANSITIONS_PANEL(27000 +334):
183 {
184 // First make sure that the sidebar is visible
185 pShell->GetViewFrame()->ShowChildWindow(SID_SIDEBAR(10000 + 336));
186 ::sfx2::sidebar::Sidebar::ShowPanel(
187 "SdSlideTransitionPanel",
188 pShell->GetViewFrame()->GetFrame().GetFrameInterface());
189 rRequest.Ignore ();
190 break;
191 }
192
193 case SID_MASTER_SLIDES_PANEL(27000 +184):
194 {
195 // First make sure that the sidebar is visible
196 pShell->GetViewFrame()->ShowChildWindow(SID_SIDEBAR(10000 + 336));
197 ::sfx2::sidebar::Sidebar::ShowPanel(
198 "SdAllMasterPagesPanel",
199 pShell->GetViewFrame()->GetFrame().GetFrameInterface());
200 rRequest.Ignore ();
201 break;
202 }
203
204 case SID_PRESENTATION_DLG(27000 +339):
205 FuSlideShowDlg::Create (
206 pShell,
207 mrSlideSorter.GetContentWindow(),
208 &mrSlideSorter.GetView(),
209 pDocument,
210 rRequest);
211 break;
212
213 case SID_CUSTOMSHOW_DLG(27000 +365):
214 FuCustomShowDlg::Create (
215 pShell,
216 mrSlideSorter.GetContentWindow(),
217 &mrSlideSorter.GetView(),
218 pDocument,
219 rRequest);
220 break;
221
222 case SID_EXPAND_PAGE(27000 +343):
223 FuExpandPage::Create (
224 pShell,
225 mrSlideSorter.GetContentWindow(),
226 &mrSlideSorter.GetView(),
227 pDocument,
228 rRequest);
229 break;
230
231 case SID_SUMMARY_PAGE(27000 +344):
232 FuSummaryPage::Create (
233 pShell,
234 mrSlideSorter.GetContentWindow(),
235 &mrSlideSorter.GetView(),
236 pDocument,
237 rRequest);
238 break;
239
240 case SID_INSERTPAGE(27000 +14):
241 case SID_INSERT_MASTER_PAGE(27000 +431):
242 InsertSlide(rRequest);
243 rRequest.Done();
244 break;
245
246 case SID_DUPLICATE_PAGE(27000 +342):
247 DuplicateSelectedSlides(rRequest);
248 rRequest.Done();
249 break;
250
251 case SID_DELETE_PAGE(27000 +80):
252 case SID_DELETE_MASTER_PAGE(27000 +432):
253 case SID_DELETE(5000 + 713): // we need SID_CUT to handle the delete key
254 // (DEL -> accelerator -> SID_CUT).
255 if (mrSlideSorter.GetModel().GetPageCount() > 1)
256 {
257 mrSlideSorter.GetView().EndTextEditAllViews();
258 mrSlideSorter.GetController().GetSelectionManager()->DeleteSelectedPages();
259 }
260
261 rRequest.Done();
262 break;
263
264 case SID_RENAMEPAGE(27000 +268):
265 case SID_RENAME_MASTER_PAGE(27000 +433):
266 RenameSlide (rRequest);
267 rRequest.Done ();
268 break;
269
270 case SID_ASSIGN_LAYOUT(27000 +435):
271 {
272 pShell->mpImpl->AssignLayout( rRequest, PageKind::Standard );
273 rRequest.Done ();
274 }
275 break;
276
277 case SID_PHOTOALBUM(27000 +336):
278 {
279 SdAbstractDialogFactory* pFact = SdAbstractDialogFactory::Create();
280 vcl::Window* pWin = mrSlideSorter.GetContentWindow();
281 ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateSdPhotoAlbumDialog(
282 pWin ? pWin->GetFrameWeld() : nullptr,
283 pDocument));
284 pDlg->Execute();
285 rRequest.Done ();
286 }
287 break;
288
289 case SID_REMOTE_DLG(27000 +337):
290 {
291#ifdef ENABLE_SDREMOTE1
292 SdAbstractDialogFactory* pFact = SdAbstractDialogFactory::Create();
293 vcl::Window* pWin = mrSlideSorter.GetContentWindow();
294 ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateRemoteDialog(pWin ? pWin->GetFrameWeld() : nullptr));
4
Assuming 'pWin' is null
5
'?' condition is false
6
Calling constructor for 'ScopedVclPtr<VclAbstractDialog>'
13
Returning from constructor for 'ScopedVclPtr<VclAbstractDialog>'
14
Calling implicit destructor for 'VclPtr<VclAbstractDialog>'
15
Calling '~Reference'
22
Returning from '~Reference'
23
Returning from destructor for 'VclPtr<VclAbstractDialog>'
295 pDlg->Execute();
24
Calling 'VclPtr::operator->'
296#endif
297 }
298 break;
299
300 default:
301 break;
302 }
303}
304
305void SlotManager::FuPermanent (SfxRequest& rRequest)
306{
307 ViewShell* pShell = mrSlideSorter.GetViewShell();
308 if (pShell == nullptr)
309 return;
310
311 if(pShell->GetCurrentFunction().is())
312 {
313 rtl::Reference<FuPoor> xEmpty;
314 if (pShell->GetOldFunction() == pShell->GetCurrentFunction())
315 pShell->SetOldFunction(xEmpty);
316
317 pShell->GetCurrentFunction()->Deactivate();
318 pShell->SetCurrentFunction(xEmpty);
319 }
320
321 switch(rRequest.GetSlot())
322 {
323 case SID_OBJECT_SELECT( 10000 + 128 ):
324 pShell->SetCurrentFunction( SelectionFunction::Create(mrSlideSorter, rRequest) );
325 rRequest.Done();
326 break;
327
328 default:
329 break;
330 }
331
332 if(pShell->GetOldFunction().is())
333 {
334 pShell->GetOldFunction()->Deactivate();
335 rtl::Reference<FuPoor> xEmpty;
336 pShell->SetOldFunction(xEmpty);
337 }
338
339 if(pShell->GetCurrentFunction().is())
340 {
341 pShell->GetCurrentFunction()->Activate();
342 pShell->SetOldFunction(pShell->GetCurrentFunction());
343 }
344
345 //! that's only until ENUM-Slots ?are
346 // Invalidate( SID_OBJECT_SELECT );
347}
348
349void SlotManager::FuSupport (SfxRequest& rRequest)
350{
351 switch (rRequest.GetSlot())
352 {
353 case SID_STYLE_FAMILYTypedWhichId<SfxUInt16Item>(5000 + 553):
354 if (rRequest.GetArgs() != nullptr)
355 {
356 SdDrawDocument* pDocument
357 = mrSlideSorter.GetModel().GetDocument();
358 if (pDocument != nullptr)
359 {
360 const SfxPoolItem& rItem (
361 rRequest.GetArgs()->Get(SID_STYLE_FAMILYTypedWhichId<SfxUInt16Item>(5000 + 553)));
362 pDocument->GetDocSh()->SetStyleFamily(
363 static_cast<SfxStyleFamily>(static_cast<const SfxUInt16Item&>(rItem).GetValue()));
364 }
365 }
366 break;
367
368 case SID_PASTE(5000 + 712):
369 {
370 SdTransferable* pTransferClip = SD_MOD()( static_cast<SdModule*>(SfxApplication::GetModule(SfxToolsModule
::Draw)) )
->pTransferClip;
371 if( pTransferClip )
372 {
373 SfxObjectShell* pTransferDocShell = pTransferClip->GetDocShell().get();
374
375 DrawDocShell* pDocShell = dynamic_cast<DrawDocShell*>(pTransferDocShell);
376 if (pDocShell && pDocShell->GetDoc()->GetPageCount() > 1)
377 {
378 mrSlideSorter.GetController().GetClipboard().HandleSlotCall(rRequest);
379 break;
380 }
381 }
382 ViewShellBase* pBase = mrSlideSorter.GetViewShellBase();
383 if (pBase != nullptr)
384 {
385 std::shared_ptr<DrawViewShell> pDrawViewShell (
386 std::dynamic_pointer_cast<DrawViewShell>(pBase->GetMainViewShell()));
387 if (pDrawViewShell != nullptr)
388 pDrawViewShell->FuSupport(rRequest);
389 }
390 }
391 break;
392
393 case SID_CUT(5000 + 710):
394 case SID_COPY(5000 + 711):
395 case SID_DELETE(5000 + 713):
396 mrSlideSorter.GetView().EndTextEditAllViews();
397 mrSlideSorter.GetController().GetClipboard().HandleSlotCall(rRequest);
398 break;
399
400 case SID_DRAWINGMODE(27000 +9):
401 case SID_NOTES_MODE(27000 +69):
402 case SID_HANDOUT_MASTER_MODE(27000 +70):
403 case SID_SLIDE_SORTER_MODE(27000 +11):
404 case SID_OUTLINE_MODE(27000 +10):
405 {
406 ViewShellBase* pBase = mrSlideSorter.GetViewShellBase();
407 if (pBase != nullptr)
408 {
409 framework::FrameworkHelper::Instance(*pBase)->HandleModeChangeSlot(
410 rRequest.GetSlot(), rRequest);
411 rRequest.Done();
412 }
413 break;
414 }
415
416 case SID_UNDO(5000 + 701):
417 {
418 SlideSorterViewShell* pViewShell
419 = dynamic_cast<SlideSorterViewShell*>(mrSlideSorter.GetViewShell());
420 if (pViewShell != nullptr)
421 {
422 pViewShell->ImpSidUndo (rRequest);
423 }
424 break;
425 }
426
427 case SID_REDO(5000 + 700):
428 {
429 SlideSorterViewShell* pViewShell
430 = dynamic_cast<SlideSorterViewShell*>(mrSlideSorter.GetViewShell());
431 if (pViewShell != nullptr)
432 {
433 pViewShell->ImpSidRedo (rRequest);
434 }
435 break;
436 }
437
438 default:
439 break;
440 }
441}
442
443void SlotManager::ExecCtrl (SfxRequest& rRequest)
444{
445 ViewShell* pViewShell = mrSlideSorter.GetViewShell();
446 sal_uInt16 nSlot = rRequest.GetSlot();
447 switch (nSlot)
448 {
449 case SID_RELOAD(5000 + 508):
450 {
451 // empty Undo-Manager
452 mrSlideSorter.GetModel().GetDocument()->GetDocSh()->ClearUndoBuffer();
453
454 // normal forwarding to ViewFrame for execution
455 if (pViewShell != nullptr)
456 pViewShell->GetViewFrame()->ExecuteSlot(rRequest);
457
458 // has to be finished right away
459 return;
460 }
461
462 case SID_OUTPUT_QUALITY_COLOR(27000 +366):
463 case SID_OUTPUT_QUALITY_GRAYSCALE(27000 +367):
464 case SID_OUTPUT_QUALITY_BLACKWHITE(27000 +368):
465 case SID_OUTPUT_QUALITY_CONTRAST(27000 +400):
466 {
467 // flush page cache
468 if (pViewShell != nullptr)
469 pViewShell->ExecReq (rRequest);
470 break;
471 }
472
473 case SID_MAIL_SCROLLBODY_PAGEDOWN(5000 + 1588):
474 {
475 if (pViewShell != nullptr)
476 pViewShell->ExecReq (rRequest);
477 break;
478 }
479
480 case SID_OPT_LOCALE_CHANGED(((((10000 + 1499) + 1) + 499) + 1) + 94):
481 {
482 mrSlideSorter.GetController().UpdateAllPages();
483 if (pViewShell != nullptr)
484 pViewShell->UpdatePreview (pViewShell->GetActualPage());
485 rRequest.Done();
486 break;
487 }
488
489 case SID_SEARCH_DLG(5000 + 961):
490 // We have to handle the SID_SEARCH_DLG slot explicitly because
491 // in some cases (when the slide sorter is displayed in the
492 // center pane) we want to disable the search dialog. Therefore
493 // we have to handle the execution of that slot as well.
494 // We try to do that by forwarding the request to the view frame
495 // of the view shell.
496 if (pViewShell != nullptr)
497 pViewShell->GetViewFrame()->ExecuteSlot(rRequest);
498 break;
499
500 default:
501 break;
502 }
503}
504
505void SlotManager::GetAttrState (SfxItemSet& rSet)
506{
507 // Iterate over all items.
508 SfxWhichIter aIter (rSet);
509 sal_uInt16 nWhich = aIter.FirstWhich();
510 while (nWhich)
511 {
512 sal_uInt16 nSlotId (nWhich);
513 if (SfxItemPool::IsWhich(nWhich) && mrSlideSorter.GetViewShell()!=nullptr)
514 nSlotId = mrSlideSorter.GetViewShell()->GetPool().GetSlotId(nWhich);
515 switch (nSlotId)
516 {
517 case SID_PAGES_PER_ROW(27000 +284):
518 rSet.Put (
519 SfxUInt16Item (
520 nSlotId,
521 static_cast<sal_uInt16>(mrSlideSorter.GetView().GetLayouter().GetColumnCount())
522 )
523 );
524 break;
525 }
526 nWhich = aIter.NextWhich();
527 }
528}
529
530void SlotManager::GetMenuState (SfxItemSet& rSet)
531{
532 EditMode eEditMode = mrSlideSorter.GetModel().GetEditMode();
533 ViewShell* pShell = mrSlideSorter.GetViewShell();
534 DrawDocShell* pDocShell = mrSlideSorter.GetModel().GetDocument()->GetDocSh();
535
536 if (pShell!=nullptr && pShell->GetCurrentFunction().is())
537 {
538 sal_uInt16 nSId = pShell->GetCurrentFunction()->GetSlotID();
539
540 rSet.Put( SfxBoolItem( nSId, true ) );
541 }
542 rSet.Put( SfxBoolItem( SID_DRAWINGMODE(27000 +9), false ) );
543 rSet.Put( SfxBoolItem( SID_SLIDE_SORTER_MODE(27000 +11), true ) );
544 rSet.Put( SfxBoolItem( SID_OUTLINE_MODE(27000 +10), false ) );
545 rSet.Put( SfxBoolItem( SID_NOTES_MODE(27000 +69), false ) );
546 rSet.Put( SfxBoolItem( SID_HANDOUT_MASTER_MODE(27000 +70), false ) );
547
548 if (pShell!=nullptr && pShell->IsMainViewShell())
549 {
550 rSet.DisableItem(SID_SPELL_DIALOG( 10000 + 243 ));
551 rSet.DisableItem(SID_SEARCH_DLG(5000 + 961));
552 }
553
554 if (SfxItemState::DEFAULT == rSet.GetItemState(SID_EXPAND_PAGE(27000 +343)))
555 {
556 bool bDisable = true;
557 if (eEditMode == EditMode::Page)
558 {
559 // At least one of the selected pages has to contain an outline
560 // presentation objects in order to enable the expand page menu
561 // entry.
562 model::PageEnumeration aSelectedPages (
563 model::PageEnumerationProvider::CreateSelectedPagesEnumeration(
564 mrSlideSorter.GetModel()));
565 while (aSelectedPages.HasMoreElements())
566 {
567 SdPage* pPage = aSelectedPages.GetNextElement()->GetPage();
568 SdrObject* pObj = pPage->GetPresObj(PresObjKind::Outline);
569 if (pObj!=nullptr )
570 {
571 if( !pObj->IsEmptyPresObj() )
572 {
573 bDisable = false;
574 }
575 else
576 {
577 // check if the object is in edit, then if it's temporarily not empty
578 SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >( pObj );
579 if( pTextObj )
580 {
581 if( pTextObj->CanCreateEditOutlinerParaObject() )
582 {
583 bDisable = false;
584 }
585 }
586 }
587 }
588 }
589 }
590
591 if (bDisable)
592 rSet.DisableItem (SID_EXPAND_PAGE(27000 +343));
593 }
594
595 if (SfxItemState::DEFAULT == rSet.GetItemState(SID_SUMMARY_PAGE(27000 +344)))
596 {
597 bool bDisable = true;
598 if (eEditMode == EditMode::Page)
599 {
600 // At least one of the selected pages has to contain a title
601 // presentation objects in order to enable the summary page menu
602 // entry.
603 model::PageEnumeration aSelectedPages (
604 model::PageEnumerationProvider::CreateSelectedPagesEnumeration(
605 mrSlideSorter.GetModel()));
606 while (aSelectedPages.HasMoreElements())
607 {
608 SdPage* pPage = aSelectedPages.GetNextElement()->GetPage();
609 SdrObject* pObj = pPage->GetPresObj(PresObjKind::Title);
610
611 if (pObj!=nullptr && !pObj->IsEmptyPresObj())
612 bDisable = false;
613 }
614 }
615 if (bDisable)
616 rSet.DisableItem (SID_SUMMARY_PAGE(27000 +344));
617 }
618
619 // starting of presentation possible?
620 if( SfxItemState::DEFAULT == rSet.GetItemState( SID_PRESENTATION( 10000 + 157 ) ) ||
621 SfxItemState::DEFAULT == rSet.GetItemState( SID_REHEARSE_TIMINGS( 10000 + 159 ) ) )
622 {
623 bool bDisable = true;
624 model::PageEnumeration aAllPages (
625 model::PageEnumerationProvider::CreateAllPagesEnumeration(mrSlideSorter.GetModel()));
626 while (aAllPages.HasMoreElements())
627 {
628 SdPage* pPage = aAllPages.GetNextElement()->GetPage();
629
630 if( !pPage->IsExcluded() )
631 bDisable = false;
632 }
633 if( bDisable || pDocShell->IsPreview())
634 {
635 rSet.DisableItem( SID_PRESENTATION( 10000 + 157 ) );
636 rSet.DisableItem( SID_REHEARSE_TIMINGS( 10000 + 159 ) );
637 }
638 }
639
640 // Disable the rename slots when there are no or more than one slides/master
641 // pages selected; disable the duplicate slot when there are no slides
642 // selected:
643 if (rSet.GetItemState(SID_RENAMEPAGE(27000 +268)) == SfxItemState::DEFAULT
644 || rSet.GetItemState(SID_RENAME_MASTER_PAGE(27000 +433)) == SfxItemState::DEFAULT
645 || rSet.GetItemState(SID_DUPLICATE_PAGE(27000 +342)) == SfxItemState::DEFAULT)
646 {
647 int n = mrSlideSorter.GetController().GetPageSelector()
648 .GetSelectedPageCount();
649 if (n != 1)
650 {
651 rSet.DisableItem(SID_RENAMEPAGE(27000 +268));
652 rSet.DisableItem(SID_RENAME_MASTER_PAGE(27000 +433));
653 }
654 if (n == 0)
655 {
656 rSet.DisableItem(SID_DUPLICATE_PAGE(27000 +342));
657 }
658 }
659
660 if (rSet.GetItemState(SID_HIDE_SLIDE( 10000 + 161 )) == SfxItemState::DEFAULT
661 || rSet.GetItemState(SID_SHOW_SLIDE(27000 +441)) == SfxItemState::DEFAULT)
662 {
663 model::PageEnumeration aSelectedPages (
664 model::PageEnumerationProvider::CreateSelectedPagesEnumeration(
665 mrSlideSorter.GetModel()));
666 const SlideExclusionState eState (GetSlideExclusionState(aSelectedPages));
667 switch (eState)
668 {
669 case MIXED:
670 // Show both entries.
671 break;
672
673 case EXCLUDED:
674 rSet.DisableItem(SID_HIDE_SLIDE( 10000 + 161 ));
675 break;
676
677 case INCLUDED:
678 rSet.DisableItem(SID_SHOW_SLIDE(27000 +441));
679 break;
680
681 case UNDEFINED:
682 rSet.DisableItem(SID_HIDE_SLIDE( 10000 + 161 ));
683 rSet.DisableItem(SID_SHOW_SLIDE(27000 +441));
684 break;
685 }
686 }
687
688 if (eEditMode == EditMode::MasterPage)
689 {
690 // Disable some slots when in master page mode.
691 rSet.DisableItem(SID_ASSIGN_LAYOUT(27000 +435));
692 rSet.DisableItem(SID_INSERTPAGE(27000 +14));
693
694 if (rSet.GetItemState(SID_DUPLICATE_PAGE(27000 +342)) == SfxItemState::DEFAULT)
695 rSet.DisableItem(SID_DUPLICATE_PAGE(27000 +342));
696 }
697}
698
699void SlotManager::GetClipboardState ( SfxItemSet& rSet)
700{
701 SdTransferable* pTransferClip = SD_MOD()( static_cast<SdModule*>(SfxApplication::GetModule(SfxToolsModule
::Draw)) )
->pTransferClip;
702
703 if (rSet.GetItemState(SID_PASTE(5000 + 712)) == SfxItemState::DEFAULT
704 || rSet.GetItemState(SID_PASTE_SPECIAL(5000 + 311)) == SfxItemState::DEFAULT)
705 {
706 // no own clipboard data?
707 if ( !pTransferClip || !pTransferClip->GetDocShell().is() )
708 {
709 rSet.DisableItem(SID_PASTE(5000 + 712));
710 rSet.DisableItem(SID_PASTE_SPECIAL(5000 + 311));
711 }
712 else
713 {
714 SfxObjectShell* pTransferDocShell = pTransferClip->GetDocShell().get();
715
716 if( !pTransferDocShell || static_cast<DrawDocShell*>(pTransferDocShell)->GetDoc()->GetPageCount() <= 1 )
717 {
718 bool bIsPastingSupported (false);
719
720 // No or just one page. Check if there is anything that can be
721 // pasted via a DrawViewShell.
722 ViewShellBase* pBase = mrSlideSorter.GetViewShellBase();
723 if (pBase != nullptr)
724 {
725 std::shared_ptr<DrawViewShell> pDrawViewShell (
726 std::dynamic_pointer_cast<DrawViewShell>(pBase->GetMainViewShell()));
727 if (pDrawViewShell != nullptr)
728 {
729 TransferableDataHelper aDataHelper (
730 TransferableDataHelper::CreateFromSystemClipboard(
731 pDrawViewShell->GetActiveWindow()));
732 if (aDataHelper.GetFormatCount() > 0)
733 bIsPastingSupported = true;
734 }
735 }
736
737 if ( ! bIsPastingSupported)
738 {
739 rSet.DisableItem(SID_PASTE(5000 + 712));
740 rSet.DisableItem(SID_PASTE_SPECIAL(5000 + 311));
741 }
742 }
743 }
744 }
745
746 // Cut, copy and paste of master pages is not yet implemented properly
747 if (rSet.GetItemState(SID_COPY(5000 + 711)) == SfxItemState::DEFAULT
748 || rSet.GetItemState(SID_PASTE(5000 + 712)) == SfxItemState::DEFAULT
749 || rSet.GetItemState(SID_PASTE_SPECIAL(5000 + 311)) == SfxItemState::DEFAULT
750 || rSet.GetItemState(SID_CUT(5000 + 710)) == SfxItemState::DEFAULT)
751 {
752 if (mrSlideSorter.GetModel().GetEditMode() == EditMode::MasterPage)
753 {
754 if (rSet.GetItemState(SID_CUT(5000 + 710)) == SfxItemState::DEFAULT)
755 rSet.DisableItem(SID_CUT(5000 + 710));
756 if (rSet.GetItemState(SID_COPY(5000 + 711)) == SfxItemState::DEFAULT)
757 rSet.DisableItem(SID_COPY(5000 + 711));
758 if (rSet.GetItemState(SID_PASTE(5000 + 712)) == SfxItemState::DEFAULT)
759 rSet.DisableItem(SID_PASTE(5000 + 712));
760 if (rSet.GetItemState(SID_PASTE_SPECIAL(5000 + 311)) == SfxItemState::DEFAULT)
761 rSet.DisableItem(SID_PASTE_SPECIAL(5000 + 311));
762 }
763 }
764
765 ViewShellBase* pBase = mrSlideSorter.GetViewShellBase();
766 if (pBase && pBase->GetObjectShell()->isContentExtractionLocked())
767 {
768 rSet.DisableItem(SID_COPY(5000 + 711));
769 rSet.DisableItem(SID_CUT(5000 + 710));
770 }
771
772 // Cut, copy, and delete page are disabled when there is no selection.
773 if (!(rSet.GetItemState(SID_CUT(5000 + 710)) == SfxItemState::DEFAULT
774 || rSet.GetItemState(SID_COPY(5000 + 711)) == SfxItemState::DEFAULT
775 || rSet.GetItemState(SID_DELETE(5000 + 713)) == SfxItemState::DEFAULT
776 || rSet.GetItemState(SID_DELETE_PAGE(27000 +80)) == SfxItemState::DEFAULT
777 || rSet.GetItemState(SID_DELETE_MASTER_PAGE(27000 +432)) == SfxItemState::DEFAULT))
778 return;
779
780 model::PageEnumeration aSelectedPages (
781 model::PageEnumerationProvider::CreateSelectedPagesEnumeration(
782 mrSlideSorter.GetModel()));
783
784 // For copy to work we have to have at least one selected page.
785 if ( ! aSelectedPages.HasMoreElements())
786 rSet.DisableItem(SID_COPY(5000 + 711));
787
788 bool bDisable = false;
789 // The operations that lead to the deletion of a page are valid if
790 // a) there is at least one selected page
791 // b) deleting the selected pages leaves at least one page in the
792 // document
793 // c) selected master pages must not be used by slides.
794
795 // Test a).
796 if ( ! aSelectedPages.HasMoreElements())
797 bDisable = true;
798 // Test b): Count the number of selected pages. It has to be less
799 // than the number of all pages.
800 else if (mrSlideSorter.GetController().GetPageSelector().GetSelectedPageCount()
801 >= mrSlideSorter.GetController().GetPageSelector().GetPageCount())
802 bDisable = true;
803 // Test c): Iterate over the selected pages and look for a master
804 // page that is used by at least one page.
805 else while (aSelectedPages.HasMoreElements())
806 {
807 SdPage* pPage = aSelectedPages.GetNextElement()->GetPage();
808 int nUseCount (mrSlideSorter.GetModel().GetDocument()
809 ->GetMasterPageUserCount(pPage));
810 if (nUseCount > 0)
811 {
812 bDisable = true;
813 break;
814 }
815 }
816
817 if (bDisable)
818 {
819 rSet.DisableItem(SID_CUT(5000 + 710));
820 rSet.DisableItem(SID_DELETE_PAGE(27000 +80));
821 rSet.DisableItem(SID_DELETE_MASTER_PAGE(27000 +432));
822 }
823}
824
825void SlotManager::GetStatusBarState (SfxItemSet& rSet)
826{
827 // page view and layout
828 SdPage* pPage = nullptr;
829 sal_uInt16 nSelectedPages = mrSlideSorter.GetController().GetPageSelector().GetSelectedPageCount();
830
831 //Set number of slides
832 if (nSelectedPages > 0)
833 {
834 model::PageEnumeration aSelectedPages (
835 model::PageEnumerationProvider::CreateSelectedPagesEnumeration(
836 mrSlideSorter.GetModel()));
837 model::SharedPageDescriptor pDescriptor (aSelectedPages.GetNextElement());
838 OUString aPageStr;
839 if (pDescriptor)
840 {
841 pPage = pDescriptor->GetPage();
842 sal_uInt16 nFirstPage = (pPage->GetPageNum()/2) + 1;
843 sal_Int32 nPageCount = mrSlideSorter.GetModel().GetPageCount();
844 sal_Int32 nActivePageCount = static_cast<sal_Int32>(mrSlideSorter.GetModel().GetDocument()->GetActiveSdPageCount());
845
846 aPageStr = (nPageCount == nActivePageCount) ? SdResId(STR_SD_PAGE_COUNTreinterpret_cast<char const *>("STR_SD_PAGE_COUNT" "\004"
u8"Slide %1 of %2")
) : SdResId(STR_SD_PAGE_COUNT_CUSTOMreinterpret_cast<char const *>("STR_SD_PAGE_COUNT_CUSTOM"
"\004" u8"Slide %1 of %2 (%3)")
);
847
848 aPageStr = aPageStr.replaceFirst("%1", OUString::number(nFirstPage));
849 aPageStr = aPageStr.replaceFirst("%2", OUString::number(nPageCount));
850 if(nPageCount != nActivePageCount)
851 aPageStr = aPageStr.replaceFirst("%3", OUString::number(nActivePageCount));
852 }
853 rSet.Put( SfxStringItem( SID_STATUS_PAGE(27000 +86), aPageStr ) );
854 }
855 //Set layout
856 if (nSelectedPages == 1 && pPage != nullptr)
857 {
858 SdPage* pFirstPage = pPage;
859 OUString aLayoutStr = pFirstPage->GetLayoutName();
860 sal_Int32 nIndex = aLayoutStr.indexOf( SD_LT_SEPARATOR"~LT~" );
861 if( nIndex != -1 )
862 aLayoutStr = aLayoutStr.copy(0, nIndex);
863 rSet.Put( SfxStringItem( SID_STATUS_LAYOUT(27000 +87), aLayoutStr ) );
864 }
865}
866
867void SlotManager::RenameSlide(const SfxRequest& rRequest)
868{
869 View* pDrView = &mrSlideSorter.GetView();
870
871 if ( pDrView->IsTextEdit() )
872 {
873 pDrView->SdrEndTextEdit();
874 }
875
876 SdPage* pSelectedPage = nullptr;
877 model::PageEnumeration aSelectedPages (
878 model::PageEnumerationProvider::CreateSelectedPagesEnumeration(
879 mrSlideSorter.GetModel()));
880 if (aSelectedPages.HasMoreElements())
881 pSelectedPage = aSelectedPages.GetNextElement()->GetPage();
882 if (pSelectedPage == nullptr)
883 return;
884
885 // tdf#107183 Set different dialog titles when renaming
886 // master slides or normal ones
887 OUString aTitle;
888 if( rRequest.GetSlot() == SID_RENAME_MASTER_PAGE(27000 +433) )
889 aTitle = SdResId( STR_TITLE_RENAMEMASTERreinterpret_cast<char const *>("STR_TITLE_RENAMEMASTER"
"\004" u8"Rename Master Slide")
);
890 else if (pDrView->GetDoc().GetDocumentType() == DocumentType::Draw)
891 aTitle = SdResId( STR_TITLE_RENAMEPAGEreinterpret_cast<char const *>("STR_TITLE_RENAMEPAGE" "\004"
u8"Rename Page")
);
892 else
893 aTitle = SdResId( STR_TITLE_RENAMESLIDEreinterpret_cast<char const *>("STR_TITLE_RENAMESLIDE" "\004"
u8"Rename Slide")
);
894
895 OUString aDescr( SdResId( STR_DESC_RENAMESLIDEreinterpret_cast<char const *>("STR_DESC_RENAMESLIDE" "\004"
u8"Name")
) );
896 OUString aPageName = pSelectedPage->GetName();
897
898 if(rRequest.GetArgs())
899 {
900 OUString aName = rRequest.GetArgs()->GetItem<const SfxStringItem>(SID_RENAMEPAGE(27000 +268))->GetValue();
901
902 bool bResult = RenameSlideFromDrawViewShell(pSelectedPage->GetPageNum()/2, aName );
903 DBG_ASSERT( bResult, "Couldn't rename slide or page" )do { if (true && (!(bResult))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx"
":" "903" ": "), "%s", "Couldn't rename slide or page"); } }
while (false)
;
904 }
905 else
906 {
907 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
908 vcl::Window* pWin = mrSlideSorter.GetContentWindow();
909 ScopedVclPtr<AbstractSvxNameDialog> aNameDlg(pFact->CreateSvxNameDialog(
910 pWin ? pWin->GetFrameWeld() : nullptr,
911 aPageName, aDescr));
912 OUString aOldName;
913 aNameDlg->GetName( aOldName );
914 aNameDlg->SetText( aTitle );
915 aNameDlg->SetCheckNameHdl( LINK( this, SlotManager, RenameSlideHdl )::tools::detail::makeLink( ::tools::detail::castTo<SlotManager
*>(this), &SlotManager::LinkStubRenameSlideHdl)
, true );
916 aNameDlg->SetCheckNameTooltipHdl( LINK( this, SlotManager, RenameSlideTooltipHdl )::tools::detail::makeLink( ::tools::detail::castTo<SlotManager
*>(this), &SlotManager::LinkStubRenameSlideTooltipHdl
)
);
917 aNameDlg->SetEditHelpId( HID_SD_NAMEDIALOG_PAGE"SD_HID_SD_NAMEDIALOG_PAGE" );
918
919 if( aNameDlg->Execute() == RET_OK )
920 {
921 OUString aNewName;
922 aNameDlg->GetName( aNewName );
923 if (aNewName != aPageName)
924 {
925 bool bResult =
926 RenameSlideFromDrawViewShell(
927 pSelectedPage->GetPageNum()/2, aNewName );
928 DBG_ASSERT( bResult, "Couldn't rename slide or page" )do { if (true && (!(bResult))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx"
":" "928" ": "), "%s", "Couldn't rename slide or page"); } }
while (false)
;
929 }
930 }
931 OUString aNewName;
932 aNameDlg->GetName( aNewName );
933 collectUIInformation({{"OldName", aOldName}, {"NewName", aNewName}}, "RENAME");
934 aNameDlg.disposeAndClear();
935 }
936 // Tell the slide sorter about the name change (necessary for
937 // accessibility.)
938 mrSlideSorter.GetController().PageNameHasChanged(
939 (pSelectedPage->GetPageNum()-1)/2, aPageName);
940}
941
942IMPL_LINK(SlotManager, RenameSlideHdl, AbstractSvxNameDialog&, rDialog, bool)bool SlotManager::LinkStubRenameSlideHdl(void * instance, AbstractSvxNameDialog
& data) { return static_cast<SlotManager *>(instance
)->RenameSlideHdl(data); } bool SlotManager::RenameSlideHdl
(AbstractSvxNameDialog& rDialog)
943{
944 OUString aNewName;
945 rDialog.GetName( aNewName );
946
947 model::SharedPageDescriptor pDescriptor (
948 mrSlideSorter.GetController().GetCurrentSlideManager()->GetCurrentSlide());
949 SdPage* pCurrentPage = nullptr;
950 if (pDescriptor)
951 pCurrentPage = pDescriptor->GetPage();
952
953 return (pCurrentPage!=nullptr && aNewName == pCurrentPage->GetName())
954 || (mrSlideSorter.GetViewShell()
955 && mrSlideSorter.GetViewShell()->GetDocSh()->IsNewPageNameValid( aNewName ) );
956}
957
958IMPL_STATIC_LINK_NOARG(SlotManager, RenameSlideTooltipHdl, AbstractSvxNameDialog&, OUString)OUString SlotManager::LinkStubRenameSlideTooltipHdl(void * instance
, AbstractSvxNameDialog& data) { return RenameSlideTooltipHdl
(static_cast<SlotManager *>(instance), data); } OUString
SlotManager::RenameSlideTooltipHdl( __attribute__ ((unused))
SlotManager *, __attribute__ ((unused)) AbstractSvxNameDialog
&)
959{
960 return SdResId(STR_TOOLTIP_RENAMEreinterpret_cast<char const *>("STR_TOOLTIP_RENAME" "\004"
u8"Duplicate or empty names are not possible")
);
961}
962
963bool SlotManager::RenameSlideFromDrawViewShell( sal_uInt16 nPageId, const OUString & rName )
964{
965 bool bOutDummy;
966 SdDrawDocument* pDocument = mrSlideSorter.GetModel().GetDocument();
967 if( pDocument->GetPageByName( rName, bOutDummy ) != SDRPAGE_NOTFOUND0xFFFF )
968 return false;
969
970 SdPage* pPageToRename = nullptr;
971
972 SfxUndoManager* pManager = pDocument->GetDocSh()->GetUndoManager();
973
974 if( mrSlideSorter.GetModel().GetEditMode() == EditMode::Page )
975 {
976 model::SharedPageDescriptor pDescriptor (
977 mrSlideSorter.GetController().GetCurrentSlideManager()->GetCurrentSlide());
978 if (pDescriptor)
979 pPageToRename = pDescriptor->GetPage();
980
981 if (pPageToRename != nullptr)
982 {
983 // Undo
984 SdPage* pUndoPage = pPageToRename;
985 SdrLayerAdmin & rLayerAdmin = pDocument->GetLayerAdmin();
986 SdrLayerID nBackground = rLayerAdmin.GetLayerID(sUNO_LayerName_background);
987 SdrLayerID nBgObj = rLayerAdmin.GetLayerID(sUNO_LayerName_background_objects);
988 SdrLayerIDSet aVisibleLayers = pPageToRename->TRG_GetMasterPageVisibleLayers();
989
990 // (#67720#)
991 pManager->AddUndoAction(
992 std::make_unique<ModifyPageUndoAction>(
993 pDocument, pUndoPage, rName, pUndoPage->GetAutoLayout(),
994 aVisibleLayers.IsSet( nBackground ),
995 aVisibleLayers.IsSet( nBgObj )));
996
997 // rename
998 pPageToRename->SetName( rName );
999
1000 // also rename notes-page
1001 SdPage* pNotesPage = pDocument->GetSdPage( nPageId, PageKind::Notes );
1002 if (pNotesPage != nullptr)
1003 pNotesPage->SetName (rName);
1004 }
1005 }
1006 else
1007 {
1008 // rename MasterPage -> rename LayoutTemplate
1009 pPageToRename = pDocument->GetMasterSdPage( nPageId, PageKind::Standard );
1010 if (pPageToRename != nullptr)
1011 {
1012 const OUString aOldLayoutName( pPageToRename->GetLayoutName() );
1013 pManager->AddUndoAction( std::make_unique<RenameLayoutTemplateUndoAction>( pDocument, aOldLayoutName, rName ) );
1014 pDocument->RenameLayoutTemplate( aOldLayoutName, rName );
1015 }
1016 }
1017
1018 bool bSuccess = pPageToRename!=nullptr && ( rName == pPageToRename->GetName() );
1019
1020 if( bSuccess )
1021 {
1022 // user edited page names may be changed by the page so update control
1023 // aTabControl.SetPageText( nPageId, rName );
1024
1025 // set document to modified state
1026 pDocument->SetChanged();
1027
1028 // inform navigator about change
1029 SfxBoolItem aItem( SID_NAVIGATOR_INIT(27000 +289), true );
1030 if (mrSlideSorter.GetViewShell() != nullptr)
1031 mrSlideSorter.GetViewShell()->GetDispatcher()->ExecuteList(
1032 SID_NAVIGATOR_INIT(27000 +289),
1033 SfxCallMode::ASYNCHRON | SfxCallMode::RECORD,
1034 { &aItem });
1035 }
1036
1037 return bSuccess;
1038}
1039
1040/** Insert a slide. The insertion position depends on a) the selection and
1041 b) the mouse position when there is no selection.
1042
1043 When there is a selection then insertion takes place after the last
1044 slide of the selection. For this to work all but the last selected
1045 slide are deselected first.
1046
1047 Otherwise, when there is no selection but the insertion marker is visible
1048 the slide is inserted at that position. The slide before that marker is
1049 selected first.
1050
1051 When both the selection and the insertion marker are not visible--can
1052 that happen?--the new slide is inserted after the last slide.
1053*/
1054void SlotManager::InsertSlide (SfxRequest& rRequest)
1055{
1056 const sal_Int32 nInsertionIndex (GetInsertionPosition());
1057
1058 PageSelector::BroadcastLock aBroadcastLock (mrSlideSorter);
1059
1060 SdPage* pNewPage = nullptr;
1061 if (mrSlideSorter.GetModel().GetEditMode() == EditMode::Page)
1062 {
1063 SlideSorterViewShell* pShell = dynamic_cast<SlideSorterViewShell*>(
1064 mrSlideSorter.GetViewShell());
1065 if (pShell != nullptr)
1066 {
1067 pNewPage = pShell->CreateOrDuplicatePage (
1068 rRequest,
1069 PageKind::Standard,
1070 nInsertionIndex>=0
1071 ? mrSlideSorter.GetModel().GetPageDescriptor(nInsertionIndex)->GetPage()
1072 : nullptr);
1073 }
1074 }
1075 else
1076 {
1077 // Use the API to create a new page.
1078 SdDrawDocument* pDocument = mrSlideSorter.GetModel().GetDocument();
1079 Reference<drawing::XMasterPagesSupplier> xMasterPagesSupplier (
1080 pDocument->getUnoModel(), UNO_QUERY);
1081 if (xMasterPagesSupplier.is())
1082 {
1083 Reference<drawing::XDrawPages> xMasterPages (
1084 xMasterPagesSupplier->getMasterPages());
1085 if (xMasterPages.is())
1086 {
1087 xMasterPages->insertNewByIndex (nInsertionIndex+1);
1088
1089 // Create shapes for the default layout.
1090 pNewPage = pDocument->GetMasterSdPage(
1091 static_cast<sal_uInt16>(nInsertionIndex+1), PageKind::Standard);
1092 pNewPage->CreateTitleAndLayout (true,true);
1093 }
1094 }
1095 }
1096 if (pNewPage == nullptr)
1097 return;
1098
1099 // When a new page has been inserted then select it, make it the
1100 // current page, and focus it.
1101 view::SlideSorterView::DrawLock aDrawLock (mrSlideSorter);
1102 PageSelector::UpdateLock aUpdateLock (mrSlideSorter);
1103 mrSlideSorter.GetController().GetPageSelector().DeselectAllPages();
1104 mrSlideSorter.GetController().GetPageSelector().SelectPage(pNewPage);
1105 collectUIInformation({{"POS", OUString::number(nInsertionIndex + 2)}}, "Insert_New_Page_or_Slide");
1106}
1107
1108void SlotManager::DuplicateSelectedSlides (SfxRequest& rRequest)
1109{
1110 // Create a list of the pages that are to be duplicated. The process of
1111 // duplication alters the selection.
1112 sal_Int32 nInsertPosition (0);
1113 ::std::vector<SdPage*> aPagesToDuplicate;
1114 model::PageEnumeration aSelectedPages (
1115 model::PageEnumerationProvider::CreateSelectedPagesEnumeration(mrSlideSorter.GetModel()));
1116 while (aSelectedPages.HasMoreElements())
1117 {
1118 model::SharedPageDescriptor pDescriptor (aSelectedPages.GetNextElement());
1119 if (pDescriptor && pDescriptor->GetPage())
1120 {
1121 aPagesToDuplicate.push_back(pDescriptor->GetPage());
1122 nInsertPosition = pDescriptor->GetPage()->GetPageNum()+2;
1123 }
1124 }
1125
1126 // Duplicate the pages in aPagesToDuplicate and collect the newly
1127 // created pages in aPagesToSelect.
1128 const bool bUndo (aPagesToDuplicate.size()>1 && mrSlideSorter.GetView().IsUndoEnabled());
1129 if (bUndo)
1130 mrSlideSorter.GetView().BegUndo(SdResId(STR_INSERTPAGEreinterpret_cast<char const *>("STR_INSERTPAGE" "\004" u8"Insert Slide"
)
));
1131
1132 ::std::vector<SdPage*> aPagesToSelect;
1133 for(const auto& rpPage : aPagesToDuplicate)
1134 {
1135 aPagesToSelect.push_back(
1136 mrSlideSorter.GetViewShell()->CreateOrDuplicatePage(
1137 rRequest, PageKind::Standard, rpPage, nInsertPosition));
1138 nInsertPosition += 2;
1139 }
1140 aPagesToDuplicate.clear();
1141
1142 if (bUndo)
1143 mrSlideSorter.GetView().EndUndo();
1144
1145 // Set the selection to the pages in aPagesToSelect.
1146 PageSelector& rSelector (mrSlideSorter.GetController().GetPageSelector());
1147 rSelector.DeselectAllPages();
1148 for (auto const& it: aPagesToSelect)
1149 {
1150 rSelector.SelectPage(it);
1151 }
1152
1153 collectUIInformation({{"POS", OUString::number(nInsertPosition + 2)}}, "Duplicate");
1154}
1155
1156void SlotManager::ChangeSlideExclusionState (
1157 const model::SharedPageDescriptor& rpDescriptor,
1158 const bool bExcludeSlide)
1159{
1160 if (rpDescriptor)
1161 {
1162 mrSlideSorter.GetView().SetState(
1163 rpDescriptor,
1164 model::PageDescriptor::ST_Excluded,
1165 bExcludeSlide);
1166 }
1167 else
1168 {
1169 model::PageEnumeration aSelectedPages (
1170 model::PageEnumerationProvider::CreateSelectedPagesEnumeration(
1171 mrSlideSorter.GetModel()));
1172 while (aSelectedPages.HasMoreElements())
1173 {
1174 model::SharedPageDescriptor pDescriptor (aSelectedPages.GetNextElement());
1175 mrSlideSorter.GetView().SetState(
1176 pDescriptor,
1177 model::PageDescriptor::ST_Excluded,
1178 bExcludeSlide);
1179 }
1180 }
1181
1182 SfxBindings& rBindings (mrSlideSorter.GetViewShell()->GetViewFrame()->GetBindings());
1183 rBindings.Invalidate(SID_PRESENTATION( 10000 + 157 ));
1184 rBindings.Invalidate(SID_REHEARSE_TIMINGS( 10000 + 159 ));
1185 rBindings.Invalidate(SID_HIDE_SLIDE( 10000 + 161 ));
1186 rBindings.Invalidate(SID_SHOW_SLIDE(27000 +441));
1187 mrSlideSorter.GetModel().GetDocument()->SetChanged();
1188}
1189
1190sal_Int32 SlotManager::GetInsertionPosition() const
1191{
1192 PageSelector& rSelector (mrSlideSorter.GetController().GetPageSelector());
1193
1194 // The insertion indicator is preferred. After all the user explicitly
1195 // used it to define the insertion position.
1196 if (mrSlideSorter.GetController().GetInsertionIndicatorHandler()->IsActive())
1197 {
1198 // Select the page before the insertion indicator.
1199 return mrSlideSorter.GetController().GetInsertionIndicatorHandler()->GetInsertionPageIndex()
1200 - 1;
1201 }
1202
1203 // Is there a stored insertion position?
1204 else if (mrSlideSorter.GetController().GetSelectionManager()->GetInsertionPosition() >= 0)
1205 {
1206 return mrSlideSorter.GetController().GetSelectionManager()->GetInsertionPosition() - 1;
1207 }
1208
1209 // Use the index of the last selected slide.
1210 else if (rSelector.GetSelectedPageCount() > 0)
1211 {
1212 for (int nIndex=rSelector.GetPageCount()-1; nIndex>=0; --nIndex)
1213 if (rSelector.IsPageSelected(nIndex))
1214 return nIndex;
1215
1216 // We should never get here.
1217 OSL_ASSERT(false)do { if (true && (!(false))) { sal_detail_logFormat((
SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx"
":" "1217" ": "), "OSL_ASSERT: %s", "false"); } } while (false
)
;
1218 return rSelector.GetPageCount() - 1;
1219 }
1220
1221 // Select the last page when there is at least one page.
1222 else if (rSelector.GetPageCount() > 0)
1223 {
1224 return rSelector.GetPageCount() - 1;
1225 }
1226
1227 // Hope for the best that CreateOrDuplicatePage() can cope with an empty
1228 // selection.
1229 else
1230 {
1231 // We should never get here because there has to be at least one page.
1232 OSL_ASSERT(false)do { if (true && (!(false))) { sal_detail_logFormat((
SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx"
":" "1232" ": "), "OSL_ASSERT: %s", "false"); } } while (false
)
;
1233 return -1;
1234 }
1235}
1236
1237void SlotManager::NotifyEditModeChange()
1238{
1239 SfxBindings& rBindings (mrSlideSorter.GetViewShell()->GetViewFrame()->GetBindings());
1240 rBindings.Invalidate(SID_PRESENTATION( 10000 + 157 ));
1241 rBindings.Invalidate(SID_INSERTPAGE(27000 +14));
1242 rBindings.Invalidate(SID_DUPLICATE_PAGE(27000 +342));
1243}
1244
1245namespace {
1246
1247SlideExclusionState GetSlideExclusionState (model::PageEnumeration& rPageSet)
1248{
1249 SlideExclusionState eState (UNDEFINED);
1250
1251 // Get toggle state of the selected pages.
1252 while (rPageSet.HasMoreElements() && eState!=MIXED)
1253 {
1254 const bool bState = rPageSet.GetNextElement()->GetPage()->IsExcluded();
1255 switch (eState)
1256 {
1257 case UNDEFINED:
1258 // Use the first selected page to set the initial value.
1259 eState = bState ? EXCLUDED : INCLUDED;
1260 break;
1261
1262 case EXCLUDED:
1263 // The pages before where all not part of the show,
1264 // this one is.
1265 if ( ! bState)
1266 eState = MIXED;
1267 break;
1268
1269 case INCLUDED:
1270 // The pages before where all part of the show,
1271 // this one is not.
1272 if (bState)
1273 eState = MIXED;
1274 break;
1275
1276 default:
1277 // No need to change anything.
1278 break;
1279 }
1280 }
1281
1282 return eState;
1283}
1284
1285} // end of anonymous namespace
1286
1287} // end of namespace ::sd::slidesorter::controller
1288
1289/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx

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
20#ifndef INCLUDED_VCL_PTR_HXX
21#define INCLUDED_VCL_PTR_HXX
22
23#include <sal/config.h>
24
25#include <rtl/ref.hxx>
26
27#include <utility>
28#include <type_traits>
29
30#ifdef DBG_UTIL
31#ifndef _WIN32
32#include <vcl/vclmain.hxx>
33#endif
34#endif
35
36class VclReferenceBase;
37
38namespace vcl::detail {
39
40template<typename>
41constexpr bool isIncompleteOrDerivedFromVclReferenceBase(...) { return true; }
42
43template<typename T> constexpr bool isIncompleteOrDerivedFromVclReferenceBase(
44 int (*)[sizeof(T)])
45{ return std::is_base_of<VclReferenceBase, T>::value; }
46
47} // namespace vcl::detail
48
49/**
50 * A thin wrapper around rtl::Reference to implement the acquire and dispose semantics we want for references to vcl::Window subclasses.
51 *
52 * For more details on the design please see vcl/README.lifecycle
53 *
54 * @param reference_type must be a subclass of vcl::Window
55 */
56template <class reference_type>
57class VclPtr
58{
59 static_assert(
60 vcl::detail::isIncompleteOrDerivedFromVclReferenceBase<reference_type>(
61 nullptr),
62 "template argument type must be derived from VclReferenceBase");
63
64 ::rtl::Reference<reference_type> m_rInnerRef;
65
66public:
67 /** Constructor...
68 */
69 VclPtr()
70 : m_rInnerRef()
71 {}
72
73 /** Constructor...
74 */
75 VclPtr (reference_type * pBody)
76 : m_rInnerRef(pBody)
77 {}
78
79 /** Constructor... that doesn't take a ref.
80 */
81 VclPtr (reference_type * pBody, __sal_NoAcquire)
82 : m_rInnerRef(pBody, SAL_NO_ACQUIRE)
83 {}
84
85 /** Up-casting conversion constructor: Copies interface reference.
86
87 Does not work for up-casts to ambiguous bases. For the special case of
88 up-casting to Reference< XInterface >, see the corresponding conversion
89 operator.
90
91 @param rRef another reference
92 */
93 template< class derived_type >
94 VclPtr(
95 const VclPtr< derived_type > & rRef,
96 typename std::enable_if<
97 std::is_base_of<reference_type, derived_type>::value, int>::type
98 = 0 )
99 : m_rInnerRef( static_cast<reference_type*>(rRef) )
100 {
101 }
102
103#if defined(DBG_UTIL) && !defined(_WIN32)
104 virtual ~VclPtr()
105 {
106 assert(m_rInnerRef.get() == nullptr || vclmain::isAlive())(static_cast <bool> (m_rInnerRef.get() == nullptr || vclmain
::isAlive()) ? void (0) : __assert_fail ("m_rInnerRef.get() == nullptr || vclmain::isAlive()"
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 106, __extension__ __PRETTY_FUNCTION__))
;
107 // We can be one of the intermediate counts, but if we are the last
108 // VclPtr keeping this object alive, then something forgot to call dispose().
109 assert((!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1)(static_cast <bool> ((!m_rInnerRef.get() || m_rInnerRef
->isDisposed() || m_rInnerRef->getRefCount() > 1) &&
"someone forgot to call dispose()") ? void (0) : __assert_fail
("(!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1) && \"someone forgot to call dispose()\""
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 110, __extension__ __PRETTY_FUNCTION__))
110 && "someone forgot to call dispose()")(static_cast <bool> ((!m_rInnerRef.get() || m_rInnerRef
->isDisposed() || m_rInnerRef->getRefCount() > 1) &&
"someone forgot to call dispose()") ? void (0) : __assert_fail
("(!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1) && \"someone forgot to call dispose()\""
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 110, __extension__ __PRETTY_FUNCTION__))
;
111 }
112 VclPtr(VclPtr const &) = default;
113 VclPtr(VclPtr &&) = default;
114 VclPtr & operator =(VclPtr const &) = default;
115 VclPtr & operator =(VclPtr &&) = default;
116#endif
117
118 /**
119 * A construction helper for VclPtr. Since VclPtr types are created
120 * with a reference-count of one - to help fit into the existing
121 * code-flow; this helps us to construct them easily.
122 *
123 * For more details on the design please see vcl/README.lifecycle
124 *
125 * @tparam reference_type must be a subclass of vcl::Window
126 */
127 template<typename... Arg> [[nodiscard]] static VclPtr< reference_type > Create(Arg &&... arg)
128 {
129 return VclPtr< reference_type >( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE );
130 }
131
132 /** Probably most common used: handle->someBodyOp().
133 */
134 reference_type * operator->() const
135 {
136 return m_rInnerRef.get();
25
Calling 'Reference::get'
137 }
138
139 /** Get the body. Can be used instead of operator->().
140 I.e. handle->someBodyOp() and handle.get()->someBodyOp()
141 are the same.
142 */
143 reference_type * get() const
144 {
145 return m_rInnerRef.get();
146 }
147
148 void set(reference_type *pBody)
149 {
150 m_rInnerRef.set(pBody);
151 }
152
153 void reset(reference_type *pBody)
154 {
155 m_rInnerRef.set(pBody);
156 }
157
158 /** Up-casting copy assignment operator.
159
160 Does not work for up-casts to ambiguous bases.
161
162 @param rRef another reference
163 */
164 template<typename derived_type>
165 typename std::enable_if<
166 std::is_base_of<reference_type, derived_type>::value,
167 VclPtr &>::type
168 operator =(VclPtr<derived_type> const & rRef)
169 {
170 m_rInnerRef.set(rRef.get());
171 return *this;
172 }
173
174 VclPtr & operator =(reference_type * pBody)
175 {
176 m_rInnerRef.set(pBody);
177 return *this;
178 }
179
180 operator reference_type * () const
181 {
182 return m_rInnerRef.get();
183 }
184
185 explicit operator bool () const
186 {
187 return m_rInnerRef.get() != nullptr;
188 }
189
190 void clear()
191 {
192 m_rInnerRef.clear();
193 }
194
195 void reset()
196 {
197 m_rInnerRef.clear();
198 }
199
200 void disposeAndClear()
201 {
202 // hold it alive for the lifetime of this method
203 ::rtl::Reference<reference_type> aTmp(m_rInnerRef);
204 m_rInnerRef.clear(); // we should use some 'swap' method ideally ;-)
205 if (aTmp.get()) {
206 aTmp->disposeOnce();
207 }
208 }
209
210 /** Needed to place VclPtr's into STL collection.
211 */
212 bool operator< (const VclPtr<reference_type> & handle) const
213 {
214 return (m_rInnerRef < handle.m_rInnerRef);
215 }
216}; // class VclPtr
217
218template<typename T1, typename T2>
219inline bool operator ==(VclPtr<T1> const & p1, VclPtr<T2> const & p2) {
220 return p1.get() == p2.get();
221}
222
223template<typename T> inline bool operator ==(VclPtr<T> const & p1, T const * p2)
224{
225 return p1.get() == p2;
226}
227
228template<typename T> inline bool operator ==(VclPtr<T> const & p1, T * p2) {
229 return p1.get() == p2;
230}
231
232template<typename T> inline bool operator ==(T const * p1, VclPtr<T> const & p2)
233{
234 return p1 == p2.get();
235}
236
237template<typename T> inline bool operator ==(T * p1, VclPtr<T> const & p2) {
238 return p1 == p2.get();
239}
240
241template<typename T1, typename T2>
242inline bool operator !=(VclPtr<T1> const & p1, VclPtr<T2> const & p2) {
243 return !(p1 == p2);
244}
245
246template<typename T> inline bool operator !=(VclPtr<T> const & p1, T const * p2)
247{
248 return !(p1 == p2);
249}
250
251template<typename T> inline bool operator !=(VclPtr<T> const & p1, T * p2) {
252 return !(p1 == p2);
253}
254
255template<typename T> inline bool operator !=(T const * p1, VclPtr<T> const & p2)
256{
257 return !(p1 == p2);
258}
259
260template<typename T> inline bool operator !=(T * p1, VclPtr<T> const & p2) {
261 return !(p1 == p2);
262}
263
264/**
265 * A construction helper for a temporary VclPtr. Since VclPtr types
266 * are created with a reference-count of one - to help fit into
267 * the existing code-flow; this helps us to construct them easily.
268 * see also VclPtr::Create and ScopedVclPtr
269 *
270 * For more details on the design please see vcl/README.lifecycle
271 *
272 * @param reference_type must be a subclass of vcl::Window
273 */
274template <class reference_type>
275class SAL_WARN_UNUSED__attribute__((warn_unused)) VclPtrInstance final : public VclPtr<reference_type>
276{
277public:
278 template<typename... Arg> VclPtrInstance(Arg &&... arg)
279 : VclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE )
280 {
281 }
282
283 /**
284 * Override and disallow this, to prevent people accidentally calling it and actually
285 * getting VclPtr::Create and getting a naked VclPtr<> instance
286 */
287 template<typename... Arg> static VclPtrInstance< reference_type > Create(Arg &&... ) = delete;
288};
289
290template <class reference_type>
291class ScopedVclPtr : public VclPtr<reference_type>
292{
293public:
294 /** Constructor...
295 */
296 ScopedVclPtr()
297 : VclPtr<reference_type>()
298 {}
299
300 /** Constructor
301 */
302 ScopedVclPtr (reference_type * pBody)
303 : VclPtr<reference_type>(pBody)
304 {}
305
306 /** Copy constructor...
307 */
308 ScopedVclPtr (const VclPtr<reference_type> & handle)
309 : VclPtr<reference_type>(handle)
7
Calling implicit copy constructor for 'VclPtr<VclAbstractDialog>'
8
Calling copy constructor for 'Reference<VclAbstractDialog>'
11
Returning from copy constructor for 'Reference<VclAbstractDialog>'
12
Returning from copy constructor for 'VclPtr<VclAbstractDialog>'
310 {}
311
312 /**
313 Assignment that releases the last reference.
314 */
315 void disposeAndReset(reference_type *pBody)
316 {
317 if (pBody != this->get()) {
318 VclPtr<reference_type>::disposeAndClear();
319 VclPtr<reference_type>::set(pBody);
320 }
321 }
322
323 /**
324 Assignment that releases the last reference.
325 */
326 ScopedVclPtr<reference_type>& operator = (reference_type * pBody)
327 {
328 disposeAndReset(pBody);
329 return *this;
330 }
331
332 /** Up-casting conversion constructor: Copies interface reference.
333
334 Does not work for up-casts to ambiguous bases. For the special case of
335 up-casting to Reference< XInterface >, see the corresponding conversion
336 operator.
337
338 @param rRef another reference
339 */
340 template< class derived_type >
341 ScopedVclPtr(
342 const VclPtr< derived_type > & rRef,
343 typename std::enable_if<
344 std::is_base_of<reference_type, derived_type>::value, int>::type
345 = 0 )
346 : VclPtr<reference_type>( rRef )
347 {
348 }
349
350 /** Up-casting assignment operator.
351
352 Does not work for up-casts to ambiguous bases.
353
354 @param rRef another VclPtr
355 */
356 template<typename derived_type>
357 typename std::enable_if<
358 std::is_base_of<reference_type, derived_type>::value,
359 ScopedVclPtr &>::type
360 operator =(VclPtr<derived_type> const & rRef)
361 {
362 disposeAndReset(rRef.get());
363 return *this;
364 }
365
366 /**
367 * Override and disallow this, to prevent people accidentally calling it and actually
368 * getting VclPtr::Create and getting a naked VclPtr<> instance
369 */
370 template<typename... Arg> static ScopedVclPtr< reference_type > Create(Arg &&... ) = delete;
371
372 ~ScopedVclPtr()
373 {
374 VclPtr<reference_type>::disposeAndClear();
375 assert(VclPtr<reference_type>::get() == nullptr)(static_cast <bool> (VclPtr<reference_type>::get(
) == nullptr) ? void (0) : __assert_fail ("VclPtr<reference_type>::get() == nullptr"
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 375, __extension__ __PRETTY_FUNCTION__))
; // make sure there are no lingering references
376 }
377
378private:
379 // Most likely we don't want this default copy-constructor.
380 ScopedVclPtr (const ScopedVclPtr<reference_type> &) = delete;
381 // And certainly we don't want a default assignment operator.
382 ScopedVclPtr<reference_type>& operator = (const ScopedVclPtr<reference_type> &) = delete;
383 // And disallow reset as that doesn't call disposeAndClear on the original reference
384 void reset() = delete;
385 void reset(reference_type *pBody) = delete;
386
387protected:
388 ScopedVclPtr (reference_type * pBody, __sal_NoAcquire)
389 : VclPtr<reference_type>(pBody, SAL_NO_ACQUIRE)
390 {}
391};
392
393/**
394 * A construction helper for ScopedVclPtr. Since VclPtr types are created
395 * with a reference-count of one - to help fit into the existing
396 * code-flow; this helps us to construct them easily.
397 *
398 * For more details on the design please see vcl/README.lifecycle
399 *
400 * @param reference_type must be a subclass of vcl::Window
401 */
402#if defined _MSC_VER
403#pragma warning(push)
404#pragma warning(disable: 4521) // " multiple copy constructors specified"
405#endif
406template <class reference_type>
407class SAL_WARN_UNUSED__attribute__((warn_unused)) ScopedVclPtrInstance final : public ScopedVclPtr<reference_type>
408{
409public:
410 template<typename... Arg> ScopedVclPtrInstance(Arg &&... arg)
411 : ScopedVclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE )
412 {
413 }
414
415 /**
416 * Override and disallow this, to prevent people accidentally calling it and actually
417 * getting VclPtr::Create and getting a naked VclPtr<> instance
418 */
419 template<typename... Arg> static ScopedVclPtrInstance< reference_type > Create(Arg &&...) = delete;
420
421private:
422 // Prevent the above perfect forwarding ctor from hijacking (accidental)
423 // attempts at ScopedVclPtrInstance copy construction (where the hijacking
424 // would typically lead to somewhat obscure error messages); both non-const
425 // and const variants are needed here, as the ScopedVclPtr base class has a
426 // const--variant copy ctor, so the implicitly declared copy ctor for
427 // ScopedVclPtrInstance would also be the const variant, so non-const copy
428 // construction attempts would be hijacked by the perfect forwarding ctor;
429 // but if we only declared a non-const variant here, the const variant would
430 // no longer be implicitly declared (as there would already be an explicitly
431 // declared copy ctor), so const copy construction attempts would then be
432 // hijacked by the perfect forwarding ctor:
433 ScopedVclPtrInstance(ScopedVclPtrInstance &) = delete;
434 ScopedVclPtrInstance(ScopedVclPtrInstance const &) = delete;
435};
436#if defined _MSC_VER
437#pragma warning(pop)
438#endif
439
440#endif // INCLUDED_VCL_PTR_HXX
441
442/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/rtl/ref.hxx

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
20#ifndef INCLUDED_RTL_REF_HXX
21#define INCLUDED_RTL_REF_HXX
22
23#include "sal/config.h"
24
25#include <cassert>
26#include <cstddef>
27#include <functional>
28#ifdef LIBO_INTERNAL_ONLY1
29#include <type_traits>
30#endif
31
32#include "sal/types.h"
33
34namespace rtl
35{
36
37/** Template reference class for reference type.
38*/
39template <class reference_type>
40class Reference
41{
42 /** The <b>reference_type</b> body pointer.
43 */
44 reference_type * m_pBody;
45
46
47public:
48 /** Constructor...
49 */
50 Reference()
51 : m_pBody (NULL__null)
52 {}
53
54
55 /** Constructor...
56 */
57 Reference (reference_type * pBody, __sal_NoAcquire)
58 : m_pBody (pBody)
59 {
60 }
61
62 /** Constructor...
63 */
64 Reference (reference_type * pBody)
65 : m_pBody (pBody)
66 {
67 if (m_pBody)
68 m_pBody->acquire();
69 }
70
71 /** Copy constructor...
72 */
73 Reference (const Reference<reference_type> & handle)
74 : m_pBody (handle.m_pBody)
75 {
76 if (m_pBody)
9
Assuming field 'm_pBody' is non-null
10
Taking true branch
77 m_pBody->acquire();
78 }
79
80#ifdef LIBO_INTERNAL_ONLY1
81 /** Move constructor...
82 */
83 Reference (Reference<reference_type> && handle) noexcept
84 : m_pBody (handle.m_pBody)
85 {
86 handle.m_pBody = nullptr;
87 }
88#endif
89
90#if defined LIBO_INTERNAL_ONLY1
91 /** Up-casting conversion constructor: Copies interface reference.
92
93 Does not work for up-casts to ambiguous bases.
94
95 @param rRef another reference
96 */
97 template< class derived_type >
98 inline Reference(
99 const Reference< derived_type > & rRef,
100 std::enable_if_t<std::is_base_of_v<reference_type, derived_type>, int> = 0 )
101 : m_pBody (rRef.get())
102 {
103 if (m_pBody)
104 m_pBody->acquire();
105 }
106#endif
107
108 /** Destructor...
109 */
110 ~Reference() COVERITY_NOEXCEPT_FALSE
111 {
112 if (m_pBody
15.1
Field 'm_pBody' is non-null
15.1
Field 'm_pBody' is non-null
15.1
Field 'm_pBody' is non-null
15.1
Field 'm_pBody' is non-null
)
16
Taking true branch
113 m_pBody->release();
17
Calling 'VclReferenceBase::release'
21
Returning; memory was released
114 }
115
116 /** Set...
117 Similar to assignment.
118 */
119 Reference<reference_type> &
120 SAL_CALL set (reference_type * pBody)
121 {
122 if (pBody)
123 pBody->acquire();
124 reference_type * const pOld = m_pBody;
125 m_pBody = pBody;
126 if (pOld)
127 pOld->release();
128 return *this;
129 }
130
131 /** Assignment.
132 Unbinds this instance from its body (if bound) and
133 bind it to the body represented by the handle.
134 */
135 Reference<reference_type> &
136 SAL_CALL operator= (const Reference<reference_type> & handle)
137 {
138 return set( handle.m_pBody );
139 }
140
141#ifdef LIBO_INTERNAL_ONLY1
142 /** Assignment.
143 * Unbinds this instance from its body (if bound),
144 * bind it to the body represented by the handle, and
145 * set the body represented by the handle to nullptr.
146 */
147 Reference<reference_type> &
148 operator= (Reference<reference_type> && handle)
149 {
150 // self-movement guts ourself
151 if (m_pBody)
152 m_pBody->release();
153 m_pBody = handle.m_pBody;
154 handle.m_pBody = nullptr;
155 return *this;
156 }
157#endif
158
159 /** Assignment...
160 */
161 Reference<reference_type> &
162 SAL_CALL operator= (reference_type * pBody)
163 {
164 return set( pBody );
165 }
166
167 /** Unbind the body from this handle.
168 Note that for a handle representing a large body,
169 "handle.clear().set(new body());" _might_
170 perform a little bit better than "handle.set(new body());",
171 since in the second case two large objects exist in memory
172 (the old body and the new body).
173 */
174 Reference<reference_type> & SAL_CALL clear()
175 {
176 if (m_pBody)
177 {
178 reference_type * const pOld = m_pBody;
179 m_pBody = NULL__null;
180 pOld->release();
181 }
182 return *this;
183 }
184
185
186 /** Get the body. Can be used instead of operator->().
187 I.e. handle->someBodyOp() and handle.get()->someBodyOp()
188 are the same.
189 */
190 reference_type * SAL_CALL get() const
191 {
192 return m_pBody;
26
Use of memory after it is freed
193 }
194
195
196 /** Probably most common used: handle->someBodyOp().
197 */
198 reference_type * SAL_CALL operator->() const
199 {
200 assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail
("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx"
, 200, __extension__ __PRETTY_FUNCTION__))
;
201 return m_pBody;
202 }
203
204
205 /** Allows (*handle).someBodyOp().
206 */
207 reference_type & SAL_CALL operator*() const
208 {
209 assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail
("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx"
, 209, __extension__ __PRETTY_FUNCTION__))
;
210 return *m_pBody;
211 }
212
213
214 /** Returns True if the handle does point to a valid body.
215 */
216 bool SAL_CALL is() const
217 {
218 return (m_pBody != NULL__null);
219 }
220
221#if defined LIBO_INTERNAL_ONLY1
222 /** Returns True if the handle does point to a valid body.
223 */
224 explicit operator bool() const
225 {
226 return is();
227 }
228#endif
229
230 /** Returns True if this points to pBody.
231 */
232 bool SAL_CALL operator== (const reference_type * pBody) const
233 {
234 return (m_pBody == pBody);
235 }
236
237
238 /** Returns True if handle points to the same body.
239 */
240 bool
241 SAL_CALL operator== (const Reference<reference_type> & handle) const
242 {
243 return (m_pBody == handle.m_pBody);
244 }
245
246
247 /** Needed to place References into STL collection.
248 */
249 bool
250 SAL_CALL operator!= (const Reference<reference_type> & handle) const
251 {
252 return (m_pBody != handle.m_pBody);
253 }
254
255
256 /** Needed to place References into STL collection.
257 */
258 bool
259 SAL_CALL operator< (const Reference<reference_type> & handle) const
260 {
261 return (m_pBody < handle.m_pBody);
262 }
263
264
265 /** Needed to place References into STL collection.
266 */
267 bool
268 SAL_CALL operator> (const Reference<reference_type> & handle) const
269 {
270 return (m_pBody > handle.m_pBody);
271 }
272};
273
274} // namespace rtl
275
276#if defined LIBO_INTERNAL_ONLY1
277namespace std
278{
279
280/// @cond INTERNAL
281/**
282 Make rtl::Reference hashable by default for use in STL containers.
283
284 @since LibreOffice 6.3
285*/
286template<typename T>
287struct hash<::rtl::Reference<T>>
288{
289 std::size_t operator()(::rtl::Reference<T> const & s) const
290 { return std::size_t(s.get()); }
291};
292/// @endcond
293
294}
295
296#endif
297
298#endif /* ! INCLUDED_RTL_REF_HXX */
299
300/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/vcl/vclreferencebase.hxx

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#ifndef INCLUDED_VCL_Reference_HXX
20#define INCLUDED_VCL_Reference_HXX
21
22#include <vcl/dllapi.h>
23#include <osl/interlck.h>
24
25class VCL_DLLPUBLIC__attribute__ ((visibility("default"))) VclReferenceBase
26{
27 mutable oslInterlockedCount mnRefCnt;
28
29 template<typename T> friend class VclPtr;
30
31public:
32 void acquire() const
33 {
34 osl_atomic_increment(&mnRefCnt)__sync_add_and_fetch((&mnRefCnt), 1);
35 }
36
37 void release() const
38 {
39 if (osl_atomic_decrement(&mnRefCnt)__sync_sub_and_fetch((&mnRefCnt), 1) == 0)
18
Assuming the condition is true
19
Taking true branch
40 delete this;
20
Memory is released
41 }
42#ifdef DBG_UTIL
43#ifndef _WIN32
44 sal_Int32 getRefCount() const { return mnRefCnt; }
45#endif
46#endif
47
48
49private:
50 VclReferenceBase(const VclReferenceBase&) = delete;
51 VclReferenceBase& operator=(const VclReferenceBase&) = delete;
52
53 bool mbDisposed : 1;
54
55protected:
56 VclReferenceBase();
57protected:
58 virtual ~VclReferenceBase();
59
60protected:
61 virtual void dispose();
62
63public:
64 void disposeOnce();
65 bool isDisposed() const { return mbDisposed; }
66
67};
68#endif