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 fupage.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/func/fupage.cxx

/home/maarten/src/libreoffice/core/sd/source/ui/func/fupage.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 <fupage.hxx>
21
22// arrange Tab-Page
23
24#include <sfx2/sfxdlg.hxx>
25#include <svx/pageitem.hxx>
26#include <svx/svxids.hrc>
27#include <svl/itempool.hxx>
28#include <sfx2/request.hxx>
29#include <vcl/prntypes.hxx>
30#include <vcl/graphicfilter.hxx>
31#include <stlsheet.hxx>
32#include <editeng/eeitem.hxx>
33#include <editeng/frmdiritem.hxx>
34#include <svx/graphichelper.hxx>
35#include <svx/xfillit0.hxx>
36#include <svx/xbtmpit.hxx>
37#include <svx/xflbstit.hxx>
38#include <svx/xflbmtit.hxx>
39#include <svx/xflgrit.hxx>
40#include <editeng/ulspitem.hxx>
41#include <editeng/lrspitem.hxx>
42#include <svx/sdr/properties/properties.hxx>
43#include <editeng/shaditem.hxx>
44#include <editeng/boxitem.hxx>
45#include <editeng/sizeitem.hxx>
46#include <editeng/pbinitem.hxx>
47#include <sfx2/opengrf.hxx>
48
49#include <strings.hrc>
50#include <sdpage.hxx>
51#include <View.hxx>
52#include <Window.hxx>
53#include <pres.hxx>
54#include <drawdoc.hxx>
55#include <DrawDocShell.hxx>
56#include <ViewShell.hxx>
57#include <DrawViewShell.hxx>
58#include <app.hrc>
59#include <unchss.hxx>
60#include <undoback.hxx>
61#include <sdabstdlg.hxx>
62#include <sdresid.hxx>
63
64#include <memory>
65
66using namespace com::sun::star;
67
68namespace sd {
69
70// 50 cm 28350
71// adapted from writer
72#define MAXHEIGHT28350 28350
73#define MAXWIDTH28350 28350
74
75
76static void mergeItemSetsImpl( SfxItemSet& rTarget, const SfxItemSet& rSource )
77{
78 const sal_uInt16* pPtr = rSource.GetRanges();
79 sal_uInt16 p1, p2;
80 while( *pPtr )
81 {
82 p1 = pPtr[0];
83 p2 = pPtr[1];
84
85 // make ranges discrete
86 while(pPtr[2] && (pPtr[2] - p2 == 1))
87 {
88 p2 = pPtr[3];
89 pPtr += 2;
90 }
91 rTarget.MergeRange( p1, p2 );
92 pPtr += 2;
93 }
94
95 rTarget.Put(rSource);
96}
97
98FuPage::FuPage( ViewShell* pViewSh, ::sd::Window* pWin, ::sd::View* pView,
99 SdDrawDocument* pDoc, SfxRequest& rReq )
100: FuPoor(pViewSh, pWin, pView, pDoc, rReq),
101 mrReq(rReq),
102 mpArgs( rReq.GetArgs() ),
103 mbPageBckgrdDeleted( false ),
104 mbMasterPage( false ),
105 mbDisplayBackgroundTabPage( true ),
106 mpPage(nullptr),
107 mpDrawViewShell(nullptr)
108{
109}
110
111rtl::Reference<FuPoor> FuPage::Create( ViewShell* pViewSh, ::sd::Window* pWin, ::sd::View* pView, SdDrawDocument* pDoc, SfxRequest& rReq )
112{
113 rtl::Reference<FuPoor> xFunc( new FuPage( pViewSh, pWin, pView, pDoc, rReq ) );
114 xFunc->DoExecute(rReq);
115 return xFunc;
116}
117
118void FuPage::DoExecute(SfxRequest& rReq)
119{
120 mpDrawViewShell = dynamic_cast<DrawViewShell*>(mpViewShell);
121 DBG_ASSERT( mpDrawViewShell, "sd::FuPage::FuPage(), called without a current DrawViewShell!" )do { if (true && (!(mpDrawViewShell))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sd/source/ui/func/fupage.cxx"
":" "121" ": "), "%s", "sd::FuPage::FuPage(), called without a current DrawViewShell!"
); } } while (false)
;
1
Assuming field 'mpDrawViewShell' is non-null
2
Taking false branch
3
Loop condition is false. Exiting loop
122
123 if( mpDrawViewShell
3.1
Field 'mpDrawViewShell' is non-null
3.1
Field 'mpDrawViewShell' is non-null
3.1
Field 'mpDrawViewShell' is non-null
3.1
Field 'mpDrawViewShell' is non-null
)
4
Taking true branch
124 {
125 mbMasterPage = mpDrawViewShell->GetEditMode() == EditMode::MasterPage;
5
Assuming the condition is false
126 // we don't really want to format page background with SID_ATTR_PAGE[_SIZE] slots
127 mbDisplayBackgroundTabPage = ( mpDrawViewShell->GetPageKind() == PageKind::Standard) &&
6
Assuming the condition is false
128 ( nSlotId != SID_ATTR_PAGE_SIZETypedWhichId<SvxSizeItem>( 10000 + 51 )) && ( nSlotId != SID_ATTR_PAGETypedWhichId<SvxPageItem>( 10000 + 50 ) );
129 mpPage = mpDrawViewShell->getCurrentPage();
130 }
131
132 if( !mpPage )
7
Assuming field 'mpPage' is non-null
8
Taking false branch
133 return;
134
135 // if there are no arguments given, open the dialog
136 const SfxPoolItem* pItem;
137 if (!mpArgs || mpArgs->GetItemState(SID_SELECT_BACKGROUND(27000 +422), true, &pItem) == SfxItemState::SET)
9
Assuming field 'mpArgs' is non-null
10
Assuming the condition is true
11
Taking true branch
138 {
139 mpView->SdrEndTextEdit();
140 mpArgs = ExecuteDialog(mpWindow ? mpWindow->GetFrameWeld() : nullptr, rReq);
12
'?' condition is false
13
Calling 'FuPage::ExecuteDialog'
141 }
142
143 // if we now have arguments, apply them to current page
144 if( mpArgs )
145 {
146 ApplyItemSet( mpArgs );
147 }
148}
149
150FuPage::~FuPage()
151{
152}
153
154void FuPage::Activate()
155{
156}
157
158void FuPage::Deactivate()
159{
160}
161
162void MergePageBackgroundFilling(SdPage *pPage, SdStyleSheet *pStyleSheet, bool bMasterPage, SfxItemSet& rMergedAttr)
163{
164 if (bMasterPage)
165 {
166 if (pStyleSheet)
167 mergeItemSetsImpl(rMergedAttr, pStyleSheet->GetItemSet());
168 }
169 else
170 {
171 // Only this page, get attributes for background fill
172 const SfxItemSet& rBackgroundAttributes = pPage->getSdrPageProperties().GetItemSet();
173
174 if(drawing::FillStyle_NONE != rBackgroundAttributes.Get(XATTR_FILLSTYLE).GetValue())
175 {
176 // page attributes are used, take them
177 rMergedAttr.Put(rBackgroundAttributes);
178 }
179 else
180 {
181 if(pStyleSheet
182 && drawing::FillStyle_NONE != pStyleSheet->GetItemSet().Get(XATTR_FILLSTYLE).GetValue())
183 {
184 // if the page has no fill style, use the settings from the
185 // background stylesheet (if used)
186 mergeItemSetsImpl(rMergedAttr, pStyleSheet->GetItemSet());
187 }
188 else
189 {
190 // no fill style from page, start with no fill style
191 rMergedAttr.Put(XFillStyleItem(drawing::FillStyle_NONE));
192 }
193 }
194 }
195}
196
197const SfxItemSet* FuPage::ExecuteDialog(weld::Window* pParent, const SfxRequest& rReq)
198{
199 if (!mpDrawViewShell
13.1
Field 'mpDrawViewShell' is non-null
13.1
Field 'mpDrawViewShell' is non-null
13.1
Field 'mpDrawViewShell' is non-null
13.1
Field 'mpDrawViewShell' is non-null
)
14
Taking false branch
200 return nullptr;
201
202 SfxItemSet aNewAttr(mpDoc->GetPool(),
203 {{mpDoc->GetPool().GetWhich(SID_ATTR_LRSPACE( 10000 + 48 )),
204 mpDoc->GetPool().GetWhich(SID_ATTR_ULSPACE( 10000 + 49 ))},
205 {SID_ATTR_PAGETypedWhichId<SvxPageItem>( 10000 + 50 ), SID_ATTR_PAGE_SHAREDTypedWhichId<SfxBoolItem>( 10000 + 61 )},
206 {SID_ATTR_BORDER_OUTER( 10000 + 24 ), SID_ATTR_BORDER_OUTER( 10000 + 24 )},
207 {SID_ATTR_BORDER_SHADOW( 10000 + 25 ), SID_ATTR_BORDER_SHADOW( 10000 + 25 )},
208 {XATTR_FILL_FIRST, XATTR_FILL_LAST},
209 {SID_ATTR_PAGE_COLOR( 10000 + 1152 ),SID_ATTR_PAGE_FILLSTYLE( 10000 + 1157 )},
210 {EE_PARA_WRITINGDIR, EE_PARA_WRITINGDIR}});
211
212 // Retrieve additional data for dialog
213
214 SvxShadowItem aShadowItem(SID_ATTR_BORDER_SHADOW( 10000 + 25 ));
215 aNewAttr.Put( aShadowItem );
216 SvxBoxItem aBoxItem( SID_ATTR_BORDER_OUTER( 10000 + 24 ) );
217 aNewAttr.Put( aBoxItem );
218
219 aNewAttr.Put( SvxFrameDirectionItem(
220 mpDoc->GetDefaultWritingMode() == css::text::WritingMode_RL_TB ? SvxFrameDirection::Horizontal_RL_TB : SvxFrameDirection::Horizontal_LR_TB,
15
Assuming the condition is false
16
'?' condition is false
221 EE_PARA_WRITINGDIR ) );
222
223 // Retrieve page-data for dialog
224
225 SvxPageItem aPageItem( SID_ATTR_PAGETypedWhichId<SvxPageItem>( 10000 + 50 ) );
226 aPageItem.SetDescName( mpPage->GetName() );
227 aPageItem.SetPageUsage( SvxPageUsage::All );
228 aPageItem.SetLandscape( mpPage->GetOrientation() == Orientation::Landscape );
17
Assuming the condition is false
229 aPageItem.SetNumType( mpDoc->GetPageNumType() );
230 aNewAttr.Put( aPageItem );
231
232 // size
233 maSize = mpPage->GetSize();
234 SvxSizeItem aSizeItem( SID_ATTR_PAGE_SIZETypedWhichId<SvxSizeItem>( 10000 + 51 ), maSize );
235 aNewAttr.Put( aSizeItem );
236
237 // Max size
238 SvxSizeItem aMaxSizeItem( SID_ATTR_PAGE_MAXSIZETypedWhichId<SvxSizeItem>( 10000 + 52 ), Size( MAXWIDTH28350, MAXHEIGHT28350 ) );
239 aNewAttr.Put( aMaxSizeItem );
240
241 // paperbin
242 SvxPaperBinItem aPaperBinItem( SID_ATTR_PAGE_PAPERBINTypedWhichId<SvxPaperBinItem>( 10000 + 54 ), static_cast<sal_uInt8>(mpPage->GetPaperBin()) );
243 aNewAttr.Put( aPaperBinItem );
244
245 SvxLRSpaceItem aLRSpaceItem( static_cast<sal_uInt16>(mpPage->GetLeftBorder()), static_cast<sal_uInt16>(mpPage->GetRightBorder()), 0, 0, mpDoc->GetPool().GetWhich(SID_ATTR_LRSPACE( 10000 + 48 )));
246 aNewAttr.Put( aLRSpaceItem );
247
248 SvxULSpaceItem aULSpaceItem( static_cast<sal_uInt16>(mpPage->GetUpperBorder()), static_cast<sal_uInt16>(mpPage->GetLowerBorder()), mpDoc->GetPool().GetWhich(SID_ATTR_ULSPACE( 10000 + 49 )));
249 aNewAttr.Put( aULSpaceItem );
250
251 // Application
252 bool bScale = mpDoc->GetDocumentType() != DocumentType::Draw;
18
Assuming the condition is false
253 aNewAttr.Put( SfxBoolItem( SID_ATTR_PAGE_EXT1( 10000 + 55 ), bScale ) );
254
255 bool bFullSize = mpPage->IsMasterPage() ?
19
Assuming the condition is true
20
'?' condition is true
256 mpPage->IsBackgroundFullSize() : static_cast<SdPage&>(mpPage->TRG_GetMasterPage()).IsBackgroundFullSize();
257
258 aNewAttr.Put( SfxBoolItem( SID_ATTR_PAGE_EXT2TypedWhichId<SfxBoolItem>( 10000 + 56 ), bFullSize ) );
259
260 // Merge ItemSet for dialog
261
262 const sal_uInt16* pPtr = aNewAttr.GetRanges();
263 sal_uInt16 p1 = pPtr[0], p2 = pPtr[1];
264 while(pPtr[2] && (pPtr[2] - p2 == 1))
21
Assuming the condition is false
265 {
266 p2 = pPtr[3];
267 pPtr += 2;
268 }
269 SfxItemSet aMergedAttr( *aNewAttr.GetPool(), {{p1, p2}} );
270
271 mergeItemSetsImpl( aMergedAttr, aNewAttr );
272
273 SdStyleSheet* pStyleSheet = mpPage->getPresentationStyle(HID_PSEUDOSHEET_BACKGROUND((32768 +27000) + 97));
274
275 // merge page background filling to the dialogs input set
276 if( mbDisplayBackgroundTabPage
21.1
Field 'mbDisplayBackgroundTabPage' is false
21.1
Field 'mbDisplayBackgroundTabPage' is false
21.1
Field 'mbDisplayBackgroundTabPage' is false
21.1
Field 'mbDisplayBackgroundTabPage' is false
)
22
Taking false branch
277 {
278 MergePageBackgroundFilling(mpPage, pStyleSheet, mbMasterPage, aMergedAttr);
279 }
280
281 std::unique_ptr< SfxItemSet > pTempSet;
282
283 const sal_uInt16 nId = GetSlotID();
284 if (nId == SID_SAVE_BACKGROUND(27000 +423))
23
Assuming the condition is false
24
Taking false branch
285 {
286 const XFillStyleItem& rStyleItem = aMergedAttr.Get(XATTR_FILLSTYLE);
287 if (drawing::FillStyle_BITMAP == rStyleItem.GetValue())
288 {
289 const XFillBitmapItem& rBitmap = aMergedAttr.Get(XATTR_FILLBITMAP);
290 const GraphicObject& rGraphicObj = rBitmap.GetGraphicObject();
291 GraphicHelper::ExportGraphic(pParent, rGraphicObj.GetGraphic(), "");
292 }
293 }
294 else if (nId == SID_SELECT_BACKGROUND(27000 +422))
25
Assuming the condition is false
26
Taking false branch
295 {
296 Graphic aGraphic;
297 ErrCode nError = ERRCODE_GRFILTER_OPENERRORErrCode(ErrCodeArea::Vcl, ErrCodeClass::General, 1);
298
299 const SfxItemSet* pArgs = rReq.GetArgs();
300 const SfxPoolItem* pItem;
301
302 if (pArgs && pArgs->GetItemState(SID_SELECT_BACKGROUND(27000 +422), true, &pItem) == SfxItemState::SET)
303 {
304 OUString aFileName(static_cast<const SfxStringItem*>(pItem)->GetValue());
305 OUString aFilterName;
306
307 if (pArgs->GetItemState(FN_PARAM_FILTER((20000 + 1100) + 30), true, &pItem) == SfxItemState::SET)
308 aFilterName = static_cast<const SfxStringItem*>(pItem)->GetValue();
309
310 nError = GraphicFilter::LoadGraphic(aFileName, aFilterName, aGraphic,
311 &GraphicFilter::GetGraphicFilter());
312 }
313 else
314 {
315 SvxOpenGraphicDialog aDlg(SdResId(STR_SET_BACKGROUND_PICTUREreinterpret_cast<char const *>("STR_SET_BACKGROUND_PICTURE"
"\004" u8"Set Background Image")
), pParent);
316
317 nError = aDlg.Execute();
318 if (nError == ERRCODE_NONEErrCode(0))
319 {
320 nError = aDlg.GetGraphic(aGraphic);
321 }
322 }
323
324 if (nError == ERRCODE_NONEErrCode(0))
325 {
326 pTempSet.reset( new SfxItemSet( mpDoc->GetPool(), svl::Items<XATTR_FILL_FIRST, XATTR_FILL_LAST>{}) );
327
328 pTempSet->Put( XFillStyleItem( drawing::FillStyle_BITMAP ) );
329
330 // MigrateItemSet makes sure the XFillBitmapItem will have a unique name
331 SfxItemSet aMigrateSet( mpDoc->GetPool(), svl::Items<XATTR_FILLBITMAP, XATTR_FILLBITMAP>{} );
332 aMigrateSet.Put(XFillBitmapItem("background", aGraphic));
333 SdrModel::MigrateItemSet( &aMigrateSet, pTempSet.get(), mpDoc );
334
335 pTempSet->Put( XFillBmpStretchItem( true ));
336 pTempSet->Put( XFillBmpTileItem( false ));
337 }
338 }
339
340 else
341 {
342 bool bIsImpressDoc = mpDrawViewShell->GetDoc()->GetDocumentType() == DocumentType::Impress;
27
Assuming the condition is false
343
344 // create the dialog
345 SdAbstractDialogFactory* pFact = SdAbstractDialogFactory::Create();
346 ScopedVclPtr<SfxAbstractTabDialog> pDlg( pFact->CreateSdTabPageDialog(mpViewShell->GetFrameWeld(), &aMergedAttr, mpDocSh, mbDisplayBackgroundTabPage, bIsImpressDoc) );
28
Calling constructor for 'ScopedVclPtr<SfxAbstractTabDialog>'
35
Returning from constructor for 'ScopedVclPtr<SfxAbstractTabDialog>'
36
Calling implicit destructor for 'VclPtr<SfxAbstractTabDialog>'
37
Calling '~Reference'
44
Returning from '~Reference'
45
Returning from destructor for 'VclPtr<SfxAbstractTabDialog>'
347 if( pDlg->Execute() == RET_OK )
46
Calling 'VclPtr::operator->'
348 pTempSet.reset( new SfxItemSet(*pDlg->GetOutputItemSet()) );
349 }
350
351 if (pTempSet && pStyleSheet)
352 {
353 pStyleSheet->AdjustToFontHeight(*pTempSet);
354
355 if( mbDisplayBackgroundTabPage )
356 {
357 // if some fillstyle-items are not set in the dialog, then
358 // try to use the items before
359 bool bChanges = false;
360 for( sal_uInt16 i=XATTR_FILL_FIRST; i<XATTR_FILL_LAST; i++ )
361 {
362 if( aMergedAttr.GetItemState( i ) != SfxItemState::DEFAULT )
363 {
364 if( pTempSet->GetItemState( i ) == SfxItemState::DEFAULT )
365 pTempSet->Put( aMergedAttr.Get( i ) );
366 else
367 if( aMergedAttr.GetItem( i ) != pTempSet->GetItem( i ) )
368 bChanges = true;
369 }
370 }
371
372 // if the background for this page was set to invisible, the background-object has to be deleted, too.
373 const XFillStyleItem* pTempFillStyleItem = pTempSet->GetItem<XFillStyleItem>(XATTR_FILLSTYLE);
374 assert(pTempFillStyleItem)(static_cast <bool> (pTempFillStyleItem) ? void (0) : __assert_fail
("pTempFillStyleItem", "/home/maarten/src/libreoffice/core/sd/source/ui/func/fupage.cxx"
, 374, __extension__ __PRETTY_FUNCTION__))
;
375 if (pTempFillStyleItem->GetValue() == drawing::FillStyle_NONE)
376 mbPageBckgrdDeleted = true;
377 else
378 {
379 if (pTempSet->GetItemState(XATTR_FILLSTYLE) == SfxItemState::DEFAULT)
380 {
381 const XFillStyleItem* pMergedFillStyleItem = aMergedAttr.GetItem<XFillStyleItem>(XATTR_FILLSTYLE);
382 assert(pMergedFillStyleItem)(static_cast <bool> (pMergedFillStyleItem) ? void (0) :
__assert_fail ("pMergedFillStyleItem", "/home/maarten/src/libreoffice/core/sd/source/ui/func/fupage.cxx"
, 382, __extension__ __PRETTY_FUNCTION__))
;
383 if (pMergedFillStyleItem->GetValue() == drawing::FillStyle_NONE)
384 mbPageBckgrdDeleted = true;
385 }
386 }
387
388 const XFillGradientItem* pTempGradItem = pTempSet->GetItem<XFillGradientItem>(XATTR_FILLGRADIENT);
389 if (pTempGradItem && pTempGradItem->GetName().isEmpty())
390 {
391 // MigrateItemSet guarantees unique gradient names
392 SfxItemSet aMigrateSet( mpDoc->GetPool(), svl::Items<XATTR_FILLGRADIENT, XATTR_FILLGRADIENT>{} );
393 aMigrateSet.Put( XFillGradientItem("gradient", pTempGradItem->GetGradientValue()) );
394 SdrModel::MigrateItemSet( &aMigrateSet, pTempSet.get(), mpDoc);
395 }
396
397 if( !mbMasterPage && bChanges && mbPageBckgrdDeleted )
398 {
399 mpBackgroundObjUndoAction.reset( new SdBackgroundObjUndoAction(
400 *mpDoc, *mpPage, mpPage->getSdrPageProperties().GetItemSet()) );
401
402 if(!mpPage->IsMasterPage())
403 {
404 // on normal pages, switch off fill attribute usage
405 SdrPageProperties& rPageProperties = mpPage->getSdrPageProperties();
406 rPageProperties.ClearItem( XATTR_FILLBITMAP );
407 rPageProperties.ClearItem( XATTR_FILLGRADIENT );
408 rPageProperties.ClearItem( XATTR_FILLHATCH );
409 rPageProperties.PutItem(XFillStyleItem(drawing::FillStyle_NONE));
410 }
411 }
412
413
414 /* Special treatment: reset the INVALIDS to
415 NULL-Pointer (otherwise INVALIDs or pointer point
416 to DefaultItems in the template; both would
417 prevent the attribute inheritance) */
418 pTempSet->ClearInvalidItems();
419
420 if( mbMasterPage )
421 {
422 mpDocSh->GetUndoManager()->AddUndoAction(std::make_unique<StyleSheetUndoAction>(
423 mpDoc, static_cast<SfxStyleSheet*>(pStyleSheet), &(*pTempSet)));
424 pStyleSheet->GetItemSet().Put( *pTempSet );
425 sdr::properties::CleanupFillProperties( pStyleSheet->GetItemSet() );
426 pStyleSheet->Broadcast(SfxHint(SfxHintId::DataChanged));
427 }
428
429 // if background filling is set to master pages then clear from page set
430 if( mbMasterPage )
431 {
432 for( sal_uInt16 nWhich = XATTR_FILL_FIRST; nWhich <= XATTR_FILL_LAST; nWhich++ )
433 {
434 pTempSet->ClearItem( nWhich );
435 }
436 pTempSet->Put(XFillStyleItem(drawing::FillStyle_NONE));
437 }
438
439 const SfxPoolItem *pItem;
440 if( SfxItemState::SET == pTempSet->GetItemState( EE_PARA_WRITINGDIR, false, &pItem ) )
441 {
442 SvxFrameDirection nVal = static_cast<const SvxFrameDirectionItem*>(pItem)->GetValue();
443 mpDoc->SetDefaultWritingMode( nVal == SvxFrameDirection::Horizontal_RL_TB ? css::text::WritingMode_RL_TB : css::text::WritingMode_LR_TB );
444 }
445
446 mpDoc->SetChanged();
447
448 // BackgroundFill of Masterpage: no hard attributes allowed
449 SdrPage& rUsedMasterPage = mpPage->IsMasterPage() ? *mpPage : mpPage->TRG_GetMasterPage();
450 OSL_ENSURE(rUsedMasterPage.IsMasterPage(), "No MasterPage (!)")do { if (true && (!(rUsedMasterPage.IsMasterPage())))
{ sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/home/maarten/src/libreoffice/core/sd/source/ui/func/fupage.cxx"
":" "450" ": "), "%s", "No MasterPage (!)"); } } while (false
)
;
451 rUsedMasterPage.getSdrPageProperties().ClearItem();
452 OSL_ENSURE(nullptr != rUsedMasterPage.getSdrPageProperties().GetStyleSheet(),do { if (true && (!(nullptr != rUsedMasterPage.getSdrPageProperties
().GetStyleSheet()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sd/source/ui/func/fupage.cxx"
":" "453" ": "), "%s", "MasterPage without StyleSheet detected (!)"
); } } while (false)
453 "MasterPage without StyleSheet detected (!)")do { if (true && (!(nullptr != rUsedMasterPage.getSdrPageProperties
().GetStyleSheet()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sd/source/ui/func/fupage.cxx"
":" "453" ": "), "%s", "MasterPage without StyleSheet detected (!)"
); } } while (false)
;
454 }
455
456 aNewAttr.Put(*pTempSet);
457 mrReq.Done( aNewAttr );
458
459 return mrReq.GetArgs();
460 }
461 else
462 {
463 return nullptr;
464 }
465}
466
467void FuPage::ApplyItemSet( const SfxItemSet* pArgs )
468{
469 if (!pArgs || !mpDrawViewShell)
470 return;
471
472 // Set new page-attributes
473 PageKind ePageKind = mpDrawViewShell->GetPageKind();
474 const SfxPoolItem* pPoolItem;
475 bool bSetPageSizeAndBorder = false;
476 Size aNewSize(maSize);
477 sal_Int32 nLeft = -1, nRight = -1, nUpper = -1, nLower = -1;
478 bool bScaleAll = true;
479 Orientation eOrientation = mpPage->GetOrientation();
480 SdPage* pMasterPage = mpPage->IsMasterPage() ? mpPage : &static_cast<SdPage&>(mpPage->TRG_GetMasterPage());
481 bool bFullSize = pMasterPage->IsBackgroundFullSize();
482 sal_uInt16 nPaperBin = mpPage->GetPaperBin();
483
484 if( pArgs->GetItemState(SID_ATTR_PAGETypedWhichId<SvxPageItem>( 10000 + 50 ), true, &pPoolItem) == SfxItemState::SET )
485 {
486 mpDoc->SetPageNumType(static_cast<const SvxPageItem*>(pPoolItem)->GetNumType());
487
488 eOrientation = static_cast<const SvxPageItem*>(pPoolItem)->IsLandscape() ?
489 Orientation::Landscape : Orientation::Portrait;
490
491 if( mpPage->GetOrientation() != eOrientation )
492 bSetPageSizeAndBorder = true;
493
494 mpDrawViewShell->ResetActualPage();
495 }
496
497 if( pArgs->GetItemState(SID_ATTR_PAGE_SIZETypedWhichId<SvxSizeItem>( 10000 + 51 ), true, &pPoolItem) == SfxItemState::SET )
498 {
499 aNewSize = static_cast<const SvxSizeItem*>(pPoolItem)->GetSize();
500
501 if( mpPage->GetSize() != aNewSize )
502 bSetPageSizeAndBorder = true;
503 }
504
505 if( pArgs->GetItemState(mpDoc->GetPool().GetWhich(SID_ATTR_LRSPACE( 10000 + 48 )),
506 true, &pPoolItem) == SfxItemState::SET )
507 {
508 nLeft = static_cast<const SvxLRSpaceItem*>(pPoolItem)->GetLeft();
509 nRight = static_cast<const SvxLRSpaceItem*>(pPoolItem)->GetRight();
510
511 if( mpPage->GetLeftBorder() != nLeft || mpPage->GetRightBorder() != nRight )
512 bSetPageSizeAndBorder = true;
513
514 }
515
516 if( pArgs->GetItemState(mpDoc->GetPool().GetWhich(SID_ATTR_ULSPACE( 10000 + 49 )),
517 true, &pPoolItem) == SfxItemState::SET )
518 {
519 nUpper = static_cast<const SvxULSpaceItem*>(pPoolItem)->GetUpper();
520 nLower = static_cast<const SvxULSpaceItem*>(pPoolItem)->GetLower();
521
522 if( mpPage->GetUpperBorder() != nUpper || mpPage->GetLowerBorder() != nLower )
523 bSetPageSizeAndBorder = true;
524 }
525
526 if( pArgs->GetItemState(mpDoc->GetPool().GetWhich(SID_ATTR_PAGE_EXT1( 10000 + 55 )), true, &pPoolItem) == SfxItemState::SET )
527 {
528 bScaleAll = static_cast<const SfxBoolItem*>(pPoolItem)->GetValue();
529 }
530
531 if( pArgs->GetItemState(mpDoc->GetPool().GetWhich(SID_ATTR_PAGE_EXT2TypedWhichId<SfxBoolItem>( 10000 + 56 )), true, &pPoolItem) == SfxItemState::SET )
532 {
533 bFullSize = static_cast<const SfxBoolItem*>(pPoolItem)->GetValue();
534
535 if(pMasterPage->IsBackgroundFullSize() != bFullSize )
536 bSetPageSizeAndBorder = true;
537 }
538
539 // Paper Bin
540 if( pArgs->GetItemState(mpDoc->GetPool().GetWhich(SID_ATTR_PAGE_PAPERBINTypedWhichId<SvxPaperBinItem>( 10000 + 54 )), true, &pPoolItem) == SfxItemState::SET )
541 {
542 nPaperBin = static_cast<const SvxPaperBinItem*>(pPoolItem)->GetValue();
543
544 if( mpPage->GetPaperBin() != nPaperBin )
545 bSetPageSizeAndBorder = true;
546 }
547
548 if (nLeft == -1 && nUpper != -1)
549 {
550 bSetPageSizeAndBorder = true;
551 nLeft = mpPage->GetLeftBorder();
552 nRight = mpPage->GetRightBorder();
553 }
554 else if (nLeft != -1 && nUpper == -1)
555 {
556 bSetPageSizeAndBorder = true;
557 nUpper = mpPage->GetUpperBorder();
558 nLower = mpPage->GetLowerBorder();
559 }
560
561 if( bSetPageSizeAndBorder || !mbMasterPage )
562 mpDrawViewShell->SetPageSizeAndBorder(ePageKind, aNewSize, nLeft, nRight, nUpper, nLower, bScaleAll, eOrientation, nPaperBin, bFullSize );
563
564 // if bMasterPage==sal_False then create a background-object for this page with the
565 // properties set in the dialog before, but if mbPageBckgrdDeleted==sal_True then
566 // the background of this page was set to invisible, so it would be a mistake
567 // to create a new background-object for this page !
568
569 if( mbDisplayBackgroundTabPage )
570 {
571 if( !mbMasterPage && !mbPageBckgrdDeleted )
572 {
573 // Only this page
574 mpBackgroundObjUndoAction.reset( new SdBackgroundObjUndoAction(
575 *mpDoc, *mpPage, mpPage->getSdrPageProperties().GetItemSet()) );
576 SfxItemSet aSet( *pArgs );
577 sdr::properties::CleanupFillProperties(aSet);
578 mpPage->getSdrPageProperties().ClearItem();
579 mpPage->getSdrPageProperties().PutItemSet(aSet);
580 }
581 }
582
583 // add undo action for background object
584 if( mpBackgroundObjUndoAction )
585 {
586 // set merge flag, because a SdUndoGroupAction could have been inserted before
587 mpDocSh->GetUndoManager()->AddUndoAction( std::move(mpBackgroundObjUndoAction), true );
588 }
589
590 // Objects can not be bigger than ViewSize
591 Size aPageSize = mpDoc->GetSdPage(0, ePageKind)->GetSize();
592 Size aViewSize(aPageSize.Width() * 3, aPageSize.Height() * 2);
593 mpDoc->SetMaxObjSize(aViewSize);
594
595 // if necessary, we tell Preview the new context
596 mpDrawViewShell->UpdatePreview( mpDrawViewShell->GetActualPage() );
597}
598
599} // end of namespace sd
600
601/* 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();
47
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)
29
Calling implicit copy constructor for 'VclPtr<SfxAbstractTabDialog>'
30
Calling copy constructor for 'Reference<SfxAbstractTabDialog>'
33
Returning from copy constructor for 'Reference<SfxAbstractTabDialog>'
34
Returning from copy constructor for 'VclPtr<SfxAbstractTabDialog>'
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)
31
Assuming field 'm_pBody' is non-null
32
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
37.1
Field 'm_pBody' is non-null
37.1
Field 'm_pBody' is non-null
37.1
Field 'm_pBody' is non-null
37.1
Field 'm_pBody' is non-null
)
38
Taking true branch
113 m_pBody->release();
39
Calling 'VclReferenceBase::release'
43
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;
48
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)
40
Assuming the condition is true
41
Taking true branch
40 delete this;
42
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