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 objcont.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 -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 SFX2_DLLIMPLEMENTATION -D ENABLE_CUPS -D SYSTEM_LIBXML -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/liborcus/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/liborcus/include -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/sfx2/inc -I /home/maarten/src/libreoffice/core/sfx2/source/inc -I /home/maarten/src/libreoffice/core/workdir/SdiTarget/sfx2/sdi -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/workdir/CustomTarget/officecfg/registry -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -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/sfx2/source/doc/objcont.cxx

/home/maarten/src/libreoffice/core/sfx2/source/doc/objcont.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
21#include <com/sun/star/uno/Reference.hxx>
22
23#include <com/sun/star/document/DocumentProperties.hpp>
24#include <com/sun/star/document/XDocumentProperties.hpp>
25#include <com/sun/star/document/UpdateDocMode.hpp>
26#include <comphelper/fileurl.hxx>
27#include <vcl/svapp.hxx>
28#include <vcl/weld.hxx>
29#include <vcl/window.hxx>
30#include <svl/style.hxx>
31
32#include <svl/intitem.hxx>
33#include <svl/ctloptions.hxx>
34#include <comphelper/processfactory.hxx>
35#include <unotools/securityoptions.hxx>
36#include <tools/datetime.hxx>
37#include <tools/diagnose_ex.h>
38#include <rtl/uri.hxx>
39
40#include <unotools/useroptions.hxx>
41#include <vcl/virdev.hxx>
42#include <vcl/settings.hxx>
43#include <vcl/gdimtf.hxx>
44
45#include <sfx2/app.hxx>
46#include <sfx2/dinfdlg.hxx>
47#include <sfx2/sfxresid.hxx>
48#include <appdata.hxx>
49#include <sfx2/docfac.hxx>
50#include <sfx2/viewsh.hxx>
51#include <sfx2/objsh.hxx>
52#include <objshimp.hxx>
53#include <sfx2/printer.hxx>
54#include <sfx2/viewfrm.hxx>
55#include <sfx2/doctempl.hxx>
56#include <sfx2/sfxsids.hrc>
57#include <sfx2/strings.hrc>
58#include <sfx2/docfile.hxx>
59#include <sfx2/docfilt.hxx>
60#include <memory>
61#include <helpids.h>
62
63using namespace ::com::sun::star;
64using namespace ::com::sun::star::uno;
65
66
67static
68bool operator> (const util::DateTime& i_rLeft, const util::DateTime& i_rRight)
69{
70 if ( i_rLeft.Year != i_rRight.Year )
71 return i_rLeft.Year > i_rRight.Year;
72
73 if ( i_rLeft.Month != i_rRight.Month )
74 return i_rLeft.Month > i_rRight.Month;
75
76 if ( i_rLeft.Day != i_rRight.Day )
77 return i_rLeft.Day > i_rRight.Day;
78
79 if ( i_rLeft.Hours != i_rRight.Hours )
80 return i_rLeft.Hours > i_rRight.Hours;
81
82 if ( i_rLeft.Minutes != i_rRight.Minutes )
83 return i_rLeft.Minutes > i_rRight.Minutes;
84
85 if ( i_rLeft.Seconds != i_rRight.Seconds )
86 return i_rLeft.Seconds > i_rRight.Seconds;
87
88 if ( i_rLeft.NanoSeconds != i_rRight.NanoSeconds )
89 return i_rLeft.NanoSeconds > i_rRight.NanoSeconds;
90
91 return false;
92}
93
94std::shared_ptr<GDIMetaFile>
95SfxObjectShell::GetPreviewMetaFile( bool bFullContent ) const
96{
97 return CreatePreviewMetaFile_Impl( bFullContent );
1
Calling 'SfxObjectShell::CreatePreviewMetaFile_Impl'
98}
99
100std::shared_ptr<GDIMetaFile>
101SfxObjectShell::CreatePreviewMetaFile_Impl( bool bFullContent ) const
102{
103 // DoDraw can only be called when no printing is done, otherwise
104 // the printer may be turned off
105 SfxViewFrame *pFrame = SfxViewFrame::GetFirst( this );
106 if ( pFrame && pFrame->GetViewShell() &&
2
Assuming 'pFrame' is null
107 pFrame->GetViewShell()->GetPrinter() &&
108 pFrame->GetViewShell()->GetPrinter()->IsPrinting() )
109 return std::shared_ptr<GDIMetaFile>();
110
111 auto xFile = std::make_shared<GDIMetaFile>();
112
113 ScopedVclPtrInstance< VirtualDevice > pDevice;
3
Calling default constructor for 'ScopedVclPtrInstance<VirtualDevice>'
5
Returning from default constructor for 'ScopedVclPtrInstance<VirtualDevice>'
114 pDevice->EnableOutput( false );
115
116 MapMode aMode( GetMapUnit() );
117 pDevice->SetMapMode( aMode );
118 xFile->SetPrefMapMode( aMode );
119
120 Size aTmpSize;
121 sal_Int8 nAspect;
122 if ( bFullContent )
6
Assuming 'bFullContent' is false
7
Taking false branch
123 {
124 nAspect = ASPECT_CONTENT1;
125 aTmpSize = GetVisArea( nAspect ).GetSize();
126 }
127 else
128 {
129 nAspect = ASPECT_THUMBNAIL2;
130 aTmpSize = GetFirstPageSize();
131 }
132
133 xFile->SetPrefSize( aTmpSize );
134 DBG_ASSERT( !aTmpSize.IsEmpty(),do { if (true && (!(!aTmpSize.IsEmpty()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objcont.cxx"
":" "135" ": "), "%s", "size of first page is 0, override GetFirstPageSize or set visible-area!"
); } } while (false)
8
Taking false branch
9
Loop condition is false. Exiting loop
135 "size of first page is 0, override GetFirstPageSize or set visible-area!" )do { if (true && (!(!aTmpSize.IsEmpty()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objcont.cxx"
":" "135" ": "), "%s", "size of first page is 0, override GetFirstPageSize or set visible-area!"
); } } while (false)
;
136
137 xFile->Record( pDevice );
138
139 LanguageType eLang;
140 SvtCTLOptions aCTLOptions;
141 if ( SvtCTLOptions::NUMERALS_HINDI == aCTLOptions.GetCTLTextNumerals() )
10
Assuming the condition is false
11
Taking false branch
142 eLang = LANGUAGE_ARABIC_SAUDI_ARABIALanguageType(0x0401);
143 else if ( SvtCTLOptions::NUMERALS_ARABIC == aCTLOptions.GetCTLTextNumerals() )
12
Assuming the condition is false
13
Taking false branch
144 eLang = LANGUAGE_ENGLISHLanguageType(0x0009);
145 else
146 eLang = Application::GetSettings().GetLanguageTag().getLanguageType();
147
148 pDevice->SetDigitLanguage( eLang );
149
150 const_cast<SfxObjectShell*>(this)->DoDraw( pDevice, Point(0,0), aTmpSize, JobSetup(), nAspect );
151
152 xFile->Stop();
153
154 return xFile;
14
Calling implicit destructor for 'ScopedVclPtrInstance<VirtualDevice>'
15
Calling '~ScopedVclPtr'
155}
156
157
158void SfxObjectShell::UpdateDocInfoForSave()
159{
160 uno::Reference<document::XDocumentProperties> xDocProps(getDocProperties());
161
162 // clear user data if recommend (see 'Tools - Options - LibreOffice - Security')
163 if ( SvtSecurityOptions().IsOptionSet(
164 SvtSecurityOptions::EOption::DocWarnRemovePersonalInfo ) )
165 {
166 xDocProps->resetUserData( OUString() );
167 }
168 else if ( IsModified() )
169 {
170 const OUString aUserName = SvtUserOptions().GetFullName();
171 if ( !IsUseUserData() )
172 {
173 // remove all data pointing to the current user
174 if (xDocProps->getAuthor() == aUserName) {
175 xDocProps->setAuthor( OUString() );
176 }
177 xDocProps->setModifiedBy( OUString() );
178 if (xDocProps->getPrintedBy() == aUserName) {
179 xDocProps->setPrintedBy( OUString() );
180 }
181 }
182 else
183 {
184 // update ModificationAuthor, revision and editing time
185 ::DateTime now( ::DateTime::SYSTEM );
186 xDocProps->setModificationDate( now.GetUNODateTime() );
187 xDocProps->setModifiedBy( aUserName );
188 UpdateTime_Impl( xDocProps );
189 }
190 }
191}
192
193
194static void
195lcl_add(util::Duration & rDur, tools::Time const& rTime)
196{
197 // here we don't care about overflow: rDur is converted back to seconds
198 // anyway, and tools::Time cannot store more than ~4000 hours
199 rDur.Hours += rTime.GetHour();
200 rDur.Minutes += rTime.GetMin();
201 rDur.Seconds += rTime.GetSec();
202}
203
204// Update the processing time
205void SfxObjectShell::UpdateTime_Impl(
206 const uno::Reference<document::XDocumentProperties> & i_xDocProps)
207{
208 // Get old time from documentinfo
209 const sal_Int32 secs = i_xDocProps->getEditingDuration();
210 util::Duration editDuration(false, 0, 0, 0,
211 secs/3600, (secs%3600)/60, secs%60, 0);
212
213 // Initialize some local member! It's necessary for follow operations!
214 DateTime aNow( DateTime::SYSTEM ); // Date and time at current moment
215 tools::Time n24Time (24,0,0,0) ; // Time-value for 24 hours - see follow calculation
216 tools::Time nAddTime (0) ; // Value to add on aOldTime
217
218 // Save impossible cases!
219 // User has changed time to the past between last editing and now... it's not possible!!!
220 DBG_ASSERT( !(aNow.GetDate()<pImpl->nTime.GetDate()), "Timestamp of last change is in the past!?..." )do { if (true && (!(!(aNow.GetDate()<pImpl->nTime
.GetDate())))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objcont.cxx"
":" "220" ": "), "%s", "Timestamp of last change is in the past!?..."
); } } while (false)
;
221
222 // Do the follow only, if user has NOT changed time to the past.
223 // Else add a time of 0 to aOldTime... !!!
224 if (aNow.GetDate()>=pImpl->nTime.GetDate())
225 {
226 // Count of days between now and last editing
227 sal_Int32 nDays = aNow.GetSecFromDateTime(Date(pImpl->nTime.GetDate()))/86400 ;
228
229 if (nDays==0)
230 {
231 // If no day between now and last editing - calculate time directly.
232 nAddTime = static_cast<const tools::Time&>(aNow) - static_cast<const tools::Time&>(pImpl->nTime);
233 }
234 else if (nDays<=31)
235 {
236 // If time of working without save greater than 1 month (!)...
237 // we add 0 to aOldTime!
238
239 // If 1 or up to 31 days between now and last editing - calculate time indirectly.
240 // nAddTime = (24h - nTime) + (nDays * 24h) + aNow
241 --nDays;
242 nAddTime = tools::Time( nDays * n24Time.GetTime());
243 nAddTime += n24Time-static_cast<const tools::Time&>(pImpl->nTime);
244 nAddTime += aNow ;
245 }
246
247 lcl_add(editDuration, nAddTime);
248 }
249
250 pImpl->nTime = aNow;
251 try {
252 const sal_Int32 newSecs( (editDuration.Hours*3600)
253 + (editDuration.Minutes*60) + editDuration.Seconds);
254 i_xDocProps->setEditingDuration(newSecs);
255 i_xDocProps->setEditingCycles(i_xDocProps->getEditingCycles() + 1);
256 }
257 catch (const lang::IllegalArgumentException &)
258 {
259 // ignore overflow
260 }
261}
262
263std::shared_ptr<SfxDocumentInfoDialog> SfxObjectShell::CreateDocumentInfoDialog(weld::Window* pParent,
264 const SfxItemSet& rSet)
265{
266 return std::make_shared<SfxDocumentInfoDialog>(pParent, rSet);
267}
268
269std::set<Color> SfxObjectShell::GetDocColors()
270{
271 std::set<Color> empty;
272 return empty;
273}
274
275sfx::AccessibilityIssueCollection SfxObjectShell::runAccessibilityCheck()
276{
277 sfx::AccessibilityIssueCollection aCollection;
278 return aCollection;
279}
280
281SfxStyleSheetBasePool* SfxObjectShell::GetStyleSheetPool()
282{
283 return nullptr;
284}
285
286namespace {
287
288struct Styles_Impl
289{
290 SfxStyleSheetBase *pSource;
291 SfxStyleSheetBase *pDest;
292};
293
294}
295
296void SfxObjectShell::LoadStyles
297(
298 SfxObjectShell &rSource /* the document template from which
299 the styles are to be loaded */
300)
301
302/* [Description]
303
304 This method is called by the SFx if styles are to be loaded from a template.
305 Existing styles are in this case overwritten. The document must then be
306 re-formatted. Therefore, applications usually override this method
307 and call the implementation in the base class.
308*/
309
310{
311 SfxStyleSheetBasePool *pSourcePool = rSource.GetStyleSheetPool();
312 DBG_ASSERT(pSourcePool, "Source-DocumentShell without StyleSheetPool")do { if (true && (!(pSourcePool))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objcont.cxx"
":" "312" ": "), "%s", "Source-DocumentShell without StyleSheetPool"
); } } while (false)
;
313 SfxStyleSheetBasePool *pMyPool = GetStyleSheetPool();
314 DBG_ASSERT(pMyPool, "Dest-DocumentShell without StyleSheetPool")do { if (true && (!(pMyPool))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objcont.cxx"
":" "314" ": "), "%s", "Dest-DocumentShell without StyleSheetPool"
); } } while (false)
;
315 auto xIter = pSourcePool->CreateIterator(SfxStyleFamily::All);
316 std::unique_ptr<Styles_Impl[]> pFound(new Styles_Impl[xIter->Count()]);
317 sal_uInt16 nFound = 0;
318
319 SfxStyleSheetBase *pSource = xIter->First();
320 while ( pSource )
321 {
322 SfxStyleSheetBase *pDest =
323 pMyPool->Find( pSource->GetName(), pSource->GetFamily() );
324 if ( !pDest )
325 {
326 pDest = &pMyPool->Make( pSource->GetName(),
327 pSource->GetFamily(), pSource->GetMask());
328 // Setting of parents, the next style
329 }
330 pFound[nFound].pSource = pSource;
331 pFound[nFound].pDest = pDest;
332 ++nFound;
333 pSource = xIter->Next();
334 }
335
336 for ( sal_uInt16 i = 0; i < nFound; ++i )
337 {
338 pFound[i].pDest->GetItemSet().PutExtended(pFound[i].pSource->GetItemSet(), SfxItemState::DONTCARE, SfxItemState::DEFAULT);
339 if(pFound[i].pSource->HasParentSupport())
340 pFound[i].pDest->SetParent(pFound[i].pSource->GetParent());
341 if(pFound[i].pSource->HasFollowSupport())
342 pFound[i].pDest->SetFollow(pFound[i].pSource->GetParent());
343 }
344}
345
346sfx2::StyleManager* SfxObjectShell::GetStyleManager()
347{
348 return nullptr;
349}
350
351namespace
352{
353 class QueryTemplateBox
354 {
355 private:
356 std::unique_ptr<weld::MessageDialog> m_xQueryBox;
357 public:
358 QueryTemplateBox(weld::Window* pParent, const OUString& rMessage)
359 : m_xQueryBox(Application::CreateMessageDialog(pParent, VclMessageType::Question, VclButtonsType::NONE, rMessage))
360 {
361 m_xQueryBox->add_button(SfxResId(STR_QRYTEMPL_UPDATE_BTNreinterpret_cast<char const *>("STR_QRYTEMPL_UPDATE_BTN"
"\004" u8"~Update Styles")
), RET_YES);
362 m_xQueryBox->add_button(SfxResId(STR_QRYTEMPL_KEEP_BTNreinterpret_cast<char const *>("STR_QRYTEMPL_KEEP_BTN" "\004"
u8"~Keep Old Styles")
), RET_NO);
363 m_xQueryBox->set_default_response(RET_YES);
364 m_xQueryBox->set_help_id(HID_QUERY_LOAD_TEMPLATE"SFX2_HID_QUERY_LOAD_TEMPLATE");
365 }
366 short run() { return m_xQueryBox->run(); }
367 };
368}
369
370void SfxObjectShell::UpdateFromTemplate_Impl( )
371
372/* [Description]
373
374 This internal method checks whether the document was created from a
375 template, and if this is newer than the document. If this is the case,
376 the user is asked if the Templates (StyleSheets) should be updated.
377 If this is answered positively, the StyleSheets are updated.
378*/
379
380{
381 // Storage-medium?
382 SfxMedium *pFile = GetMedium();
383 DBG_ASSERT( pFile, "cannot UpdateFromTemplate without medium" )do { if (true && (!(pFile))) { sal_detail_logFormat((
SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objcont.cxx"
":" "383" ": "), "%s", "cannot UpdateFromTemplate without medium"
); } } while (false)
;
384 if ( !pFile )
385 return;
386
387 if ( !comphelper::isFileUrl( pFile->GetName() ) )
388 // update only for documents loaded from the local file system
389 return;
390
391 // tdf#113935 - do not remove this line - somehow, it makes the process
392 // of switching from viewing a read-only document to opening it in writable
393 // mode much faster.
394 uno::Reference< embed::XStorage > xDocStor = pFile->GetStorage(false);
395
396 // only for own storage formats
397 if ( !pFile->GetFilter() || !pFile->GetFilter()->IsOwnFormat() )
398 return;
399
400 const SfxUInt16Item* pUpdateDocItem = SfxItemSet::GetItem<SfxUInt16Item>(pFile->GetItemSet(), SID_UPDATEDOCMODE(5000 + 1668), false);
401 sal_Int16 bCanUpdateFromTemplate = pUpdateDocItem ? pUpdateDocItem->GetValue() : document::UpdateDocMode::NO_UPDATE;
402
403 // created from template?
404 uno::Reference<document::XDocumentProperties> xDocProps(getDocProperties());
405 const OUString aTemplName( xDocProps->getTemplateName() );
406 OUString aTemplURL( xDocProps->getTemplateURL() );
407 OUString aFoundName;
408
409 if ( !aTemplName.isEmpty() || (!aTemplURL.isEmpty() && !IsReadOnly()) )
410 {
411 // try to locate template, first using filename this must be done
412 // because writer global document uses this "great" idea to manage
413 // the templates of all parts in the master document but it is NOT
414 // an error if the template filename points not to a valid file
415 SfxDocumentTemplates aTempl;
416 if (!aTemplURL.isEmpty())
417 {
418 try {
419 aFoundName = ::rtl::Uri::convertRelToAbs(GetMedium()->GetName(),
420 aTemplURL);
421 } catch (::rtl::MalformedUriException const&) {
422 assert(false)(static_cast <bool> (false) ? void (0) : __assert_fail (
"false", "/home/maarten/src/libreoffice/core/sfx2/source/doc/objcont.cxx"
, 422, __extension__ __PRETTY_FUNCTION__))
; // don't think that's supposed to happen?
423 }
424 }
425
426 if( aFoundName.isEmpty() && !aTemplName.isEmpty() )
427 // if the template filename did not lead to success,
428 // try to get a file name for the logical template name
429 aTempl.GetFull( OUString(), aTemplName, aFoundName );
430 }
431
432 if ( aFoundName.isEmpty() )
433 return;
434
435 // check existence of template storage
436 aTemplURL = aFoundName;
437
438 // should the document checked against changes in the template ?
439 if ( !IsQueryLoadTemplate() )
440 return;
441
442 bool bLoad = false;
443
444 // load document properties of template
445 bool bOK = false;
446 util::DateTime aTemplDate;
447 try
448 {
449 Reference<document::XDocumentProperties> const
450 xTemplateDocProps( document::DocumentProperties::create(
451 ::comphelper::getProcessComponentContext()));
452 xTemplateDocProps->loadFromMedium(aTemplURL,
453 Sequence<beans::PropertyValue>());
454 aTemplDate = xTemplateDocProps->getModificationDate();
455 bOK = true;
456 }
457 catch (const Exception&)
458 {
459 TOOLS_INFO_EXCEPTION("sfx.doc", "")do { css::uno::Any tools_warn_exception( DbgGetCaughtException
() ); do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "sfx.doc")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "" << " " <<
exceptionToString(tools_warn_exception)) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objcont.cxx"
":" "459" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "" << " " << exceptionToString
(tools_warn_exception)), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "" << " " << exceptionToString
(tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objcont.cxx"
":" "459" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "" << " " << exceptionToString(tools_warn_exception
)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), (
"sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objcont.cxx"
":" "459" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "" << " " << exceptionToString
(tools_warn_exception)), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "" << " " << exceptionToString
(tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objcont.cxx"
":" "459" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false); } while (false)
;
460 }
461
462 // if modify date was read successfully
463 if ( bOK )
464 {
465 // compare modify data of template with the last check date of the document
466 const util::DateTime aInfoDate( xDocProps->getTemplateDate() );
467 if ( aTemplDate > aInfoDate )
468 {
469 // ask user
470 if( bCanUpdateFromTemplate == document::UpdateDocMode::QUIET_UPDATE
471 || bCanUpdateFromTemplate == document::UpdateDocMode::FULL_UPDATE )
472 bLoad = true;
473 else if ( bCanUpdateFromTemplate == document::UpdateDocMode::ACCORDING_TO_CONFIG )
474 {
475 const OUString sMessage( SfxResId(STR_QRYTEMPL_MESSAGEreinterpret_cast<char const *>("STR_QRYTEMPL_MESSAGE" "\004"
u8"The template '$(ARG1)' on which this document is based, has been modified. Do you want to update style based formatting according to the modified template?"
)
).replaceAll( "$(ARG1)", aTemplName ) );
476 vcl::Window *pWin = GetDialogParent();
477 QueryTemplateBox aBox(pWin ? pWin->GetFrameWeld() : nullptr, sMessage);
478 if (RET_YES == aBox.run())
479 bLoad = true;
480 }
481
482 if( !bLoad )
483 {
484 // user refuses, so don't ask again for this document
485 SetQueryLoadTemplate(false);
486 SetModified();
487 }
488 }
489 }
490
491 if ( !bLoad )
492 return;
493
494 // styles should be updated, create document in organizer mode to read in the styles
495 //TODO: testen!
496 SfxObjectShellLock xTemplDoc = CreateObjectByFactoryName( GetFactory().GetFactoryName(), SfxObjectCreateMode::ORGANIZER );
497 xTemplDoc->DoInitNew();
498
499 // TODO/MBA: do we need a BaseURL? Then LoadFrom must be extended!
500 //xTemplDoc->SetBaseURL( aFoundName );
501
502 // TODO/LATER: make sure that we don't use binary templates!
503 SfxMedium aMedium( aFoundName, StreamMode::STD_READ );
504 if ( xTemplDoc->LoadFrom( aMedium ) )
505 {
506 // transfer styles from xTemplDoc to this document
507 // TODO/MBA: make sure that no BaseURL is needed in *this* document
508 LoadStyles(*xTemplDoc);
509
510 // remember date/time of check
511 xDocProps->setTemplateDate(aTemplDate);
512 // TODO/LATER: new functionality to store document info is required ( didn't work for SO7 XML format )
513 }
514}
515
516bool SfxObjectShell::IsHelpDocument() const
517{
518 std::shared_ptr<const SfxFilter> pFilter = GetMedium()->GetFilter();
519 return (pFilter && pFilter->GetFilterName() == "writer_web_HTML_help");
520}
521
522void SfxObjectShell::ResetFromTemplate( const OUString& rTemplateName, const OUString& rFileName )
523{
524 // only care about resetting this data for LibreOffice formats otherwise
525 if ( !IsOwnStorageFormat( *GetMedium()) )
526 return;
527
528 uno::Reference<document::XDocumentProperties> xDocProps(getDocProperties());
529 xDocProps->setTemplateURL( OUString() );
530 xDocProps->setTemplateName( OUString() );
531 xDocProps->setTemplateDate( util::DateTime() );
532 xDocProps->resetUserData( OUString() );
533
534 // TODO/REFACTOR:
535 // Title?
536
537 if( !comphelper::isFileUrl( rFileName ) )
538 return;
539
540 OUString aFoundName;
541 if( SfxGetpApp()->Get_Impl()->GetDocumentTemplates()->GetFull( OUString(), rTemplateName, aFoundName ) )
542 {
543 INetURLObject aObj( rFileName );
544 xDocProps->setTemplateURL( aObj.GetMainURL(INetURLObject::DecodeMechanism::ToIUri) );
545 xDocProps->setTemplateName( rTemplateName );
546
547 ::DateTime now( ::DateTime::SYSTEM );
548 xDocProps->setTemplateDate( now.GetUNODateTime() );
549
550 SetQueryLoadTemplate( true );
551 }
552}
553
554bool SfxObjectShell::IsQueryLoadTemplate() const
555{
556 return pImpl->bQueryLoadTemplate;
557}
558
559bool SfxObjectShell::IsUseUserData() const
560{
561 return pImpl->bUseUserData;
562}
563
564bool SfxObjectShell::IsUseThumbnailSave() const
565{
566 return pImpl->bUseThumbnailSave;
567}
568
569void SfxObjectShell::SetQueryLoadTemplate( bool bNew )
570{
571 if ( pImpl->bQueryLoadTemplate != bNew )
572 SetModified();
573 pImpl->bQueryLoadTemplate = bNew;
574}
575
576void SfxObjectShell::SetUseUserData( bool bNew )
577{
578 if ( pImpl->bUseUserData != bNew )
579 SetModified();
580 pImpl->bUseUserData = bNew;
581}
582
583void SfxObjectShell::SetUseThumbnailSave( bool _bNew )
584{
585 if ( pImpl->bUseThumbnailSave != _bNew )
586 SetModified();
587 pImpl->bUseThumbnailSave = _bNew;
588}
589
590bool SfxObjectShell::IsLoadReadonly() const
591{
592 return pImpl->bLoadReadonly;
593}
594
595bool SfxObjectShell::IsSaveVersionOnClose() const
596{
597 return pImpl->bSaveVersionOnClose;
598}
599
600void SfxObjectShell::SetLoadReadonly( bool bNew )
601{
602 if ( pImpl->bLoadReadonly != bNew )
603 SetModified();
604 pImpl->bLoadReadonly = bNew;
605}
606
607void SfxObjectShell::SetSaveVersionOnClose( bool bNew )
608{
609 if ( pImpl->bSaveVersionOnClose != bNew )
610 SetModified();
611 pImpl->bSaveVersionOnClose = bNew;
612}
613
614sal_uInt32 SfxObjectShell::GetModifyPasswordHash() const
615{
616 return pImpl->m_nModifyPasswordHash;
617}
618
619bool SfxObjectShell::SetModifyPasswordHash( sal_uInt32 nHash )
620{
621 if ( ( !IsReadOnly() && !IsReadOnlyUI() )
622 || !(pImpl->nFlagsInProgress & SfxLoadedFlags::MAINDOCUMENT ) )
623 {
624 // the hash can be changed only in editable documents,
625 // or during loading of document
626 pImpl->m_nModifyPasswordHash = nHash;
627 return true;
628 }
629
630 return false;
631}
632
633const uno::Sequence< beans::PropertyValue >& SfxObjectShell::GetModifyPasswordInfo() const
634{
635 return pImpl->m_aModifyPasswordInfo;
636}
637
638bool SfxObjectShell::SetModifyPasswordInfo( const uno::Sequence< beans::PropertyValue >& aInfo )
639{
640 if ( ( !IsReadOnly() && !IsReadOnlyUI() )
641 || !(pImpl->nFlagsInProgress & SfxLoadedFlags::MAINDOCUMENT ) )
642 {
643 // the hash can be changed only in editable documents,
644 // or during loading of document
645 pImpl->m_aModifyPasswordInfo = aInfo;
646 return true;
647 }
648
649 return false;
650}
651
652void SfxObjectShell::SetModifyPasswordEntered( bool bEntered )
653{
654 pImpl->m_bModifyPasswordEntered = bEntered;
655}
656
657bool SfxObjectShell::IsModifyPasswordEntered() const
658{
659 return pImpl->m_bModifyPasswordEntered;
660}
661
662/* 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 ;-)
17
Calling 'Reference::clear'
24
Returning; memory was released
205 if (aTmp.get()) {
25
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();
16
Calling 'VclPtr::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 )
4
Memory is allocated
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
17.1
Field 'm_pBody' is non-null
17.1
Field 'm_pBody' is non-null
17.1
Field 'm_pBody' is non-null
17.1
Field 'm_pBody' is non-null
)
18
Taking true branch
177 {
178 reference_type * const pOld = m_pBody;
179 m_pBody = NULL__null;
180 pOld->release();
19
Calling 'VclReferenceBase::release'
23
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;
26
Use of memory after it is freed
193 }
194
195
196 /** Probably most common used: handle->someBodyOp().
197 */
198 reference_type * SAL_CALL operator->() const
199 {
200 assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail
("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx"
, 200, __extension__ __PRETTY_FUNCTION__))
;
201 return m_pBody;
202 }
203
204
205 /** Allows (*handle).someBodyOp().
206 */
207 reference_type & SAL_CALL operator*() const
208 {
209 assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail
("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx"
, 209, __extension__ __PRETTY_FUNCTION__))
;
210 return *m_pBody;
211 }
212
213
214 /** Returns True if the handle does point to a valid body.
215 */
216 bool SAL_CALL is() const
217 {
218 return (m_pBody != NULL__null);
219 }
220
221#if defined LIBO_INTERNAL_ONLY1
222 /** Returns True if the handle does point to a valid body.
223 */
224 explicit operator bool() const
225 {
226 return is();
227 }
228#endif
229
230 /** Returns True if this points to pBody.
231 */
232 bool SAL_CALL operator== (const reference_type * pBody) const
233 {
234 return (m_pBody == pBody);
235 }
236
237
238 /** Returns True if handle points to the same body.
239 */
240 bool
241 SAL_CALL operator== (const Reference<reference_type> & handle) const
242 {
243 return (m_pBody == handle.m_pBody);
244 }
245
246
247 /** Needed to place References into STL collection.
248 */
249 bool
250 SAL_CALL operator!= (const Reference<reference_type> & handle) const
251 {
252 return (m_pBody != handle.m_pBody);
253 }
254
255
256 /** Needed to place References into STL collection.
257 */
258 bool
259 SAL_CALL operator< (const Reference<reference_type> & handle) const
260 {
261 return (m_pBody < handle.m_pBody);
262 }
263
264
265 /** Needed to place References into STL collection.
266 */
267 bool
268 SAL_CALL operator> (const Reference<reference_type> & handle) const
269 {
270 return (m_pBody > handle.m_pBody);
271 }
272};
273
274} // namespace rtl
275
276#if defined LIBO_INTERNAL_ONLY1
277namespace std
278{
279
280/// @cond INTERNAL
281/**
282 Make rtl::Reference hashable by default for use in STL containers.
283
284 @since LibreOffice 6.3
285*/
286template<typename T>
287struct hash<::rtl::Reference<T>>
288{
289 std::size_t operator()(::rtl::Reference<T> const & s) const
290 { return std::size_t(s.get()); }
291};
292/// @endcond
293
294}
295
296#endif
297
298#endif /* ! INCLUDED_RTL_REF_HXX */
299
300/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

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

1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19#ifndef INCLUDED_VCL_Reference_HXX
20#define INCLUDED_VCL_Reference_HXX
21
22#include <vcl/dllapi.h>
23#include <osl/interlck.h>
24
25class VCL_DLLPUBLIC__attribute__ ((visibility("default"))) VclReferenceBase
26{
27 mutable oslInterlockedCount mnRefCnt;
28
29 template<typename T> friend class VclPtr;
30
31public:
32 void acquire() const
33 {
34 osl_atomic_increment(&mnRefCnt)__sync_add_and_fetch((&mnRefCnt), 1);
35 }
36
37 void release() const
38 {
39 if (osl_atomic_decrement(&mnRefCnt)__sync_sub_and_fetch((&mnRefCnt), 1) == 0)
20
Assuming the condition is true
21
Taking true branch
40 delete this;
22
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