Bug Summary

File:home/maarten/src/libreoffice/core/sfx2/source/doc/objmisc.cxx
Warning:line 1650, column 5
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 objmisc.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/objmisc.cxx

/home/maarten/src/libreoffice/core/sfx2/source/doc/objmisc.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 <config_features.h>
21
22#include <tools/inetmsg.hxx>
23#include <tools/diagnose_ex.h>
24#include <svl/eitem.hxx>
25#include <svl/stritem.hxx>
26#include <svl/intitem.hxx>
27#include <svtools/svparser.hxx>
28#include <cppuhelper/exc_hlp.hxx>
29#include <sal/log.hxx>
30
31#include <com/sun/star/beans/XPropertySet.hpp>
32#include <com/sun/star/container/XChild.hpp>
33#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
34#include <com/sun/star/document/XDocumentProperties.hpp>
35#include <com/sun/star/document/MacroExecMode.hpp>
36#include <com/sun/star/document/XScriptInvocationContext.hpp>
37#include <com/sun/star/embed/EmbedStates.hpp>
38#include <com/sun/star/embed/XEmbeddedObject.hpp>
39#include <com/sun/star/script/provider/theMasterScriptProviderFactory.hpp>
40#include <com/sun/star/script/provider/XScript.hpp>
41#include <com/sun/star/script/provider/XScriptProvider.hpp>
42#include <com/sun/star/script/provider/XScriptProviderSupplier.hpp>
43#include <com/sun/star/uri/UriReferenceFactory.hpp>
44#include <com/sun/star/uri/XVndSunStarScriptUrl.hpp>
45#include <com/sun/star/util/XModifiable.hpp>
46
47#include <toolkit/helper/vclunohelper.hxx>
48
49#include <com/sun/star/uno/Reference.h>
50#include <com/sun/star/uno/Any.h>
51#include <com/sun/star/task/ErrorCodeRequest.hpp>
52
53#include <comphelper/processfactory.hxx>
54#include <comphelper/string.hxx>
55
56#include <com/sun/star/security/DocumentDigitalSignatures.hpp>
57#include <com/sun/star/task/DocumentMacroConfirmationRequest.hpp>
58#include <com/sun/star/task/InteractionClassification.hpp>
59#include <com/sun/star/task/XInteractionHandler.hpp>
60#include <com/sun/star/frame/XModel.hpp>
61
62#include <basic/basmgr.hxx>
63#include <basic/sberrors.hxx>
64#include <vcl/weld.hxx>
65#include <basic/sbx.hxx>
66#include <svtools/sfxecode.hxx>
67
68#include <unotools/ucbhelper.hxx>
69#include <tools/urlobj.hxx>
70#include <svl/sharecontrolfile.hxx>
71#include <rtl/uri.hxx>
72#include <vcl/svapp.hxx>
73#include <framework/interaction.hxx>
74#include <framework/documentundoguard.hxx>
75#include <comphelper/interaction.hxx>
76#include <comphelper/storagehelper.hxx>
77#include <comphelper/documentconstants.hxx>
78#include <comphelper/namedvaluecollection.hxx>
79#include <officecfg/Office/Common.hxx>
80
81#include <sfx2/signaturestate.hxx>
82#include <sfx2/app.hxx>
83#include <appdata.hxx>
84#include <sfx2/request.hxx>
85#include <sfx2/bindings.hxx>
86#include <sfx2/sfxresid.hxx>
87#include <sfx2/docfile.hxx>
88#include <sfx2/docfilt.hxx>
89#include <sfx2/objsh.hxx>
90#include <objshimp.hxx>
91#include <sfx2/event.hxx>
92#include <sfx2/viewfrm.hxx>
93#include <sfx2/sfxuno.hxx>
94#include <sfx2/module.hxx>
95#include <sfx2/docfac.hxx>
96#include <sfx2/sfxsids.hrc>
97#include <sfx2/strings.hrc>
98#include <workwin.hxx>
99#include <sfx2/sfxdlg.hxx>
100#include <sfx2/infobar.hxx>
101#include <openflag.hxx>
102#include "objstor.hxx"
103#include <appopen.hxx>
104
105#include <memory>
106
107using namespace ::com::sun::star;
108using namespace ::com::sun::star::uno;
109using namespace ::com::sun::star::ucb;
110using namespace ::com::sun::star::document;
111using namespace ::com::sun::star::frame;
112using namespace ::com::sun::star::script;
113using namespace ::com::sun::star::script::provider;
114using namespace ::com::sun::star::container;
115
116// class SfxHeaderAttributes_Impl ----------------------------------------
117
118namespace {
119
120class SfxHeaderAttributes_Impl : public SvKeyValueIterator
121{
122private:
123 SfxObjectShell* pDoc;
124 SvKeyValueIteratorRef xIter;
125 bool bAlert;
126
127public:
128 explicit SfxHeaderAttributes_Impl( SfxObjectShell* pSh ) :
129 SvKeyValueIterator(), pDoc( pSh ),
130 xIter( pSh->GetMedium()->GetHeaderAttributes_Impl() ),
131 bAlert( false ) {}
132
133 virtual bool GetFirst( SvKeyValue& rKV ) override { return xIter->GetFirst( rKV ); }
134 virtual bool GetNext( SvKeyValue& rKV ) override { return xIter->GetNext( rKV ); }
135 virtual void Append( const SvKeyValue& rKV ) override;
136
137 void ClearForSourceView() { xIter = new SvKeyValueIterator; bAlert = false; }
138 void SetAttributes();
139 void SetAttribute( const SvKeyValue& rKV );
140};
141
142}
143
144sal_uInt16 const aTitleMap_Impl[3][2] =
145{
146 // local remote
147 /* SFX_TITLE_CAPTION */ { SFX_TITLE_FILENAME1, SFX_TITLE_TITLE0 },
148 /* SFX_TITLE_PICKLIST */ { 32, SFX_TITLE_FULLNAME2 },
149 /* SFX_TITLE_HISTORY */ { 32, SFX_TITLE_FULLNAME2 }
150};
151
152
153bool SfxObjectShell::IsAbortingImport() const
154{
155 return pImpl->bIsAbortingImport;
156}
157
158
159uno::Reference<document::XDocumentProperties>
160SfxObjectShell::getDocProperties() const
161{
162 uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
163 GetModel(), uno::UNO_QUERY_THROW);
164 uno::Reference<document::XDocumentProperties> xDocProps(
165 xDPS->getDocumentProperties());
166 DBG_ASSERT(xDocProps.is(),do { if (true && (!(xDocProps.is()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objmisc.cxx"
":" "167" ": "), "%s", "SfxObjectShell: model has no DocumentProperties"
); } } while (false)
167 "SfxObjectShell: model has no DocumentProperties")do { if (true && (!(xDocProps.is()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objmisc.cxx"
":" "167" ": "), "%s", "SfxObjectShell: model has no DocumentProperties"
); } } while (false)
;
168 return xDocProps;
169}
170
171
172void SfxObjectShell::DoFlushDocInfo()
173{
174}
175
176
177// Note: the only thing that calls this is the modification event handler
178// that is installed at the XDocumentProperties
179void SfxObjectShell::FlushDocInfo()
180{
181 if ( IsLoading() )
182 return;
183
184 SetModified();
185 uno::Reference<document::XDocumentProperties> xDocProps(getDocProperties());
186 DoFlushDocInfo(); // call template method
187 const OUString url(xDocProps->getAutoloadURL());
188 sal_Int32 delay(xDocProps->getAutoloadSecs());
189 SetAutoLoad( INetURLObject(url), delay * 1000,
190 (delay > 0) || !url.isEmpty() );
191}
192
193void SfxObjectShell::AppendInfoBarWhenReady(const OUString& sId, const OUString& sPrimaryMessage,
194 const OUString& sSecondaryMessage,
195 InfobarType aInfobarType, bool bShowCloseButton)
196{
197 InfobarData aInfobarData;
198 aInfobarData.msId = sId;
199 aInfobarData.msPrimaryMessage = sPrimaryMessage;
200 aInfobarData.msSecondaryMessage = sSecondaryMessage;
201 aInfobarData.maInfobarType = aInfobarType;
202 aInfobarData.mbShowCloseButton = bShowCloseButton;
203 Get_Impl()->m_aPendingInfobars.emplace_back(aInfobarData);
204}
205
206std::vector<InfobarData>& SfxObjectShell::getPendingInfobars()
207{
208 return Get_Impl()->m_aPendingInfobars;
209}
210
211void SfxObjectShell::SetError(ErrCode lErr)
212{
213 if (pImpl->lErr==ERRCODE_NONEErrCode(0))
214 {
215 pImpl->lErr=lErr;
216 }
217}
218
219ErrCode SfxObjectShell::GetError() const
220{
221 return GetErrorCode().IgnoreWarning();
222}
223
224ErrCode SfxObjectShell::GetErrorCode() const
225{
226 ErrCode lError=pImpl->lErr;
227 if(!lError && GetMedium())
228 lError=GetMedium()->GetErrorCode();
229 return lError;
230}
231
232void SfxObjectShell::ResetError()
233{
234 pImpl->lErr=ERRCODE_NONEErrCode(0);
235 SfxMedium * pMed = GetMedium();
236 if( pMed )
237 pMed->ResetError();
238}
239
240void SfxObjectShell::EnableSetModified( bool bEnable )
241{
242 SAL_INFO_IF( bEnable == pImpl->m_bEnableSetModified, "sfx", "SFX_PERSIST: EnableSetModified 2x called with the same value" )do { if (true && (bEnable == pImpl->m_bEnableSetModified
)) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "sfx")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "SFX_PERSIST: EnableSetModified 2x called with the same value"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objmisc.cxx"
":" "242" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "SFX_PERSIST: EnableSetModified 2x called with the same value"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "SFX_PERSIST: EnableSetModified 2x called with the same value"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx"),
("/home/maarten/src/libreoffice/core/sfx2/source/doc/objmisc.cxx"
":" "242" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "SFX_PERSIST: EnableSetModified 2x called with the same value"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objmisc.cxx"
":" "242" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "SFX_PERSIST: EnableSetModified 2x called with the same value"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "SFX_PERSIST: EnableSetModified 2x called with the same value"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx"),
("/home/maarten/src/libreoffice/core/sfx2/source/doc/objmisc.cxx"
":" "242" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
243 pImpl->m_bEnableSetModified = bEnable;
244}
245
246
247bool SfxObjectShell::IsEnableSetModified() const
248{
249 return pImpl->m_bEnableSetModified && !IsReadOnly();
250}
251
252
253bool SfxObjectShell::IsModified() const
254{
255 if ( pImpl->m_bIsModified )
256 return true;
257
258 if ( !pImpl->m_xDocStorage.is() || IsReadOnly() )
259 {
260 // if the document still has no storage and is not set to be modified explicitly it is not modified
261 // a readonly document is also not modified
262
263 return false;
264 }
265
266 if (pImpl->mxObjectContainer)
267 {
268 const uno::Sequence < OUString > aNames = GetEmbeddedObjectContainer().GetObjectNames();
269 for ( const auto& rName : aNames )
270 {
271 uno::Reference < embed::XEmbeddedObject > xObj = GetEmbeddedObjectContainer().GetEmbeddedObject( rName );
272 OSL_ENSURE( xObj.is(), "An empty entry in the embedded objects list!" )do { if (true && (!(xObj.is()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objmisc.cxx"
":" "272" ": "), "%s", "An empty entry in the embedded objects list!"
); } } while (false)
;
273 if ( xObj.is() )
274 {
275 try
276 {
277 sal_Int32 nState = xObj->getCurrentState();
278 if ( nState != embed::EmbedStates::LOADED )
279 {
280 uno::Reference< util::XModifiable > xModifiable( xObj->getComponent(), uno::UNO_QUERY );
281 if ( xModifiable.is() && xModifiable->isModified() )
282 return true;
283 }
284 }
285 catch( uno::Exception& )
286 {}
287 }
288 }
289 }
290
291 return false;
292}
293
294
295void SfxObjectShell::SetModified( bool bModifiedP )
296{
297 SAL_INFO_IF( !bModifiedP && !IsEnableSetModified(), "sfx",do { if (true && (!bModifiedP && !IsEnableSetModified
())) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "sfx")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "SFX_PERSIST: SetModified( sal_False ), although IsEnableSetModified() == sal_False"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objmisc.cxx"
":" "298" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "SFX_PERSIST: SetModified( sal_False ), although IsEnableSetModified() == sal_False"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "SFX_PERSIST: SetModified( sal_False ), although IsEnableSetModified() == sal_False"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx"),
("/home/maarten/src/libreoffice/core/sfx2/source/doc/objmisc.cxx"
":" "298" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "SFX_PERSIST: SetModified( sal_False ), although IsEnableSetModified() == sal_False"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objmisc.cxx"
":" "298" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "SFX_PERSIST: SetModified( sal_False ), although IsEnableSetModified() == sal_False"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "SFX_PERSIST: SetModified( sal_False ), although IsEnableSetModified() == sal_False"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx"),
("/home/maarten/src/libreoffice/core/sfx2/source/doc/objmisc.cxx"
":" "298" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
298 "SFX_PERSIST: SetModified( sal_False ), although IsEnableSetModified() == sal_False" )do { if (true && (!bModifiedP && !IsEnableSetModified
())) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "sfx")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "SFX_PERSIST: SetModified( sal_False ), although IsEnableSetModified() == sal_False"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objmisc.cxx"
":" "298" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "SFX_PERSIST: SetModified( sal_False ), although IsEnableSetModified() == sal_False"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "SFX_PERSIST: SetModified( sal_False ), although IsEnableSetModified() == sal_False"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx"),
("/home/maarten/src/libreoffice/core/sfx2/source/doc/objmisc.cxx"
":" "298" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "SFX_PERSIST: SetModified( sal_False ), although IsEnableSetModified() == sal_False"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objmisc.cxx"
":" "298" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "SFX_PERSIST: SetModified( sal_False ), although IsEnableSetModified() == sal_False"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "SFX_PERSIST: SetModified( sal_False ), although IsEnableSetModified() == sal_False"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx"),
("/home/maarten/src/libreoffice/core/sfx2/source/doc/objmisc.cxx"
":" "298" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
299
300 if( !IsEnableSetModified() )
301 return;
302
303 if( pImpl->m_bIsModified != bModifiedP )
304 {
305 pImpl->m_bIsModified = bModifiedP;
306 ModifyChanged();
307 }
308}
309
310
311void SfxObjectShell::ModifyChanged()
312{
313 if ( pImpl->bClosing )
314 // SetModified dispose of the models!
315 return;
316
317
318 SfxViewFrame* pViewFrame = SfxViewFrame::Current();
319 if ( pViewFrame )
320 pViewFrame->GetBindings().Invalidate( SID_SAVEDOCS(5000 + 309) );
321
322 Invalidate( SID_SIGNATURE(5000 + 1643) );
323 Invalidate( SID_MACRO_SIGNATURE(5000 + 1704) );
324 Broadcast( SfxHint( SfxHintId::TitleChanged ) ); // xmlsec05, signed state might change in title...
325
326 SfxGetpApp()->NotifyEvent( SfxEventHint( SfxEventHintId::ModifyChanged, GlobalEventConfig::GetEventName(GlobalEventId::MODIFYCHANGED), this ) );
327}
328
329
330bool SfxObjectShell::IsReadOnlyUI() const
331
332/* [Description]
333
334 Returns sal_True if the document for the UI is treated as r/o. This is
335 regardless of the actual r/o, which can be checked with <IsReadOnly()>.
336*/
337
338{
339 return pImpl->bReadOnlyUI;
340}
341
342
343bool SfxObjectShell::IsReadOnlyMedium() const
344
345/* [Description]
346
347 Returns sal_True when the medium is r/o, for instance when opened as r/o.
348*/
349
350{
351 if ( !pMedium )
352 return true;
353 return pMedium->IsReadOnly();
354}
355
356bool SfxObjectShell::IsOriginallyReadOnlyMedium() const
357{
358 return pMedium == nullptr || pMedium->IsOriginallyReadOnly();
359}
360
361bool SfxObjectShell::IsOriginallyLoadedReadOnlyMedium() const
362{
363 return pMedium != nullptr && pMedium->IsOriginallyLoadedReadOnly();
364}
365
366
367void SfxObjectShell::SetReadOnlyUI( bool bReadOnly )
368
369/* [Description]
370
371 Turns the document in a r/o and r/w state respectively without reloading
372 it and without changing the open mode of the medium.
373*/
374
375{
376 if ( bReadOnly != pImpl->bReadOnlyUI )
377 {
378 pImpl->bReadOnlyUI = bReadOnly;
379 Broadcast( SfxHint(SfxHintId::ModeChanged) );
380 }
381}
382
383
384void SfxObjectShell::SetReadOnly()
385{
386 // Let the document be completely readonly, means that the
387 // medium open mode is adjusted accordingly, and the write lock
388 // on the file is removed.
389
390 if ( !pMedium || IsReadOnlyMedium() )
391 return;
392
393 bool bWasROUI = IsReadOnly();
394
395 pMedium->UnlockFile( false );
396
397 // the storage-based mediums are already based on the temporary file
398 // so UnlockFile has already closed the locking stream
399 if ( !pMedium->HasStorage_Impl() && IsLoadingFinished() )
400 pMedium->CloseInStream();
401
402 pMedium->SetOpenMode( SFX_STREAM_READONLY(StreamMode::READ | StreamMode::SHARE_DENYWRITE), true );
403 pMedium->GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY(5000 + 590), true ) );
404
405 if ( !bWasROUI )
406 Broadcast( SfxHint(SfxHintId::ModeChanged) );
407}
408
409
410bool SfxObjectShell::IsReadOnly() const
411{
412 return pImpl->bReadOnlyUI || pMedium == nullptr;
413}
414
415
416bool SfxObjectShell::IsInModalMode() const
417{
418 return pImpl->bModalMode || pImpl->bRunningMacro;
419}
420
421bool SfxObjectShell::AcceptStateUpdate() const
422{
423 return !IsInModalMode();
424}
425
426
427void SfxObjectShell::SetMacroMode_Impl( bool bModal )
428{
429 if ( !pImpl->bRunningMacro != !bModal )
430 {
431 pImpl->bRunningMacro = bModal;
432 Broadcast( SfxHint( SfxHintId::ModeChanged ) );
433 }
434}
435
436
437void SfxObjectShell::SetModalMode_Impl( bool bModal )
438{
439 // Broadcast only if modified, or otherwise it will possibly go into
440 // an endless loop
441 if ( pImpl->bModalMode == bModal )
442 return;
443
444 // Central count
445 sal_uInt16 &rDocModalCount = SfxGetpApp()->Get_Impl()->nDocModalMode;
446 if ( bModal )
447 ++rDocModalCount;
448 else
449 --rDocModalCount;
450
451 // Switch
452 pImpl->bModalMode = bModal;
453 Broadcast( SfxHint( SfxHintId::ModeChanged ) );
454}
455
456#if HAVE_FEATURE_MULTIUSER_ENVIRONMENT1
457
458bool SfxObjectShell::SwitchToShared( bool bShared, bool bSave )
459{
460 bool bResult = true;
461
462 if ( bShared != IsDocShared() )
463 {
464 OUString aOrigURL = GetMedium()->GetURLObject().GetMainURL( INetURLObject::DecodeMechanism::NONE );
465
466 if ( aOrigURL.isEmpty() && bSave )
467 {
468 // this is a new document, let it be stored before switching to the shared mode;
469 // the storing should be done without shared flag, since it is possible that the
470 // target location does not allow to create sharing control file;
471 // the shared flag will be set later after creation of sharing control file
472 SfxViewFrame* pViewFrame = SfxViewFrame::GetFirst( this );
473
474 if ( pViewFrame )
475 {
476 // TODO/LATER: currently the application guards against the reentrance problem
477 const SfxPoolItem* pItem = pViewFrame->GetBindings().ExecuteSynchron( HasName() ? SID_SAVEDOC(5000 + 505) : SID_SAVEASDOC(5000 + 502) );
478 const SfxBoolItem* pResult = dynamic_cast<const SfxBoolItem*>( pItem );
479 bResult = ( pResult && pResult->GetValue() );
480 if ( bResult )
481 aOrigURL = GetMedium()->GetURLObject().GetMainURL( INetURLObject::DecodeMechanism::NONE );
482 }
483 }
484
485 bool bOldValue = HasSharedXMLFlagSet();
486 SetSharedXMLFlag( bShared );
487
488 bool bRemoveEntryOnError = false;
489 if ( bResult && bShared )
490 {
491 try
492 {
493 ::svt::ShareControlFile aControlFile( aOrigURL );
494 aControlFile.InsertOwnEntry();
495 bRemoveEntryOnError = true;
496 }
497 catch( uno::Exception& )
498 {
499 bResult = false;
500 }
501 }
502
503 if ( bResult && bSave )
504 {
505 SfxViewFrame* pViewFrame = SfxViewFrame::GetFirst( this );
506
507 if ( pViewFrame )
508 {
509 // TODO/LATER: currently the application guards against the reentrance problem
510 SetModified(); // the modified flag has to be set to let the document be stored with the shared flag
511 const SfxPoolItem* pItem = pViewFrame->GetBindings().ExecuteSynchron( HasName() ? SID_SAVEDOC(5000 + 505) : SID_SAVEASDOC(5000 + 502) );
512 const SfxBoolItem* pResult = dynamic_cast<const SfxBoolItem*>( pItem );
513 bResult = ( pResult && pResult->GetValue() );
514 }
515 }
516
517 if ( bResult )
518 {
519 // TODO/LATER: Is it possible that the following calls fail?
520 if ( bShared )
521 {
522 pImpl->m_aSharedFileURL = aOrigURL;
523 GetMedium()->SwitchDocumentToTempFile();
524 }
525 else
526 {
527 const OUString aTempFileURL = pMedium->GetURLObject().GetMainURL( INetURLObject::DecodeMechanism::NONE );
528 GetMedium()->SwitchDocumentToFile( GetSharedFileURL() );
529 pImpl->m_aSharedFileURL.clear();
530
531 // now remove the temporary file the document was based on
532 ::utl::UCBContentHelper::Kill( aTempFileURL );
533
534 try
535 {
536 // aOrigURL can not be used since it contains an old value
537 ::svt::ShareControlFile aControlFile( GetMedium()->GetURLObject().GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
538 aControlFile.RemoveFile();
539 }
540 catch( uno::Exception& )
541 {
542 }
543 }
544 }
545 else
546 {
547 // the saving has failed!
548 if ( bRemoveEntryOnError )
549 {
550 try
551 {
552 ::svt::ShareControlFile aControlFile( aOrigURL );
553 aControlFile.RemoveEntry();
554 }
555 catch( uno::Exception& )
556 {}
557 }
558
559 SetSharedXMLFlag( bOldValue );
560 }
561 }
562 else
563 bResult = false; // the second switch to the same mode
564
565 if ( bResult )
566 SetTitle( "" );
567
568 return bResult;
569}
570
571
572void SfxObjectShell::FreeSharedFile( const OUString& aTempFileURL )
573{
574 SetSharedXMLFlag( false );
575
576 if ( !IsDocShared() || aTempFileURL.isEmpty()
577 || ::utl::UCBContentHelper::EqualURLs( aTempFileURL, GetSharedFileURL() ) )
578 return;
579
580 if ( pImpl->m_bAllowShareControlFileClean )
581 {
582 try
583 {
584 ::svt::ShareControlFile aControlFile( GetSharedFileURL() );
585 aControlFile.RemoveEntry();
586 }
587 catch( uno::Exception& )
588 {
589 }
590 }
591
592 // the cleaning is forbidden only once
593 pImpl->m_bAllowShareControlFileClean = true;
594
595 // now remove the temporary file the document is based currently on
596 ::utl::UCBContentHelper::Kill( aTempFileURL );
597
598 pImpl->m_aSharedFileURL.clear();
599}
600
601
602void SfxObjectShell::DoNotCleanShareControlFile()
603{
604 pImpl->m_bAllowShareControlFileClean = false;
605}
606
607
608void SfxObjectShell::SetSharedXMLFlag( bool bFlag ) const
609{
610 pImpl->m_bSharedXMLFlag = bFlag;
611}
612
613
614bool SfxObjectShell::HasSharedXMLFlagSet() const
615{
616 return pImpl->m_bSharedXMLFlag;
617}
618
619#endif
620
621bool SfxObjectShell::IsDocShared() const
622{
623#if HAVE_FEATURE_MULTIUSER_ENVIRONMENT1
624 return ( !pImpl->m_aSharedFileURL.isEmpty() );
625#else
626 return false;
627#endif
628}
629
630
631OUString SfxObjectShell::GetSharedFileURL() const
632{
633#if HAVE_FEATURE_MULTIUSER_ENVIRONMENT1
634 return pImpl->m_aSharedFileURL;
635#else
636 return OUString();
637#endif
638}
639
640Size SfxObjectShell::GetFirstPageSize() const
641{
642 return GetVisArea(ASPECT_THUMBNAIL2).GetSize();
643}
644
645
646IndexBitSet& SfxObjectShell::GetNoSet_Impl()
647{
648 return pImpl->aBitSet;
649}
650
651
652// changes the title of the document
653
654void SfxObjectShell::SetTitle
655(
656 const OUString& rTitle // the new Document Title
657)
658
659/* [Description]
660
661 With this method, the title of the document can be set.
662 This corresponds initially to the full file name. A setting of the
663 title does not affect the file name, but it will be shown in the
664 Caption-Bars of the MDI-window.
665*/
666
667{
668
669 // Nothing to do?
670 if ( ( ( HasName() && pImpl->aTitle == rTitle )
671 || ( !HasName() && GetTitle() == rTitle ) )
672 && !IsDocShared() )
673 return;
674
675 SfxApplication *pSfxApp = SfxGetpApp();
676
677 // If possible release the unnamed number.
678 if ( pImpl->bIsNamedVisible && USHRT_MAX(32767 *2 +1) != pImpl->nVisualDocumentNumber )
679 {
680 pSfxApp->ReleaseIndex(pImpl->nVisualDocumentNumber);
681 pImpl->bIsNamedVisible = false;
682 }
683
684 // Set Title
685 pImpl->aTitle = rTitle;
686
687 // Notification
688 if ( GetMedium() )
689 {
690 SfxShell::SetName( GetTitle(SFX_TITLE_APINAME3) );
691 Broadcast( SfxHint(SfxHintId::TitleChanged) );
692 }
693}
694
695
696
697OUString SfxObjectShell::GetTitle( sal_uInt16 nMaxLength ) const
698
699/* [Description]
700
701 Returns the title or logical file name of the document, depending on the
702 'nMaxLength'.
703
704 If the file name with path is used, the Name shortened by replacing one or
705 more directory names with "...", URLs are currently always returned
706 in complete form.
707*/
708
709{
710 SfxMedium *pMed = GetMedium();
711 if ( IsLoading() )
712 return OUString();
713
714 // Create Title?
715 if ( SFX_TITLE_DETECT4 == nMaxLength && pImpl->aTitle.isEmpty() )
716 {
717 static bool bRecur = false;
718 if ( bRecur )
719 return "-not available-";
720 bRecur = true;
721
722 OUString aTitle;
723
724 if ( pMed )
725 {
726 const SfxStringItem* pNameItem = SfxItemSet::GetItem<SfxStringItem>(pMed->GetItemSet(), SID_DOCINFO_TITLE(5000 + 557), false);
727 if ( pNameItem )
728 aTitle = pNameItem->GetValue();
729 }
730
731 if ( aTitle.isEmpty() )
732 aTitle = GetTitle( SFX_TITLE_FILENAME1 );
733
734 bRecur = false;
735 return aTitle;
736 }
737
738 if (SFX_TITLE_APINAME3 == nMaxLength )
739 return GetAPIName();
740
741 // Picklist/Caption is mapped
742 if ( pMed && ( nMaxLength == SFX_TITLE_CAPTION5 || nMaxLength == SFX_TITLE_PICKLIST6 ) )
743 {
744 // If a specific title was given at open:
745 // important for URLs: use INetProtocol::File for which the set title is not
746 // considered. (See below, analysis of aTitleMap_Impl)
747 const SfxStringItem* pNameItem = SfxItemSet::GetItem<SfxStringItem>(pMed->GetItemSet(), SID_DOCINFO_TITLE(5000 + 557), false);
748 if ( pNameItem )
749 return pNameItem->GetValue();
750 }
751
752 // Still unnamed?
753 DBG_ASSERT( !HasName() || pMed, "HasName() but no Medium?!?" )do { if (true && (!(!HasName() || pMed))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objmisc.cxx"
":" "753" ": "), "%s", "HasName() but no Medium?!?"); } } while
(false)
;
754 if ( !HasName() || !pMed )
755 {
756 // Title already set?
757 if ( !pImpl->aTitle.isEmpty() )
758 return pImpl->aTitle;
759
760 // must it be numbered?
761 const OUString aNoName(SfxResId(STR_NONAMEreinterpret_cast<char const *>("STR_NONAME" "\004" u8"Untitled"
)
));
762 if (pImpl->bIsNamedVisible)
763 {
764 // Append number
765 return aNoName + " " + OUString::number(pImpl->nVisualDocumentNumber);
766 }
767
768 // Document called "Untitled" for the time being
769 return aNoName;
770 }
771 assert(pMed)(static_cast <bool> (pMed) ? void (0) : __assert_fail (
"pMed", "/home/maarten/src/libreoffice/core/sfx2/source/doc/objmisc.cxx"
, 771, __extension__ __PRETTY_FUNCTION__))
;
772
773 const INetURLObject aURL( IsDocShared() ? GetSharedFileURL() : GetMedium()->GetName() );
774 if ( nMaxLength > SFX_TITLE_CAPTION5 && nMaxLength <= SFX_TITLE_HISTORY7 )
775 {
776 sal_uInt16 nRemote;
777 if (aURL.GetProtocol() == INetProtocol::File)
778 nRemote = 0;
779 else
780 nRemote = 1;
781 nMaxLength = aTitleMap_Impl[nMaxLength-SFX_TITLE_CAPTION5][nRemote];
782 }
783
784 // Local file?
785 if ( aURL.GetProtocol() == INetProtocol::File )
786 {
787 if ( nMaxLength == SFX_TITLE_FULLNAME2 )
788 return aURL.HasMark() ? INetURLObject( aURL.GetURLNoMark() ).PathToFileName() : aURL.PathToFileName();
789 if ( nMaxLength == SFX_TITLE_FILENAME1 )
790 return aURL.getName(INetURLObject::LAST_SEGMENT, true, INetURLObject::DecodeMechanism::WithCharset);
791 if ( pImpl->aTitle.isEmpty() )
792 pImpl->aTitle = aURL.getBase( INetURLObject::LAST_SEGMENT,
793 true, INetURLObject::DecodeMechanism::WithCharset );
794 }
795 else
796 {
797 if ( nMaxLength >= SFX_TITLE_MAXLEN10 )
798 {
799 const OUString aComplete( aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
800 if( aComplete.getLength() > nMaxLength )
801 return "..." + aComplete.copy( aComplete.getLength() - nMaxLength + 3, nMaxLength - 3 );
802 return aComplete;
803 }
804 if ( nMaxLength == SFX_TITLE_FILENAME1 )
805 {
806 const OUString aName = INetURLObject::decode( aURL.GetBase(), INetURLObject::DecodeMechanism::WithCharset );
807 return aName.isEmpty() ? aURL.GetURLNoPass() : aName;
808 }
809 if ( nMaxLength == SFX_TITLE_FULLNAME2 )
810 return aURL.GetMainURL( INetURLObject::DecodeMechanism::ToIUri );
811
812 // Generate Title from file name if possible
813 if ( pImpl->aTitle.isEmpty() )
814 pImpl->aTitle = aURL.GetBase();
815
816 // workaround for the case when the name can not be retrieved from URL by INetURLObject
817 if ( pImpl->aTitle.isEmpty() )
818 pImpl->aTitle = aURL.GetMainURL( INetURLObject::DecodeMechanism::WithCharset );
819 }
820
821 // Complete Title
822 return pImpl->aTitle;
823}
824
825
826void SfxObjectShell::InvalidateName()
827
828/* [Description]
829
830 Returns the title of the new document, DocInfo-Title or
831 File name. Is required for loading from template or SaveAs.
832*/
833
834{
835 pImpl->aTitle.clear();
836 SetName( GetTitle( SFX_TITLE_APINAME3 ) );
837
838 Broadcast( SfxHint(SfxHintId::TitleChanged) );
839}
840
841
842void SfxObjectShell::SetNamedVisibility_Impl()
843{
844 if ( !pImpl->bIsNamedVisible )
845 {
846 pImpl->bIsNamedVisible = true;
847 if ( !HasName() && USHRT_MAX(32767 *2 +1) == pImpl->nVisualDocumentNumber && pImpl->aTitle.isEmpty() )
848 {
849 pImpl->nVisualDocumentNumber = SfxGetpApp()->GetFreeIndex();
850 Broadcast( SfxHint(SfxHintId::TitleChanged) );
851 }
852 }
853
854 SetName( GetTitle(SFX_TITLE_APINAME3) );
855}
856
857void SfxObjectShell::SetNoName()
858{
859 bHasName = false;
860 GetModel()->attachResource( OUString(), GetModel()->getArgs() );
861}
862
863
864SfxProgress* SfxObjectShell::GetProgress() const
865{
866 return pImpl->pProgress;
867}
868
869
870void SfxObjectShell::SetProgress_Impl
871(
872 SfxProgress *pProgress /* to started <SfxProgress> or 0,
873 if the progress is to be reset */
874)
875
876/* [Description]
877
878 Internal method to set or reset the Progress modes for
879 SfxObjectShell.
880*/
881
882{
883 DBG_ASSERT( ( !pImpl->pProgress && pProgress ) ||do { if (true && (!(( !pImpl->pProgress &&
pProgress ) || ( pImpl->pProgress && !pProgress )
))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objmisc.cxx"
":" "885" ": "), "%s", "Progress activation/deactivation mismatch"
); } } while (false)
884 ( pImpl->pProgress && !pProgress ),do { if (true && (!(( !pImpl->pProgress &&
pProgress ) || ( pImpl->pProgress && !pProgress )
))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objmisc.cxx"
":" "885" ": "), "%s", "Progress activation/deactivation mismatch"
); } } while (false)
885 "Progress activation/deactivation mismatch" )do { if (true && (!(( !pImpl->pProgress &&
pProgress ) || ( pImpl->pProgress && !pProgress )
))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objmisc.cxx"
":" "885" ": "), "%s", "Progress activation/deactivation mismatch"
); } } while (false)
;
886 pImpl->pProgress = pProgress;
887}
888
889
890void SfxObjectShell::PostActivateEvent_Impl( SfxViewFrame const * pFrame )
891{
892 SfxApplication* pSfxApp = SfxGetpApp();
893 if ( pSfxApp->IsDowning() || IsLoading() || !pFrame || pFrame->GetFrame().IsClosing_Impl() )
894 return;
895
896 const SfxBoolItem* pHiddenItem = SfxItemSet::GetItem<SfxBoolItem>(pMedium->GetItemSet(), SID_HIDDEN(5000 + 534), false);
897 if ( !pHiddenItem || !pHiddenItem->GetValue() )
898 {
899 SfxEventHintId nId = pImpl->nEventId;
900 pImpl->nEventId = SfxEventHintId::NONE;
901 if ( nId == SfxEventHintId::OpenDoc )
902 pSfxApp->NotifyEvent(SfxViewEventHint( nId, GlobalEventConfig::GetEventName(GlobalEventId::OPENDOC), this, pFrame->GetFrame().GetController() ), false);
903 else if (nId == SfxEventHintId::CreateDoc )
904 pSfxApp->NotifyEvent(SfxViewEventHint( nId, GlobalEventConfig::GetEventName(GlobalEventId::CREATEDOC), this, pFrame->GetFrame().GetController() ), false);
905 }
906}
907
908
909void SfxObjectShell::SetActivateEvent_Impl(SfxEventHintId nId )
910{
911 pImpl->nEventId = nId;
912}
913
914bool SfxObjectShell::IsAutoLoadLocked() const
915
916/* Returns whether an Autoload is allowed to be executed. Before the
917 surrounding FrameSet of the AutoLoad is also taken into account as well.
918*/
919
920{
921 return !IsReadOnly();
922}
923
924
925void SfxObjectShell::BreakMacroSign_Impl( bool bBreakMacroSign )
926{
927 pImpl->m_bMacroSignBroken = bBreakMacroSign;
928}
929
930
931void SfxObjectShell::CheckSecurityOnLoading_Impl()
932{
933 // make sure LO evaluates the macro signatures, so it can be preserved
934 GetScriptingSignatureState();
935
936 uno::Reference< task::XInteractionHandler > xInteraction;
937 if ( GetMedium() )
938 xInteraction = GetMedium()->GetInteractionHandler();
939
940 // check if there is a broken signature...
941 CheckForBrokenDocSignatures_Impl();
942
943 CheckEncryption_Impl( xInteraction );
944
945 // check macro security
946 pImpl->aMacroMode.checkMacrosOnLoading( xInteraction );
947}
948
949
950void SfxObjectShell::CheckEncryption_Impl( const uno::Reference< task::XInteractionHandler >& xHandler )
951{
952 OUString aVersion;
953 bool bIsEncrypted = false;
954 bool bHasNonEncrypted = false;
955
956 try
957 {
958 uno::Reference < beans::XPropertySet > xPropSet( GetStorage(), uno::UNO_QUERY_THROW );
959 xPropSet->getPropertyValue("Version") >>= aVersion;
960 xPropSet->getPropertyValue("HasEncryptedEntries") >>= bIsEncrypted;
961 xPropSet->getPropertyValue("HasNonEncryptedEntries") >>= bHasNonEncrypted;
962 }
963 catch( uno::Exception& )
964 {
965 }
966
967 if ( aVersion.compareTo( ODFVER_012_TEXT"1.2" ) < 0 )
968 return;
969
970 // this is ODF1.2 or later
971 if ( !(bIsEncrypted && bHasNonEncrypted) )
972 return;
973
974 if ( !pImpl->m_bIncomplEncrWarnShown )
975 {
976 // this is an encrypted document with nonencrypted streams inside, show the warning
977 css::task::ErrorCodeRequest aErrorCode;
978 aErrorCode.ErrCode = sal_uInt32(ERRCODE_SFX_INCOMPLETE_ENCRYPTIONErrCode(WarningFlag::Yes, ErrCodeArea::Sfx, ErrCodeClass::NONE
, 55)
);
979
980 SfxMedium::CallApproveHandler( xHandler, uno::makeAny( aErrorCode ), false );
981 pImpl->m_bIncomplEncrWarnShown = true;
982 }
983
984 // broken signatures imply no macro execution at all
985 pImpl->aMacroMode.disallowMacroExecution();
986}
987
988
989void SfxObjectShell::CheckForBrokenDocSignatures_Impl()
990{
991 SignatureState nSignatureState = GetDocumentSignatureState();
992 bool bSignatureBroken = ( nSignatureState == SignatureState::BROKEN );
993 if ( !bSignatureBroken )
994 return;
995
996 // broken signatures imply no macro execution at all
997 pImpl->aMacroMode.disallowMacroExecution();
998}
999
1000
1001void SfxObjectShell::SetAutoLoad(
1002 const INetURLObject& rUrl, sal_uInt32 nTime, bool bReload )
1003{
1004 pImpl->pReloadTimer.reset();
1005 if ( bReload )
1006 {
1007 pImpl->pReloadTimer.reset(new AutoReloadTimer_Impl(
1008 rUrl.GetMainURL( INetURLObject::DecodeMechanism::ToIUri ),
1009 nTime, this ));
1010 pImpl->pReloadTimer->Start();
1011 }
1012}
1013
1014void SfxObjectShell::SetLoading(SfxLoadedFlags nFlags)
1015{
1016 pImpl->nLoadedFlags = nFlags;
1017}
1018
1019bool SfxObjectShell::IsLoadingFinished() const
1020{
1021 return ( pImpl->nLoadedFlags == SfxLoadedFlags::ALL );
1022}
1023
1024void SfxObjectShell::InitOwnModel_Impl()
1025{
1026 if ( pImpl->bModelInitialized )
1027 return;
1028
1029 const SfxStringItem* pSalvageItem = SfxItemSet::GetItem<SfxStringItem>(pMedium->GetItemSet(), SID_DOC_SALVAGE(5000 + 531), false);
1030 if ( pSalvageItem )
1031 {
1032 pImpl->aTempName = pMedium->GetPhysicalName();
1033 pMedium->GetItemSet()->ClearItem( SID_DOC_SALVAGE(5000 + 531) );
1034 pMedium->GetItemSet()->ClearItem( SID_FILE_NAME(5000 + 507) );
1035 pMedium->GetItemSet()->Put( SfxStringItem( SID_FILE_NAME(5000 + 507), pMedium->GetOrigURL() ) );
1036 }
1037 else
1038 {
1039 pMedium->GetItemSet()->ClearItem( SID_PROGRESS_STATUSBAR_CONTROL(5000 + 1597) );
1040 pMedium->GetItemSet()->ClearItem( SID_DOCUMENT(5000 + 588) );
1041 }
1042
1043 pMedium->GetItemSet()->ClearItem( SID_REFERER(5000 + 654) );
1044 uno::Reference< frame::XModel > xModel = GetModel();
1045 if ( xModel.is() )
1046 {
1047 SfxItemSet *pSet = GetMedium()->GetItemSet();
1048 if ( !GetMedium()->IsReadOnly() )
1049 pSet->ClearItem( SID_INPUTSTREAM(5000 + 1648) );
1050 uno::Sequence< beans::PropertyValue > aArgs;
1051 TransformItems( SID_OPENDOC(5000 + 501), *pSet, aArgs );
1052 xModel->attachResource( GetMedium()->GetOrigURL(), aArgs );
1053 impl_addToModelCollection(xModel);
1054 }
1055
1056 pImpl->bModelInitialized = true;
1057}
1058
1059void SfxObjectShell::FinishedLoading( SfxLoadedFlags nFlags )
1060{
1061 bool bSetModifiedTRUE = false;
1062 const SfxStringItem* pSalvageItem = SfxItemSet::GetItem<SfxStringItem>(pMedium->GetItemSet(), SID_DOC_SALVAGE(5000 + 531), false);
1063 if( ( nFlags & SfxLoadedFlags::MAINDOCUMENT ) && !(pImpl->nLoadedFlags & SfxLoadedFlags::MAINDOCUMENT )
1064 && !(pImpl->nFlagsInProgress & SfxLoadedFlags::MAINDOCUMENT ))
1065 {
1066 pImpl->nFlagsInProgress |= SfxLoadedFlags::MAINDOCUMENT;
1067 static_cast<SfxHeaderAttributes_Impl*>(GetHeaderAttributes())->SetAttributes();
1068
1069 if ( ( GetModifyPasswordHash() || GetModifyPasswordInfo().hasElements() ) && !IsModifyPasswordEntered() )
1070 SetReadOnly();
1071
1072 // Salvage
1073 if ( pSalvageItem )
1074 bSetModifiedTRUE = true;
1075
1076 if ( !IsEnableSetModified() )
1077 EnableSetModified();
1078
1079 if( !bSetModifiedTRUE && IsEnableSetModified() )
1080 SetModified( false );
1081
1082 CheckSecurityOnLoading_Impl();
1083
1084 bHasName = true; // the document is loaded, so the name should already available
1085 GetTitle( SFX_TITLE_DETECT4 );
1086 InitOwnModel_Impl();
1087 pImpl->nFlagsInProgress &= ~SfxLoadedFlags::MAINDOCUMENT;
1088 }
1089
1090 if( ( nFlags & SfxLoadedFlags::IMAGES ) && !(pImpl->nLoadedFlags & SfxLoadedFlags::IMAGES )
1091 && !(pImpl->nFlagsInProgress & SfxLoadedFlags::IMAGES ))
1092 {
1093 pImpl->nFlagsInProgress |= SfxLoadedFlags::IMAGES;
1094 uno::Reference<document::XDocumentProperties> xDocProps(
1095 getDocProperties());
1096 const OUString url(xDocProps->getAutoloadURL());
1097 sal_Int32 delay(xDocProps->getAutoloadSecs());
1098 SetAutoLoad( INetURLObject(url), delay * 1000,
1099 (delay > 0) || !url.isEmpty() );
1100 if( !bSetModifiedTRUE && IsEnableSetModified() )
1101 SetModified( false );
1102 Invalidate( SID_SAVEASDOC(5000 + 502) );
1103 pImpl->nFlagsInProgress &= ~SfxLoadedFlags::IMAGES;
1104 }
1105
1106 pImpl->nLoadedFlags |= nFlags;
1107
1108 if ( pImpl->nFlagsInProgress != SfxLoadedFlags::NONE )
1109 return;
1110
1111 // in case of reentrance calls the first called FinishedLoading() call on the stack
1112 // should do the notification, in result the notification is done when all the FinishedLoading() calls are finished
1113
1114 if ( bSetModifiedTRUE )
1115 SetModified();
1116 else
1117 SetModified( false );
1118
1119 if ( (pImpl->nLoadedFlags & SfxLoadedFlags::MAINDOCUMENT ) && (pImpl->nLoadedFlags & SfxLoadedFlags::IMAGES ) )
1120 {
1121 const SfxBoolItem* pTemplateItem = SfxItemSet::GetItem<SfxBoolItem>(pMedium->GetItemSet(), SID_TEMPLATE(5000 + 1519), false);
1122 bool bTemplate = pTemplateItem && pTemplateItem->GetValue();
1123
1124 // closing the streams on loading should be under control of SFX!
1125 DBG_ASSERT( pMedium->IsOpen(), "Don't close the medium when loading documents!" )do { if (true && (!(pMedium->IsOpen()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objmisc.cxx"
":" "1125" ": "), "%s", "Don't close the medium when loading documents!"
); } } while (false)
;
1126
1127 if ( bTemplate )
1128 {
1129 TemplateDisconnectionAfterLoad();
1130 }
1131 else
1132 {
1133 // if a readonly medium has storage then it's stream is already based on temporary file
1134 if( !(pMedium->GetOpenMode() & StreamMode::WRITE) && !pMedium->HasStorage_Impl() )
1135 // don't lock file opened read only
1136 pMedium->CloseInStream();
1137 }
1138 }
1139
1140 SetInitialized_Impl( false );
1141
1142 // Title is not available until loading has finished
1143 Broadcast( SfxHint( SfxHintId::TitleChanged ) );
1144 if ( pImpl->nEventId != SfxEventHintId::NONE )
1145 PostActivateEvent_Impl(SfxViewFrame::GetFirst(this));
1146}
1147
1148void SfxObjectShell::TemplateDisconnectionAfterLoad()
1149{
1150 // document is created from a template
1151 //TODO/LATER: should the templates always be XML docs!
1152
1153 SfxMedium* pTmpMedium = pMedium;
1154 if ( !pTmpMedium )
1155 return;
1156
1157 const OUString aName( pTmpMedium->GetName() );
1158 const SfxStringItem* pTemplNamItem = SfxItemSet::GetItem<SfxStringItem>(pTmpMedium->GetItemSet(), SID_TEMPLATE_NAME(5000 + 660), false);
1159 OUString aTemplateName;
1160 if ( pTemplNamItem )
1161 aTemplateName = pTemplNamItem->GetValue();
1162 else
1163 {
1164 // !TODO/LATER: what's this?!
1165 // Interactive ( DClick, Contextmenu ) no long name is included
1166 aTemplateName = getDocProperties()->getTitle();
1167 if ( aTemplateName.isEmpty() )
1168 {
1169 INetURLObject aURL( aName );
1170 aURL.CutExtension();
1171 aTemplateName = aURL.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DecodeMechanism::WithCharset );
1172 }
1173 }
1174
1175 // set medium to noname
1176 pTmpMedium->SetName( OUString(), true );
1177 pTmpMedium->Init_Impl();
1178
1179 // drop resource
1180 SetNoName();
1181 InvalidateName();
1182
1183 if( IsPackageStorageFormat_Impl( *pTmpMedium ) )
1184 {
1185 // untitled document must be based on temporary storage
1186 // the medium should not dispose the storage in this case
1187 uno::Reference < embed::XStorage > xTmpStor = ::comphelper::OStorageHelper::GetTemporaryStorage();
1188 GetStorage()->copyToStorage( xTmpStor );
1189
1190 // the medium should disconnect from the original location
1191 // the storage should not be disposed since the document is still
1192 // based on it, but in DoSaveCompleted it will be disposed
1193 pTmpMedium->CanDisposeStorage_Impl( false );
1194 pTmpMedium->Close();
1195
1196 // setting the new storage the medium will be based on
1197 pTmpMedium->SetStorage_Impl( xTmpStor );
1198
1199 pMedium = nullptr;
1200 bool ok = DoSaveCompleted( pTmpMedium );
1201 assert(pMedium != nullptr)(static_cast <bool> (pMedium != nullptr) ? void (0) : __assert_fail
("pMedium != nullptr", "/home/maarten/src/libreoffice/core/sfx2/source/doc/objmisc.cxx"
, 1201, __extension__ __PRETTY_FUNCTION__))
;
1202 if( ok )
1203 {
1204 const SfxStringItem* pSalvageItem = SfxItemSet::GetItem<SfxStringItem>(pMedium->GetItemSet(), SID_DOC_SALVAGE(5000 + 531), false);
1205 bool bSalvage = pSalvageItem != nullptr;
1206
1207 if ( !bSalvage )
1208 {
1209 // some further initializations for templates
1210 SetTemplate_Impl( aName, aTemplateName, this );
1211 }
1212
1213 // the medium should not dispose the storage, DoSaveCompleted() has let it to do so
1214 pTmpMedium->CanDisposeStorage_Impl( false );
1215 }
1216 else
1217 {
1218 SetError(ERRCODE_IO_GENERALErrCode( ErrCodeArea::Io, ErrCodeClass::General, 13 ));
1219 }
1220 }
1221 else
1222 {
1223 // some further initializations for templates
1224 SetTemplate_Impl( aName, aTemplateName, this );
1225 pTmpMedium->CreateTempFile();
1226 }
1227
1228 // templates are never readonly
1229 pTmpMedium->GetItemSet()->ClearItem( SID_DOC_READONLY(5000 + 590) );
1230 pTmpMedium->SetOpenMode( SFX_STREAM_READWRITE(StreamMode::READWRITE | StreamMode::SHARE_DENYWRITE), true );
1231
1232 // notifications about possible changes in readonly state and document info
1233 Broadcast( SfxHint(SfxHintId::ModeChanged) );
1234
1235 // created untitled document can't be modified
1236 SetModified( false );
1237}
1238
1239
1240bool SfxObjectShell::IsLoading() const
1241/* [Description]
1242
1243 Has FinishedLoading been called?
1244*/
1245{
1246 return !( pImpl->nLoadedFlags & SfxLoadedFlags::MAINDOCUMENT );
1247}
1248
1249
1250void SfxObjectShell::CancelTransfers()
1251/* [Description]
1252
1253 Here can Transfers get canceled, which were not registered
1254 by RegisterTransfer.
1255*/
1256{
1257 if( ( pImpl->nLoadedFlags & SfxLoadedFlags::ALL ) != SfxLoadedFlags::ALL )
1258 {
1259 pImpl->bIsAbortingImport = true;
1260 if( IsLoading() )
1261 FinishedLoading();
1262 }
1263}
1264
1265
1266AutoReloadTimer_Impl::AutoReloadTimer_Impl(
1267 const OUString& rURL, sal_uInt32 nTime, SfxObjectShell* pSh )
1268 : aUrl( rURL ), pObjSh( pSh )
1269{
1270 SetTimeout( nTime );
1271}
1272
1273
1274void AutoReloadTimer_Impl::Invoke()
1275{
1276 SfxViewFrame *pFrame = SfxViewFrame::GetFirst( pObjSh );
1277
1278 if ( pFrame )
1279 {
1280 // Not possible/meaningful at the moment?
1281 if ( !pObjSh->CanReload_Impl() || pObjSh->IsAutoLoadLocked() || Application::IsUICaptured() )
1282 {
1283 // Allow a retry
1284 Start();
1285 return;
1286 }
1287
1288 SfxAllItemSet aSet( SfxGetpApp()->GetPool() );
1289 aSet.Put( SfxBoolItem( SID_AUTOLOAD(5000 + 1509), true ) );
1290 if ( !aUrl.isEmpty() )
1291 aSet.Put( SfxStringItem( SID_FILE_NAME(5000 + 507), aUrl ) );
1292 if (pObjSh->HasName()) {
1293 aSet.Put(
1294 SfxStringItem(SID_REFERER(5000 + 654), pObjSh->GetMedium()->GetName()));
1295 }
1296 SfxRequest aReq( SID_RELOAD(5000 + 508), SfxCallMode::SLOT, aSet );
1297 // this will delete this
1298 pObjSh->Get_Impl()->pReloadTimer.reset();
1299 pFrame->ExecReload_Impl( aReq );
1300 return;
1301 }
1302
1303 // this will delete this
1304 pObjSh->Get_Impl()->pReloadTimer.reset();
1305}
1306
1307SfxModule* SfxObjectShell::GetModule() const
1308{
1309 return GetFactory().GetModule();
1310}
1311
1312ErrCode SfxObjectShell::CallBasic( const OUString& rMacro,
1313 const OUString& rBasic, SbxArray* pArgs,
1314 SbxValue* pRet )
1315{
1316 SfxApplication* pApp = SfxGetpApp();
1317 if( pApp->GetName() != rBasic )
1318 {
1319 if ( !AdjustMacroMode() )
1320 return ERRCODE_IO_ACCESSDENIEDErrCode( ErrCodeArea::Io, ErrCodeClass::Access, 7 );
1321 }
1322
1323 BasicManager *pMgr = GetBasicManager();
1324 if( pApp->GetName() == rBasic )
1325 pMgr = SfxApplication::GetBasicManager();
1326 ErrCode nRet = SfxApplication::CallBasic( rMacro, pMgr, pArgs, pRet );
1327 return nRet;
1328}
1329
1330bool SfxObjectShell::isScriptAccessAllowed( const Reference< XInterface >& _rxScriptContext )
1331{
1332 try
1333 {
1334 Reference< XEmbeddedScripts > xScripts( _rxScriptContext, UNO_QUERY );
1335 if ( !xScripts.is() )
1336 {
1337 Reference< XScriptInvocationContext > xContext( _rxScriptContext, UNO_QUERY_THROW );
1338 xScripts.set( xContext->getScriptContainer(), UNO_SET_THROW );
1339 }
1340
1341 return xScripts->getAllowMacroExecution();
1342 }
1343 catch( const Exception& )
1344 {
1345 DBG_UNHANDLED_EXCEPTION("sfx.doc")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/sfx2/source/doc/objmisc.cxx"
":" "1345" ": ", "sfx.doc" );
;
1346 }
1347 return false;
1348}
1349
1350// don't allow LibreLogo to be used with our mouseover/etc dom-alike events
1351bool SfxObjectShell::UnTrustedScript(const OUString& rScriptURL)
1352{
1353 if (!rScriptURL.startsWith("vnd.sun.star.script:"))
1354 return false;
1355
1356 // ensure URL Escape Codes are decoded
1357 css::uno::Reference<css::uri::XUriReference> uri(
1358 css::uri::UriReferenceFactory::create(comphelper::getProcessComponentContext())->parse(rScriptURL));
1359 css::uno::Reference<css::uri::XVndSunStarScriptUrl> sfUri(uri, css::uno::UNO_QUERY);
1360
1361 if (!sfUri.is())
1362 return false;
1363
1364 // pyuno encodes path separator as |
1365 OUString sScript = sfUri->getName().replace('|', '/');
1366
1367 // check if any path portion matches LibreLogo and ban it if it does
1368 sal_Int32 nIndex = 0;
1369 do
1370 {
1371 OUString aToken = sScript.getToken(0, '/', nIndex);
1372 if (aToken.startsWithIgnoreAsciiCase("LibreLogo") || aToken.indexOf('~') != -1)
1373 {
1374 return true;
1375 }
1376 }
1377 while (nIndex >= 0);
1378
1379 return false;
1380}
1381
1382ErrCode SfxObjectShell::CallXScript( const Reference< XInterface >& _rxScriptContext, const OUString& _rScriptURL,
1383 const Sequence< Any >& aParams, Any& aRet, Sequence< sal_Int16 >& aOutParamIndex, Sequence< Any >& aOutParam, bool bRaiseError, const css::uno::Any* pCaller )
1384{
1385 SAL_INFO("sfx", "in CallXScript" )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "sfx")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "in CallXScript") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objmisc.cxx"
":" "1385" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "in CallXScript"), 0); } else { ::std
::ostringstream sal_detail_stream; sal_detail_stream <<
"in CallXScript"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objmisc.cxx"
":" "1385" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "in CallXScript") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objmisc.cxx"
":" "1385" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "in CallXScript"), 0); } else { ::std
::ostringstream sal_detail_stream; sal_detail_stream <<
"in CallXScript"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objmisc.cxx"
":" "1385" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1386 ErrCode nErr = ERRCODE_NONEErrCode(0);
1387
1388 bool bCaughtException = false;
1389 Any aException;
1390 try
1391 {
1392 if (!isScriptAccessAllowed(_rxScriptContext))
1393 return ERRCODE_IO_ACCESSDENIEDErrCode( ErrCodeArea::Io, ErrCodeClass::Access, 7 );
1394
1395 if ( UnTrustedScript(_rScriptURL) )
1396 return ERRCODE_IO_ACCESSDENIEDErrCode( ErrCodeArea::Io, ErrCodeClass::Access, 7 );
1397
1398 // obtain/create a script provider
1399 Reference< provider::XScriptProvider > xScriptProvider;
1400 Reference< provider::XScriptProviderSupplier > xSPS( _rxScriptContext, UNO_QUERY );
1401 if ( xSPS.is() )
1402 xScriptProvider.set( xSPS->getScriptProvider() );
1403
1404 if ( !xScriptProvider.is() )
1405 {
1406 Reference< provider::XScriptProviderFactory > xScriptProviderFactory =
1407 provider::theMasterScriptProviderFactory::get( ::comphelper::getProcessComponentContext() );
1408 xScriptProvider.set( xScriptProviderFactory->createScriptProvider( makeAny( _rxScriptContext ) ), UNO_SET_THROW );
1409 }
1410
1411 // ry to protect the invocation context's undo manager (if present), just in case the script tampers with it
1412 ::framework::DocumentUndoGuard aUndoGuard( _rxScriptContext.get() );
1413
1414 // obtain the script, and execute it
1415 Reference< provider::XScript > xScript( xScriptProvider->getScript( _rScriptURL ), UNO_SET_THROW );
1416 if ( pCaller && pCaller->hasValue() )
1417 {
1418 Reference< beans::XPropertySet > xProps( xScript, uno::UNO_QUERY );
1419 if ( xProps.is() )
1420 {
1421 Sequence< uno::Any > aArgs( 1 );
1422 aArgs[ 0 ] = *pCaller;
1423 xProps->setPropertyValue("Caller", uno::makeAny( aArgs ) );
1424 }
1425 }
1426 aRet = xScript->invoke( aParams, aOutParamIndex, aOutParam );
1427 }
1428 catch ( const uno::Exception& )
1429 {
1430 aException = ::cppu::getCaughtException();
1431 bCaughtException = true;
1432 nErr = ERRCODE_BASIC_INTERNAL_ERRORErrCode( ErrCodeArea::Sbx, ErrCodeClass::Unknown, 9);
1433 }
1434
1435 if ( bCaughtException && bRaiseError )
1436 {
1437 SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
1438 pFact->ShowAsyncScriptErrorDialog( nullptr, aException );
1439 }
1440
1441 SAL_INFO("sfx", "leaving CallXScript" )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "sfx")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "leaving CallXScript") == 1) { ::sal_detail_log( (
::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objmisc.cxx"
":" "1441" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "leaving CallXScript"), 0); } else {
::std::ostringstream sal_detail_stream; sal_detail_stream <<
"leaving CallXScript"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objmisc.cxx"
":" "1441" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "leaving CallXScript") == 1) { ::sal_detail_log( (
::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objmisc.cxx"
":" "1441" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "leaving CallXScript"), 0); } else {
::std::ostringstream sal_detail_stream; sal_detail_stream <<
"leaving CallXScript"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objmisc.cxx"
":" "1441" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1442 return nErr;
1443}
1444
1445// perhaps rename to CallScript once we get rid of the existing CallScript
1446// and Call, CallBasic, CallStarBasic methods
1447ErrCode SfxObjectShell::CallXScript( const OUString& rScriptURL,
1448 const css::uno::Sequence< css::uno::Any >& aParams,
1449 css::uno::Any& aRet,
1450 css::uno::Sequence< sal_Int16 >& aOutParamIndex,
1451 css::uno::Sequence< css::uno::Any >& aOutParam,
1452 bool bRaiseError,
1453 const css::uno::Any* pCaller )
1454{
1455 return CallXScript( GetModel(), rScriptURL, aParams, aRet, aOutParamIndex, aOutParam, bRaiseError, pCaller );
1456}
1457
1458void SfxHeaderAttributes_Impl::SetAttributes()
1459{
1460 bAlert = true;
1461 SvKeyValue aPair;
1462 for( bool bCont = xIter->GetFirst( aPair ); bCont;
1463 bCont = xIter->GetNext( aPair ) )
1464 SetAttribute( aPair );
1465}
1466
1467void SfxHeaderAttributes_Impl::SetAttribute( const SvKeyValue& rKV )
1468{
1469 const OUString& aValue = rKV.GetValue();
1470 if( rKV.GetKey().equalsIgnoreAsciiCase("refresh") && !rKV.GetValue().isEmpty() )
1471 {
1472 sal_Int32 nIdx{ 0 };
1473 const sal_Int32 nTime{ aValue.getToken( 0, ';', nIdx ).toInt32() };
1474 const OUString aURL{ comphelper::string::strip(aValue.getToken( 0, ';', nIdx ), ' ') };
1475 uno::Reference<document::XDocumentProperties> xDocProps(
1476 pDoc->getDocProperties());
1477 if( aURL.startsWithIgnoreAsciiCase( "url=" ) )
1478 {
1479 try {
1480 xDocProps->setAutoloadURL(
1481 rtl::Uri::convertRelToAbs(pDoc->GetMedium()->GetName(), aURL.copy( 4 )) );
1482 } catch (rtl::MalformedUriException &) {
1483 TOOLS_WARN_EXCEPTION("sfx", "")do { css::uno::Any tools_warn_exception( DbgGetCaughtException
() ); do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "sfx")) { 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_WARN), (
"sfx"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objmisc.cxx"
":" "1483" ": "), ::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_WARN
), ("sfx"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objmisc.cxx"
":" "1483" ": "), 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_WARN), (
"sfx"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objmisc.cxx"
":" "1483" ": "), ::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_WARN
), ("sfx"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objmisc.cxx"
":" "1483" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false); } while (false)
;
1484 }
1485 }
1486 try
1487 {
1488 xDocProps->setAutoloadSecs( nTime );
1489 }
1490 catch (lang::IllegalArgumentException &)
1491 {
1492 // ignore
1493 }
1494 }
1495 else if( rKV.GetKey().equalsIgnoreAsciiCase( "expires" ) )
1496 {
1497 DateTime aDateTime( DateTime::EMPTY );
1498 if( INetMIMEMessage::ParseDateField( rKV.GetValue(), aDateTime ) )
1499 {
1500 aDateTime.ConvertToLocalTime();
1501 pDoc->GetMedium()->SetExpired_Impl( aDateTime );
1502 }
1503 else
1504 {
1505 pDoc->GetMedium()->SetExpired_Impl( Date( 1, 1, 1970 ) );
1506 }
1507 }
1508}
1509
1510void SfxHeaderAttributes_Impl::Append( const SvKeyValue& rKV )
1511{
1512 xIter->Append( rKV );
1513 if( bAlert ) SetAttribute( rKV );
1514}
1515
1516SvKeyValueIterator* SfxObjectShell::GetHeaderAttributes()
1517{
1518 if( !pImpl->xHeaderAttributes.is() )
1519 {
1520 DBG_ASSERT( pMedium, "No Medium" )do { if (true && (!(pMedium))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objmisc.cxx"
":" "1520" ": "), "%s", "No Medium"); } } while (false)
;
1521 pImpl->xHeaderAttributes = new SfxHeaderAttributes_Impl( this );
1522 }
1523 return static_cast<SvKeyValueIterator*>( pImpl->xHeaderAttributes.get() );
1524}
1525
1526void SfxObjectShell::ClearHeaderAttributesForSourceViewHack()
1527{
1528 static_cast<SfxHeaderAttributes_Impl*>(GetHeaderAttributes())
1529 ->ClearForSourceView();
1530}
1531
1532
1533void SfxObjectShell::SetHeaderAttributesForSourceViewHack()
1534{
1535 static_cast<SfxHeaderAttributes_Impl*>(GetHeaderAttributes())
1536 ->SetAttributes();
1537}
1538
1539bool SfxObjectShell::IsPreview() const
1540{
1541 if ( !pMedium )
1542 return false;
1543
1544 bool bPreview = false;
1545 const SfxStringItem* pFlags = SfxItemSet::GetItem<SfxStringItem>(pMedium->GetItemSet(), SID_OPTIONS(5000 + 940), false);
1546 if ( pFlags )
1547 {
1548 // Distributed values among individual items
1549 const OUString aFileFlags = pFlags->GetValue().toAsciiUpperCase();
1550 if ( -1 != aFileFlags.indexOf( 'B' ) )
1551 bPreview = true;
1552 }
1553
1554 if ( !bPreview )
1555 {
1556 const SfxBoolItem* pItem = SfxItemSet::GetItem<SfxBoolItem>(pMedium->GetItemSet(), SID_PREVIEWTypedWhichId<SfxBoolItem>(5000 + 1404), false);
1557 if ( pItem )
1558 bPreview = pItem->GetValue();
1559 }
1560
1561 return bPreview;
1562}
1563
1564void SfxObjectShell::SetWaitCursor( bool bSet ) const
1565{
1566 for( SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this ); pFrame; pFrame = SfxViewFrame::GetNext( *pFrame, this ) )
1567 {
1568 if ( bSet )
1569 pFrame->GetFrame().GetWindow().EnterWait();
1570 else
1571 pFrame->GetFrame().GetWindow().LeaveWait();
1572 }
1573}
1574
1575OUString SfxObjectShell::GetAPIName() const
1576{
1577 INetURLObject aURL( IsDocShared() ? GetSharedFileURL() : GetMedium()->GetName() );
1578 OUString aName( aURL.GetBase() );
1579 if( aName.isEmpty() )
1580 aName = aURL.GetURLNoPass();
1581 if ( aName.isEmpty() )
1582 aName = GetTitle( SFX_TITLE_DETECT4 );
1583 return aName;
1584}
1585
1586void SfxObjectShell::Invalidate( sal_uInt16 nId )
1587{
1588 for( SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this ); pFrame; pFrame = SfxViewFrame::GetNext( *pFrame, this ) )
1589 Invalidate_Impl( pFrame->GetBindings(), nId );
1590}
1591
1592bool SfxObjectShell::AdjustMacroMode()
1593{
1594 uno::Reference< task::XInteractionHandler > xInteraction;
1595 if ( pMedium )
1596 xInteraction = pMedium->GetInteractionHandler();
1597
1598 CheckForBrokenDocSignatures_Impl();
1599
1600 CheckEncryption_Impl( xInteraction );
1601
1602 return pImpl->aMacroMode.adjustMacroMode( xInteraction );
1603}
1604
1605vcl::Window* SfxObjectShell::GetDialogParent( SfxMedium const * pLoadingMedium )
1606{
1607 VclPtr<vcl::Window> pWindow;
1608 SfxItemSet* pSet = pLoadingMedium ? pLoadingMedium->GetItemSet() : GetMedium()->GetItemSet();
1
Assuming 'pLoadingMedium' is null
2
'?' condition is false
1609 const SfxUnoFrameItem* pUnoItem = SfxItemSet::GetItem<SfxUnoFrameItem>(pSet, SID_FILLFRAME(5000 + 1516), false);
1610 if ( pUnoItem
2.1
'pUnoItem' is non-null
2.1
'pUnoItem' is non-null
2.1
'pUnoItem' is non-null
)
3
Taking true branch
1611 {
1612 const uno::Reference < frame::XFrame >& xFrame( pUnoItem->GetFrame() );
1613 pWindow = VCLUnoHelper::GetWindow( xFrame->getContainerWindow() );
1614 }
1615
1616 if ( !pWindow )
4
Taking false branch
1617 {
1618 SfxFrame* pFrame = nullptr;
1619 const SfxFrameItem* pFrameItem = SfxItemSet::GetItem<SfxFrameItem>(pSet, SID_DOCFRAME(5000 + 598), false);
1620 if( pFrameItem && pFrameItem->GetFrame() )
1621 // get target frame from ItemSet
1622 pFrame = pFrameItem->GetFrame();
1623 else
1624 {
1625 // try the current frame
1626 SfxViewFrame* pView = SfxViewFrame::Current();
1627 if ( !pView || pView->GetObjectShell() != this )
1628 // get any visible frame
1629 pView = SfxViewFrame::GetFirst(this);
1630 if ( pView )
1631 pFrame = &pView->GetFrame();
1632 }
1633
1634 if ( pFrame )
1635 // get topmost window
1636 pWindow = VCLUnoHelper::GetWindow( pFrame->GetFrameInterface()->getContainerWindow() );
1637 }
1638
1639 if ( pWindow )
5
Taking true branch
1640 {
1641 // this frame may be invisible, show it if it is allowed
1642 const SfxBoolItem* pHiddenItem = SfxItemSet::GetItem<SfxBoolItem>(pSet, SID_HIDDEN(5000 + 534), false);
1643 if ( !pHiddenItem
5.1
'pHiddenItem' is non-null
5.1
'pHiddenItem' is non-null
5.1
'pHiddenItem' is non-null
|| !pHiddenItem->GetValue() )
6
Assuming the condition is false
7
Taking false branch
1644 {
1645 pWindow->Show();
1646 pWindow->ToTop();
1647 }
1648 }
1649
1650 return pWindow;
8
Calling implicit destructor for 'VclPtr<vcl::Window>'
9
Calling '~Reference'
16
Returning from '~Reference'
17
Returning from destructor for 'VclPtr<vcl::Window>'
18
Use of memory after it is freed
1651}
1652
1653void SfxObjectShell::SetCreateMode_Impl( SfxObjectCreateMode nMode )
1654{
1655 eCreateMode = nMode;
1656}
1657
1658bool SfxObjectShell::IsInPlaceActive() const
1659{
1660 if ( eCreateMode != SfxObjectCreateMode::EMBEDDED )
1661 return false;
1662
1663 SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this );
1664 return pFrame && pFrame->GetFrame().IsInPlace();
1665}
1666
1667bool SfxObjectShell::IsUIActive() const
1668{
1669 if ( eCreateMode != SfxObjectCreateMode::EMBEDDED )
1670 return false;
1671
1672 SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this );
1673 return pFrame && pFrame->GetFrame().IsInPlace() && pFrame->GetFrame().GetWorkWindow_Impl()->IsVisible_Impl();
1674}
1675
1676bool SfxObjectShell::UseInteractionToHandleError(
1677 const uno::Reference< task::XInteractionHandler >& xHandler,
1678 ErrCode nError )
1679{
1680 bool bResult = false;
1681
1682 if ( xHandler.is() )
1683 {
1684 try
1685 {
1686 uno::Any aInteraction;
1687 uno::Sequence< uno::Reference< task::XInteractionContinuation > > lContinuations(2);
1688 ::comphelper::OInteractionAbort* pAbort = new ::comphelper::OInteractionAbort();
1689 ::comphelper::OInteractionApprove* pApprove = new ::comphelper::OInteractionApprove();
1690 lContinuations[0].set( static_cast< task::XInteractionContinuation* >( pAbort ), uno::UNO_QUERY );
1691 lContinuations[1].set( static_cast< task::XInteractionContinuation* >( pApprove ), uno::UNO_QUERY );
1692
1693 task::ErrorCodeRequest aErrorCode;
1694 aErrorCode.ErrCode = sal_uInt32(nError);
1695 aInteraction <<= aErrorCode;
1696 xHandler->handle(::framework::InteractionRequest::CreateRequest (aInteraction,lContinuations));
1697 bResult = pAbort->wasSelected();
1698 }
1699 catch( uno::Exception& )
1700 {}
1701 }
1702
1703 return bResult;
1704}
1705
1706sal_Int16 SfxObjectShell_Impl::getCurrentMacroExecMode() const
1707{
1708 sal_Int16 nImposedExecMode( MacroExecMode::NEVER_EXECUTE );
1709
1710 const SfxMedium* pMedium( rDocShell.GetMedium() );
1711 OSL_PRECOND( pMedium, "SfxObjectShell_Impl::getCurrentMacroExecMode: no medium!" )do { if (true && (!(pMedium))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objmisc.cxx"
":" "1711" ": "), "%s", "SfxObjectShell_Impl::getCurrentMacroExecMode: no medium!"
); } } while (false)
;
1712 if ( pMedium )
1713 {
1714 const SfxUInt16Item* pMacroModeItem = SfxItemSet::GetItem<SfxUInt16Item>(pMedium->GetItemSet(), SID_MACROEXECMODE(5000 + 1319), false);
1715 if ( pMacroModeItem )
1716 nImposedExecMode = pMacroModeItem->GetValue();
1717 }
1718 return nImposedExecMode;
1719}
1720
1721void SfxObjectShell_Impl::setCurrentMacroExecMode( sal_uInt16 nMacroMode )
1722{
1723 const SfxMedium* pMedium( rDocShell.GetMedium() );
1724 OSL_PRECOND( pMedium, "SfxObjectShell_Impl::getCurrentMacroExecMode: no medium!" )do { if (true && (!(pMedium))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objmisc.cxx"
":" "1724" ": "), "%s", "SfxObjectShell_Impl::getCurrentMacroExecMode: no medium!"
); } } while (false)
;
1725 if ( pMedium )
1726 {
1727 pMedium->GetItemSet()->Put( SfxUInt16Item( SID_MACROEXECMODE(5000 + 1319), nMacroMode ) );
1728 }
1729}
1730
1731OUString SfxObjectShell_Impl::getDocumentLocation() const
1732{
1733 OUString sLocation;
1734
1735 const SfxMedium* pMedium( rDocShell.GetMedium() );
1736 OSL_PRECOND( pMedium, "SfxObjectShell_Impl::getDocumentLocation: no medium!" )do { if (true && (!(pMedium))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objmisc.cxx"
":" "1736" ": "), "%s", "SfxObjectShell_Impl::getDocumentLocation: no medium!"
); } } while (false)
;
1737 if ( pMedium )
1738 {
1739 sLocation = pMedium->GetName();
1740 if ( sLocation.isEmpty() )
1741 {
1742 // for documents made from a template: get the name of the template
1743 sLocation = rDocShell.getDocProperties()->getTemplateURL();
1744 }
1745
1746 // tdf#128006 take document base url as location
1747 if (sLocation.isEmpty())
1748 sLocation = rDocShell.getDocumentBaseURL();
1749 }
1750
1751 return sLocation;
1752}
1753
1754bool SfxObjectShell_Impl::documentStorageHasMacros() const
1755{
1756 return ::sfx2::DocumentMacroMode::storageHasMacros( m_xDocStorage );
1757}
1758
1759bool SfxObjectShell_Impl::macroCallsSeenWhileLoading() const
1760{
1761 return rDocShell.GetMacroCallsSeenWhileLoading();
1762}
1763
1764Reference< XEmbeddedScripts > SfxObjectShell_Impl::getEmbeddedDocumentScripts() const
1765{
1766 return Reference< XEmbeddedScripts >( rDocShell.GetModel(), UNO_QUERY );
1767}
1768
1769SignatureState SfxObjectShell_Impl::getScriptingSignatureState()
1770{
1771 SignatureState nSignatureState( rDocShell.GetScriptingSignatureState() );
1772
1773 if ( nSignatureState != SignatureState::NOSIGNATURES && m_bMacroSignBroken )
1774 {
1775 // if there is a macro signature it must be handled as broken
1776 nSignatureState = SignatureState::BROKEN;
1777 }
1778
1779 return nSignatureState;
1780}
1781
1782bool SfxObjectShell_Impl::hasTrustedScriptingSignature( bool bAllowUIToAddAuthor )
1783{
1784 bool bResult = false;
1785
1786 try
1787 {
1788 OUString aVersion;
1789 try
1790 {
1791 uno::Reference < beans::XPropertySet > xPropSet( rDocShell.GetStorage(), uno::UNO_QUERY_THROW );
1792 xPropSet->getPropertyValue("Version") >>= aVersion;
1793 }
1794 catch( uno::Exception& )
1795 {
1796 }
1797
1798 uno::Reference< security::XDocumentDigitalSignatures > xSigner( security::DocumentDigitalSignatures::createWithVersion(comphelper::getProcessComponentContext(), aVersion) );
1799
1800 if ( nScriptingSignatureState == SignatureState::UNKNOWN
1801 || nScriptingSignatureState == SignatureState::OK
1802 || nScriptingSignatureState == SignatureState::NOTVALIDATED )
1803 {
1804 uno::Sequence< security::DocumentSignatureInformation > aInfo = rDocShell.GetDocumentSignatureInformation( true, xSigner );
1805
1806 if ( aInfo.hasElements() )
1807 {
1808 if ( nScriptingSignatureState == SignatureState::UNKNOWN )
1809 nScriptingSignatureState = DocumentSignatures::getSignatureState(aInfo);
1810
1811 if ( nScriptingSignatureState == SignatureState::OK
1812 || nScriptingSignatureState == SignatureState::NOTVALIDATED )
1813 {
1814 bResult = std::any_of(aInfo.begin(), aInfo.end(),
1815 [&xSigner](const security::DocumentSignatureInformation& rInfo) {
1816 return xSigner->isAuthorTrusted( rInfo.Signer ); });
1817
1818 if ( !bResult && bAllowUIToAddAuthor )
1819 {
1820 uno::Reference< task::XInteractionHandler > xInteraction;
1821 if ( rDocShell.GetMedium() )
1822 xInteraction = rDocShell.GetMedium()->GetInteractionHandler();
1823
1824 if ( xInteraction.is() )
1825 {
1826 task::DocumentMacroConfirmationRequest aRequest;
1827 aRequest.DocumentURL = getDocumentLocation();
1828 aRequest.DocumentStorage = rDocShell.GetMedium()->GetZipStorageToSign_Impl();
1829 aRequest.DocumentSignatureInformation = aInfo;
1830 aRequest.DocumentVersion = aVersion;
1831 aRequest.Classification = task::InteractionClassification_QUERY;
1832 bResult = SfxMedium::CallApproveHandler( xInteraction, uno::makeAny( aRequest ), true );
1833 }
1834 }
1835 }
1836 }
1837 }
1838 }
1839 catch( uno::Exception& )
1840 {}
1841
1842 return bResult;
1843}
1844
1845bool SfxObjectShell::IsContinueImportOnFilterExceptions(const OUString& aErrMessage)
1846{
1847 if (mbContinueImportOnFilterExceptions == undefined)
1848 {
1849 if (Application::GetDialogCancelMode() == DialogCancelMode::Off)
1850 {
1851 // Ask the user to try to continue or abort loading
1852 OUString aMessage = SfxResId(STR_QMSG_ERROR_OPENING_FILEreinterpret_cast<char const *>("STR_QMSG_ERROR_OPENING_FILE"
"\004" u8"An error occurred during opening the file. This may be caused by incorrect file contents.\n"
)
);
1853 if (!aErrMessage.isEmpty())
1854 aMessage += SfxResId(STR_QMSG_ERROR_OPENING_FILE_DETAILSreinterpret_cast<char const *>("STR_QMSG_ERROR_OPENING_FILE_DETAILS"
"\004" u8"The error details are:\n")
) + aErrMessage;
1855 aMessage += SfxResId(STR_QMSG_ERROR_OPENING_FILE_CONTINUEreinterpret_cast<char const *>("STR_QMSG_ERROR_OPENING_FILE_CONTINUE"
"\004" u8"\nProceeding with import may cause data loss or corruption, and application may become unstable or crash.\n\nDo you want to ignore the error and attempt to continue loading the file?"
)
);
1856 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(nullptr,
1857 VclMessageType::Question, VclButtonsType::YesNo, aMessage));
1858 mbContinueImportOnFilterExceptions = (xBox->run() == RET_YES) ? yes : no;
1859 }
1860 else
1861 mbContinueImportOnFilterExceptions = no;
1862 }
1863 return mbContinueImportOnFilterExceptions == yes;
1864}
1865
1866bool SfxObjectShell::isEditDocLocked() const
1867{
1868 Reference<XModel> xModel = GetModel();
1869 if (!xModel.is())
1870 return false;
1871 if (!officecfg::Office::Common::Misc::AllowEditReadonlyDocs::get())
1872 return true;
1873 comphelper::NamedValueCollection aArgs(xModel->getArgs());
1874 return aArgs.getOrDefault("LockEditDoc", false);
1875}
1876
1877bool SfxObjectShell::isContentExtractionLocked() const
1878{
1879 Reference<XModel> xModel = GetModel();
1880 if (!xModel.is())
1881 return false;
1882 comphelper::NamedValueCollection aArgs(xModel->getArgs());
1883 return aArgs.getOrDefault("LockContentExtraction", false);
1884}
1885
1886bool SfxObjectShell::isExportLocked() const
1887{
1888 Reference<XModel> xModel = GetModel();
1889 if (!xModel.is())
1890 return false;
1891 comphelper::NamedValueCollection aArgs(xModel->getArgs());
1892 return aArgs.getOrDefault("LockExport", false);
1893}
1894
1895bool SfxObjectShell::isPrintLocked() const
1896{
1897 Reference<XModel> xModel = GetModel();
1898 if (!xModel.is())
1899 return false;
1900 comphelper::NamedValueCollection aArgs(xModel->getArgs());
1901 return aArgs.getOrDefault("LockPrint", false);
1902}
1903
1904bool SfxObjectShell::isSaveLocked() const
1905{
1906 Reference<XModel> xModel = GetModel();
1907 if (!xModel.is())
1908 return false;
1909 comphelper::NamedValueCollection aArgs(xModel->getArgs());
1910 return aArgs.getOrDefault("LockSave", false);
1911}
1912
1913/* 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
9.1
Field 'm_pBody' is non-null
9.1
Field 'm_pBody' is non-null
9.1
Field 'm_pBody' is non-null
)
10
Taking true branch
113 m_pBody->release();
11
Calling 'VclReferenceBase::release'
15
Returning; memory was released
114 }
115
116 /** Set...
117 Similar to assignment.
118 */
119 Reference<reference_type> &
120 SAL_CALL set (reference_type * pBody)
121 {
122 if (pBody)
123 pBody->acquire();
124 reference_type * const pOld = m_pBody;
125 m_pBody = pBody;
126 if (pOld)
127 pOld->release();
128 return *this;
129 }
130
131 /** Assignment.
132 Unbinds this instance from its body (if bound) and
133 bind it to the body represented by the handle.
134 */
135 Reference<reference_type> &
136 SAL_CALL operator= (const Reference<reference_type> & handle)
137 {
138 return set( handle.m_pBody );
139 }
140
141#ifdef LIBO_INTERNAL_ONLY1
142 /** Assignment.
143 * Unbinds this instance from its body (if bound),
144 * bind it to the body represented by the handle, and
145 * set the body represented by the handle to nullptr.
146 */
147 Reference<reference_type> &
148 operator= (Reference<reference_type> && handle)
149 {
150 // self-movement guts ourself
151 if (m_pBody)
152 m_pBody->release();
153 m_pBody = handle.m_pBody;
154 handle.m_pBody = nullptr;
155 return *this;
156 }
157#endif
158
159 /** Assignment...
160 */
161 Reference<reference_type> &
162 SAL_CALL operator= (reference_type * pBody)
163 {
164 return set( pBody );
165 }
166
167 /** Unbind the body from this handle.
168 Note that for a handle representing a large body,
169 "handle.clear().set(new body());" _might_
170 perform a little bit better than "handle.set(new body());",
171 since in the second case two large objects exist in memory
172 (the old body and the new body).
173 */
174 Reference<reference_type> & SAL_CALL clear()
175 {
176 if (m_pBody)
177 {
178 reference_type * const pOld = m_pBody;
179 m_pBody = NULL__null;
180 pOld->release();
181 }
182 return *this;
183 }
184
185
186 /** Get the body. Can be used instead of operator->().
187 I.e. handle->someBodyOp() and handle.get()->someBodyOp()
188 are the same.
189 */
190 reference_type * SAL_CALL get() const
191 {
192 return m_pBody;
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)
12
Assuming the condition is true
13
Taking true branch
40 delete this;
14
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