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 docshel4.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/docshell/docshel4.cxx

/home/maarten/src/libreoffice/core/sd/source/ui/docshell/docshel4.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 <sal/config.h>
21#include <sal/log.hxx>
22
23#include <memory>
24#include <utility>
25
26#include <DrawDocShell.hxx>
27#include <com/sun/star/document/PrinterIndependentLayout.hpp>
28#include <editeng/outlobj.hxx>
29#include <tools/urlobj.hxx>
30#include <svx/svxids.hrc>
31#include <editeng/editeng.hxx>
32#include <editeng/editstat.hxx>
33#include <editeng/flstitem.hxx>
34#include <svl/flagitem.hxx>
35#include <sot/storage.hxx>
36#include <sfx2/dinfdlg.hxx>
37#include <sfx2/docfile.hxx>
38#include <sfx2/docfilt.hxx>
39#include <sfx2/dispatch.hxx>
40#include <svx/svdotext.hxx>
41#include <sfx2/printer.hxx>
42#include <svtools/ctrltool.hxx>
43#include <comphelper/classids.hxx>
44#include <sot/formats.hxx>
45#include <sfx2/viewfrm.hxx>
46#include <vcl/syswin.hxx>
47#include <com/sun/star/drawing/XDrawPage.hpp>
48#include <com/sun/star/drawing/XDrawView.hpp>
49
50#include <app.hrc>
51#include <strings.hrc>
52#include <FrameView.hxx>
53#include <optsitem.hxx>
54#include <Outliner.hxx>
55#include <sdattr.hrc>
56#include <drawdoc.hxx>
57#include <ViewShell.hxx>
58#include <sdmod.hxx>
59#include <View.hxx>
60#include <EffectMigration.hxx>
61#include <CustomAnimationEffect.hxx>
62#include <sdpage.hxx>
63#include <sdresid.hxx>
64#include <DrawViewShell.hxx>
65#include <ViewShellBase.hxx>
66#include <Window.hxx>
67#include <OutlineView.hxx>
68#include <OutlineViewShell.hxx>
69#include <sdxmlwrp.hxx>
70#include <sdpptwrp.hxx>
71#include <sdcgmfilter.hxx>
72#include <sdgrffilter.hxx>
73#include <sdhtmlfilter.hxx>
74#include <sdpdffilter.hxx>
75#include <framework/FrameworkHelper.hxx>
76
77#include <sfx2/zoomitem.hxx>
78
79using namespace ::com::sun::star;
80using namespace ::com::sun::star::uno;
81using ::sd::framework::FrameworkHelper;
82
83// PowerPoint-Filter
84constexpr OUStringLiteral pFilterPowerPoint97( u"MS PowerPoint 97" );
85constexpr OUStringLiteral pFilterPowerPoint97Template( u"MS PowerPoint 97 Vorlage" );
86constexpr OUStringLiteral pFilterPowerPoint97AutoPlay( u"MS PowerPoint 97 AutoPlay" );
87
88namespace sd {
89
90/**
91 * Creates (if necessary) and returns a SfxPrinter
92 */
93SfxPrinter* DrawDocShell::GetPrinter(bool bCreate)
94{
95 if (bCreate && !mpPrinter)
96 {
97 // create ItemSet with special pool area
98 auto pSet = std::make_unique<SfxItemSet>( GetPool(),
99 svl::Items<SID_PRINTER_NOTFOUND_WARN(5000 + 320), SID_PRINTER_NOTFOUND_WARN(5000 + 320),
100 SID_PRINTER_CHANGESTODOC(5000 + 324), SID_PRINTER_CHANGESTODOC(5000 + 324),
101 ATTR_OPTIONS_PRINT27000 + 1234 + 6 + 1 + 15 + 1 + 10 + 1 + 5 + 1 + 7 + 1 + 2 + 1
+ 4
, ATTR_OPTIONS_PRINT27000 + 1234 + 6 + 1 + 15 + 1 + 10 + 1 + 5 + 1 + 7 + 1 + 2 + 1
+ 4
>{} );
102 // set PrintOptionsSet
103 SdOptionsPrintItem aPrintItem( SD_MOD()( static_cast<SdModule*>(SfxApplication::GetModule(SfxToolsModule
::Draw)) )
->GetSdOptions(mpDoc->GetDocumentType()) );
104 SfxFlagItem aFlagItem( SID_PRINTER_CHANGESTODOC(5000 + 324) );
105 SfxPrinterChangeFlags nFlags =
106 (aPrintItem.GetOptionsPrint().IsWarningSize() ? SfxPrinterChangeFlags::CHG_SIZE : SfxPrinterChangeFlags::NONE) |
107 (aPrintItem.GetOptionsPrint().IsWarningOrientation() ? SfxPrinterChangeFlags::CHG_ORIENTATION : SfxPrinterChangeFlags::NONE);
108 aFlagItem.SetValue( static_cast<int>(nFlags) );
109
110 pSet->Put( aPrintItem );
111 pSet->Put( SfxBoolItem( SID_PRINTER_NOTFOUND_WARN(5000 + 320), aPrintItem.GetOptionsPrint().IsWarningPrinter() ) );
112 pSet->Put( aFlagItem );
113
114 mpPrinter = VclPtr<SfxPrinter>::Create(std::move(pSet));
115 mbOwnPrinter = true;
116
117 // set output quality
118 sal_uInt16 nQuality = aPrintItem.GetOptionsPrint().GetOutputQuality();
119
120 DrawModeFlags nMode = DrawModeFlags::Default;
121 // 1 == Grayscale, 2 == Black & White (with grayscale images)
122 if( nQuality == 1 )
123 nMode = DrawModeFlags::GrayLine | DrawModeFlags::GrayFill | DrawModeFlags::GrayText | DrawModeFlags::GrayBitmap | DrawModeFlags::GrayGradient;
124 else if( nQuality == 2 )
125 nMode = DrawModeFlags::BlackLine | DrawModeFlags::WhiteFill | DrawModeFlags::BlackText | DrawModeFlags::GrayBitmap | DrawModeFlags::WhiteGradient;
126
127 mpPrinter->SetDrawMode( nMode );
128
129 MapMode aMM (mpPrinter->GetMapMode());
130 aMM.SetMapUnit(MapUnit::Map100thMM);
131 mpPrinter->SetMapMode(aMM);
132 UpdateRefDevice();
133 }
134 return mpPrinter;
135}
136
137/**
138 * Set new SfxPrinter (transfer of ownership)
139 */
140void DrawDocShell::SetPrinter(SfxPrinter *pNewPrinter)
141{
142 if ( mpViewShell )
6
Assuming field 'mpViewShell' is null
7
Taking false branch
143 {
144 ::sd::View* pView = mpViewShell->GetView();
145 if ( pView->IsTextEdit() )
146 pView->SdrEndTextEdit();
147 }
148
149 if ( mpPrinter && mbOwnPrinter && (mpPrinter.get() != pNewPrinter) )
8
Assuming field 'mbOwnPrinter' is true
9
Taking true branch
150 mpPrinter.disposeAndClear();
10
Calling 'VclPtr::disposeAndClear'
151
152 mpPrinter = pNewPrinter;
153 mbOwnPrinter = true;
154 if ( mpDoc->GetPrinterIndependentLayout() == css::document::PrinterIndependentLayout::DISABLED )
155 UpdateFontList();
156 UpdateRefDevice();
157}
158
159void DrawDocShell::UpdateFontList()
160{
161 mpFontList.reset();
162 OutputDevice* pRefDevice = nullptr;
163 if ( mpDoc->GetPrinterIndependentLayout() == css::document::PrinterIndependentLayout::DISABLED )
164 pRefDevice = GetPrinter(true);
165 else
166 pRefDevice = SD_MOD()( static_cast<SdModule*>(SfxApplication::GetModule(SfxToolsModule
::Draw)) )
->GetVirtualRefDevice();
167 mpFontList.reset( new FontList(pRefDevice, nullptr) );
168 SvxFontListItem aFontListItem( mpFontList.get(), SID_ATTR_CHAR_FONTLIST( 10000 + 22 ) );
169 PutItem( aFontListItem );
170}
171
172Printer* DrawDocShell::GetDocumentPrinter()
173{
174 return GetPrinter(false);
175}
176
177void DrawDocShell::OnDocumentPrinterChanged(Printer* pNewPrinter)
178{
179 // if we already have a printer, see if it's the same
180 if( mpPrinter )
1
Taking true branch
181 {
182 // easy case
183 if( mpPrinter == pNewPrinter )
2
Assuming the condition is false
3
Taking false branch
184 return;
185
186 // compare if it's the same printer with the same job setup
187 if( (mpPrinter->GetName() == pNewPrinter->GetName()) &&
188 (mpPrinter->GetJobSetup() == pNewPrinter->GetJobSetup()))
189 return;
190 }
191
192 SfxPrinter* const pSfxPrinter = dynamic_cast<SfxPrinter*>(pNewPrinter);
193 if (pSfxPrinter
3.1
'pSfxPrinter' is non-null
3.1
'pSfxPrinter' is non-null
3.1
'pSfxPrinter' is non-null
3.1
'pSfxPrinter' is non-null
)
4
Taking true branch
194 {
195 SetPrinter(pSfxPrinter);
5
Calling 'DrawDocShell::SetPrinter'
196
197 // container owns printer
198 mbOwnPrinter = false;
199 }
200}
201
202void DrawDocShell::UpdateRefDevice()
203{
204 if( !mpDoc )
205 return;
206
207 // Determine the device for which the output will be formatted.
208 VclPtr< OutputDevice > pRefDevice;
209 switch (mpDoc->GetPrinterIndependentLayout())
210 {
211 case css::document::PrinterIndependentLayout::DISABLED:
212 pRefDevice = mpPrinter.get();
213 break;
214
215 case css::document::PrinterIndependentLayout::ENABLED:
216 pRefDevice = SD_MOD()( static_cast<SdModule*>(SfxApplication::GetModule(SfxToolsModule
::Draw)) )
->GetVirtualRefDevice();
217 break;
218
219 default:
220 // We are confronted with an invalid or un-implemented
221 // layout mode. Use the printer as formatting device
222 // as a fall-back.
223 SAL_WARN( "sd", "DrawDocShell::UpdateRefDevice(): Unexpected printer layout mode")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "sd")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "DrawDocShell::UpdateRefDevice(): Unexpected printer layout mode"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sd"
), ("/home/maarten/src/libreoffice/core/sd/source/ui/docshell/docshel4.cxx"
":" "223" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "DrawDocShell::UpdateRefDevice(): Unexpected printer layout mode"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "DrawDocShell::UpdateRefDevice(): Unexpected printer layout mode"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sd"), (
"/home/maarten/src/libreoffice/core/sd/source/ui/docshell/docshel4.cxx"
":" "223" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "DrawDocShell::UpdateRefDevice(): Unexpected printer layout mode"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sd"
), ("/home/maarten/src/libreoffice/core/sd/source/ui/docshell/docshel4.cxx"
":" "223" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "DrawDocShell::UpdateRefDevice(): Unexpected printer layout mode"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "DrawDocShell::UpdateRefDevice(): Unexpected printer layout mode"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sd"), (
"/home/maarten/src/libreoffice/core/sd/source/ui/docshell/docshel4.cxx"
":" "223" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
224
225 pRefDevice = mpPrinter.get();
226 break;
227 }
228 mpDoc->SetRefDevice( pRefDevice.get() );
229
230 SdOutliner* pOutl = mpDoc->GetOutliner( false );
231
232 if( pOutl )
233 pOutl->SetRefDevice( pRefDevice );
234
235 SdOutliner* pInternalOutl = mpDoc->GetInternalOutliner( false );
236
237 if( pInternalOutl )
238 pInternalOutl->SetRefDevice( pRefDevice );
239}
240
241/**
242 * Creates new document, opens streams
243 */
244bool DrawDocShell::InitNew( const css::uno::Reference< css::embed::XStorage >& xStorage )
245{
246 bool bRet = SfxObjectShell::InitNew( xStorage );
247
248 ::tools::Rectangle aVisArea( Point(0, 0), Size(14100, 10000) );
249 SetVisArea(aVisArea);
250
251 if (bRet)
252 {
253 if( !mbSdDataObj )
254 mpDoc->NewOrLoadCompleted(DocCreationMode::New); // otherwise calling
255 // NewOrLoadCompleted(NEW_LOADED) in
256 // SdDrawDocument::AllocModel()
257 }
258 return bRet;
259}
260
261/**
262 * loads pools and document
263 */
264bool DrawDocShell::Load( SfxMedium& rMedium )
265{
266 // If this is an ODF file being loaded, then by default, use legacy processing
267 // for tdf#99729 (if required, it will be overridden in *::ReadUserDataSequence())
268 if (IsOwnStorageFormat(rMedium))
269 {
270 mpDoc->SetAnchoredTextOverflowLegacy(true);
271 }
272
273 bool bRet = false;
274 bool bStartPresentation = false;
275 ErrCode nError = ERRCODE_NONEErrCode(0);
276
277 SfxItemSet* pSet = rMedium.GetItemSet();
278
279 if( pSet )
280 {
281 if( ( SfxItemState::SET == pSet->GetItemState(SID_PREVIEWTypedWhichId<SfxBoolItem>(5000 + 1404) ) ) && pSet->Get( SID_PREVIEWTypedWhichId<SfxBoolItem>(5000 + 1404) ).GetValue() )
282 {
283 mpDoc->SetStarDrawPreviewMode( true );
284 }
285
286 if( SfxItemState::SET == pSet->GetItemState(SID_DOC_STARTPRESENTATIONTypedWhichId<SfxBoolItem>(5000 + 695))&&
287 pSet->Get( SID_DOC_STARTPRESENTATIONTypedWhichId<SfxBoolItem>(5000 + 695) ).GetValue() )
288 {
289 bStartPresentation = true;
290 mpDoc->SetStartWithPresentation( true );
291 }
292 }
293
294 bRet = SfxObjectShell::Load( rMedium );
295 if (bRet)
296 {
297 comphelper::EmbeddedObjectContainer& rEmbeddedObjectContainer = getEmbeddedObjectContainer();
298 rEmbeddedObjectContainer.setUserAllowsLinkUpdate(false);
299 bRet = SdXMLFilter( rMedium, *this, SdXMLFilterMode::Normal, SotStorage::GetVersion( rMedium.GetStorage() ) ).Import( nError );
300 }
301
302 if( bRet )
303 {
304 // for legacy markup in OOoXML filter, convert the animations now
305 EffectMigration::DocumentLoaded(*GetDoc());
306 UpdateTablePointers();
307
308 // If we're an embedded OLE object, use tight bounds
309 // for our visArea. No point in showing the user lots of empty
310 // space. Had to remove the check for empty VisArea below,
311 // since XML load always sets a VisArea before.
312 //TODO/LATER: looks a little bit strange!
313 if( ( GetCreateMode() == SfxObjectCreateMode::EMBEDDED ) && SfxObjectShell::GetVisArea( ASPECT_CONTENT1 ).IsEmpty() )
314 {
315 SdPage* pPage = mpDoc->GetSdPage( 0, PageKind::Standard );
316
317 if( pPage )
318 SetVisArea( pPage->GetAllObjBoundRect() );
319 }
320
321 FinishedLoading();
322
323 const INetURLObject aUrl;
324 SfxObjectShell::SetAutoLoad( aUrl, 0, false );
325 }
326 else
327 {
328 if( nError == ERRCODE_IO_BROKENPACKAGEErrCode( ErrCodeArea::Io, ErrCodeClass::Format, 38 ) )
329 SetError(ERRCODE_IO_BROKENPACKAGEErrCode( ErrCodeArea::Io, ErrCodeClass::Format, 38 ));
330
331 // TODO/LATER: correct error handling?!
332 //pStore->SetError(SVSTREAM_WRONGVERSION);
333 else
334 SetError(ERRCODE_ABORTErrCode( ErrCodeArea::Io, ErrCodeClass::Abort, 27 ));
335 }
336
337 // tell SFX to change viewshell when in preview mode
338 if( IsPreview() || bStartPresentation )
339 {
340 SfxItemSet *pMediumSet = GetMedium()->GetItemSet();
341 if( pMediumSet )
342 pMediumSet->Put( SfxUInt16Item( SID_VIEW_ID(5000 + 523), bStartPresentation ? 1 : 5 ) );
343 }
344
345 return bRet;
346}
347
348/**
349 * loads content for organizer
350 */
351bool DrawDocShell::LoadFrom( SfxMedium& rMedium )
352{
353 std::unique_ptr<weld::WaitObject> pWait;
354 if( mpViewShell )
355 pWait.reset(new weld::WaitObject(mpViewShell->GetFrameWeld()));
356
357 mpDoc->NewOrLoadCompleted( DocCreationMode::New );
358 mpDoc->CreateFirstPages();
359 mpDoc->StopWorkStartupDelay();
360
361 // TODO/LATER: nobody is interested in the error code?!
362 ErrCode nError = ERRCODE_NONEErrCode(0);
363 bool bRet = SdXMLFilter( rMedium, *this, SdXMLFilterMode::Organizer, SotStorage::GetVersion( rMedium.GetStorage() ) ).Import( nError );
364
365 // tell SFX to change viewshell when in preview mode
366 if( IsPreview() )
367 {
368 SfxItemSet *pSet = GetMedium()->GetItemSet();
369
370 if( pSet )
371 pSet->Put( SfxUInt16Item( SID_VIEW_ID(5000 + 523), 5 ) );
372 }
373
374 return bRet;
375}
376
377/**
378 * load from 3rd party format
379 */
380bool DrawDocShell::ImportFrom(SfxMedium &rMedium,
381 uno::Reference<text::XTextRange> const& xInsertPosition)
382{
383 const OUString aFilterName( rMedium.GetFilter()->GetFilterName() );
384 if (aFilterName == "Impress MS PowerPoint 2007 XML" ||
385 aFilterName == "Impress MS PowerPoint 2007 XML AutoPlay" ||
386 aFilterName == "Impress MS PowerPoint 2007 XML VBA")
387 {
388 // As this is a MSFT format, we should use the "MS Compat"
389 // mode for spacing before and after paragraphs.
390
391 // This is copied from what is done for .ppt import in
392 // ImplSdPPTImport::Import() in sd/source/filter/ppt/pptin.cxx
393 // in. We need to tell both the edit engine of the draw outliner,
394 // and the document, to do "summation of paragraphs".
395 SdrOutliner& rOutl = mpDoc->GetDrawOutliner();
396 EEControlBits nControlWord = rOutl.GetEditEngine().GetControlWord();
397 nControlWord |= EEControlBits::ULSPACESUMMATION;
398 const_cast<EditEngine&>(rOutl.GetEditEngine()).SetControlWord( nControlWord );
399
400 mpDoc->SetSummationOfParagraphs();
401 }
402
403 const bool bRet = SfxObjectShell::ImportFrom(rMedium, xInsertPosition);
404
405 SfxItemSet* pSet = rMedium.GetItemSet();
406 if( pSet )
407 {
408 if( SfxItemState::SET == pSet->GetItemState(SID_DOC_STARTPRESENTATIONTypedWhichId<SfxBoolItem>(5000 + 695))&&
409 pSet->Get( SID_DOC_STARTPRESENTATIONTypedWhichId<SfxBoolItem>(5000 + 695) ).GetValue() )
410 {
411 mpDoc->SetStartWithPresentation( true );
412
413 // tell SFX to change viewshell when in preview mode
414 if( IsPreview() )
415 {
416 SfxItemSet *pMediumSet = GetMedium()->GetItemSet();
417 if( pMediumSet )
418 pMediumSet->Put( SfxUInt16Item( SID_VIEW_ID(5000 + 523), 1 ) );
419 }
420 }
421 }
422
423 return bRet;
424}
425
426/**
427 * load from a foreign format
428 */
429bool DrawDocShell::ConvertFrom( SfxMedium& rMedium )
430{
431 const OUString aFilterName( rMedium.GetFilter()->GetFilterName() );
432 bool bRet = false;
433 bool bStartPresentation = false;
434
435 SetWaitCursor( true );
436
437 SfxItemSet* pSet = rMedium.GetItemSet();
438 if( pSet )
439 {
440 if( ( SfxItemState::SET == pSet->GetItemState(SID_PREVIEWTypedWhichId<SfxBoolItem>(5000 + 1404) ) ) && pSet->Get( SID_PREVIEWTypedWhichId<SfxBoolItem>(5000 + 1404) ).GetValue() )
441 {
442 mpDoc->SetStarDrawPreviewMode( true );
443 }
444
445 if( SfxItemState::SET == pSet->GetItemState(SID_DOC_STARTPRESENTATIONTypedWhichId<SfxBoolItem>(5000 + 695))&&
446 pSet->Get( SID_DOC_STARTPRESENTATIONTypedWhichId<SfxBoolItem>(5000 + 695) ).GetValue() )
447 {
448 bStartPresentation = true;
449 mpDoc->SetStartWithPresentation( true );
450 }
451 }
452
453 if( aFilterName == pFilterPowerPoint97
454 || aFilterName == pFilterPowerPoint97Template
455 || aFilterName == pFilterPowerPoint97AutoPlay)
456 {
457 mpDoc->StopWorkStartupDelay();
458 bRet = SdPPTFilter( rMedium, *this ).Import();
459 }
460 else if (aFilterName.indexOf("impress8") >= 0 ||
461 aFilterName.indexOf("draw8") >= 0)
462 {
463 // TODO/LATER: nobody is interested in the error code?!
464 mpDoc->CreateFirstPages();
465 mpDoc->StopWorkStartupDelay();
466 ErrCode nError = ERRCODE_NONEErrCode(0);
467 bRet = SdXMLFilter( rMedium, *this ).Import( nError );
468
469 }
470 else if (aFilterName.indexOf("StarOffice XML (Draw)") >= 0 ||
471 aFilterName.indexOf("StarOffice XML (Impress)") >= 0)
472 {
473 // TODO/LATER: nobody is interested in the error code?!
474 mpDoc->CreateFirstPages();
475 mpDoc->StopWorkStartupDelay();
476 ErrCode nError = ERRCODE_NONEErrCode(0);
477 bRet = SdXMLFilter( rMedium, *this, SdXMLFilterMode::Normal, SOFFICE_FILEFORMAT_606200 ).Import( nError );
478 }
479 else if (aFilterName == "CGM - Computer Graphics Metafile")
480 {
481 mpDoc->CreateFirstPages();
482 mpDoc->StopWorkStartupDelay();
483 bRet = SdCGMFilter( rMedium, *this ).Import();
484 }
485 else if (aFilterName == "draw_pdf_import")
486 {
487 mpDoc->CreateFirstPages();
488 mpDoc->StopWorkStartupDelay();
489 bRet = SdPdfFilter(rMedium, *this).Import();
490 }
491 else
492 {
493 mpDoc->CreateFirstPages();
494 mpDoc->StopWorkStartupDelay();
495 bRet = SdGRFFilter( rMedium, *this ).Import();
496 }
497
498 FinishedLoading();
499
500 // tell SFX to change viewshell when in preview mode
501 if( IsPreview() )
502 {
503 SfxItemSet *pMediumSet = GetMedium()->GetItemSet();
504
505 if( pMediumSet )
506 pMediumSet->Put( SfxUInt16Item( SID_VIEW_ID(5000 + 523), 5 ) );
507 }
508 SetWaitCursor( false );
509
510 // tell SFX to change viewshell when in preview mode
511 if( IsPreview() || bStartPresentation )
512 {
513 SfxItemSet *pMediumSet = GetMedium()->GetItemSet();
514 if( pMediumSet )
515 pMediumSet->Put( SfxUInt16Item( SID_VIEW_ID(5000 + 523), bStartPresentation ? 1 : 5 ) );
516 }
517
518 return bRet;
519}
520
521/**
522 * Writes pools and document to the open streams
523 */
524bool DrawDocShell::Save()
525{
526 mpDoc->StopWorkStartupDelay();
527
528 //TODO/LATER: why this?!
529 if( GetCreateMode() == SfxObjectCreateMode::STANDARD )
530 SfxObjectShell::SetVisArea( ::tools::Rectangle() );
531
532 bool bRet = SfxObjectShell::Save();
533
534 if( bRet )
535 bRet = SdXMLFilter( *GetMedium(), *this, SdXMLFilterMode::Normal, SotStorage::GetVersion( GetMedium()->GetStorage() ) ).Export();
536
537 return bRet;
538}
539
540/**
541 * Writes pools and document to the provided storage
542 */
543bool DrawDocShell::SaveAs( SfxMedium& rMedium )
544{
545 mpDoc->setDocAccTitle(OUString());
546 if (SfxViewFrame* pFrame1 = SfxViewFrame::GetFirst(this))
547 {
548 if (vcl::Window* pSysWin = pFrame1->GetWindow().GetSystemWindow())
549 {
550 pSysWin->SetAccessibleName(OUString());
551 }
552 }
553 mpDoc->StopWorkStartupDelay();
554
555 //With custom animation, if Outliner is modified, update text before saving
556 if( mpViewShell )
557 {
558 SdPage* pPage = mpViewShell->getCurrentPage();
559 if( pPage && pPage->getMainSequence()->getCount() )
560 {
561 SdrObject* pObj = mpViewShell->GetView()->GetTextEditObject();
562 SdrOutliner* pOutl = mpViewShell->GetView()->GetTextEditOutliner();
563 if( pObj && pOutl && pOutl->IsModified() )
564 {
565 std::unique_ptr<OutlinerParaObject> pNewText = pOutl->CreateParaObject( 0, pOutl->GetParagraphCount() );
566 pObj->SetOutlinerParaObject( std::move(pNewText) );
567 pOutl->ClearModifyFlag();
568 }
569 }
570 }
571
572 //TODO/LATER: why this?!
573 if( GetCreateMode() == SfxObjectCreateMode::STANDARD )
574 SfxObjectShell::SetVisArea( ::tools::Rectangle() );
575
576 bool bRet = SfxObjectShell::SaveAs( rMedium );
577
578 if( bRet )
579 bRet = SdXMLFilter( rMedium, *this, SdXMLFilterMode::Normal, SotStorage::GetVersion( rMedium.GetStorage() ) ).Export();
580
581 if( GetError() == ERRCODE_NONEErrCode(0) )
582 SetError(ERRCODE_NONEErrCode(0));
583
584 return bRet;
585}
586
587/**
588 * save to foreign format
589 */
590bool DrawDocShell::ConvertTo( SfxMedium& rMedium )
591{
592 bool bRet = false;
593
594 if( mpDoc->GetPageCount() )
595 {
596 std::shared_ptr<const SfxFilter> pMediumFilter = rMedium.GetFilter();
597 const OUString aTypeName( pMediumFilter->GetTypeName() );
598 std::unique_ptr<SdFilter> xFilter;
599
600 if( aTypeName.indexOf( "graphic_HTML" ) >= 0 )
601 {
602 xFilter = std::make_unique<SdHTMLFilter>(rMedium, *this);
603 }
604 else if( aTypeName.indexOf( "MS_PowerPoint_97" ) >= 0 )
605 {
606 xFilter = std::make_unique<SdPPTFilter>(rMedium, *this);
607 static_cast<SdPPTFilter*>(xFilter.get())->PreSaveBasic();
608 }
609 else if ( aTypeName.indexOf( "CGM_Computer_Graphics_Metafile" ) >= 0 )
610 {
611 xFilter = std::make_unique<SdCGMFilter>(rMedium, *this);
612 }
613 else if( aTypeName.indexOf( "draw8" ) >= 0 ||
614 aTypeName.indexOf( "impress8" ) >= 0 )
615 {
616 xFilter = std::make_unique<SdXMLFilter>(rMedium, *this);
617 }
618 else if( aTypeName.indexOf( "StarOffice_XML_Impress" ) >= 0 ||
619 aTypeName.indexOf( "StarOffice_XML_Draw" ) >= 0 )
620 {
621 xFilter = std::make_unique<SdXMLFilter>(rMedium, *this, SdXMLFilterMode::Normal, SOFFICE_FILEFORMAT_606200);
622 }
623 else
624 {
625 xFilter = std::make_unique<SdGRFFilter>(rMedium, *this);
626 }
627
628 if (xFilter)
629 {
630 if ( mpViewShell )
631 {
632 ::sd::View* pView = mpViewShell->GetView();
633 if ( pView->IsTextEdit() )
634 pView->SdrEndTextEdit();
635 }
636
637 bRet = xFilter->Export();
638 }
639 }
640
641 return bRet;
642}
643
644/**
645 * Reopen own streams to ensure that nobody else can prevent use from opening
646 * them.
647 */
648bool DrawDocShell::SaveCompleted( const css::uno::Reference< css::embed::XStorage >& xStorage )
649{
650 bool bRet = false;
651
652 if( SfxObjectShell::SaveCompleted(xStorage) )
653 {
654 mpDoc->NbcSetChanged( false );
655
656 if( mpViewShell )
657 {
658 if( dynamic_cast< OutlineViewShell *>( mpViewShell ) != nullptr )
659 static_cast<OutlineView*>(mpViewShell->GetView())
660 ->GetOutliner().ClearModifyFlag();
661
662 SdrOutliner* pOutl = mpViewShell->GetView()->GetTextEditOutliner();
663 if( pOutl )
664 {
665 SdrObject* pObj = mpViewShell->GetView()->GetTextEditObject();
666 if( pObj )
667 pObj->NbcSetOutlinerParaObject( pOutl->CreateParaObject() );
668
669 pOutl->ClearModifyFlag();
670 }
671 }
672
673 bRet = true;
674
675 SfxViewFrame* pFrame = ( mpViewShell && mpViewShell->GetViewFrame() ) ?
676 mpViewShell->GetViewFrame() :
677 SfxViewFrame::Current();
678
679 if( pFrame )
680 pFrame->GetBindings().Invalidate( SID_NAVIGATOR_STATE(27000 +288), true );
681 }
682 return bRet;
683}
684
685SfxStyleSheetBasePool* DrawDocShell::GetStyleSheetPool()
686{
687 return mpDoc->GetStyleSheetPool();
688}
689
690void DrawDocShell::GotoBookmark(const OUString& rBookmark)
691{
692 auto pDrawViewShell = dynamic_cast<DrawViewShell *>( mpViewShell );
693 if (!pDrawViewShell)
694 return;
695
696 ViewShellBase& rBase (mpViewShell->GetViewShellBase());
697
698 bool bIsMasterPage = false;
699 sal_uInt16 nPageNumber = SDRPAGE_NOTFOUND0xFFFF;
700 SdrObject* pObj = nullptr;
701
702 const OUString sInteraction( "action?" );
703 if ( rBookmark.match( sInteraction ) )
704 {
705 const OUString sJump( "jump=" );
706 if ( rBookmark.match( sJump, sInteraction.getLength() ) )
707 {
708 OUString aDestination( rBookmark.copy( sInteraction.getLength() + sJump.getLength() ) );
709 if ( aDestination.match( "firstslide" ) )
710 {
711 nPageNumber = 1;
712 }
713 else if ( aDestination.match( "lastslide" ) )
714 {
715 nPageNumber = mpDoc->GetPageCount() - 2;
716 }
717 else if ( aDestination.match( "previousslide" ) )
718 {
719 SdPage* pPage = pDrawViewShell->GetActualPage();
720 nPageNumber = pPage->GetPageNum();
721 nPageNumber = nPageNumber > 2 ? nPageNumber - 2 : SDRPAGE_NOTFOUND0xFFFF;
722 }
723 else if ( aDestination.match( "nextslide" ) )
724 {
725 SdPage* pPage = pDrawViewShell->GetActualPage();
726 nPageNumber = pPage->GetPageNum() + 2;
727 if ( nPageNumber >= mpDoc->GetPageCount() )
728 nPageNumber = SDRPAGE_NOTFOUND0xFFFF;
729 }
730 }
731 }
732 else
733 {
734 // Is the bookmark a page?
735 nPageNumber = mpDoc->GetPageByName( rBookmark, bIsMasterPage );
736
737 if (nPageNumber == SDRPAGE_NOTFOUND0xFFFF)
738 {
739 // Is the bookmark an object?
740 pObj = mpDoc->GetObj(rBookmark);
741
742 if (pObj)
743 {
744 nPageNumber = pObj->getSdrPageFromSdrObject()->GetPageNum();
745 }
746 }
747 }
748 if (nPageNumber != SDRPAGE_NOTFOUND0xFFFF)
749 {
750 // Jump to the bookmarked page. This is done in three steps.
751
752 SdPage* pPage;
753 if (bIsMasterPage)
754 pPage = static_cast<SdPage*>( mpDoc->GetMasterPage(nPageNumber) );
755 else
756 pPage = static_cast<SdPage*>( mpDoc->GetPage(nPageNumber) );
757
758 // 1.) Change the view shell to the edit view, the notes view,
759 // or the handout view.
760 PageKind eNewPageKind = pPage->GetPageKind();
761
762 if( (eNewPageKind != PageKind::Standard) && (mpDoc->GetDocumentType() == DocumentType::Draw) )
763 return;
764
765 if (eNewPageKind != pDrawViewShell->GetPageKind())
766 {
767 // change work area
768 GetFrameView()->SetPageKind(eNewPageKind);
769 OUString sViewURL;
770 switch (eNewPageKind)
771 {
772 case PageKind::Standard:
773 sViewURL = FrameworkHelper::msImpressViewURL;
774 break;
775 case PageKind::Notes:
776 sViewURL = FrameworkHelper::msNotesViewURL;
777 break;
778 case PageKind::Handout:
779 sViewURL = FrameworkHelper::msHandoutViewURL;
780 break;
781 default:
782 break;
783 }
784 if (!sViewURL.isEmpty())
785 {
786 std::shared_ptr<FrameworkHelper> pHelper (
787 FrameworkHelper::Instance(rBase));
788 pHelper->RequestView(
789 sViewURL,
790 FrameworkHelper::msCenterPaneURL);
791 pHelper->WaitForUpdate();
792
793 // Get the new DrawViewShell.
794 mpViewShell = pHelper->GetViewShell(FrameworkHelper::msCenterPaneURL).get();
795 pDrawViewShell = dynamic_cast<sd::DrawViewShell*>(mpViewShell);
796 }
797 else
798 {
799 pDrawViewShell = nullptr;
800 }
801 }
802
803 if (pDrawViewShell != nullptr)
804 {
805 setEditMode(pDrawViewShell, bIsMasterPage);
806
807 // Make the bookmarked page the current page. This is done
808 // by using the API because this takes care of all the
809 // little things to be done. Especially writing the view
810 // data to the frame view.
811 sal_uInt16 nSdPgNum = (nPageNumber - 1) / 2;
812 Reference<drawing::XDrawView> xController (rBase.GetController(), UNO_QUERY);
813 if (xController.is())
814 {
815 Reference<drawing::XDrawPage> xDrawPage (pPage->getUnoPage(), UNO_QUERY);
816 xController->setCurrentPage (xDrawPage);
817 }
818 else
819 {
820 // As a fall back switch to the page via the core.
821 DBG_ASSERT (xController.is(),do { if (true && (!(xController.is()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sd/source/ui/docshell/docshel4.cxx"
":" "822" ": "), "%s", "DrawDocShell::GotoBookmark: can't switch page via API"
); } } while (false)
822 "DrawDocShell::GotoBookmark: can't switch page via API")do { if (true && (!(xController.is()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sd/source/ui/docshell/docshel4.cxx"
":" "822" ": "), "%s", "DrawDocShell::GotoBookmark: can't switch page via API"
); } } while (false)
;
823 pDrawViewShell->SwitchPage(nSdPgNum);
824 }
825
826 if (pDrawViewShell->GetDispatcher())
827 {
828 // show page
829 SvxZoomItem aZoom;
830 aZoom.SetType( SvxZoomType::WHOLEPAGE );
831 pDrawViewShell->GetDispatcher()->ExecuteList(SID_ATTR_ZOOMTypedWhichId<SvxZoomItem>(10000 + 0), SfxCallMode::ASYNCHRON, { &aZoom });
832 }
833
834 if (pObj != nullptr)
835 {
836 // select object
837 pDrawViewShell->GetView()->UnmarkAll();
838 pDrawViewShell->GetView()->MarkObj(
839 pObj,
840 pDrawViewShell->GetView()->GetSdrPageView());
841 }
842 }
843 }
844
845 SfxBindings& rBindings = ((pDrawViewShell && pDrawViewShell->GetViewFrame()!=nullptr)
846 ? pDrawViewShell->GetViewFrame()
847 : SfxViewFrame::Current() )->GetBindings();
848
849 rBindings.Invalidate(SID_NAVIGATOR_STATE(27000 +288), true);
850 rBindings.Invalidate(SID_NAVIGATOR_PAGENAME(27000 +287));
851}
852
853/**
854 * If it should become a document template.
855 */
856bool DrawDocShell::SaveAsOwnFormat( SfxMedium& rMedium )
857{
858
859 std::shared_ptr<const SfxFilter> pFilter = rMedium.GetFilter();
860
861 if (pFilter->IsOwnTemplateFormat())
862 {
863 /* now the StarDraw specialty:
864 we assign known layout names to the layout template of the first
865 page, we set the layout names of the affected masterpages and pages.
866 We inform all text objects of the affected standard, note and
867 masterpages about the name change.
868 */
869
870 OUString aLayoutName;
871
872 SfxStringItem const * pLayoutItem;
873 if( rMedium.GetItemSet()->GetItemState(SID_TEMPLATE_NAME(5000 + 660), false, reinterpret_cast<const SfxPoolItem**>(& pLayoutItem) ) == SfxItemState::SET )
874 {
875 aLayoutName = pLayoutItem->GetValue();
876 }
877 else
878 {
879 INetURLObject aURL( rMedium.GetName() );
880 aURL.removeExtension();
881 aLayoutName = aURL.getName();
882 }
883
884 if (aLayoutName.isEmpty())
885 {
886 sal_uInt32 nCount = mpDoc->GetMasterSdPageCount(PageKind::Standard);
887 for (sal_uInt32 i = 0; i < nCount; ++i)
888 {
889 OUString aOldPageLayoutName = mpDoc->GetMasterSdPage(i, PageKind::Standard)->GetLayoutName();
890 OUString aNewLayoutName = aLayoutName;
891 // Don't add suffix for the first master page
892 if( i > 0 )
893 aNewLayoutName += OUString::number(i);
894
895 mpDoc->RenameLayoutTemplate(aOldPageLayoutName, aNewLayoutName);
896 }
897 }
898 }
899
900 return SfxObjectShell::SaveAsOwnFormat(rMedium);
901}
902
903void DrawDocShell::FillClass(SvGlobalName* pClassName,
904 SotClipboardFormatId* pFormat,
905 OUString* pFullTypeName,
906 sal_Int32 nFileFormat,
907 bool bTemplate /* = false */) const
908{
909 if (nFileFormat == SOFFICE_FILEFORMAT_606200)
910 {
911 if ( meDocType == DocumentType::Draw )
912 {
913 *pClassName = SvGlobalName(SO3_SDRAW_CLASSID_600x4BAB8970, 0x8A3B, 0x45B3, 0x99, 0x1C, 0xCB, 0xEE, 0xAC, 0x6B
, 0xD5, 0xE3
);
914 *pFormat = SotClipboardFormatId::STARDRAW_60;
915 *pFullTypeName = SdResId(STR_GRAPHIC_DOCUMENT_FULLTYPE_60reinterpret_cast<char const *>("STR_GRAPHIC_DOCUMENT_FULLTYPE_60"
"\004" u8"%PRODUCTNAME Drawing format (Draw 6)")
);
916 }
917 else
918 {
919 *pClassName = SvGlobalName(SO3_SIMPRESS_CLASSID_600x9176E48A, 0x637A, 0x4D1F, 0x80, 0x3B, 0x99, 0xD9, 0xBF, 0xAC
, 0x10, 0x47
);
920 *pFormat = SotClipboardFormatId::STARIMPRESS_60;
921 *pFullTypeName = SdResId(STR_IMPRESS_DOCUMENT_FULLTYPE_60reinterpret_cast<char const *>("STR_IMPRESS_DOCUMENT_FULLTYPE_60"
"\004" u8"%PRODUCTNAME Presentation format (Impress 6)")
);
922 }
923 }
924 else if (nFileFormat == SOFFICE_FILEFORMAT_86800)
925 {
926 if ( meDocType == DocumentType::Draw )
927 {
928 *pClassName = SvGlobalName(SO3_SDRAW_CLASSID_600x4BAB8970, 0x8A3B, 0x45B3, 0x99, 0x1C, 0xCB, 0xEE, 0xAC, 0x6B
, 0xD5, 0xE3
);
929 *pFormat = bTemplate ? SotClipboardFormatId::STARDRAW_8_TEMPLATE : SotClipboardFormatId::STARDRAW_8;
930 *pFullTypeName = SdResId(STR_GRAPHIC_DOCUMENT_FULLTYPE_80reinterpret_cast<char const *>("STR_GRAPHIC_DOCUMENT_FULLTYPE_80"
"\004" u8"%PRODUCTNAME %PRODUCTVERSION Drawing")
); // HACK: method will be removed with new storage API
931 }
932 else
933 {
934 *pClassName = SvGlobalName(SO3_SIMPRESS_CLASSID_600x9176E48A, 0x637A, 0x4D1F, 0x80, 0x3B, 0x99, 0xD9, 0xBF, 0xAC
, 0x10, 0x47
);
935 *pFormat = bTemplate ? SotClipboardFormatId::STARIMPRESS_8_TEMPLATE : SotClipboardFormatId::STARIMPRESS_8;
936 *pFullTypeName = SdResId(STR_IMPRESS_DOCUMENT_FULLTYPE_80reinterpret_cast<char const *>("STR_IMPRESS_DOCUMENT_FULLTYPE_80"
"\004" u8"%PRODUCTNAME %PRODUCTVERSION Presentation")
); // HACK: method will be removed with new storage API
937 }
938 }
939}
940
941OutputDevice* DrawDocShell::GetDocumentRefDev()
942{
943 OutputDevice* pReferenceDevice = SfxObjectShell::GetDocumentRefDev ();
944 // Only when our parent does not have a reference device then we return
945 // our own.
946 if (pReferenceDevice == nullptr && mpDoc != nullptr)
947 pReferenceDevice = mpDoc->GetRefDevice ();
948 return pReferenceDevice;
949}
950
951/** executes the SID_OPENDOC slot to let the framework open a document
952 with the given URL and this document as a referer */
953void DrawDocShell::OpenBookmark( const OUString& rBookmarkURL )
954{
955 SfxStringItem aStrItem( SID_FILE_NAME(5000 + 507), rBookmarkURL );
956 SfxStringItem aReferer( SID_REFERER(5000 + 654), GetMedium()->GetName() );
957 const SfxPoolItem* ppArgs[] = { &aStrItem, &aReferer, nullptr };
958 ( mpViewShell ? mpViewShell->GetViewFrame() : SfxViewFrame::Current() )->GetBindings().Execute( SID_OPENHYPERLINK(5000 + 1676), ppArgs );
959}
960
961std::shared_ptr<SfxDocumentInfoDialog> DrawDocShell::CreateDocumentInfoDialog(weld::Window* pParent, const SfxItemSet &rSet)
962{
963 std::shared_ptr<SfxDocumentInfoDialog> xDlg = std::make_shared<SfxDocumentInfoDialog>(pParent, rSet);
964 DrawDocShell* pDocSh = dynamic_cast<DrawDocShell*>(SfxObjectShell::Current());
965 if( pDocSh == this )
966 {
967 xDlg->AddFontTabPage();
968 }
969 return xDlg;
970}
971
972void DrawDocShell::setEditMode(DrawViewShell* pDrawViewShell, bool isMasterPage)
973{
974 // Set the edit mode to either the normal edit mode or the
975 // master page mode.
976 EditMode eNewEditMode = EditMode::Page;
977 if (isMasterPage)
978 {
979 eNewEditMode = EditMode::MasterPage;
980 }
981
982 if (eNewEditMode != pDrawViewShell->GetEditMode())
983 {
984 // Set EditMode
985 pDrawViewShell->ChangeEditMode(eNewEditMode, false);
986 }
987}
988} // end of namespace sd
989
990/* 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();
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 ;-)
11
Calling 'Reference::clear'
18
Returning; memory was released
205 if (aTmp.get()) {
19
Calling 'Reference::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)
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)
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)
113 m_pBody->release();
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
11.1
Field 'm_pBody' is non-null
11.1
Field 'm_pBody' is non-null
11.1
Field 'm_pBody' is non-null
11.1
Field 'm_pBody' is non-null
)
12
Taking true branch
177 {
178 reference_type * const pOld = m_pBody;
179 m_pBody = NULL__null;
180 pOld->release();
13
Calling 'VclReferenceBase::release'
17
Returning; memory was released
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;
20
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)
14
Assuming the condition is true
15
Taking true branch
40 delete this;
16
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