Bug Summary

File:home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx
Warning:line 2083, column 5
Called C++ object pointer is null

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 objstor.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/objstor.cxx
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
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 <sal/config.h>
23#include <sal/log.hxx>
24
25#include <cassert>
26
27#include <svl/eitem.hxx>
28#include <svl/stritem.hxx>
29#include <svl/intitem.hxx>
30#include <com/sun/star/frame/theGlobalEventBroadcaster.hpp>
31#include <com/sun/star/frame/XModel.hpp>
32#include <com/sun/star/document/XFilter.hpp>
33#include <com/sun/star/document/XImporter.hpp>
34#include <com/sun/star/document/XExporter.hpp>
35#include <com/sun/star/packages/zip/ZipIOException.hpp>
36#include <com/sun/star/task/XInteractionHandler.hpp>
37#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
38#include <com/sun/star/document/MacroExecMode.hpp>
39#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
40#include <com/sun/star/beans/XPropertySetInfo.hpp>
41#include <com/sun/star/lang/XMultiServiceFactory.hpp>
42#include <com/sun/star/beans/PropertyValue.hpp>
43#include <com/sun/star/beans/XPropertySet.hpp>
44#include <com/sun/star/container/XNameAccess.hpp>
45#include <com/sun/star/embed/ElementModes.hpp>
46#include <com/sun/star/embed/EmbedStates.hpp>
47#include <com/sun/star/embed/XTransactedObject.hpp>
48#include <com/sun/star/embed/XEmbeddedObject.hpp>
49#include <com/sun/star/embed/XEmbedPersist.hpp>
50#include <com/sun/star/embed/XOptimizedStorage.hpp>
51#include <com/sun/star/embed/XEncryptionProtectedStorage.hpp>
52#include <com/sun/star/io/WrongFormatException.hpp>
53#include <com/sun/star/io/XTruncate.hpp>
54#include <com/sun/star/util/XModifiable.hpp>
55#include <com/sun/star/util/RevisionTag.hpp>
56#include <com/sun/star/security/DocumentDigitalSignatures.hpp>
57#include <com/sun/star/text/XTextRange.hpp>
58#include <com/sun/star/xml/crypto/CipherID.hpp>
59#include <com/sun/star/xml/crypto/DigestID.hpp>
60
61#include <com/sun/star/document/XDocumentProperties.hpp>
62#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
63#include <comphelper/fileformat.h>
64#include <comphelper/processfactory.hxx>
65#include <svtools/langtab.hxx>
66#include <svtools/sfxecode.hxx>
67#include <unotools/configmgr.hxx>
68#include <unotools/streamwrap.hxx>
69
70#include <unotools/saveopt.hxx>
71#include <unotools/useroptions.hxx>
72#include <unotools/securityoptions.hxx>
73#include <tools/urlobj.hxx>
74#include <tools/diagnose_ex.h>
75#include <unotools/ucbhelper.hxx>
76#include <unotools/tempfile.hxx>
77#include <unotools/docinfohelper.hxx>
78#include <ucbhelper/content.hxx>
79#include <sot/storage.hxx>
80#include <sot/exchange.hxx>
81#include <sot/formats.hxx>
82#include <comphelper/storagehelper.hxx>
83#include <comphelper/documentconstants.hxx>
84#include <comphelper/string.hxx>
85#include <vcl/errinf.hxx>
86#include <vcl/svapp.hxx>
87#include <vcl/weld.hxx>
88#include <basic/modsizeexceeded.hxx>
89#include <officecfg/Office/Common.hxx>
90#include <osl/file.hxx>
91#include <comphelper/scopeguard.hxx>
92#include <comphelper/lok.hxx>
93
94#include <sfx2/signaturestate.hxx>
95#include <sfx2/app.hxx>
96#include <sfx2/objsh.hxx>
97#include <sfx2/sfxresid.hxx>
98#include <sfx2/docfile.hxx>
99#include <sfx2/fcontnr.hxx>
100#include <sfx2/docfilt.hxx>
101#include <sfx2/docfac.hxx>
102#include <appopen.hxx>
103#include <objshimp.hxx>
104#include <sfx2/strings.hrc>
105#include <sfx2/sfxsids.hrc>
106#include <sfx2/dispatch.hxx>
107#include <sfx2/sfxuno.hxx>
108#include <sfx2/event.hxx>
109#include <fltoptint.hxx>
110#include <sfx2/viewfrm.hxx>
111#include "graphhelp.hxx"
112#include <appbaslib.hxx>
113#include "objstor.hxx"
114#include "exoticfileloadexception.hxx"
115
116using namespace ::com::sun::star;
117using namespace ::com::sun::star::container;
118using namespace ::com::sun::star::lang;
119using namespace ::com::sun::star::ui::dialogs;
120using namespace ::com::sun::star::uno;
121using namespace ::com::sun::star::beans;
122using namespace ::com::sun::star::ucb;
123using namespace ::com::sun::star::task;
124using namespace ::com::sun::star::document;
125using namespace ::cppu;
126
127
128void impl_addToModelCollection(const css::uno::Reference< css::frame::XModel >& xModel)
129{
130 if (!xModel.is())
131 return;
132
133 css::uno::Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
134 css::uno::Reference< css::frame::XGlobalEventBroadcaster > xModelCollection =
135 css::frame::theGlobalEventBroadcaster::get(xContext);
136 try
137 {
138 xModelCollection->insert(css::uno::makeAny(xModel));
139 }
140 catch ( uno::Exception& )
141 {
142 SAL_WARN( "sfx.doc", "The document seems to be in the collection already!" )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "sfx.doc")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "The document seems to be in the collection already!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "142" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "The document seems to be in the collection already!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "The document seems to be in the collection already!"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "142" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "The document seems to be in the collection already!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "142" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "The document seems to be in the collection already!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "The document seems to be in the collection already!"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "142" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
143 }
144}
145
146
147bool SfxObjectShell::Save()
148{
149 SaveChildren();
150 return true;
151}
152
153
154bool SfxObjectShell::SaveAs( SfxMedium& rMedium )
155{
156 return SaveAsChildren( rMedium );
157}
158
159
160bool SfxObjectShell::QuerySlotExecutable( sal_uInt16 /*nSlotId*/ )
161{
162 return true;
163}
164
165
166bool GetEncryptionData_Impl( const SfxItemSet* pSet, uno::Sequence< beans::NamedValue >& o_rEncryptionData )
167{
168 bool bResult = false;
169 if ( pSet )
170 {
171 const SfxUnoAnyItem* pEncryptionDataItem = SfxItemSet::GetItem<SfxUnoAnyItem>(pSet, SID_ENCRYPTIONDATA(5000 + 1722), false);
172 if ( pEncryptionDataItem )
173 {
174 pEncryptionDataItem->GetValue() >>= o_rEncryptionData;
175 bResult = true;
176 }
177 else
178 {
179 const SfxStringItem* pPasswordItem = SfxItemSet::GetItem<SfxStringItem>(pSet, SID_PASSWORD(((((10000 + 1499) + 1) + 499) + 1) + 36), false);
180 if ( pPasswordItem )
181 {
182 o_rEncryptionData = ::comphelper::OStorageHelper::CreatePackageEncryptionData( pPasswordItem->GetValue() );
183 bResult = true;
184 }
185 }
186 }
187
188 return bResult;
189}
190
191
192bool SfxObjectShell::PutURLContentsToVersionStream_Impl(
193 const OUString& aURL,
194 const uno::Reference< embed::XStorage >& xDocStorage,
195 const OUString& aStreamName )
196{
197 bool bResult = false;
198 try
199 {
200 uno::Reference< embed::XStorage > xVersion = xDocStorage->openStorageElement(
201 "Versions",
202 embed::ElementModes::READWRITE );
203
204 DBG_ASSERT( xVersion.is(),do { if (true && (!(xVersion.is()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "205" ": "), "%s", "The method must throw an exception if the storage can not be opened!"
); } } while (false)
205 "The method must throw an exception if the storage can not be opened!" )do { if (true && (!(xVersion.is()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "205" ": "), "%s", "The method must throw an exception if the storage can not be opened!"
); } } while (false)
;
206 if ( !xVersion.is() )
207 throw uno::RuntimeException();
208
209 uno::Reference< io::XStream > xVerStream = xVersion->openStreamElement(
210 aStreamName,
211 embed::ElementModes::READWRITE );
212 DBG_ASSERT( xVerStream.is(), "The method must throw an exception if the storage can not be opened!" )do { if (true && (!(xVerStream.is()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "212" ": "), "%s", "The method must throw an exception if the storage can not be opened!"
); } } while (false)
;
213 if ( !xVerStream.is() )
214 throw uno::RuntimeException();
215
216 uno::Reference< io::XOutputStream > xOutStream = xVerStream->getOutputStream();
217 uno::Reference< io::XTruncate > xTrunc( xOutStream, uno::UNO_QUERY_THROW );
218
219 uno::Reference< io::XInputStream > xTmpInStream =
220 ::comphelper::OStorageHelper::GetInputStreamFromURL(
221 aURL, comphelper::getProcessComponentContext() );
222 assert( xTmpInStream.is() )(static_cast <bool> (xTmpInStream.is()) ? void (0) : __assert_fail
("xTmpInStream.is()", "/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
, 222, __extension__ __PRETTY_FUNCTION__))
;
223
224 xTrunc->truncate();
225 ::comphelper::OStorageHelper::CopyInputToOutput( xTmpInStream, xOutStream );
226 xOutStream->closeOutput();
227
228 uno::Reference< embed::XTransactedObject > xTransact( xVersion, uno::UNO_QUERY );
229 DBG_ASSERT( xTransact.is(), "The storage must implement XTransacted interface!\n" )do { if (true && (!(xTransact.is()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "229" ": "), "%s", "The storage must implement XTransacted interface!\n"
); } } while (false)
;
230 if ( xTransact.is() )
231 xTransact->commit();
232
233 bResult = true;
234 }
235 catch( uno::Exception& )
236 {
237 // TODO/LATER: handle the error depending on exception
238 SetError(ERRCODE_IO_GENERALErrCode( ErrCodeArea::Io, ErrCodeClass::General, 13 ));
239 }
240
241 return bResult;
242}
243
244
245OUString SfxObjectShell::CreateTempCopyOfStorage_Impl( const uno::Reference< embed::XStorage >& xStorage )
246{
247 OUString aTempURL = ::utl::TempFile().GetURL();
248
249 DBG_ASSERT( !aTempURL.isEmpty(), "Can't create a temporary file!\n" )do { if (true && (!(!aTempURL.isEmpty()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "249" ": "), "%s", "Can't create a temporary file!\n"); }
} while (false)
;
250 if ( !aTempURL.isEmpty() )
251 {
252 try
253 {
254 uno::Reference< embed::XStorage > xTempStorage =
255 ::comphelper::OStorageHelper::GetStorageFromURL( aTempURL, embed::ElementModes::READWRITE );
256
257 // the password will be transferred from the xStorage to xTempStorage by storage implementation
258 xStorage->copyToStorage( xTempStorage );
259
260 // the temporary storage was committed by the previous method and it will die by refcount
261 }
262 catch ( uno::Exception& )
263 {
264 SAL_WARN( "sfx.doc", "Creation of a storage copy is failed!" )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "sfx.doc")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "Creation of a storage copy is failed!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "264" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "Creation of a storage copy is failed!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Creation of a storage copy is failed!"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "264" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Creation of a storage copy is failed!") == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"), (
"/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "264" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "Creation of a storage copy is failed!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Creation of a storage copy is failed!"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "264" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
265 ::utl::UCBContentHelper::Kill( aTempURL );
266
267 aTempURL.clear();
268
269 // TODO/LATER: may need error code setting based on exception
270 SetError(ERRCODE_IO_GENERALErrCode( ErrCodeArea::Io, ErrCodeClass::General, 13 ));
271 }
272 }
273
274 return aTempURL;
275}
276
277
278SvGlobalName const & SfxObjectShell::GetClassName() const
279{
280 return GetFactory().GetClassId();
281}
282
283
284void SfxObjectShell::SetupStorage( const uno::Reference< embed::XStorage >& xStorage,
285 sal_Int32 nVersion, bool bTemplate ) const
286{
287 uno::Reference< beans::XPropertySet > xProps( xStorage, uno::UNO_QUERY );
288
289 if ( !xProps.is() )
290 return;
291
292 SotClipboardFormatId nClipFormat = SotClipboardFormatId::NONE;
293
294 SvGlobalName aName;
295 OUString aFullTypeName;
296 FillClass( &aName, &nClipFormat, &aFullTypeName, nVersion, bTemplate );
297
298 if ( nClipFormat == SotClipboardFormatId::NONE )
299 return;
300
301 // basic doesn't have a ClipFormat
302 // without MediaType the storage is not really usable, but currently the BasicIDE still
303 // is an SfxObjectShell and so we can't take this as an error
304 datatransfer::DataFlavor aDataFlavor;
305 SotExchange::GetFormatDataFlavor( nClipFormat, aDataFlavor );
306 if ( aDataFlavor.MimeType.isEmpty() )
307 return;
308
309 try
310 {
311 xProps->setPropertyValue("MediaType", uno::makeAny( aDataFlavor.MimeType ) );
312 }
313 catch( uno::Exception& )
314 {
315 const_cast<SfxObjectShell*>( this )->SetError(ERRCODE_IO_GENERALErrCode( ErrCodeArea::Io, ErrCodeClass::General, 13 ));
316 }
317
318 SvtSaveOptions::ODFSaneDefaultVersion nDefVersion = SvtSaveOptions::ODFSVER_013;
319 if (!utl::ConfigManager::IsFuzzing())
320 {
321 SvtSaveOptions aSaveOpt;
322 nDefVersion = aSaveOpt.GetODFSaneDefaultVersion();
323 }
324
325 // the default values, that should be used for ODF1.1 and older formats
326 uno::Sequence< beans::NamedValue > aEncryptionAlgs
327 {
328 { "StartKeyGenerationAlgorithm", css::uno::makeAny(xml::crypto::DigestID::SHA1) },
329 { "EncryptionAlgorithm", css::uno::makeAny(xml::crypto::CipherID::BLOWFISH_CFB_8) },
330 { "ChecksumAlgorithm", css::uno::makeAny(xml::crypto::DigestID::SHA1_1K) }
331 };
332
333 if (nDefVersion >= SvtSaveOptions::ODFSVER_012)
334 {
335 try
336 {
337 // older versions can not have this property set, it exists only starting from ODF1.2
338 if (SvtSaveOptions::ODFSVER_013 <= nDefVersion)
339 {
340 xProps->setPropertyValue("Version", uno::makeAny<OUString>(ODFVER_013_TEXT"1.3"));
341 }
342 else
343 {
344 xProps->setPropertyValue("Version", uno::makeAny<OUString>(ODFVER_012_TEXT"1.2"));
345 }
346 }
347 catch( uno::Exception& )
348 {
349 }
350
351 aEncryptionAlgs[0].Value <<= xml::crypto::DigestID::SHA256;
352 aEncryptionAlgs[2].Value <<= xml::crypto::DigestID::SHA256_1K;
353 aEncryptionAlgs[1].Value <<= xml::crypto::CipherID::AES_CBC_W3C_PADDING;
354 }
355
356 try
357 {
358 // set the encryption algorithms accordingly;
359 // the setting does not trigger encryption,
360 // it just provides the format for the case that contents should be encrypted
361 uno::Reference< embed::XEncryptionProtectedStorage > xEncr( xStorage, uno::UNO_QUERY_THROW );
362 xEncr->setEncryptionAlgorithms( aEncryptionAlgs );
363 }
364 catch( uno::Exception& )
365 {
366 const_cast<SfxObjectShell*>( this )->SetError(ERRCODE_IO_GENERALErrCode( ErrCodeArea::Io, ErrCodeClass::General, 13 ));
367 }
368}
369
370
371void SfxObjectShell::PrepareSecondTryLoad_Impl()
372{
373 // only for internal use
374 pImpl->m_xDocStorage.clear();
375 pImpl->m_bIsInit = false;
376 ResetError();
377}
378
379
380bool SfxObjectShell::GeneralInit_Impl( const uno::Reference< embed::XStorage >& xStorage,
381 bool bTypeMustBeSetAlready )
382{
383 if ( pImpl->m_bIsInit )
384 return false;
385
386 pImpl->m_bIsInit = true;
387 if ( xStorage.is() )
388 {
389 // no notification is required the storage is set the first time
390 pImpl->m_xDocStorage = xStorage;
391
392 try {
393 uno::Reference < beans::XPropertySet > xPropSet( xStorage, uno::UNO_QUERY_THROW );
394 Any a = xPropSet->getPropertyValue("MediaType");
395 OUString aMediaType;
396 if ( !(a>>=aMediaType) || aMediaType.isEmpty() )
397 {
398 if ( bTypeMustBeSetAlready )
399 {
400 SetError(ERRCODE_IO_BROKENPACKAGEErrCode( ErrCodeArea::Io, ErrCodeClass::Format, 38 ));
401 return false;
402 }
403
404 SetupStorage( xStorage, SOFFICE_FILEFORMAT_CURRENT6800, false );
405 }
406 }
407 catch ( uno::Exception& )
408 {
409 SAL_WARN( "sfx.doc", "Can't check storage's mediatype!" )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "sfx.doc")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "Can't check storage's mediatype!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "409" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "Can't check storage's mediatype!"), 0
); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Can't check storage's mediatype!"; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "409" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Can't check storage's mediatype!") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "409" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "Can't check storage's mediatype!"), 0
); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Can't check storage's mediatype!"; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "409" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
410 }
411 }
412 else
413 pImpl->m_bCreateTempStor = true;
414
415 return true;
416}
417
418
419bool SfxObjectShell::InitNew( const uno::Reference< embed::XStorage >& xStorage )
420{
421 return GeneralInit_Impl( xStorage, false );
422}
423
424
425bool SfxObjectShell::Load( SfxMedium& rMedium )
426{
427 return GeneralInit_Impl( rMedium.GetStorage(), true );
428}
429
430void SfxObjectShell::DoInitUnitTest()
431{
432 pMedium = new SfxMedium;
433}
434
435bool SfxObjectShell::DoInitNew( SfxMedium* pMed )
436/* [Description]
437
438 This from SvPersist inherited virtual method is called to initialize
439 the SfxObjectShell instance from a storage (PStore! = 0) or (PStore == 0)
440
441 Like with all Do...-methods there is a from a control, the actual
442 implementation is done by the virtual method in which also the
443 InitNew(SvStorate *) from the SfxObjectShell-Subclass is implemented.
444
445 For pStore == 0 the SfxObjectShell-instance is connected to an empty
446 SfxMedium, otherwise a SfxMedium, which refers to the SotStorage
447 passed as a parameter.
448
449 The object is only initialized correctly after InitNew() or Load().
450
451 [Return value]
452 true The object has been initialized.
453 false The object could not be initialized
454*/
455
456{
457 ModifyBlocker_Impl aBlock( this );
458 pMedium = pMed;
459 if ( !pMedium )
460 {
461 pMedium = new SfxMedium;
462 }
463
464 pMedium->CanDisposeStorage_Impl( true );
465
466 if ( InitNew( pMed ? pMed->GetStorage() : uno::Reference < embed::XStorage >() ) )
467 {
468 // empty documents always get their macros from the user, so there is no reason to restrict access
469 pImpl->aMacroMode.allowMacroExecution();
470 if ( SfxObjectCreateMode::EMBEDDED == eCreateMode )
471 SetTitle(SfxResId(STR_NONAMEreinterpret_cast<char const *>("STR_NONAME" "\004" u8"Untitled"
)
));
472
473 uno::Reference< frame::XModel > xModel = GetModel();
474 if ( xModel.is() )
475 {
476 SfxItemSet *pSet = GetMedium()->GetItemSet();
477 uno::Sequence< beans::PropertyValue > aArgs;
478 TransformItems( SID_OPENDOC(5000 + 501), *pSet, aArgs );
479 sal_Int32 nLength = aArgs.getLength();
480 aArgs.realloc( nLength + 1 );
481 aArgs[nLength].Name = "Title";
482 aArgs[nLength].Value <<= GetTitle( SFX_TITLE_DETECT4 );
483 xModel->attachResource( OUString(), aArgs );
484 if (!utl::ConfigManager::IsFuzzing())
485 impl_addToModelCollection(xModel);
486 }
487
488 SetInitialized_Impl( true );
489 return true;
490 }
491
492 return false;
493}
494
495bool SfxObjectShell::ImportFromGeneratedStream_Impl(
496 const uno::Reference< io::XStream >& xStream,
497 const uno::Sequence< beans::PropertyValue >& rMediaDescr )
498{
499 if ( !xStream.is() )
500 return false;
501
502 if ( pMedium && pMedium->HasStorage_Impl() )
503 pMedium->CloseStorage();
504
505 bool bResult = false;
506
507 try
508 {
509 uno::Reference< embed::XStorage > xStorage =
510 ::comphelper::OStorageHelper::GetStorageFromStream( xStream );
511
512 if ( !xStorage.is() )
513 throw uno::RuntimeException();
514
515 if ( !pMedium )
516 pMedium = new SfxMedium( xStorage, OUString() );
517 else
518 pMedium->SetStorage_Impl( xStorage );
519
520 SfxAllItemSet aSet( SfxGetpApp()->GetPool() );
521 TransformParameters( SID_OPENDOC(5000 + 501), rMediaDescr, aSet );
522 pMedium->GetItemSet()->Put( aSet );
523 pMedium->CanDisposeStorage_Impl( false );
524 uno::Reference<text::XTextRange> xInsertTextRange;
525 for (const auto& rProp : rMediaDescr)
526 {
527 if (rProp.Name == "TextInsertModeRange")
528 {
529 rProp.Value >>= xInsertTextRange;
530 }
531 }
532
533 if (xInsertTextRange.is())
534 {
535 bResult = InsertGeneratedStream(*pMedium, xInsertTextRange);
536 }
537 else
538 {
539
540 // allow the subfilter to reinit the model
541 if ( pImpl->m_bIsInit )
542 pImpl->m_bIsInit = false;
543
544 if ( LoadOwnFormat( *pMedium ) )
545 {
546 bHasName = true;
547 if ( !IsReadOnly() && IsLoadReadonly() )
548 SetReadOnlyUI();
549
550 bResult = true;
551 OSL_ENSURE( pImpl->m_xDocStorage == xStorage, "Wrong storage is used!" )do { if (true && (!(pImpl->m_xDocStorage == xStorage
))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "551" ": "), "%s", "Wrong storage is used!"); } } while (
false)
;
552 }
553 }
554
555 // now the medium can be disconnected from the storage
556 // the medium is not allowed to dispose the storage so CloseStorage() can be used
557 pMedium->CloseStorage();
558 }
559 catch( uno::Exception& )
560 {
561 }
562
563 return bResult;
564}
565
566
567bool SfxObjectShell::DoLoad( SfxMedium *pMed )
568{
569 ModifyBlocker_Impl aBlock( this );
570 struct FontLockGuard {
571 FontLockGuard() { Application::LockFontUpdates(true); }
572 ~FontLockGuard() { Application::LockFontUpdates(false); }
573 } aFontLockGuard;
574
575 pMedium = pMed;
576 pMedium->CanDisposeStorage_Impl( true );
577
578 bool bOk = false;
579 std::shared_ptr<const SfxFilter> pFilter = pMed->GetFilter();
580 SfxItemSet* pSet = pMedium->GetItemSet();
581 if( pImpl->nEventId == SfxEventHintId::NONE )
582 {
583 const SfxBoolItem* pTemplateItem = SfxItemSet::GetItem<SfxBoolItem>(pSet, SID_TEMPLATE(5000 + 1519), false);
584 SetActivateEvent_Impl(
585 ( pTemplateItem && pTemplateItem->GetValue() )
586 ? SfxEventHintId::CreateDoc : SfxEventHintId::OpenDoc );
587 }
588
589 const SfxStringItem* pBaseItem = SfxItemSet::GetItem<SfxStringItem>(pSet, SID_BASEURL(5000 + 1518), false);
590 OUString aBaseURL;
591 const SfxStringItem* pSalvageItem = SfxItemSet::GetItem<SfxStringItem>(pMedium->GetItemSet(), SID_DOC_SALVAGE(5000 + 531), false);
592 if( pBaseItem )
593 aBaseURL = pBaseItem->GetValue();
594 else
595 {
596 if ( pSalvageItem )
597 {
598 osl::FileBase::getFileURLFromSystemPath( pMed->GetPhysicalName(), aBaseURL );
599 }
600 else
601 aBaseURL = pMed->GetBaseURL();
602 }
603 pMed->GetItemSet()->Put( SfxStringItem( SID_DOC_BASEURL(5000 + 1700), aBaseURL ) );
604
605 pImpl->nLoadedFlags = SfxLoadedFlags::NONE;
606 pImpl->bModelInitialized = false;
607
608 if (pFilter && !pFilter->IsEnabled())
609 {
610 SetError( ERRCODE_IO_FILTERDISABLEDErrCode( ErrCodeArea::Io, ErrCodeClass::Format, 40 ) );
611 }
612
613 if ( pFilter && pFilter->IsExoticFormat() && !QueryAllowExoticFormat_Impl( getInteractionHandler(), aBaseURL, pMed->GetFilter()->GetUIName() ) )
614 {
615 SetError( ERRCODE_IO_ABORTErrCode( ErrCodeArea::Io, ErrCodeClass::Abort, 27 ) );
616 }
617
618 // initialize static language table so language-related extensions are learned before the document loads
619 (void)SvtLanguageTable::GetLanguageEntryCount();
620
621 //TODO/LATER: make a clear strategy how to handle "UsesStorage" etc.
622 bool bOwnStorageFormat = IsOwnStorageFormat( *pMedium );
623 bool bHasStorage = IsPackageStorageFormat_Impl( *pMedium );
624 if ( pMedium->GetFilter() )
625 {
626 ErrCode nError = HandleFilter( pMedium, this );
627 if ( nError != ERRCODE_NONEErrCode(0) )
628 SetError(nError);
629
630 if (pMedium->GetFilter()->GetFilterFlags() & SfxFilterFlags::STARTPRESENTATION)
631 pSet->Put( SfxBoolItem( SID_DOC_STARTPRESENTATIONTypedWhichId<SfxBoolItem>(5000 + 695), true) );
632 }
633
634 EnableSetModified( false );
635
636 pMedium->LockOrigFileOnDemand( true, false );
637 if ( GetError() == ERRCODE_NONEErrCode(0) && bOwnStorageFormat && ( !pFilter || !( pFilter->GetFilterFlags() & SfxFilterFlags::STARONEFILTER ) ) )
638 {
639 uno::Reference< embed::XStorage > xStorage;
640 if ( pMedium->GetError() == ERRCODE_NONEErrCode(0) )
641 xStorage = pMedium->GetStorage();
642
643 if( xStorage.is() && pMedium->GetLastStorageCreationState() == ERRCODE_NONEErrCode(0) )
644 {
645 DBG_ASSERT( pFilter, "No filter for storage found!" )do { if (true && (!(pFilter))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "645" ": "), "%s", "No filter for storage found!"); } } while
(false)
;
646
647 try
648 {
649 bool bWarnMediaTypeFallback = false;
650 const SfxBoolItem* pRepairPackageItem = SfxItemSet::GetItem<SfxBoolItem>(pMedium->GetItemSet(), SID_REPAIRPACKAGE(5000 + 1683), false);
651
652 // treat the package as broken if the mediatype was retrieved as a fallback
653 uno::Reference< beans::XPropertySet > xStorProps( xStorage, uno::UNO_QUERY_THROW );
654 xStorProps->getPropertyValue("MediaTypeFallbackUsed")
655 >>= bWarnMediaTypeFallback;
656
657 if ( pRepairPackageItem && pRepairPackageItem->GetValue() )
658 {
659 // the macros in repaired documents should be disabled
660 pMedium->GetItemSet()->Put( SfxUInt16Item( SID_MACROEXECMODE(5000 + 1319), document::MacroExecMode::NEVER_EXECUTE ) );
661
662 // the mediatype was retrieved by using fallback solution but this is a repairing mode
663 // so it is acceptable to open the document if there is no contents that required manifest.xml
664 bWarnMediaTypeFallback = false;
665 }
666
667 if ( bWarnMediaTypeFallback || !xStorage->getElementNames().hasElements() )
668 SetError(ERRCODE_IO_BROKENPACKAGEErrCode( ErrCodeArea::Io, ErrCodeClass::Format, 38 ));
669 }
670 catch( uno::Exception& )
671 {
672 // TODO/LATER: may need error code setting based on exception
673 SetError(ERRCODE_IO_GENERALErrCode( ErrCodeArea::Io, ErrCodeClass::General, 13 ));
674 }
675
676 // Load
677 if ( !GetError() )
678 {
679 pImpl->nLoadedFlags = SfxLoadedFlags::NONE;
680 pImpl->bModelInitialized = false;
681 bOk = xStorage.is() && LoadOwnFormat( *pMed );
682 if ( bOk )
683 {
684 // the document loaded from template has no name
685 const SfxBoolItem* pTemplateItem = SfxItemSet::GetItem<SfxBoolItem>(pMedium->GetItemSet(), SID_TEMPLATE(5000 + 1519), false);
686 if ( !pTemplateItem || !pTemplateItem->GetValue() )
687 bHasName = true;
688 }
689 else
690 SetError(ERRCODE_ABORTErrCode( ErrCodeArea::Io, ErrCodeClass::Abort, 27 ));
691 }
692 }
693 else
694 SetError(pMed->GetLastStorageCreationState());
695 }
696 else if ( GetError() == ERRCODE_NONEErrCode(0) && InitNew(nullptr) )
697 {
698 // set name before ConvertFrom, so that GetSbxObject() already works
699 bHasName = true;
700 SetName( SfxResId(STR_NONAMEreinterpret_cast<char const *>("STR_NONAME" "\004" u8"Untitled"
)
) );
701
702 if( !bHasStorage )
703 pMedium->GetInStream();
704 else
705 pMedium->GetStorage();
706
707 if ( GetError() == ERRCODE_NONEErrCode(0) )
708 {
709 // Experimental PDF importing using PDFium. This is currently enabled for LOK only and
710 // we handle it not via XmlFilterAdaptor but a new SdPdfFiler.
711#if !HAVE_FEATURE_POPPLER1
712 constexpr bool bUsePdfium = true;
713#else
714 const bool bUsePdfium
715 = comphelper::LibreOfficeKit::isActive() || getenv("LO_IMPORT_USE_PDFIUM");
716#endif
717 const bool bPdfiumImport
718 = bUsePdfium && pMedium->GetFilter()
719 && (pMedium->GetFilter()->GetFilterName() == "draw_pdf_import");
720
721 pImpl->nLoadedFlags = SfxLoadedFlags::NONE;
722 pImpl->bModelInitialized = false;
723 if (pMedium->GetFilter()
724 && (pMedium->GetFilter()->GetFilterFlags() & SfxFilterFlags::STARONEFILTER)
725 && !bPdfiumImport)
726 {
727 uno::Reference < beans::XPropertySet > xSet( GetModel(), uno::UNO_QUERY );
728 const OUString sLockUpdates("LockUpdates");
729 bool bSetProperty = true;
730 try
731 {
732 xSet->setPropertyValue( sLockUpdates, makeAny( true ) );
733 }
734 catch(const beans::UnknownPropertyException& )
735 {
736 bSetProperty = false;
737 }
738 bOk = ImportFrom(*pMedium, nullptr);
739 if(bSetProperty)
740 {
741 try
742 {
743 xSet->setPropertyValue( sLockUpdates, makeAny( false ) );
744 }
745 catch(const beans::UnknownPropertyException& )
746 {}
747 }
748 UpdateLinks();
749 FinishedLoading();
750 }
751 else
752 {
753 bOk = ConvertFrom(*pMedium);
754 InitOwnModel_Impl();
755 }
756 }
757 }
758
759 if ( bOk )
760 {
761 if ( IsReadOnlyMedium() || IsLoadReadonly() )
762 SetReadOnlyUI();
763
764 try
765 {
766 ::ucbhelper::Content aContent( pMedium->GetName(), utl::UCBContentHelper::getDefaultCommandEnvironment(), comphelper::getProcessComponentContext() );
767 css::uno::Reference < XPropertySetInfo > xProps = aContent.getProperties();
768 if ( xProps.is() )
769 {
770 const OUString aAuthor( "Author" );
771 const OUString aKeywords( "Keywords" );
772 const OUString aSubject( "Subject" );
773 Any aAny;
774 OUString aValue;
775 uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
776 GetModel(), uno::UNO_QUERY_THROW);
777 uno::Reference<document::XDocumentProperties> xDocProps
778 = xDPS->getDocumentProperties();
779 if ( xProps->hasPropertyByName( aAuthor ) )
780 {
781 aAny = aContent.getPropertyValue( aAuthor );
782 if ( aAny >>= aValue )
783 xDocProps->setAuthor(aValue);
784 }
785 if ( xProps->hasPropertyByName( aKeywords ) )
786 {
787 aAny = aContent.getPropertyValue( aKeywords );
788 if ( aAny >>= aValue )
789 xDocProps->setKeywords(
790 ::comphelper::string::convertCommaSeparated(aValue));
791;
792 }
793 if ( xProps->hasPropertyByName( aSubject ) )
794 {
795 aAny = aContent.getPropertyValue( aSubject );
796 if ( aAny >>= aValue ) {
797 xDocProps->setSubject(aValue);
798 }
799 }
800 }
801 }
802 catch( Exception& )
803 {
804 }
805
806 // If not loaded asynchronously call FinishedLoading
807 if ( !( pImpl->nLoadedFlags & SfxLoadedFlags::MAINDOCUMENT ) &&
808 ( !pMedium->GetFilter() || pMedium->GetFilter()->UsesStorage() )
809 )
810 FinishedLoading( SfxLoadedFlags::MAINDOCUMENT );
811
812 Broadcast( SfxHint(SfxHintId::NameChanged) );
813
814 if ( SfxObjectCreateMode::EMBEDDED != eCreateMode )
815 {
816 const SfxBoolItem* pAsTempItem = SfxItemSet::GetItem<SfxBoolItem>(pMedium->GetItemSet(), SID_TEMPLATE(5000 + 1519), false);
817 const SfxBoolItem* pPreviewItem = SfxItemSet::GetItem<SfxBoolItem>(pMedium->GetItemSet(), SID_PREVIEWTypedWhichId<SfxBoolItem>(5000 + 1404), false);
818 const SfxBoolItem* pHiddenItem = SfxItemSet::GetItem<SfxBoolItem>(pMedium->GetItemSet(), SID_HIDDEN(5000 + 534), false);
819 if( bOk && !pMedium->GetOrigURL().isEmpty()
820 && !( pAsTempItem && pAsTempItem->GetValue() )
821 && !( pPreviewItem && pPreviewItem->GetValue() )
822 && !( pHiddenItem && pHiddenItem->GetValue() ) )
823 {
824 AddToRecentlyUsedList();
825 }
826 }
827
828 const SfxBoolItem* pDdeReconnectItem = SfxItemSet::GetItem<SfxBoolItem>(pMedium->GetItemSet(), SID_DDE_RECONNECT_ONLOAD(5000 + 696), false);
829
830 bool bReconnectDde = true; // by default, we try to auto-connect DDE connections.
831 if (pDdeReconnectItem)
832 bReconnectDde = pDdeReconnectItem->GetValue();
833
834 if (bReconnectDde)
835 ReconnectDdeLinks(*this);
836 }
837
838 return bOk;
839}
840
841bool SfxObjectShell::DoLoadExternal( SfxMedium *pMed )
842{
843 pMedium = pMed;
844 return LoadExternal(*pMedium);
845}
846
847ErrCode SfxObjectShell::HandleFilter( SfxMedium* pMedium, SfxObjectShell const * pDoc )
848{
849 ErrCode nError = ERRCODE_NONEErrCode(0);
850 SfxItemSet* pSet = pMedium->GetItemSet();
851 const SfxStringItem* pOptions = SfxItemSet::GetItem<SfxStringItem>(pSet, SID_FILE_FILTEROPTIONS(5000 + 527), false);
852 const SfxUnoAnyItem* pData = SfxItemSet::GetItem<SfxUnoAnyItem>(pSet, SID_FILTER_DATA(5000 + 1375), false);
853 if ( !pData && !pOptions )
854 {
855 css::uno::Reference< XMultiServiceFactory > xServiceManager = ::comphelper::getProcessServiceFactory();
856 css::uno::Reference< XNameAccess > xFilterCFG;
857 if( xServiceManager.is() )
858 {
859 xFilterCFG.set( xServiceManager->createInstance("com.sun.star.document.FilterFactory"),
860 UNO_QUERY );
861 }
862
863 if( xFilterCFG.is() )
864 {
865 try {
866 bool bAbort = false;
867 std::shared_ptr<const SfxFilter> pFilter = pMedium->GetFilter();
868 Sequence < PropertyValue > aProps;
869 Any aAny = xFilterCFG->getByName( pFilter->GetName() );
870 if ( aAny >>= aProps )
871 {
872 auto pProp = std::find_if(aProps.begin(), aProps.end(),
873 [](const PropertyValue& rProp) { return rProp.Name == "UIComponent"; });
874 if (pProp != aProps.end())
875 {
876 OUString aServiceName;
877 pProp->Value >>= aServiceName;
878 if( !aServiceName.isEmpty() )
879 {
880 css::uno::Reference< XInteractionHandler > rHandler = pMedium->GetInteractionHandler();
881 if( rHandler.is() )
882 {
883 // we need some properties in the media descriptor, so we have to make sure that they are in
884 Any aStreamAny;
885 aStreamAny <<= pMedium->GetInputStream();
886 if ( pSet->GetItemState( SID_INPUTSTREAM(5000 + 1648) ) < SfxItemState::SET )
887 pSet->Put( SfxUnoAnyItem( SID_INPUTSTREAM(5000 + 1648), aStreamAny ) );
888 if ( pSet->GetItemState( SID_FILE_NAME(5000 + 507) ) < SfxItemState::SET )
889 pSet->Put( SfxStringItem( SID_FILE_NAME(5000 + 507), pMedium->GetName() ) );
890 if ( pSet->GetItemState( SID_FILTER_NAME(5000 + 530) ) < SfxItemState::SET )
891 pSet->Put( SfxStringItem( SID_FILTER_NAME(5000 + 530), pFilter->GetName() ) );
892
893 Sequence< PropertyValue > rProperties;
894 TransformItems( SID_OPENDOC(5000 + 501), *pSet, rProperties );
895 RequestFilterOptions* pFORequest = new RequestFilterOptions( pDoc->GetModel(), rProperties );
896
897 css::uno::Reference< XInteractionRequest > rRequest( pFORequest );
898 rHandler->handle( rRequest );
899
900 if ( !pFORequest->isAbort() )
901 {
902 SfxAllItemSet aNewParams( pDoc->GetPool() );
903 TransformParameters( SID_OPENDOC(5000 + 501),
904 pFORequest->getFilterOptions(),
905 aNewParams );
906
907 const SfxStringItem* pFilterOptions = aNewParams.GetItem<SfxStringItem>(SID_FILE_FILTEROPTIONS(5000 + 527), false);
908 if ( pFilterOptions )
909 pSet->Put( *pFilterOptions );
910
911 const SfxUnoAnyItem* pFilterData = aNewParams.GetItem<SfxUnoAnyItem>(SID_FILTER_DATA(5000 + 1375), false);
912 if ( pFilterData )
913 pSet->Put( *pFilterData );
914 }
915 else
916 bAbort = true;
917 }
918 }
919 }
920 }
921
922 if( bAbort )
923 {
924 // filter options were not entered
925 nError = ERRCODE_ABORTErrCode( ErrCodeArea::Io, ErrCodeClass::Abort, 27 );
926 }
927 }
928 catch( NoSuchElementException& )
929 {
930 // the filter name is unknown
931 nError = ERRCODE_IO_INVALIDPARAMETERErrCode( ErrCodeArea::Io, ErrCodeClass::Parameter, 26 );
932 }
933 catch( Exception& )
934 {
935 nError = ERRCODE_ABORTErrCode( ErrCodeArea::Io, ErrCodeClass::Abort, 27 );
936 }
937 }
938 }
939
940 return nError;
941}
942
943
944bool SfxObjectShell::IsOwnStorageFormat(const SfxMedium &rMedium)
945{
946 return !rMedium.GetFilter() || // Embedded
947 ( rMedium.GetFilter()->IsOwnFormat() &&
948 rMedium.GetFilter()->UsesStorage() &&
949 rMedium.GetFilter()->GetVersion() >= SOFFICE_FILEFORMAT_606200 );
950}
951
952
953bool SfxObjectShell::IsPackageStorageFormat_Impl(const SfxMedium &rMedium)
954{
955 return !rMedium.GetFilter() || // Embedded
956 ( rMedium.GetFilter()->UsesStorage() &&
957 rMedium.GetFilter()->GetVersion() >= SOFFICE_FILEFORMAT_606200 );
958}
959
960
961bool SfxObjectShell::DoSave()
962// DoSave is only invoked for OLE. Save your own documents in the SFX through
963// DoSave_Impl order to allow for the creation of backups.
964// Save in your own format again.
965{
966 bool bOk = false ;
967 {
968 ModifyBlocker_Impl aBlock( this );
969
970 pImpl->bIsSaving = true;
971
972 if (IsOwnStorageFormat(*GetMedium()))
973 {
974 SvtSaveOptions::ODFSaneDefaultVersion nDefVersion = SvtSaveOptions::ODFSVER_013;
975 if (!utl::ConfigManager::IsFuzzing())
976 {
977 SvtSaveOptions aSaveOpt;
978 nDefVersion = aSaveOpt.GetODFSaneDefaultVersion();
979 }
980 uno::Reference<beans::XPropertySet> const xProps(GetMedium()->GetStorage(), uno::UNO_QUERY);
981 assert(xProps.is())(static_cast <bool> (xProps.is()) ? void (0) : __assert_fail
("xProps.is()", "/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
, 981, __extension__ __PRETTY_FUNCTION__))
;
982 if (nDefVersion >= SvtSaveOptions::ODFSVER_012) // property exists only since ODF 1.2
983 {
984 try // tdf#134582 set Version on embedded objects as they
985 { // could have been loaded with a different/old version
986 if (SvtSaveOptions::ODFSVER_013 <= nDefVersion)
987 {
988 xProps->setPropertyValue("Version", uno::makeAny<OUString>(ODFVER_013_TEXT"1.3"));
989 }
990 else
991 {
992 xProps->setPropertyValue("Version", uno::makeAny<OUString>(ODFVER_012_TEXT"1.2"));
993 }
994 }
995 catch (uno::Exception&)
996 {
997 TOOLS_WARN_EXCEPTION("sfx.doc", "SfxObjectShell::DoSave")do { css::uno::Any tools_warn_exception( DbgGetCaughtException
() ); do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "sfx.doc")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "SfxObjectShell::DoSave"
<< " " << exceptionToString(tools_warn_exception
)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), (
"sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "997" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "SfxObjectShell::DoSave" << " " <<
exceptionToString(tools_warn_exception)), 0); } else { ::std
::ostringstream sal_detail_stream; sal_detail_stream <<
"SfxObjectShell::DoSave" << " " << exceptionToString
(tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "997" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "SfxObjectShell::DoSave" << " " << exceptionToString
(tools_warn_exception)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "997" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "SfxObjectShell::DoSave" << " " <<
exceptionToString(tools_warn_exception)), 0); } else { ::std
::ostringstream sal_detail_stream; sal_detail_stream <<
"SfxObjectShell::DoSave" << " " << exceptionToString
(tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "997" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false); } while (false)
;
998 }
999 }
1000 }
1001
1002 uno::Sequence< beans::NamedValue > aEncryptionData;
1003 if ( IsPackageStorageFormat_Impl( *GetMedium() ) )
1004 {
1005 if ( GetEncryptionData_Impl( GetMedium()->GetItemSet(), aEncryptionData ) )
1006 {
1007 try
1008 {
1009 //TODO/MBA: GetOutputStorage?! Special mode, because it's "Save"?!
1010 ::comphelper::OStorageHelper::SetCommonStorageEncryptionData( GetMedium()->GetStorage(), aEncryptionData );
1011 bOk = true;
1012 }
1013 catch( uno::Exception& )
1014 {
1015 SetError(ERRCODE_IO_GENERALErrCode( ErrCodeArea::Io, ErrCodeClass::General, 13 ));
1016 }
1017
1018 DBG_ASSERT( bOk, "The root storage must allow to set common password!\n" )do { if (true && (!(bOk))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1018" ": "), "%s", "The root storage must allow to set common password!\n"
); } } while (false)
;
1019 }
1020 else
1021 bOk = true;
1022#if HAVE_FEATURE_SCRIPTING1
1023 if ( HasBasic() )
1024 {
1025 try
1026 {
1027 // The basic and dialogs related contents are still not able to proceed with save operation ( saveTo only )
1028 // so since the document storage is locked a workaround has to be used
1029
1030 uno::Reference< embed::XStorage > xTmpStorage = ::comphelper::OStorageHelper::GetTemporaryStorage();
1031 DBG_ASSERT( xTmpStorage.is(), "If a storage can not be created an exception must be thrown!\n" )do { if (true && (!(xTmpStorage.is()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1031" ": "), "%s", "If a storage can not be created an exception must be thrown!\n"
); } } while (false)
;
1032 if ( !xTmpStorage.is() )
1033 throw uno::RuntimeException();
1034
1035 const OUString aBasicStorageName( "Basic" );
1036 const OUString aDialogsStorageName( "Dialogs" );
1037 if ( GetMedium()->GetStorage()->hasByName( aBasicStorageName ) )
1038 GetMedium()->GetStorage()->copyElementTo( aBasicStorageName, xTmpStorage, aBasicStorageName );
1039 if ( GetMedium()->GetStorage()->hasByName( aDialogsStorageName ) )
1040 GetMedium()->GetStorage()->copyElementTo( aDialogsStorageName, xTmpStorage, aDialogsStorageName );
1041
1042 GetBasicManager();
1043
1044 // disconnect from the current storage
1045 pImpl->aBasicManager.setStorage( xTmpStorage );
1046
1047 // store to the current storage
1048 pImpl->aBasicManager.storeLibrariesToStorage( GetMedium()->GetStorage() );
1049
1050 // connect to the current storage back
1051 pImpl->aBasicManager.setStorage( GetMedium()->GetStorage() );
1052 }
1053 catch( uno::Exception& )
1054 {
1055 SetError(ERRCODE_IO_GENERALErrCode( ErrCodeArea::Io, ErrCodeClass::General, 13 ));
1056 bOk = false;
1057 }
1058 }
1059#endif
1060 }
1061
1062 if (bOk)
1063 bOk = Save();
1064
1065 if (bOk)
1066 bOk = pMedium->Commit();
1067 }
1068
1069 return bOk;
1070}
1071
1072namespace
1073{
1074class LockUIGuard
1075{
1076public:
1077 LockUIGuard(SfxObjectShell const* pDoc)
1078 : m_pDoc(pDoc)
1079 {
1080 Lock_Impl();
1081 }
1082 ~LockUIGuard() { Unlock(); }
1083
1084 void Unlock()
1085 {
1086 if (m_bUnlock)
1087 Lock_Impl();
1088 }
1089
1090private:
1091 void Lock_Impl()
1092 {
1093 SfxViewFrame* pFrame = SfxViewFrame::GetFirst(m_pDoc);
1094 while (pFrame)
1095 {
1096 pFrame->GetDispatcher()->Lock(!m_bUnlock);
1097 pFrame->Enable(m_bUnlock);
1098 pFrame = SfxViewFrame::GetNext(*pFrame, m_pDoc);
1099 }
1100 m_bUnlock = !m_bUnlock;
1101 }
1102 SfxObjectShell const* m_pDoc;
1103 bool m_bUnlock = false;
1104};
1105}
1106
1107static OUString lcl_strip_template(const OUString &aString)
1108{
1109 static constexpr OUStringLiteral sPostfix(u"_template");
1110 OUString sRes(aString);
1111 if (sRes.endsWith(sPostfix))
1112 sRes = sRes.copy(0, sRes.getLength() - sPostfix.getLength());
1113 return sRes;
1114}
1115
1116bool SfxObjectShell::SaveTo_Impl
1117(
1118 SfxMedium &rMedium, // Medium, in which it will be stored
1119 const SfxItemSet* pSet
1120)
1121
1122/* [Description]
1123
1124 Writes the current contents to the medium rMedium. If the target medium is
1125 no storage, then saving to a temporary storage, or directly if the medium
1126 is transacted, if we ourselves have opened it, and if we are a server
1127 either the container a transacted storage provides or created a
1128 temporary storage by one self.
1129*/
1130
1131{
1132 SAL_INFO( "sfx.doc", "saving \"" << rMedium.GetName() << "\"" )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() << "saving \"" << rMedium
.GetName() << "\"") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1132" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "saving \"" << rMedium.GetName
() << "\""), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "saving \"" << rMedium.GetName
() << "\""; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1132" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "saving \"" << rMedium.GetName() << "\""
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx.doc"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1132" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "saving \"" << rMedium.GetName
() << "\""), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "saving \"" << rMedium.GetName
() << "\""; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1132" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1133
1134 UpdateDocInfoForSave();
1135
1136 ModifyBlocker_Impl aMod(this);
1137 // tdf#41063, tdf#135244: prevent jumping to cursor at any temporary modification
1138 auto aViewGuard(LockAllViews());
1139
1140 std::shared_ptr<const SfxFilter> pFilter = rMedium.GetFilter();
1141 if ( !pFilter )
1142 {
1143 // if no filter was set, use the default filter
1144 // this should be changed in the feature, it should be an error!
1145 SAL_WARN( "sfx.doc","No filter set!")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "sfx.doc")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "No filter set!") == 1
) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1145" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "No filter set!"), 0); } else { ::std
::ostringstream sal_detail_stream; sal_detail_stream <<
"No filter set!"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1145" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "No filter set!") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1145" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "No filter set!"), 0); } else { ::std
::ostringstream sal_detail_stream; sal_detail_stream <<
"No filter set!"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1145" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1146 pFilter = GetFactory().GetFilterContainer()->GetAnyFilter( SfxFilterFlags::IMPORT | SfxFilterFlags::EXPORT );
1147 rMedium.SetFilter(pFilter);
1148 }
1149
1150 bool bStorageBasedSource = IsPackageStorageFormat_Impl( *pMedium );
1151 bool bStorageBasedTarget = IsPackageStorageFormat_Impl( rMedium );
1152 bool bOwnSource = IsOwnStorageFormat( *pMedium );
1153 bool bOwnTarget = IsOwnStorageFormat( rMedium );
1154
1155 // Examine target format to determine whether to query if any password
1156 // protected libraries exceed the size we can handler
1157 if ( bOwnTarget && !QuerySaveSizeExceededModules_Impl( rMedium.GetInteractionHandler() ) )
1158 {
1159 SetError(ERRCODE_IO_ABORTErrCode( ErrCodeArea::Io, ErrCodeClass::Abort, 27 ));
1160 return false;
1161 }
1162
1163 bool bNeedsDisconnectionOnFail = false;
1164
1165 bool bStoreToSameLocation = false;
1166
1167 // the detection whether the script is changed should be done before saving
1168 bool bTryToPreserveScriptSignature = false;
1169 // no way to detect whether a filter is oasis format, have to wait for saving process
1170 bool bNoPreserveForOasis = false;
1171 if ( bOwnSource && bOwnTarget
1172 && ( pImpl->nScriptingSignatureState == SignatureState::OK
1173 || pImpl->nScriptingSignatureState == SignatureState::NOTVALIDATED
1174 || pImpl->nScriptingSignatureState == SignatureState::INVALID ) )
1175 {
1176 // the checking of the library modified state iterates over the libraries, should be done only when required
1177 // currently the check is commented out since it is broken, we have to check the signature every time we save
1178 // TODO/LATER: let isAnyContainerModified() work!
1179 bTryToPreserveScriptSignature = true; // !pImpl->pBasicManager->isAnyContainerModified();
1180 if ( bTryToPreserveScriptSignature )
1181 {
1182 // check that the storage format stays the same
1183 SvtSaveOptions aSaveOpt;
1184 SvtSaveOptions::ODFSaneDefaultVersion nVersion = aSaveOpt.GetODFSaneDefaultVersion();
1185
1186 OUString aODFVersion;
1187 try
1188 {
1189 uno::Reference < beans::XPropertySet > xPropSet( GetStorage(), uno::UNO_QUERY_THROW );
1190 xPropSet->getPropertyValue("Version") >>= aODFVersion;
1191 }
1192 catch( uno::Exception& )
1193 {}
1194
1195 // preserve only if the same filter has been used
1196 // for templates, strip the _template from the filter name for comparison
1197 const OUString aMediumFilter = lcl_strip_template(pMedium->GetFilter()->GetFilterName());
1198 bTryToPreserveScriptSignature = pMedium->GetFilter() && pFilter && aMediumFilter == lcl_strip_template(pFilter->GetFilterName());
1199
1200 // signatures were specified in ODF 1.2 but were used since much longer.
1201 // LO will still correctly validate an old style signature on an ODF 1.2
1202 // document, but technically this is not correct, so this prevents old
1203 // signatures to be copied over to a version 1.2 document
1204 bNoPreserveForOasis = (
1205 (0 <= aODFVersion.compareTo(ODFVER_012_TEXT"1.2") && nVersion < SvtSaveOptions::ODFSVER_012) ||
1206 (aODFVersion.isEmpty() && nVersion >= SvtSaveOptions::ODFSVER_012)
1207 );
1208 }
1209 }
1210
1211 // use UCB for case sensitive/insensitive file name comparison
1212 if ( !pMedium->GetName().equalsIgnoreAsciiCase("private:stream")
1213 && !rMedium.GetName().equalsIgnoreAsciiCase("private:stream")
1214 && ::utl::UCBContentHelper::EqualURLs( pMedium->GetName(), rMedium.GetName() ) )
1215 {
1216 // Do not unlock the file during saving.
1217 // need to modify this for WebDAV if this method is called outside of
1218 // the process of saving a file
1219 pMedium->DisableUnlockWebDAV();
1220 bStoreToSameLocation = true;
1221
1222 if ( pMedium->DocNeedsFileDateCheck() )
1223 rMedium.CheckFileDate( pMedium->GetInitFileDate( false ) );
1224
1225 // before we overwrite the original file, we will make a backup if there is a demand for that
1226 // if the backup is not created here it will be created internally and will be removed in case of successful saving
1227 const bool bDoBackup = SvtSaveOptions().IsBackup();
1228 if ( bDoBackup )
1229 {
1230 rMedium.DoBackup_Impl();
1231 if ( rMedium.GetError() )
1232 {
1233 SetError(rMedium.GetErrorCode());
1234 rMedium.ResetError();
1235 }
1236 }
1237
1238 if ( bStorageBasedSource && bStorageBasedTarget )
1239 {
1240 // The active storage must be switched. The simple saving is not enough.
1241 // The problem is that the target medium contains target MediaDescriptor.
1242
1243 // In future the switch of the persistence could be done on stream level:
1244 // a new wrapper service will be implemented that allows to exchange
1245 // persistence on the fly. So the real persistence will be set
1246 // to that stream only after successful commit of the storage.
1247 // TODO/LATER:
1248 // create wrapper stream based on the URL
1249 // create a new storage based on this stream
1250 // store to this new storage
1251 // commit the new storage
1252 // call saveCompleted based with this new storage ( get rid of old storage and "frees" URL )
1253 // commit the wrapper stream ( the stream will connect the URL only on commit, after that it will hold it )
1254 // if the last step is failed the stream should stay to be transacted and should be committed on any flush
1255 // so we can forget the stream in any way and the next storage commit will flush it
1256
1257 bNeedsDisconnectionOnFail = DisconnectStorage_Impl(
1258 *pMedium, rMedium );
1259 if ( bNeedsDisconnectionOnFail
1260 || ConnectTmpStorage_Impl( pMedium->GetStorage(), pMedium ) )
1261 {
1262 pMedium->CloseAndRelease();
1263
1264 // TODO/LATER: for now the medium must be closed since it can already contain streams from old medium
1265 // in future those streams should not be copied in case a valid target url is provided,
1266 // if the url is not provided ( means the document is based on a stream ) this code is not
1267 // reachable.
1268 rMedium.CloseAndRelease();
1269 rMedium.SetHasEmbeddedObjects(GetEmbeddedObjectContainer().HasEmbeddedObjects());
1270 rMedium.GetOutputStorage();
1271 rMedium.SetHasEmbeddedObjects(false);
1272 }
1273 }
1274 else if ( !bStorageBasedSource && !bStorageBasedTarget )
1275 {
1276 // the source and the target formats are alien
1277 // just disconnect the stream from the source format
1278 // so that the target medium can use it
1279
1280 pMedium->CloseAndRelease();
1281 rMedium.CloseAndRelease();
1282 rMedium.CreateTempFileNoCopy();
1283 rMedium.GetOutStream();
1284 }
1285 else if ( !bStorageBasedSource && bStorageBasedTarget )
1286 {
1287 // the source format is an alien one but the target
1288 // format is an own one so just disconnect the source
1289 // medium
1290
1291 pMedium->CloseAndRelease();
1292 rMedium.CloseAndRelease();
1293 rMedium.GetOutputStorage();
1294 }
1295 else // means if ( bStorageBasedSource && !bStorageBasedTarget )
1296 {
1297 // the source format is an own one but the target is
1298 // an alien format, just connect the source to temporary
1299 // storage
1300
1301 bNeedsDisconnectionOnFail = DisconnectStorage_Impl(
1302 *pMedium, rMedium );
1303 if ( bNeedsDisconnectionOnFail
1304 || ConnectTmpStorage_Impl( pMedium->GetStorage(), pMedium ) )
1305 {
1306 pMedium->CloseAndRelease();
1307 rMedium.CloseAndRelease();
1308 rMedium.CreateTempFileNoCopy();
1309 rMedium.GetOutStream();
1310 }
1311 }
1312 pMedium->DisableUnlockWebDAV(false);
1313 }
1314 else
1315 {
1316 // This is SaveAs or export action, prepare the target medium
1317 // the alien filters still might write directly to the file, that is of course a bug,
1318 // but for now the framework has to be ready for it
1319 // TODO/LATER: let the medium be prepared for alien formats as well
1320
1321 rMedium.CloseAndRelease();
1322 if ( bStorageBasedTarget )
1323 {
1324 rMedium.SetHasEmbeddedObjects(GetEmbeddedObjectContainer().HasEmbeddedObjects());
1325 rMedium.GetOutputStorage();
1326 rMedium.SetHasEmbeddedObjects(false);
1327 }
1328 }
1329
1330 // TODO/LATER: error handling
1331 if( rMedium.GetErrorCode() || pMedium->GetErrorCode() || GetErrorCode() )
1332 {
1333 SAL_WARN("sfx.doc", "SfxObjectShell::SaveTo_Impl: very early error return")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "sfx.doc")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "SfxObjectShell::SaveTo_Impl: very early error return"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1333" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "SfxObjectShell::SaveTo_Impl: very early error return"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "SfxObjectShell::SaveTo_Impl: very early error return"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1333" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "SfxObjectShell::SaveTo_Impl: very early error return"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1333" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "SfxObjectShell::SaveTo_Impl: very early error return"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "SfxObjectShell::SaveTo_Impl: very early error return"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1333" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1334 return false;
1335 }
1336
1337 rMedium.LockOrigFileOnDemand( false, false );
1338
1339 if ( bStorageBasedTarget )
1340 {
1341 if ( rMedium.GetErrorCode() )
1342 return false;
1343
1344 // If the filter is a "cross export" filter ( f.e. a filter for exporting an impress document from
1345 // a draw document ), the ClassId of the destination storage is different from the ClassId of this
1346 // document. It can be retrieved from the default filter for the desired target format
1347 SotClipboardFormatId nFormat = rMedium.GetFilter()->GetFormat();
1348 SfxFilterMatcher& rMatcher = SfxGetpApp()->GetFilterMatcher();
1349 std::shared_ptr<const SfxFilter> pFilt = rMatcher.GetFilter4ClipBoardId( nFormat );
1350 if ( pFilt )
1351 {
1352 if ( pFilt->GetServiceName() != rMedium.GetFilter()->GetServiceName() )
1353 {
1354 datatransfer::DataFlavor aDataFlavor;
1355 SotExchange::GetFormatDataFlavor( nFormat, aDataFlavor );
1356
1357 try
1358 {
1359 uno::Reference< beans::XPropertySet > xProps( rMedium.GetStorage(), uno::UNO_QUERY_THROW );
1360 xProps->setPropertyValue("MediaType",
1361 uno::makeAny( aDataFlavor.MimeType ) );
1362 }
1363 catch( uno::Exception& )
1364 {
1365 }
1366 }
1367 }
1368 }
1369
1370 // TODO/LATER: error handling
1371 if( rMedium.GetErrorCode() || pMedium->GetErrorCode() || GetErrorCode() )
1372 return false;
1373
1374 bool bOldStat = pImpl->bForbidReload;
1375 pImpl->bForbidReload = true;
1376
1377 // lock user interface while saving the document
1378 LockUIGuard aLockUIGuard(this);
1379
1380 bool bCopyTo = false;
1381 SfxItemSet *pMedSet = rMedium.GetItemSet();
1382 if( pMedSet )
1383 {
1384 const SfxBoolItem* pSaveToItem = SfxItemSet::GetItem<SfxBoolItem>(pMedSet, SID_SAVETOTypedWhichId<SfxBoolItem>(5000 + 1546), false);
1385 bCopyTo = GetCreateMode() == SfxObjectCreateMode::EMBEDDED ||
1386 (pSaveToItem && pSaveToItem->GetValue());
1387 }
1388
1389 bool bOk = false;
1390 // TODO/LATER: get rid of bOk
1391 if (bOwnTarget && pFilter && !(pFilter->GetFilterFlags() & SfxFilterFlags::STARONEFILTER))
1392 {
1393 uno::Reference< embed::XStorage > xMedStorage = rMedium.GetStorage();
1394 if ( !xMedStorage.is() )
1395 {
1396 // no saving without storage
1397 pImpl->bForbidReload = bOldStat;
1398 return false;
1399 }
1400
1401 // transfer password from the parameters to the storage
1402 uno::Sequence< beans::NamedValue > aEncryptionData;
1403 bool bPasswdProvided = false;
1404 if ( GetEncryptionData_Impl( rMedium.GetItemSet(), aEncryptionData ) )
1405 {
1406 bPasswdProvided = true;
1407 try {
1408 ::comphelper::OStorageHelper::SetCommonStorageEncryptionData( xMedStorage, aEncryptionData );
1409 bOk = true;
1410 }
1411 catch( uno::Exception& )
1412 {
1413 SAL_WARN( "sfx.doc", "Setting of common encryption key failed!" )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "sfx.doc")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "Setting of common encryption key failed!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1413" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Setting of common encryption key failed!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Setting of common encryption key failed!"; ::sal::
detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1413" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Setting of common encryption key failed!") == 1)
{ ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1413" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Setting of common encryption key failed!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Setting of common encryption key failed!"; ::sal::
detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1413" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1414 SetError(ERRCODE_IO_GENERALErrCode( ErrCodeArea::Io, ErrCodeClass::General, 13 ));
1415 }
1416 }
1417 else
1418 bOk = true;
1419
1420 pFilter = rMedium.GetFilter();
1421
1422 const SfxStringItem *pVersionItem = !rMedium.IsInCheckIn()? SfxItemSet::GetItem<SfxStringItem>(pSet, SID_DOCINFO_COMMENTS(5000 + 592), false): nullptr;
1423 OUString aTmpVersionURL;
1424
1425 if ( bOk )
1426 {
1427 bOk = false;
1428 // currently the case that the storage is the same should be impossible
1429 if ( xMedStorage == GetStorage() )
1430 {
1431 OSL_ENSURE( !pVersionItem, "This scenario is impossible currently!" )do { if (true && (!(!pVersionItem))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1431" ": "), "%s", "This scenario is impossible currently!"
); } } while (false)
;
1432 // usual save procedure
1433 bOk = Save();
1434 }
1435 else
1436 {
1437 // save to target
1438 bOk = SaveAsOwnFormat( rMedium );
1439 if ( bOk && pVersionItem )
1440 {
1441 aTmpVersionURL = CreateTempCopyOfStorage_Impl( xMedStorage );
1442 bOk = !aTmpVersionURL.isEmpty();
1443 }
1444 }
1445 }
1446
1447 //fdo#61320: only store thumbnail image if the corresponding option is enabled in the configuration
1448 if ( bOk && officecfg::Office::Common::Save::Document::GenerateThumbnail::get()
1449 && GetCreateMode() != SfxObjectCreateMode::EMBEDDED && !bPasswdProvided && IsUseThumbnailSave() )
1450 {
1451 // store the thumbnail representation image
1452 // the thumbnail is not stored in case of encrypted document
1453 if ( !GenerateAndStoreThumbnail( bPasswdProvided, xMedStorage ) )
1454 {
1455 // TODO: error handling
1456 SAL_WARN( "sfx.doc", "Couldn't store thumbnail representation!" )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "sfx.doc")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "Couldn't store thumbnail representation!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1456" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Couldn't store thumbnail representation!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Couldn't store thumbnail representation!"; ::sal::
detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1456" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Couldn't store thumbnail representation!") == 1)
{ ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1456" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Couldn't store thumbnail representation!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Couldn't store thumbnail representation!"; ::sal::
detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1456" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1457 }
1458 }
1459
1460 if ( bOk )
1461 {
1462 if ( pImpl->bIsSaving || pImpl->bPreserveVersions )
1463 {
1464 try
1465 {
1466 const Sequence < util::RevisionTag > aVersions = rMedium.GetVersionList();
1467 if ( aVersions.hasElements() )
1468 {
1469 // copy the version streams
1470 const OUString aVersionsName( "Versions" );
1471 uno::Reference< embed::XStorage > xNewVerStor = xMedStorage->openStorageElement(
1472 aVersionsName,
1473 embed::ElementModes::READWRITE );
1474 uno::Reference< embed::XStorage > xOldVerStor = GetStorage()->openStorageElement(
1475 aVersionsName,
1476 embed::ElementModes::READ );
1477 if ( !xNewVerStor.is() || !xOldVerStor.is() )
1478 throw uno::RuntimeException();
1479
1480 for ( const auto& rVersion : aVersions )
1481 {
1482 if ( xOldVerStor->hasByName( rVersion.Identifier ) )
1483 xOldVerStor->copyElementTo( rVersion.Identifier, xNewVerStor, rVersion.Identifier );
1484 }
1485
1486 uno::Reference< embed::XTransactedObject > xTransact( xNewVerStor, uno::UNO_QUERY );
1487 if ( xTransact.is() )
1488 xTransact->commit();
1489 }
1490 }
1491 catch( uno::Exception& )
1492 {
1493 SAL_WARN( "sfx.doc", "Couldn't copy versions!" )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "sfx.doc")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "Couldn't copy versions!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1493" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Couldn't copy versions!"), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"Couldn't copy versions!"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1493" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Couldn't copy versions!") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1493" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Couldn't copy versions!"), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"Couldn't copy versions!"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1493" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1494 bOk = false;
1495 // TODO/LATER: a specific error could be set
1496 }
1497 }
1498
1499 if ( bOk && pVersionItem && !rMedium.IsInCheckIn() )
1500 {
1501 // store a version also
1502 const SfxStringItem *pAuthorItem = SfxItemSet::GetItem<SfxStringItem>(pSet, SID_DOCINFO_AUTHOR(5000 + 593), false);
1503
1504 // version comment
1505 util::RevisionTag aInfo;
1506 aInfo.Comment = pVersionItem->GetValue();
1507
1508 // version author
1509 if ( pAuthorItem )
1510 aInfo.Author = pAuthorItem->GetValue();
1511 else
1512 // if not transferred as a parameter, get it from user settings
1513 aInfo.Author = SvtUserOptions().GetFullName();
1514
1515 DateTime aTime( DateTime::SYSTEM );
1516 aInfo.TimeStamp.Day = aTime.GetDay();
1517 aInfo.TimeStamp.Month = aTime.GetMonth();
1518 aInfo.TimeStamp.Year = aTime.GetYear();
1519 aInfo.TimeStamp.Hours = aTime.GetHour();
1520 aInfo.TimeStamp.Minutes = aTime.GetMin();
1521 aInfo.TimeStamp.Seconds = aTime.GetSec();
1522
1523 // add new version information into the versionlist and save the versionlist
1524 // the version list must have been transferred from the "old" medium before
1525 rMedium.AddVersion_Impl(aInfo);
1526 rMedium.SaveVersionList_Impl();
1527 bOk = PutURLContentsToVersionStream_Impl(aTmpVersionURL, xMedStorage,
1528 aInfo.Identifier);
1529 }
1530 else if ( bOk && ( pImpl->bIsSaving || pImpl->bPreserveVersions ) )
1531 {
1532 rMedium.SaveVersionList_Impl();
1533 }
1534 }
1535
1536 if ( !aTmpVersionURL.isEmpty() )
1537 ::utl::UCBContentHelper::Kill( aTmpVersionURL );
1538 }
1539 else
1540 {
1541 // it's a "SaveAs" in an alien format
1542 if ( rMedium.GetFilter() && ( rMedium.GetFilter()->GetFilterFlags() & SfxFilterFlags::STARONEFILTER ) )
1543 bOk = ExportTo( rMedium );
1544 else
1545 bOk = ConvertTo( rMedium );
1546
1547 // after saving the document, the temporary object storage must be updated
1548 // if the old object storage was not a temporary one, it will be updated also, because it will be used
1549 // as a source for copying the objects into the new temporary storage that will be created below
1550 // updating means: all child objects must be stored into it
1551 // ( same as on loading, where these objects are copied to the temporary storage )
1552 // but don't commit these changes, because in the case when the old object storage is not a temporary one,
1553 // all changes will be written into the original file !
1554
1555 if( bOk && !bCopyTo )
1556 // we also don't touch any graphical replacements here
1557 SaveChildren( true );
1558 }
1559
1560 if ( bOk )
1561 {
1562 // if ODF version of oasis format changes on saving the signature should not be preserved
1563 if ( bTryToPreserveScriptSignature && bNoPreserveForOasis )
1564 bTryToPreserveScriptSignature = ( SotStorage::GetVersion( rMedium.GetStorage() ) == SOFFICE_FILEFORMAT_606200 );
1565
1566 uno::Reference< security::XDocumentDigitalSignatures > xDDSigns;
1567 if (bTryToPreserveScriptSignature)
1568 {
1569 // if the scripting code was not changed and it is signed the signature should be preserved
1570 // unfortunately at this point we have only information whether the basic code has changed or not
1571 // so the only way is to check the signature if the basic was not changed
1572 try
1573 {
1574 // get the ODF version of the new medium
1575 OUString aVersion;
1576 try
1577 {
1578 uno::Reference < beans::XPropertySet > xPropSet( rMedium.GetStorage(), uno::UNO_QUERY_THROW );
1579 xPropSet->getPropertyValue("Version") >>= aVersion;
1580 }
1581 catch( uno::Exception& )
1582 {
1583 }
1584
1585 xDDSigns = security::DocumentDigitalSignatures::createWithVersion(comphelper::getProcessComponentContext(), aVersion);
1586
1587 const OUString aScriptSignName = xDDSigns->getScriptingContentSignatureDefaultStreamName();
1588
1589 if ( !aScriptSignName.isEmpty() )
1590 {
1591 // target medium is still not committed, it should not be closed
1592 // commit the package storage and close it, but leave the streams open
1593 rMedium.StorageCommit_Impl();
1594 rMedium.CloseStorage();
1595
1596 uno::Reference< embed::XStorage > xReadOrig = pMedium->GetZipStorageToSign_Impl();
1597 if ( !xReadOrig.is() )
1598 throw uno::RuntimeException();
1599 uno::Reference< embed::XStorage > xMetaInf = xReadOrig->openStorageElement(
1600 "META-INF",
1601 embed::ElementModes::READ );
1602
1603 uno::Reference< embed::XStorage > xTarget = rMedium.GetZipStorageToSign_Impl( false );
1604 if ( !xTarget.is() )
1605 throw uno::RuntimeException();
1606 uno::Reference< embed::XStorage > xTargetMetaInf = xTarget->openStorageElement(
1607 "META-INF",
1608 embed::ElementModes::READWRITE );
1609
1610 if ( xMetaInf.is() && xTargetMetaInf.is() )
1611 {
1612 xMetaInf->copyElementTo( aScriptSignName, xTargetMetaInf, aScriptSignName );
1613
1614 uno::Reference< embed::XTransactedObject > xTransact( xTargetMetaInf, uno::UNO_QUERY );
1615 if ( xTransact.is() )
1616 xTransact->commit();
1617
1618 xTargetMetaInf->dispose();
1619
1620 // now check the copied signature
1621 uno::Sequence< security::DocumentSignatureInformation > aInfos =
1622 xDDSigns->verifyScriptingContentSignatures( xTarget,
1623 uno::Reference< io::XInputStream >() );
1624 SignatureState nState = DocumentSignatures::getSignatureState(aInfos);
1625 if ( nState == SignatureState::OK || nState == SignatureState::NOTVALIDATED
1626 || nState == SignatureState::PARTIAL_OK)
1627 {
1628 rMedium.SetCachedSignatureState_Impl( nState );
1629
1630 // commit the ZipStorage from target medium
1631 xTransact.set( xTarget, uno::UNO_QUERY );
1632 if ( xTransact.is() )
1633 xTransact->commit();
1634 }
1635 else
1636 {
1637 // it should not happen, the copies signature is invalid!
1638 // throw the changes away
1639 SAL_WARN( "sfx.doc", "An invalid signature was copied!" )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "sfx.doc")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "An invalid signature was copied!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1639" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "An invalid signature was copied!"),
0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "An invalid signature was copied!"; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1639" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "An invalid signature was copied!") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1639" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "An invalid signature was copied!"),
0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "An invalid signature was copied!"; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1639" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1640 }
1641 }
1642 }
1643 }
1644 catch( uno::Exception& )
1645 {
1646 }
1647
1648 rMedium.CloseZipStorage_Impl();
1649 }
1650
1651 const OUString sName( rMedium.GetName( ) );
1652 bOk = rMedium.Commit();
1653 const OUString sNewName( rMedium.GetName( ) );
1654
1655 if ( sName != sNewName )
1656 GetMedium( )->SwitchDocumentToFile( sNewName );
1657
1658 if ( bOk )
1659 {
1660 // if the target medium is an alien format and the "old" medium was an own format and the "old" medium
1661 // has a name, the object storage must be exchanged, because now we need a new temporary storage
1662 // as object storage
1663 if ( !bCopyTo && bStorageBasedSource && !bStorageBasedTarget )
1664 {
1665 if ( bStoreToSameLocation )
1666 {
1667 // if the old medium already disconnected from document storage, the storage still must
1668 // be switched if backup file is used
1669 if ( bNeedsDisconnectionOnFail )
1670 ConnectTmpStorage_Impl( pImpl->m_xDocStorage, nullptr );
1671 }
1672 else if (!pMedium->GetName().isEmpty()
1673 || ( pMedium->HasStorage_Impl() && pMedium->WillDisposeStorageOnClose_Impl() ) )
1674 {
1675 OSL_ENSURE(!pMedium->GetName().isEmpty(), "Fallback is used, the medium without name should not dispose the storage!")do { if (true && (!(!pMedium->GetName().isEmpty())
)) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1675" ": "), "%s", "Fallback is used, the medium without name should not dispose the storage!"
); } } while (false)
;
1676 // copy storage of old medium to new temporary storage and take this over
1677 if( !ConnectTmpStorage_Impl( pMedium->GetStorage(), pMedium ) )
1678 {
1679 SAL_WARN( "sfx.doc", "Process after storing has failed." )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "sfx.doc")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "Process after storing has failed."
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1679" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Process after storing has failed.")
, 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Process after storing has failed."; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1679" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Process after storing has failed.") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1679" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Process after storing has failed.")
, 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Process after storing has failed."; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1679" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1680 bOk = false;
1681 }
1682 }
1683 }
1684 }
1685 else
1686 {
1687 SAL_WARN( "sfx.doc", "Storing has failed." )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "sfx.doc")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "Storing has failed."
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1687" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Storing has failed."), 0); } else {
::std::ostringstream sal_detail_stream; sal_detail_stream <<
"Storing has failed."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1687" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Storing has failed.") == 1) { ::sal_detail_log( (
::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1687" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Storing has failed."), 0); } else {
::std::ostringstream sal_detail_stream; sal_detail_stream <<
"Storing has failed."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1687" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1688
1689 // in case the document storage was connected to backup temporarily it must be disconnected now
1690 if ( bNeedsDisconnectionOnFail )
1691 ConnectTmpStorage_Impl( pImpl->m_xDocStorage, nullptr );
1692 }
1693 }
1694
1695 // unlock user interface
1696 aLockUIGuard.Unlock();
1697 pImpl->bForbidReload = bOldStat;
1698
1699 if ( bOk )
1700 {
1701 try
1702 {
1703 ::ucbhelper::Content aContent( rMedium.GetName(), utl::UCBContentHelper::getDefaultCommandEnvironment(), comphelper::getProcessComponentContext() );
1704 css::uno::Reference < XPropertySetInfo > xProps = aContent.getProperties();
1705 if ( xProps.is() )
1706 {
1707 const OUString aAuthor( "Author" );
1708 const OUString aKeywords( "Keywords" );
1709 const OUString aSubject( "Subject" );
1710
1711 uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
1712 GetModel(), uno::UNO_QUERY_THROW);
1713 uno::Reference<document::XDocumentProperties> xDocProps
1714 = xDPS->getDocumentProperties();
1715
1716 if ( xProps->hasPropertyByName( aAuthor ) )
1717 {
1718 aContent.setPropertyValue( aAuthor, Any(xDocProps->getAuthor()) );
1719 }
1720 if ( xProps->hasPropertyByName( aKeywords ) )
1721 {
1722 Any aAny;
1723 aAny <<= ::comphelper::string::convertCommaSeparated(
1724 xDocProps->getKeywords());
1725 aContent.setPropertyValue( aKeywords, aAny );
1726 }
1727 if ( xProps->hasPropertyByName( aSubject ) )
1728 {
1729 aContent.setPropertyValue( aSubject, Any(xDocProps->getSubject()) );
1730 }
1731 }
1732 }
1733 catch( Exception& )
1734 {
1735 }
1736 }
1737
1738 return bOk;
1739}
1740
1741bool SfxObjectShell::DisconnectStorage_Impl( SfxMedium& rSrcMedium, SfxMedium& rTargetMedium )
1742{
1743 // this method disconnects the storage from source medium, and attaches it to the backup created by the target medium
1744
1745 uno::Reference< embed::XStorage > xStorage = rSrcMedium.GetStorage();
1746
1747 bool bResult = false;
1748 if ( xStorage == pImpl->m_xDocStorage )
1749 {
1750 try
1751 {
1752 uno::Reference< embed::XOptimizedStorage > xOptStorage( xStorage, uno::UNO_QUERY_THROW );
1753 const OUString aBackupURL = rTargetMedium.GetBackup_Impl();
1754 if ( aBackupURL.isEmpty() )
1755 {
1756 // the backup could not be created, try to disconnect the storage and close the source SfxMedium
1757 // in this case the optimization is not possible, connect storage to a temporary file
1758 rTargetMedium.ResetError();
1759 xOptStorage->writeAndAttachToStream( uno::Reference< io::XStream >() );
1760 rSrcMedium.CanDisposeStorage_Impl( false );
1761 rSrcMedium.Close();
1762
1763 // now try to create the backup
1764 rTargetMedium.GetBackup_Impl();
1765 }
1766 else
1767 {
1768 // the following call will only compare stream sizes
1769 // TODO/LATER: this is a very risky part, since if the URL contents are different from the storage
1770 // contents, the storage will be broken
1771 xOptStorage->attachToURL( aBackupURL, true );
1772
1773 // the storage is successfully attached to backup, thus it is owned by the document not by the medium
1774 rSrcMedium.CanDisposeStorage_Impl( false );
1775 bResult = true;
1776 }
1777 }
1778 catch ( uno::Exception& )
1779 {}
1780 }
1781 return bResult;
1782}
1783
1784
1785bool SfxObjectShell::ConnectTmpStorage_Impl(
1786 const uno::Reference< embed::XStorage >& xStorage,
1787 SfxMedium* pMediumArg )
1788
1789/* [Description]
1790
1791 If the application operates on a temporary storage, then it may not take
1792 the temporary storage from the SaveCompleted. Therefore the new storage
1793 is connected already here in this case and SaveCompleted then does nothing.
1794*/
1795
1796{
1797 bool bResult = false;
1798
1799 if ( xStorage.is() )
1800 {
1801 try
1802 {
1803 // the empty argument means that the storage will create temporary stream itself
1804 uno::Reference< embed::XOptimizedStorage > xOptStorage( xStorage, uno::UNO_QUERY_THROW );
1805 xOptStorage->writeAndAttachToStream( uno::Reference< io::XStream >() );
1806
1807 // the storage is successfully disconnected from the original sources, thus the medium must not dispose it
1808 if ( pMediumArg )
1809 pMediumArg->CanDisposeStorage_Impl( false );
1810
1811 bResult = true;
1812 }
1813 catch( uno::Exception& )
1814 {
1815 }
1816
1817 // if switching of the storage does not work for any reason ( nonroot storage for example ) use the old method
1818 if ( !bResult ) try
1819 {
1820 uno::Reference< embed::XStorage > xTmpStorage = ::comphelper::OStorageHelper::GetTemporaryStorage();
1821
1822 DBG_ASSERT( xTmpStorage.is(), "If a storage can not be created an exception must be thrown!\n" )do { if (true && (!(xTmpStorage.is()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1822" ": "), "%s", "If a storage can not be created an exception must be thrown!\n"
); } } while (false)
;
1823 if ( !xTmpStorage.is() )
1824 throw uno::RuntimeException();
1825
1826 // TODO/LATER: may be it should be done in SwitchPersistence also
1827 // TODO/LATER: find faster way to copy storage; perhaps sharing with backup?!
1828 xStorage->copyToStorage( xTmpStorage );
1829 bResult = SaveCompleted( xTmpStorage );
1830
1831 if ( bResult )
1832 {
1833 pImpl->aBasicManager.setStorage( xTmpStorage );
1834
1835 // Get rid of this workaround after issue i113914 is fixed
1836 try
1837 {
1838 uno::Reference< script::XStorageBasedLibraryContainer > xBasicLibraries( pImpl->xBasicLibraries, uno::UNO_QUERY_THROW );
1839 xBasicLibraries->setRootStorage( xTmpStorage );
1840 }
1841 catch( uno::Exception& )
1842 {}
1843 try
1844 {
1845 uno::Reference< script::XStorageBasedLibraryContainer > xDialogLibraries( pImpl->xDialogLibraries, uno::UNO_QUERY_THROW );
1846 xDialogLibraries->setRootStorage( xTmpStorage );
1847 }
1848 catch( uno::Exception& )
1849 {}
1850 }
1851 }
1852 catch( uno::Exception& )
1853 {}
1854
1855 if ( !bResult )
1856 {
1857 // TODO/LATER: may need error code setting based on exception
1858 SetError(ERRCODE_IO_GENERALErrCode( ErrCodeArea::Io, ErrCodeClass::General, 13 ));
1859 }
1860 }
1861 else if (!GetMedium()->GetFilter()->IsOwnFormat())
1862 bResult = true;
1863
1864 return bResult;
1865}
1866
1867
1868bool SfxObjectShell::DoSaveObjectAs( SfxMedium& rMedium, bool bCommit )
1869{
1870 bool bOk = false;
1871
1872 ModifyBlocker_Impl aBlock( this );
1873
1874 uno::Reference < embed::XStorage > xNewStor = rMedium.GetStorage();
1875 if ( !xNewStor.is() )
1876 return false;
1877
1878 uno::Reference < beans::XPropertySet > xPropSet( xNewStor, uno::UNO_QUERY );
1879 if ( !xPropSet.is() )
1880 return false;
1881
1882 Any a = xPropSet->getPropertyValue("MediaType");
1883 OUString aMediaType;
1884 if ( !(a>>=aMediaType) || aMediaType.isEmpty() )
1885 {
1886 SAL_WARN( "sfx.doc", "The mediatype must be set already!" )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "sfx.doc")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "The mediatype must be set already!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1886" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "The mediatype must be set already!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "The mediatype must be set already!"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1886" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "The mediatype must be set already!") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1886" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "The mediatype must be set already!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "The mediatype must be set already!"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1886" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1887 SetupStorage( xNewStor, SOFFICE_FILEFORMAT_CURRENT6800, false );
1888 }
1889
1890 pImpl->bIsSaving = false;
1891 bOk = SaveAsOwnFormat( rMedium );
1892
1893 if ( bCommit )
1894 {
1895 try {
1896 uno::Reference< embed::XTransactedObject > xTransact( xNewStor, uno::UNO_QUERY_THROW );
1897 xTransact->commit();
1898 }
1899 catch( uno::Exception& )
1900 {
1901 SAL_WARN( "sfx.doc", "The storage was not committed on DoSaveAs!" )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "sfx.doc")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "The storage was not committed on DoSaveAs!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1901" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "The storage was not committed on DoSaveAs!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "The storage was not committed on DoSaveAs!"; ::sal
::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1901" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "The storage was not committed on DoSaveAs!") == 1
) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1901" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "The storage was not committed on DoSaveAs!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "The storage was not committed on DoSaveAs!"; ::sal
::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1901" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1902 }
1903 }
1904
1905 return bOk;
1906}
1907
1908
1909// TODO/LATER: may be the call must be removed completely
1910bool SfxObjectShell::DoSaveAs( SfxMedium& rMedium )
1911{
1912 // here only root storages are included, which are stored via temp file
1913 rMedium.CreateTempFileNoCopy();
1914 SetError(rMedium.GetErrorCode());
1915 if ( GetError() )
1916 return false;
1917
1918 // copy version list from "old" medium to target medium, so it can be used on saving
1919 if ( pImpl->bPreserveVersions )
1920 rMedium.TransferVersionList_Impl( *pMedium );
1921
1922 bool bRet = SaveTo_Impl( rMedium, nullptr );
1923 if ( !bRet )
1924 SetError(rMedium.GetErrorCode());
1925 return bRet;
1926}
1927
1928
1929bool SfxObjectShell::DoSaveCompleted( SfxMedium* pNewMed, bool bRegisterRecent )
1930{
1931 bool bOk = true;
1932 bool bMedChanged = pNewMed
33.1
'pNewMed' is null
&& pNewMed!=pMedium;
1933
1934 DBG_ASSERT( !pNewMed || pNewMed->GetError() == ERRCODE_NONE, "DoSaveCompleted: Medium has error!" )do { if (true && (!(!pNewMed || pNewMed->GetError(
) == ErrCode(0)))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "1934" ": "), "%s", "DoSaveCompleted: Medium has error!"
); } } while (false)
;
34
Taking false branch
35
Loop condition is false. Exiting loop
1935
1936 // delete Medium (and Storage!) after all notifications
1937 SfxMedium* pOld = pMedium;
1938 if ( bMedChanged
35.1
'bMedChanged' is false
)
36
Taking false branch
1939 {
1940 pMedium = pNewMed;
1941 pMedium->CanDisposeStorage_Impl( true );
1942 }
1943
1944 std::shared_ptr<const SfxFilter> pFilter = pMedium ? pMedium->GetFilter() : nullptr;
37
Assuming field 'pMedium' is null
38
'?' condition is false
1945 if ( pNewMed
38.1
'pNewMed' is null
)
39
Taking false branch
1946 {
1947 if( bMedChanged )
1948 {
1949 if (!pNewMed->GetName().isEmpty())
1950 bHasName = true;
1951 Broadcast( SfxHint(SfxHintId::NameChanged) );
1952 EnableSetModified(false);
1953 getDocProperties()->setGenerator(
1954 ::utl::DocInfoHelper::GetGeneratorString() );
1955 EnableSetModified();
1956 }
1957
1958 uno::Reference< embed::XStorage > xStorage;
1959 if ( !pFilter || IsPackageStorageFormat_Impl( *pMedium ) )
1960 {
1961 uno::Reference < embed::XStorage > xOld = GetStorage();
1962
1963 // when the package based medium is broken and has no storage or if the storage
1964 // is the same as the document storage the current document storage should be preserved
1965 xStorage = pMedium->GetStorage();
1966 bOk = SaveCompleted( xStorage );
1967 if ( bOk && xStorage.is() && xOld != xStorage
1968 && (!pOld || !pOld->HasStorage_Impl() || xOld != pOld->GetStorage() ) )
1969 {
1970 // old own storage was not controlled by old Medium -> dispose it
1971 try {
1972 xOld->dispose();
1973 } catch( uno::Exception& )
1974 {
1975 // the storage is disposed already
1976 // can happen during reload scenario when the medium has
1977 // disposed it during the closing
1978 // will be fixed in one of the next milestones
1979 }
1980 }
1981 }
1982 else
1983 {
1984 if (pImpl->m_bSavingForSigning && pFilter && pFilter->GetSupportsSigning())
1985 // So that pMedium->pImpl->xStream becomes a non-empty
1986 // reference, and at the end we attempt locking again in
1987 // SfxMedium::LockOrigFileOnDemand().
1988 pMedium->GetMedium_Impl();
1989
1990 if( pMedium->GetOpenMode() & StreamMode::WRITE )
1991 pMedium->GetInStream();
1992 xStorage = GetStorage();
1993 }
1994
1995 // TODO/LATER: may be this code will be replaced, but not sure
1996 // Set storage in document library containers
1997 pImpl->aBasicManager.setStorage( xStorage );
1998
1999 // Get rid of this workaround after issue i113914 is fixed
2000 try
2001 {
2002 uno::Reference< script::XStorageBasedLibraryContainer > xBasicLibraries( pImpl->xBasicLibraries, uno::UNO_QUERY_THROW );
2003 xBasicLibraries->setRootStorage( xStorage );
2004 }
2005 catch( uno::Exception& )
2006 {}
2007 try
2008 {
2009 uno::Reference< script::XStorageBasedLibraryContainer > xDialogLibraries( pImpl->xDialogLibraries, uno::UNO_QUERY_THROW );
2010 xDialogLibraries->setRootStorage( xStorage );
2011 }
2012 catch( uno::Exception& )
2013 {}
2014 }
2015 else
2016 {
2017 if( pMedium
39.1
Field 'pMedium' is null
)
40
Taking false branch
2018 {
2019 if( pFilter && !IsPackageStorageFormat_Impl( *pMedium ) && (pMedium->GetOpenMode() & StreamMode::WRITE ))
2020 {
2021 pMedium->ReOpen();
2022 bOk = SaveCompletedChildren();
2023 }
2024 else
2025 bOk = SaveCompleted( nullptr );
2026 }
2027 // either Save or ConvertTo
2028 else
2029 bOk = SaveCompleted( nullptr );
2030 }
2031
2032 if ( bOk
40.1
'bOk' is true
&& pNewMed
40.2
'pNewMed' is null
)
41
Taking false branch
2033 {
2034 if( bMedChanged )
2035 {
2036 delete pOld;
2037
2038 uno::Reference< frame::XModel > xModel = GetModel();
2039 if ( xModel.is() )
2040 {
2041 const OUString& aURL {pNewMed->GetOrigURL()};
2042 uno::Sequence< beans::PropertyValue > aMediaDescr;
2043 TransformItems( SID_OPENDOC(5000 + 501), *pNewMed->GetItemSet(), aMediaDescr );
2044 try
2045 {
2046 xModel->attachResource( aURL, aMediaDescr );
2047 }
2048 catch( uno::Exception& )
2049 {}
2050 }
2051
2052 const SfxBoolItem* pTemplateItem = SfxItemSet::GetItem<SfxBoolItem>(pMedium->GetItemSet(), SID_TEMPLATE(5000 + 1519), false);
2053 bool bTemplate = pTemplateItem && pTemplateItem->GetValue();
2054
2055 // before the title regenerated the document must lose the signatures
2056 pImpl->nDocumentSignatureState = SignatureState::NOSIGNATURES;
2057 if (!bTemplate)
2058 {
2059 pImpl->nScriptingSignatureState = pNewMed->GetCachedSignatureState_Impl();
2060 OSL_ENSURE( pImpl->nScriptingSignatureState != SignatureState::BROKEN, "The signature must not be broken at this place" )do { if (true && (!(pImpl->nScriptingSignatureState
!= SignatureState::BROKEN))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "2060" ": "), "%s", "The signature must not be broken at this place"
); } } while (false)
;
2061
2062 // TODO/LATER: in future the medium must control own signature state, not the document
2063 pNewMed->SetCachedSignatureState_Impl( SignatureState::NOSIGNATURES ); // set the default value back
2064 }
2065 else
2066 pNewMed->SetCachedSignatureState_Impl( pImpl->nScriptingSignatureState );
2067
2068 // Set new title
2069 if (!pNewMed->GetName().isEmpty() && SfxObjectCreateMode::EMBEDDED != eCreateMode)
2070 InvalidateName();
2071 SetModified(false); // reset only by set medium
2072 Broadcast( SfxHint(SfxHintId::ModeChanged) );
2073
2074 // this is the end of the saving process, it is possible that
2075 // the file was changed
2076 // between medium commit and this step (attributes change and so on)
2077 // so get the file date again
2078 if ( pNewMed->DocNeedsFileDateCheck() )
2079 pNewMed->GetInitFileDate( true );
2080 }
2081 }
2082
2083 pMedium->ClearBackup_Impl();
42
Called C++ object pointer is null
2084 pMedium->LockOrigFileOnDemand( true, false );
2085
2086 if (bRegisterRecent)
2087 AddToRecentlyUsedList();
2088
2089 return bOk;
2090}
2091
2092void SfxObjectShell::AddToRecentlyUsedList()
2093{
2094 INetURLObject aUrl( pMedium->GetOrigURL() );
2095
2096 if ( aUrl.GetProtocol() == INetProtocol::File )
2097 {
2098 std::shared_ptr<const SfxFilter> pOrgFilter = pMedium->GetFilter();
2099 Application::AddToRecentDocumentList( aUrl.GetURLNoPass( INetURLObject::DecodeMechanism::NONE ),
2100 pOrgFilter ? pOrgFilter->GetMimeType() : OUString(),
2101 pOrgFilter ? pOrgFilter->GetServiceName() : OUString() );
2102 }
2103}
2104
2105
2106bool SfxObjectShell::ConvertFrom
2107(
2108 SfxMedium& /*rMedium*/ /* <SfxMedium>, which describes the source file
2109 (for example file name, <SfxFilter>,
2110 Open-Modi and so on) */
2111)
2112
2113/* [Description]
2114
2115 This method is called for loading of documents over all filters which are
2116 not SfxFilterFlags::OWN or for which no clipboard format has been registered
2117 (thus no storage format that is used). In other words, with this method
2118 it is imported.
2119
2120 Files which are to be opened here should be opened through 'rMedium'
2121 to guarantee the right open modes. Especially if the format is retained
2122 (only possible with SfxFilterFlags::SIMULATE or SfxFilterFlags::OWN) file which must
2123 be opened STREAM_SHARE_DENYWRITE.
2124
2125 [Return value]
2126
2127 bool true
2128 The document could be loaded.
2129
2130 false
2131 The document could not be loaded, an error code
2132 received through <SvMedium::GetError()const>
2133
2134 [Example]
2135
2136 bool DocSh::ConvertFrom( SfxMedium &rMedium )
2137 {
2138 SvStreamRef xStream = rMedium.GetInStream();
2139 if( xStream.is() )
2140 {
2141 xStream->SetBufferSize(4096);
2142 *xStream >> ...;
2143
2144 // Do not call 'rMedium.CloseInStream()'! Keep File locked!
2145 return ERRCODE_NONE == rMedium.GetError();
2146 }
2147
2148 return false;
2149 }
2150
2151 [Cross-references]
2152
2153 <SfxObjectShell::ConvertTo(SfxMedium&)>
2154 <SfxFilterFlags::REGISTRATION>
2155*/
2156{
2157 return false;
2158}
2159
2160bool SfxObjectShell::ImportFrom(SfxMedium& rMedium,
2161 css::uno::Reference<css::text::XTextRange> const& xInsertPosition)
2162{
2163 const OUString aFilterName( rMedium.GetFilter()->GetFilterName() );
2164
2165 uno::Reference< lang::XMultiServiceFactory > xMan = ::comphelper::getProcessServiceFactory();
2166 uno::Reference < lang::XMultiServiceFactory > xFilterFact (
2167 xMan->createInstance( "com.sun.star.document.FilterFactory" ), uno::UNO_QUERY );
2168
2169 uno::Sequence < beans::PropertyValue > aProps;
2170 uno::Reference < container::XNameAccess > xFilters ( xFilterFact, uno::UNO_QUERY );
2171 if ( xFilters->hasByName( aFilterName ) )
2172 {
2173 xFilters->getByName( aFilterName ) >>= aProps;
2174 rMedium.GetItemSet()->Put( SfxStringItem( SID_FILTER_NAME(5000 + 530), aFilterName ) );
2175 }
2176
2177 OUString aFilterImplName;
2178 auto pProp = std::find_if(aProps.begin(), aProps.end(),
2179 [](const beans::PropertyValue& rFilterProp) { return rFilterProp.Name == "FilterService"; });
2180 if (pProp != aProps.end())
2181 pProp->Value >>= aFilterImplName;
2182
2183 uno::Reference< document::XFilter > xLoader;
2184 if ( !aFilterImplName.isEmpty() )
2185 {
2186 try
2187 {
2188 xLoader.set( xFilterFact->createInstanceWithArguments( aFilterName, uno::Sequence < uno::Any >() ), uno::UNO_QUERY );
2189 }
2190 catch(const uno::Exception&)
2191 {
2192 xLoader.clear();
2193 }
2194 }
2195 if ( xLoader.is() )
2196 {
2197 // it happens that xLoader does not support xImporter!
2198 try
2199 {
2200 uno::Reference< lang::XComponent > xComp( GetModel(), uno::UNO_QUERY_THROW );
2201 uno::Reference< document::XImporter > xImporter( xLoader, uno::UNO_QUERY_THROW );
2202 xImporter->setTargetDocument( xComp );
2203
2204 uno::Sequence < beans::PropertyValue > lDescriptor;
2205 rMedium.GetItemSet()->Put( SfxStringItem( SID_FILE_NAME(5000 + 507), rMedium.GetName() ) );
2206 TransformItems( SID_OPENDOC(5000 + 501), *rMedium.GetItemSet(), lDescriptor );
2207
2208 css::uno::Sequence < css::beans::PropertyValue > aArgs ( lDescriptor.getLength() );
2209 css::beans::PropertyValue * pNewValue = aArgs.getArray();
2210 const css::beans::PropertyValue * pOldValue = lDescriptor.getConstArray();
2211 const OUString sInputStream ( "InputStream" );
2212
2213 bool bHasInputStream = false;
2214 bool bHasBaseURL = false;
2215 sal_Int32 nEnd = lDescriptor.getLength();
2216
2217 for ( sal_Int32 i = 0; i < nEnd; i++ )
2218 {
2219 pNewValue[i] = pOldValue[i];
2220 if ( pOldValue [i].Name == sInputStream )
2221 bHasInputStream = true;
2222 else if ( pOldValue[i].Name == "DocumentBaseURL" )
2223 bHasBaseURL = true;
2224 }
2225
2226 if ( !bHasInputStream )
2227 {
2228 aArgs.realloc ( ++nEnd );
2229 aArgs[nEnd-1].Name = sInputStream;
2230 aArgs[nEnd-1].Value <<= css::uno::Reference < css::io::XInputStream > ( new utl::OSeekableInputStreamWrapper ( *rMedium.GetInStream() ) );
2231 }
2232
2233 if ( !bHasBaseURL )
2234 {
2235 aArgs.realloc ( ++nEnd );
2236 aArgs[nEnd-1].Name = "DocumentBaseURL";
2237 aArgs[nEnd-1].Value <<= rMedium.GetBaseURL();
2238 }
2239
2240 if (xInsertPosition.is()) {
2241 aArgs.realloc( ++nEnd );
2242 aArgs[nEnd-1].Name = "InsertMode";
2243 aArgs[nEnd-1].Value <<= true;
2244 aArgs.realloc( ++nEnd );
2245 aArgs[nEnd-1].Name = "TextInsertModeRange";
2246 aArgs[nEnd-1].Value <<= xInsertPosition;
2247 }
2248
2249 // #i119492# During loading, some OLE objects like chart will be set
2250 // modified flag, so needs to reset the flag to false after loading
2251 bool bRtn = xLoader->filter( aArgs );
2252 const uno::Sequence < OUString > aNames = GetEmbeddedObjectContainer().GetObjectNames();
2253 for ( const auto& rName : aNames )
2254 {
2255 uno::Reference < embed::XEmbeddedObject > xObj = GetEmbeddedObjectContainer().GetEmbeddedObject( rName );
2256 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/objstor.cxx"
":" "2256" ": "), "%s", "An empty entry in the embedded objects list!"
); } } while (false)
;
2257 if ( xObj.is() )
2258 {
2259 sal_Int32 nState = xObj->getCurrentState();
2260 if ( nState == embed::EmbedStates::LOADED || nState == embed::EmbedStates::RUNNING ) // means that the object is not active
2261 {
2262 uno::Reference< util::XModifiable > xModifiable( xObj->getComponent(), uno::UNO_QUERY );
2263 if (xModifiable.is() && xModifiable->isModified())
2264 {
2265 uno::Reference<embed::XEmbedPersist> const xPers(xObj, uno::UNO_QUERY);
2266 assert(xPers.is() && "Modified object without persistence!")(static_cast <bool> (xPers.is() && "Modified object without persistence!"
) ? void (0) : __assert_fail ("xPers.is() && \"Modified object without persistence!\""
, "/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
, 2266, __extension__ __PRETTY_FUNCTION__))
;
2267 // store it before resetting modified!
2268 xPers->storeOwn();
2269 xModifiable->setModified(false);
2270 }
2271 }
2272 }
2273 }
2274
2275 // tdf#107690 import custom document property _MarkAsFinal as SecurityOptOpenReadonly
2276 // (before this fix, LibreOffice opened read-only OOXML documents as editable,
2277 // also saved and exported _MarkAsFinal=true silently, resulting unintended read-only
2278 // warning info bar in MSO)
2279 uno::Reference< document::XDocumentPropertiesSupplier > xPropSupplier(GetModel(), uno::UNO_QUERY_THROW);
2280 uno::Reference<document::XDocumentProperties> xDocProps = xPropSupplier->getDocumentProperties() ;
2281 uno::Reference<beans::XPropertyContainer> xPropertyContainer = xDocProps->getUserDefinedProperties();
2282 if (xPropertyContainer.is())
2283 {
2284 uno::Reference<beans::XPropertySet> xPropertySet(xPropertyContainer, uno::UNO_QUERY);
2285 if (xPropertySet.is())
2286 {
2287 uno::Reference<beans::XPropertySetInfo> xPropertySetInfo = xPropertySet->getPropertySetInfo();
2288 if (xPropertySetInfo.is() && xPropertySetInfo->hasPropertyByName("_MarkAsFinal"))
2289 {
2290 if (xPropertySet->getPropertyValue("_MarkAsFinal").get<bool>())
2291 {
2292 uno::Reference< lang::XMultiServiceFactory > xFactory(GetModel(), uno::UNO_QUERY);
2293 uno::Reference< beans::XPropertySet > xSettings(xFactory->createInstance("com.sun.star.document.Settings"), uno::UNO_QUERY);
2294 xSettings->setPropertyValue("LoadReadonly", uno::makeAny(true));
2295 }
2296 xPropertyContainer->removeProperty("_MarkAsFinal");
2297 }
2298 }
2299 }
2300
2301 return bRtn;
2302 }
2303 catch (const packages::zip::ZipIOException&)
2304 {
2305 SetError(ERRCODE_IO_BROKENPACKAGEErrCode( ErrCodeArea::Io, ErrCodeClass::Format, 38 ));
2306 }
2307 catch (const lang::WrappedTargetRuntimeException& rWrapped)
2308 {
2309 io::WrongFormatException e;
2310 if (rWrapped.TargetException >>= e)
2311 {
2312 SetError(*new StringErrorInfo(ERRCODE_SFX_FORMAT_ROWCOLErrCode(ErrCodeArea::Sfx, ErrCodeClass::NONE, 57),
2313 e.Message, DialogMask::ButtonsOk | DialogMask::MessageError ));
2314 }
2315 }
2316 catch (const css::io::IOException& e)
2317 {
2318 SetError(*new StringErrorInfo(ERRCODE_SFX_FORMAT_ROWCOLErrCode(ErrCodeArea::Sfx, ErrCodeClass::NONE, 57),
2319 e.Message, DialogMask::ButtonsOk | DialogMask::MessageError ));
2320 }
2321 catch (const std::exception& e)
2322 {
2323 const char *msg = e.what();
2324 const OUString sError(msg, strlen(msg), RTL_TEXTENCODING_ASCII_US(((rtl_TextEncoding) 11)));
2325 SetError(*new StringErrorInfo(ERRCODE_SFX_DOLOADFAILEDErrCode(ErrCodeArea::Sfx, ErrCodeClass::Read, 4),
2326 sError, DialogMask::ButtonsOk | DialogMask::MessageError));
2327 }
2328 catch (...)
2329 {
2330 std::abort(); // cannot happen
2331 }
2332 }
2333
2334 return false;
2335}
2336
2337bool SfxObjectShell::ExportTo( SfxMedium& rMedium )
2338{
2339 const OUString aFilterName( rMedium.GetFilter()->GetFilterName() );
2340 uno::Reference< document::XExporter > xExporter;
2341
2342 {
2343 uno::Reference< lang::XMultiServiceFactory > xMan = ::comphelper::getProcessServiceFactory();
2344 uno::Reference < lang::XMultiServiceFactory > xFilterFact (
2345 xMan->createInstance( "com.sun.star.document.FilterFactory" ), uno::UNO_QUERY );
2346
2347 uno::Sequence < beans::PropertyValue > aProps;
2348 uno::Reference < container::XNameAccess > xFilters ( xFilterFact, uno::UNO_QUERY );
2349 if ( xFilters->hasByName( aFilterName ) )
2350 xFilters->getByName( aFilterName ) >>= aProps;
2351
2352 OUString aFilterImplName;
2353 auto pProp = std::find_if(aProps.begin(), aProps.end(),
2354 [](const beans::PropertyValue& rFilterProp) { return rFilterProp.Name == "FilterService"; });
2355 if (pProp != aProps.end())
2356 pProp->Value >>= aFilterImplName;
2357
2358 if ( !aFilterImplName.isEmpty() )
2359 {
2360 try
2361 {
2362 xExporter.set( xFilterFact->createInstanceWithArguments( aFilterName, uno::Sequence < uno::Any >() ), uno::UNO_QUERY );
2363 }
2364 catch(const uno::Exception&)
2365 {
2366 xExporter.clear();
2367 }
2368 }
2369 }
2370
2371 if ( xExporter.is() )
2372 {
2373 try{
2374 uno::Reference< lang::XComponent > xComp( GetModel(), uno::UNO_QUERY_THROW );
2375 uno::Reference< document::XFilter > xFilter( xExporter, uno::UNO_QUERY_THROW );
2376 xExporter->setSourceDocument( xComp );
2377
2378 css::uno::Sequence < css::beans::PropertyValue > aOldArgs;
2379 SfxItemSet* pItems = rMedium.GetItemSet();
2380 TransformItems( SID_SAVEASDOC(5000 + 502), *pItems, aOldArgs );
2381
2382 const css::beans::PropertyValue * pOldValue = aOldArgs.getConstArray();
2383 css::uno::Sequence < css::beans::PropertyValue > aArgs ( aOldArgs.getLength() );
2384 css::beans::PropertyValue * pNewValue = aArgs.getArray();
2385
2386 // put in the REAL file name, and copy all PropertyValues
2387 const OUString sOutputStream ( "OutputStream" );
2388 const OUString sStream ( "StreamForOutput" );
2389 bool bHasOutputStream = false;
2390 bool bHasStream = false;
2391 bool bHasBaseURL = false;
2392 bool bHasFilterName = false;
2393 bool bIsRedactMode = false;
2394 sal_Int32 nEnd = aOldArgs.getLength();
2395
2396 for ( sal_Int32 i = 0; i < nEnd; i++ )
2397 {
2398 pNewValue[i] = pOldValue[i];
2399 if ( pOldValue[i].Name == "FileName" )
2400 pNewValue[i].Value <<= rMedium.GetName();
2401 else if ( pOldValue[i].Name == sOutputStream )
2402 bHasOutputStream = true;
2403 else if ( pOldValue[i].Name == sStream )
2404 bHasStream = true;
2405 else if ( pOldValue[i].Name == "DocumentBaseURL" )
2406 bHasBaseURL = true;
2407 else if( pOldValue[i].Name == "FilterName" )
2408 bHasFilterName = true;
2409 }
2410
2411 // FIXME: Handle this inside TransformItems()
2412 if (pItems->GetItemState(SID_IS_REDACT_MODE(5000 + 1733)) == SfxItemState::SET)
2413 bIsRedactMode = true;
2414
2415 if ( !bHasOutputStream )
2416 {
2417 aArgs.realloc ( ++nEnd );
2418 aArgs[nEnd-1].Name = sOutputStream;
2419 aArgs[nEnd-1].Value <<= css::uno::Reference < css::io::XOutputStream > ( new utl::OOutputStreamWrapper ( *rMedium.GetOutStream() ) );
2420 }
2421
2422 // add stream as well, for OOX export and maybe others
2423 if ( !bHasStream )
2424 {
2425 aArgs.realloc ( ++nEnd );
2426 aArgs[nEnd-1].Name = sStream;
2427 aArgs[nEnd-1].Value <<= css::uno::Reference < css::io::XStream > ( new utl::OStreamWrapper ( *rMedium.GetOutStream() ) );
2428 }
2429
2430 if ( !bHasBaseURL )
2431 {
2432 aArgs.realloc ( ++nEnd );
2433 aArgs[nEnd-1].Name = "DocumentBaseURL";
2434 aArgs[nEnd-1].Value <<= rMedium.GetBaseURL( true );
2435 }
2436
2437 if( !bHasFilterName )
2438 {
2439 aArgs.realloc( ++nEnd );
2440 aArgs[nEnd-1].Name = "FilterName";
2441 aArgs[nEnd-1].Value <<= aFilterName;
2442 }
2443
2444 if (bIsRedactMode)
2445 {
2446 aArgs.realloc( ++nEnd );
2447 aArgs[nEnd-1].Name = "IsRedactMode";
2448 aArgs[nEnd-1].Value <<= bIsRedactMode;
2449 }
2450
2451 return xFilter->filter( aArgs );
2452 }catch(...)
2453 {}
2454 }
2455
2456 return false;
2457}
2458
2459
2460bool SfxObjectShell::ConvertTo
2461(
2462 SfxMedium& /*rMedium*/ /* <SfxMedium>, which describes the target file
2463 (for example file name, <SfxFilter>,
2464 Open-Modi and so on) */
2465)
2466
2467/* [Description]
2468
2469 This method is called for saving of documents over all filters which are
2470 not SfxFilterFlags::OWN or for which no clipboard format has been registered
2471 (thus no storage format that is used). In other words, with this method
2472 it is exported.
2473
2474 Files which are to be opened here should be opened through 'rMedium'
2475 to guarantee the right open modes. Especially if the format is retained
2476 (only possible with SfxFilterFlags::SIMULATE or SfxFilterFlags::OWN) file which must
2477 be opened STREAM_SHARE_DENYWRITE.
2478
2479 [Return value]
2480
2481 bool true
2482 The document could be saved.
2483
2484 false
2485 The document could not be saved, an error code is
2486 received by <SvMedium::GetError()const>
2487
2488
2489 [Example]
2490
2491 bool DocSh::ConvertTo( SfxMedium &rMedium )
2492 {
2493 SvStreamRef xStream = rMedium.GetOutStream();
2494 if ( xStream.is() )
2495 {
2496 xStream->SetBufferSize(4096);
2497 *xStream << ...;
2498
2499 rMedium.CloseOutStream(); // opens the InStream automatically
2500 return ERRCODE_NONE == rMedium.GetError();
2501 }
2502 return false ;
2503 }
2504
2505 [Cross-references]
2506
2507 <SfxObjectShell::ConvertFrom(SfxMedium&)>
2508 <SfxFilterFlags::REGISTRATION>
2509*/
2510
2511{
2512 return false;
2513}
2514
2515
2516bool SfxObjectShell::DoSave_Impl( const SfxItemSet* pArgs )
2517{
2518 SfxMedium* pRetrMedium = GetMedium();
2519 std::shared_ptr<const SfxFilter> pFilter = pRetrMedium->GetFilter();
2520
2521 // copy the original itemset, but remove the "version" item, because pMediumTmp
2522 // is a new medium "from scratch", so no version should be stored into it
2523 std::shared_ptr<SfxItemSet> pSet = std::make_shared<SfxAllItemSet>(*pRetrMedium->GetItemSet());
2524 pSet->ClearItem( SID_VERSION(5000 + 1583) );
2525 pSet->ClearItem( SID_DOC_BASEURL(5000 + 1700) );
2526
2527 // copy the version comment and major items for the checkin only
2528 if ( pRetrMedium->IsInCheckIn( ) )
2529 {
2530 const SfxPoolItem* pMajor = pArgs->GetItem( SID_DOCINFO_MAJOR(5000 + 594) );
2531 if ( pMajor )
2532 pSet->Put( *pMajor );
2533
2534 const SfxPoolItem* pComments = pArgs->GetItem( SID_DOCINFO_COMMENTS(5000 + 592) );
2535 if ( pComments )
2536 pSet->Put( *pComments );
2537 }
2538
2539 // create a medium as a copy; this medium is only for writing, because it
2540 // uses the same name as the original one writing is done through a copy,
2541 // that will be transferred to the target (of course after calling HandsOff)
2542 SfxMedium* pMediumTmp = new SfxMedium( pRetrMedium->GetName(), pRetrMedium->GetOpenMode(), pFilter, std::move(pSet) );
2543 pMediumTmp->SetInCheckIn( pRetrMedium->IsInCheckIn( ) );
2544 pMediumTmp->SetLongName( pRetrMedium->GetLongName() );
2545 if ( pMediumTmp->GetErrorCode() != ERRCODE_NONEErrCode(0) )
2546 {
2547 SetError(pMediumTmp->GetError());
2548 delete pMediumTmp;
2549 return false;
2550 }
2551
2552 // copy version list from "old" medium to target medium, so it can be used on saving
2553 pMediumTmp->TransferVersionList_Impl( *pRetrMedium );
2554
2555 // an interaction handler here can acquire only in case of GUI Saving
2556 // and should be removed after the saving is done
2557 css::uno::Reference< XInteractionHandler > xInteract;
2558 const SfxUnoAnyItem* pxInteractionItem = SfxItemSet::GetItem<SfxUnoAnyItem>(pArgs, SID_INTERACTIONHANDLER(5000 + 1675), false);
2559 if ( pxInteractionItem && ( pxInteractionItem->GetValue() >>= xInteract ) && xInteract.is() )
2560 pMediumTmp->GetItemSet()->Put( SfxUnoAnyItem( SID_INTERACTIONHANDLER(5000 + 1675), makeAny( xInteract ) ) );
2561
2562 const SfxBoolItem* pNoFileSync = pArgs->GetItem<SfxBoolItem>(SID_NO_FILE_SYNC(5000 + 1729), false);
2563 if (pNoFileSync && pNoFileSync->GetValue())
2564 pMediumTmp->DisableFileSync(true);
2565
2566 bool bSaved = false;
2567 if( !GetError() && SaveTo_Impl( *pMediumTmp, pArgs ) )
2568 {
2569 bSaved = true;
2570
2571 if( pMediumTmp->GetItemSet() )
2572 {
2573 pMediumTmp->GetItemSet()->ClearItem( SID_INTERACTIONHANDLER(5000 + 1675) );
2574 pMediumTmp->GetItemSet()->ClearItem( SID_PROGRESS_STATUSBAR_CONTROL(5000 + 1597) );
2575 }
2576
2577 SetError(pMediumTmp->GetErrorCode());
2578
2579 bool bOpen = DoSaveCompleted( pMediumTmp );
2580
2581 DBG_ASSERT(bOpen,"Error handling for DoSaveCompleted not implemented")do { if (true && (!(bOpen))) { sal_detail_logFormat((
SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "2581" ": "), "%s", "Error handling for DoSaveCompleted not implemented"
); } } while (false)
;
2582 }
2583 else
2584 {
2585 // transfer error code from medium to objectshell
2586 SetError(pMediumTmp->GetError());
2587
2588 // reconnect to object storage
2589 DoSaveCompleted();
2590
2591 if( pRetrMedium->GetItemSet() )
2592 {
2593 pRetrMedium->GetItemSet()->ClearItem( SID_INTERACTIONHANDLER(5000 + 1675) );
2594 pRetrMedium->GetItemSet()->ClearItem( SID_PROGRESS_STATUSBAR_CONTROL(5000 + 1597) );
2595 }
2596
2597 delete pMediumTmp;
2598 }
2599
2600 SetModified( !bSaved );
2601 return bSaved;
2602}
2603
2604
2605bool SfxObjectShell::Save_Impl( const SfxItemSet* pSet )
2606{
2607 if ( IsReadOnly() )
2608 {
2609 SetError(ERRCODE_SFX_DOCUMENTREADONLYErrCode(ErrCodeArea::Sfx, ErrCodeClass::Write, 12));
2610 return false;
2611 }
2612
2613 pImpl->bIsSaving = true;
2614 bool bSaved = false;
2615 const SfxStringItem* pSalvageItem = SfxItemSet::GetItem<SfxStringItem>(GetMedium()->GetItemSet(), SID_DOC_SALVAGE(5000 + 531), false);
2616 if ( pSalvageItem )
2617 {
2618 const SfxStringItem* pFilterItem = SfxItemSet::GetItem<SfxStringItem>(GetMedium()->GetItemSet(), SID_FILTER_NAME(5000 + 530), false);
2619 std::shared_ptr<const SfxFilter> pFilter;
2620 if ( pFilterItem )
2621 pFilter = SfxFilterMatcher( GetFactory().GetFactoryName() ).GetFilter4FilterName( OUString() );
2622
2623 SfxMedium *pMed = new SfxMedium(
2624 pSalvageItem->GetValue(), StreamMode::READWRITE | StreamMode::SHARE_DENYWRITE | StreamMode::TRUNC, pFilter );
2625
2626 const SfxStringItem* pPasswordItem = SfxItemSet::GetItem<SfxStringItem>(GetMedium()->GetItemSet(), SID_PASSWORD(((((10000 + 1499) + 1) + 499) + 1) + 36), false);
2627 if ( pPasswordItem )
2628 pMed->GetItemSet()->Put( *pPasswordItem );
2629
2630 bSaved = DoSaveAs( *pMed );
2631 if ( bSaved )
2632 bSaved = DoSaveCompleted( pMed );
2633 else
2634 delete pMed;
2635 }
2636 else
2637 bSaved = DoSave_Impl( pSet );
2638 return bSaved;
2639}
2640
2641bool SfxObjectShell::CommonSaveAs_Impl(const INetURLObject& aURL, const OUString& aFilterName,
2642 SfxItemSet& rItemSet,
2643 const uno::Sequence<beans::PropertyValue>& rArgs)
2644{
2645 if( aURL.HasError() )
1
Taking false branch
2646 {
2647 SetError(ERRCODE_IO_INVALIDPARAMETERErrCode( ErrCodeArea::Io, ErrCodeClass::Parameter, 26 ));
2648 return false;
2649 }
2650
2651 if ( aURL != INetURLObject( OUString( "private:stream" ) ) )
2
Taking false branch
2652 {
2653 // Is there already a Document with this name?
2654 SfxObjectShell* pDoc = nullptr;
2655 for ( SfxObjectShell* pTmp = SfxObjectShell::GetFirst();
2656 pTmp && !pDoc;
2657 pTmp = SfxObjectShell::GetNext(*pTmp) )
2658 {
2659 if( ( pTmp != this ) && pTmp->GetMedium() )
2660 {
2661 INetURLObject aCompare( pTmp->GetMedium()->GetName() );
2662 if ( aCompare == aURL )
2663 pDoc = pTmp;
2664 }
2665 }
2666 if ( pDoc )
2667 {
2668 // Then error message: "already opened"
2669 SetError(ERRCODE_SFX_ALREADYOPENErrCode(ErrCodeArea::Sfx, ErrCodeClass::AlreadyExists, 10));
2670 return false;
2671 }
2672 }
2673
2674 DBG_ASSERT( aURL.GetProtocol() != INetProtocol::NotValid, "Illegal URL!" )do { if (true && (!(aURL.GetProtocol() != INetProtocol
::NotValid))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "2674" ": "), "%s", "Illegal URL!"); } } while (false)
;
3
Taking false branch
4
Loop condition is false. Exiting loop
2675 DBG_ASSERT( rItemSet.Count() != 0, "Incorrect Parameter")do { if (true && (!(rItemSet.Count() != 0))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "2675" ": "), "%s", "Incorrect Parameter"); } } while (false
)
;
5
Assuming the condition is false
6
Taking true branch
7
Loop condition is false. Exiting loop
2676
2677 const SfxBoolItem* pSaveToItem = rItemSet.GetItem<SfxBoolItem>(SID_SAVETOTypedWhichId<SfxBoolItem>(5000 + 1546), false);
2678 bool bSaveTo = pSaveToItem
7.1
'pSaveToItem' is non-null
&& pSaveToItem->GetValue();
2679
2680 std::shared_ptr<const SfxFilter> pFilter = GetFactory().GetFilterContainer()->GetFilter4FilterName( aFilterName );
2681 if ( !pFilter
2682 || !pFilter->CanExport()
2683 || (!bSaveTo && !pFilter->CanImport()) )
8
Assuming 'bSaveTo' is true
2684 {
2685 SetError(ERRCODE_IO_INVALIDPARAMETERErrCode( ErrCodeArea::Io, ErrCodeClass::Parameter, 26 ));
2686 return false;
2687 }
2688
2689
2690 const SfxBoolItem* pCopyStreamItem = rItemSet.GetItem<SfxBoolItem>(SID_COPY_STREAM_IF_POSSIBLE(5000 + 1706), false);
2691 if ( bSaveTo
8.1
'bSaveTo' is true
&& pCopyStreamItem
8.2
'pCopyStreamItem' is null
&& pCopyStreamItem->GetValue() && !IsModified() )
2692 {
2693 if (pMedium->TryDirectTransfer(aURL.GetMainURL(INetURLObject::DecodeMechanism::NONE), rItemSet))
2694 return true;
2695 }
2696 rItemSet.ClearItem( SID_COPY_STREAM_IF_POSSIBLE(5000 + 1706) );
2697
2698 SfxMedium *pActMed = GetMedium();
2699 const INetURLObject aActName(pActMed->GetName());
2700
2701 bool bWasReadonly = IsReadOnly();
2702
2703 if ( aURL == aActName && aURL != INetURLObject( OUString("private:stream") )
9
Assuming the condition is false
10
Taking false branch
2704 && IsReadOnly() )
2705 {
2706 SetError(ERRCODE_SFX_DOCUMENTREADONLYErrCode(ErrCodeArea::Sfx, ErrCodeClass::Write, 12));
2707 return false;
2708 }
2709
2710 if (SfxItemState::SET != rItemSet.GetItemState(SID_UNPACK(5000 + 1662)) && officecfg::Office::Common::Save::Document::Unpacked::get())
11
Assuming the condition is false
12
Taking false branch
2711 rItemSet.Put(SfxBoolItem(SID_UNPACK(5000 + 1662), false));
2712
2713 OUString aTempFileURL;
2714 if ( IsDocShared() )
13
Assuming the condition is false
14
Taking false branch
2715 aTempFileURL = pMedium->GetURLObject().GetMainURL( INetURLObject::DecodeMechanism::NONE );
2716
2717 if (PreDoSaveAs_Impl(aURL.GetMainURL(INetURLObject::DecodeMechanism::NONE), aFilterName,
15
Calling 'SfxObjectShell::PreDoSaveAs_Impl'
2718 rItemSet, rArgs))
2719 {
2720 // Update Data on media
2721 SfxItemSet *pSet = GetMedium()->GetItemSet();
2722 pSet->ClearItem( SID_INTERACTIONHANDLER(5000 + 1675) );
2723 pSet->ClearItem( SID_PROGRESS_STATUSBAR_CONTROL(5000 + 1597) );
2724 pSet->ClearItem( SID_STANDARD_DIR(5000 + 450) );
2725 pSet->ClearItem( SID_PATH(5000 + 308) );
2726
2727 if ( !bSaveTo )
2728 {
2729 pSet->ClearItem( SID_REFERER(5000 + 654) );
2730 pSet->ClearItem( SID_POSTDATA(5000 + 1536) );
2731 pSet->ClearItem( SID_TEMPLATE(5000 + 1519) );
2732 pSet->ClearItem( SID_DOC_READONLY(5000 + 590) );
2733 pSet->ClearItem( SID_CONTENTTYPE(5000 + 1541) );
2734 pSet->ClearItem( SID_CHARSET(5000 + 1633) );
2735 pSet->ClearItem( SID_FILTER_NAME(5000 + 530) );
2736 pSet->ClearItem( SID_OPTIONS(5000 + 940) );
2737 pSet->ClearItem( SID_VERSION(5000 + 1583) );
2738 pSet->ClearItem( SID_EDITDOC(5000 + 1312) );
2739 pSet->ClearItem( SID_OVERWRITE(5000 + 1634) );
2740 pSet->ClearItem( SID_DEFAULTFILEPATH(5000 + 571) );
2741 pSet->ClearItem( SID_DEFAULTFILENAME(5000 + 1717) );
2742
2743 const SfxStringItem* pFilterItem = rItemSet.GetItem<SfxStringItem>(SID_FILTER_NAME(5000 + 530), false);
2744 if ( pFilterItem )
2745 pSet->Put( *pFilterItem );
2746
2747 const SfxStringItem* pOptionsItem = rItemSet.GetItem<SfxStringItem>(SID_OPTIONS(5000 + 940), false);
2748 if ( pOptionsItem )
2749 pSet->Put( *pOptionsItem );
2750
2751 const SfxStringItem* pFilterOptItem = rItemSet.GetItem<SfxStringItem>(SID_FILE_FILTEROPTIONS(5000 + 527), false);
2752 if ( pFilterOptItem )
2753 pSet->Put( *pFilterOptItem );
2754
2755#if HAVE_FEATURE_MULTIUSER_ENVIRONMENT1
2756 if ( IsDocShared() && !aTempFileURL.isEmpty() )
2757 {
2758 // this is a shared document that has to be disconnected from the old location
2759 FreeSharedFile( aTempFileURL );
2760
2761 if ( pFilter->IsOwnFormat()
2762 && pFilter->UsesStorage()
2763 && pFilter->GetVersion() >= SOFFICE_FILEFORMAT_606200 )
2764 {
2765 // the target format is the own format
2766 // the target document must be shared
2767 SwitchToShared( true, false );
2768 }
2769 }
2770#endif
2771 }
2772
2773 if ( bWasReadonly && !bSaveTo )
2774 Broadcast( SfxHint(SfxHintId::ModeChanged) );
2775
2776 return true;
2777 }
2778 else
2779 return false;
2780}
2781
2782bool SfxObjectShell::PreDoSaveAs_Impl(const OUString& rFileName, const OUString& aFilterName,
2783 SfxItemSet const& rItemSet,
2784 const uno::Sequence<beans::PropertyValue>& rArgs)
2785{
2786 // copy all items stored in the itemset of the current medium
2787 std::shared_ptr<SfxAllItemSet> xMergedParams = std::make_shared<SfxAllItemSet>( *pMedium->GetItemSet() );
2788
2789 // in "SaveAs" title and password will be cleared ( maybe the new itemset contains new values, otherwise they will be empty )
2790 // #i119366# - As the SID_ENCRYPTIONDATA and SID_PASSWORD are using for setting password together, we need to clear them both.
2791 // Also, ( maybe the new itemset contains new values, otherwise they will be empty )
2792 if (xMergedParams->HasItem( SID_PASSWORD(((((10000 + 1499) + 1) + 499) + 1) + 36) ))
16
Assuming the condition is false
17
Taking false branch
2793 {
2794 xMergedParams->ClearItem( SID_PASSWORD(((((10000 + 1499) + 1) + 499) + 1) + 36) );
2795 xMergedParams->ClearItem( SID_ENCRYPTIONDATA(5000 + 1722) );
2796 }
2797 xMergedParams->ClearItem( SID_DOCINFO_TITLE(5000 + 557) );
2798
2799 xMergedParams->ClearItem( SID_INPUTSTREAM(5000 + 1648) );
2800 xMergedParams->ClearItem( SID_STREAM(5000 + 1699) );
2801 xMergedParams->ClearItem( SID_CONTENT(5000 + 1679) );
2802 xMergedParams->ClearItem( SID_DOC_READONLY(5000 + 590) );
2803 xMergedParams->ClearItem( SID_DOC_BASEURL(5000 + 1700) );
2804
2805 xMergedParams->ClearItem( SID_REPAIRPACKAGE(5000 + 1683) );
2806
2807 // "SaveAs" will never store any version information - it's a complete new file !
2808 xMergedParams->ClearItem( SID_VERSION(5000 + 1583) );
2809
2810 // merge the new parameters into the copy
2811 // all values present in both itemsets will be overwritten by the new parameters
2812 xMergedParams->Put(rItemSet);
2813
2814 SAL_WARN_IF( xMergedParams->GetItemState( SID_DOC_SALVAGE) >= SfxItemState::SET,do { if (true && (xMergedParams->GetItemState( (5000
+ 531)) >= SfxItemState::SET)) { switch (sal_detail_log_report
(::SAL_DETAIL_LOG_LEVEL_WARN, "sfx.doc")) { case SAL_DETAIL_LOG_ACTION_IGNORE
: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "Salvage item present in Itemset, check the parameters!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "2815" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Salvage item present in Itemset, check the parameters!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Salvage item present in Itemset, check the parameters!"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "2815" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Salvage item present in Itemset, check the parameters!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "2815" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Salvage item present in Itemset, check the parameters!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Salvage item present in Itemset, check the parameters!"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "2815" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
18
Assuming the condition is false
19
Taking false branch
20
Loop condition is false. Exiting loop
2815 "sfx.doc","Salvage item present in Itemset, check the parameters!")do { if (true && (xMergedParams->GetItemState( (5000
+ 531)) >= SfxItemState::SET)) { switch (sal_detail_log_report
(::SAL_DETAIL_LOG_LEVEL_WARN, "sfx.doc")) { case SAL_DETAIL_LOG_ACTION_IGNORE
: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "Salvage item present in Itemset, check the parameters!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "2815" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Salvage item present in Itemset, check the parameters!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Salvage item present in Itemset, check the parameters!"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "2815" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Salvage item present in Itemset, check the parameters!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "2815" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Salvage item present in Itemset, check the parameters!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Salvage item present in Itemset, check the parameters!"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "2815" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
2816
2817 // should be unnecessary - too hot to handle!
2818 xMergedParams->ClearItem( SID_DOC_SALVAGE(5000 + 531) );
2819
2820 // create a medium for the target URL
2821 SfxMedium *pNewFile = new SfxMedium( rFileName, StreamMode::READWRITE | StreamMode::SHARE_DENYWRITE | StreamMode::TRUNC, nullptr, xMergedParams );
2822 pNewFile->SetArgs(rArgs);
2823
2824 const SfxBoolItem* pNoFileSync = xMergedParams->GetItem<SfxBoolItem>(SID_NO_FILE_SYNC(5000 + 1729), false);
2825 if (pNoFileSync
20.1
'pNoFileSync' is null
&& pNoFileSync->GetValue())
2826 pNewFile->DisableFileSync(true);
2827
2828 bool bUseThumbnailSave = IsUseThumbnailSave();
2829 comphelper::ScopeGuard aThumbnailGuard(
2830 [this, bUseThumbnailSave] { this->SetUseThumbnailSave(bUseThumbnailSave); });
2831 const SfxBoolItem* pNoThumbnail = xMergedParams->GetItem<SfxBoolItem>(SID_NO_THUMBNAIL(5000 + 1730), false);
2832 if (pNoThumbnail
20.2
'pNoThumbnail' is non-null
)
21
Taking true branch
2833 // Thumbnail generation should be avoided just for this save.
2834 SetUseThumbnailSave(!pNoThumbnail->GetValue());
22
Assuming the condition is false
2835 else
2836 aThumbnailGuard.dismiss();
2837
2838 // set filter; if no filter is given, take the default filter of the factory
2839 if ( !aFilterName.isEmpty() )
23
Taking false branch
2840 {
2841 pNewFile->SetFilter( GetFactory().GetFilterContainer()->GetFilter4FilterName( aFilterName ) );
2842
2843 if(aFilterName == "writer_pdf_Export" && pNewFile->GetItemSet())
2844 {
2845 uno::Sequence< beans::PropertyValue > aSaveToFilterDataOptions(2);
2846 bool bRet = false;
2847
2848 for(int i = 0 ; i< rArgs.getLength() ; ++i)
2849 {
2850 auto aProp = rArgs[i];
2851 if(aProp.Name == "EncryptFile")
2852 {
2853 aSaveToFilterDataOptions[0].Name = aProp.Name;
2854 aSaveToFilterDataOptions[0].Value = aProp.Value;
2855 bRet = true;
2856 }
2857 if(aProp.Name == "DocumentOpenPassword")
2858 {
2859 aSaveToFilterDataOptions[1].Name = aProp.Name;
2860 aSaveToFilterDataOptions[1].Value = aProp.Value;
2861 bRet = true;
2862 }
2863 }
2864
2865 if( bRet )
2866 pNewFile->GetItemSet()->Put( SfxUnoAnyItem(SID_FILTER_DATA(5000 + 1375), uno::makeAny(aSaveToFilterDataOptions)));
2867 }
2868 }
2869 else
2870 pNewFile->SetFilter( GetFactory().GetFilterContainer()->GetAnyFilter( SfxFilterFlags::IMPORT | SfxFilterFlags::EXPORT ) );
2871
2872 if ( pNewFile->GetErrorCode() != ERRCODE_NONEErrCode(0) )
24
Taking false branch
2873 {
2874 // creating temporary file failed ( f.e. floppy disk not inserted! )
2875 SetError(pNewFile->GetError());
2876 delete pNewFile;
2877 return false;
2878 }
2879
2880 if (comphelper::LibreOfficeKit::isActive())
25
Assuming the condition is false
26
Taking false branch
2881 {
2882 // Before saving, commit in-flight changes.
2883 TerminateEditing();
2884 }
2885
2886 // check if a "SaveTo" is wanted, no "SaveAs"
2887 const SfxBoolItem* pSaveToItem = xMergedParams->GetItem<SfxBoolItem>(SID_SAVETOTypedWhichId<SfxBoolItem>(5000 + 1546), false);
2888 bool bCopyTo = GetCreateMode() == SfxObjectCreateMode::EMBEDDED || (pSaveToItem
27.1
'pSaveToItem' is null
&& pSaveToItem->GetValue());
27
Assuming the condition is false
2889
2890 // distinguish between "Save" and "SaveAs"
2891 pImpl->bIsSaving = false;
2892
2893 // copy version list from "old" medium to target medium, so it can be used on saving
2894 if ( pImpl->bPreserveVersions )
28
Assuming field 'bPreserveVersions' is false
29
Taking false branch
2895 pNewFile->TransferVersionList_Impl( *pMedium );
2896
2897 // Save the document ( first as temporary file, then transfer to the target URL by committing the medium )
2898 bool bOk = false;
2899 if ( !pNewFile->GetErrorCode() && SaveTo_Impl( *pNewFile, nullptr ) )
30
Assuming the condition is false
31
Taking false branch
2900 {
2901 // transfer a possible error from the medium to the document
2902 SetError(pNewFile->GetErrorCode());
2903
2904 // notify the document that saving was done successfully
2905 if ( !bCopyTo )
2906 {
2907 bOk = DoSaveCompleted( pNewFile );
2908 }
2909 else
2910 bOk = DoSaveCompleted();
2911
2912 if( bOk )
2913 {
2914 if( !bCopyTo )
2915 SetModified( false );
2916 }
2917 else
2918 {
2919 // TODO/LATER: the code below must be dead since the storage commit makes all the stuff
2920 // and the DoSaveCompleted call should not be able to fail in general
2921
2922 DBG_ASSERT( !bCopyTo, "Error while reconnecting to medium, can't be handled!")do { if (true && (!(!bCopyTo))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "2922" ": "), "%s", "Error while reconnecting to medium, can't be handled!"
); } } while (false)
;
2923 SetError(pNewFile->GetErrorCode());
2924
2925 if ( !bCopyTo )
2926 {
2927 // reconnect to the old medium
2928 bool bRet = DoSaveCompleted( pMedium );
2929 DBG_ASSERT( bRet, "Error in DoSaveCompleted, can't be handled!")do { if (true && (!(bRet))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "2929" ": "), "%s", "Error in DoSaveCompleted, can't be handled!"
); } } while (false)
;
2930 }
2931
2932 // TODO/LATER: disconnect the new file from the storage for the case when pure saving is done
2933 // if storing has corrupted the file, probably it must be restored either here or
2934 // by the storage
2935 delete pNewFile;
2936 pNewFile = nullptr;
2937 }
2938 }
2939 else
2940 {
2941 SetError(pNewFile->GetErrorCode());
32
Value assigned to field 'pMedium'
2942
2943 // reconnect to the old storage
2944 DoSaveCompleted();
33
Calling 'SfxObjectShell::DoSaveCompleted'
2945
2946 delete pNewFile;
2947 pNewFile = nullptr;
2948 }
2949
2950 if ( bCopyTo )
2951 delete pNewFile;
2952 else if( !bOk )
2953 SetModified();
2954
2955 return bOk;
2956}
2957
2958
2959bool SfxObjectShell::LoadFrom( SfxMedium& /*rMedium*/ )
2960{
2961 SAL_WARN( "sfx.doc", "Base implementation, must not be called in general!" )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "sfx.doc")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "Base implementation, must not be called in general!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "2961" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Base implementation, must not be called in general!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Base implementation, must not be called in general!"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "2961" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Base implementation, must not be called in general!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "2961" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Base implementation, must not be called in general!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Base implementation, must not be called in general!"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "2961" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
2962 return true;
2963}
2964
2965
2966bool SfxObjectShell::CanReload_Impl()
2967
2968/* [Description]
2969
2970 Internal method for determining whether a reload of the document
2971 (as RevertToSaved or last known version) is possible.
2972*/
2973
2974{
2975 return pMedium && HasName() && !IsInModalMode() && !pImpl->bForbidReload;
2976}
2977
2978
2979HiddenInformation SfxObjectShell::GetHiddenInformationState( HiddenInformation nStates )
2980{
2981 HiddenInformation nState = HiddenInformation::NONE;
2982 if ( nStates & HiddenInformation::DOCUMENTVERSIONS )
2983 {
2984 if ( GetMedium()->GetVersionList().hasElements() )
2985 nState |= HiddenInformation::DOCUMENTVERSIONS;
2986 }
2987
2988 return nState;
2989}
2990
2991sal_Int16 SfxObjectShell::QueryHiddenInformation(HiddenWarningFact eFact, weld::Window* pParent)
2992{
2993 sal_Int16 nRet = RET_YES;
2994 const char* pResId = nullptr;
2995 SvtSecurityOptions::EOption eOption = SvtSecurityOptions::EOption();
2996
2997 switch ( eFact )
2998 {
2999 case HiddenWarningFact::WhenSaving :
3000 {
3001 pResId = STR_HIDDENINFO_CONTINUE_SAVINGreinterpret_cast<char const *>("STR_HIDDENINFO_CONTINUE_SAVING"
"\004" u8"Do you want to continue saving the document?")
;
3002 eOption = SvtSecurityOptions::EOption::DocWarnSaveOrSend;
3003 break;
3004 }
3005 case HiddenWarningFact::WhenPrinting :
3006 {
3007 pResId = STR_HIDDENINFO_CONTINUE_PRINTINGreinterpret_cast<char const *>("STR_HIDDENINFO_CONTINUE_PRINTING"
"\004" u8"Do you want to continue printing the document?")
;
3008 eOption = SvtSecurityOptions::EOption::DocWarnPrint;
3009 break;
3010 }
3011 case HiddenWarningFact::WhenSigning :
3012 {
3013 pResId = STR_HIDDENINFO_CONTINUE_SIGNINGreinterpret_cast<char const *>("STR_HIDDENINFO_CONTINUE_SIGNING"
"\004" u8"Do you want to continue signing the document?")
;
3014 eOption = SvtSecurityOptions::EOption::DocWarnSigning;
3015 break;
3016 }
3017 case HiddenWarningFact::WhenCreatingPDF :
3018 {
3019 pResId = STR_HIDDENINFO_CONTINUE_CREATEPDFreinterpret_cast<char const *>("STR_HIDDENINFO_CONTINUE_CREATEPDF"
"\004" u8"Do you want to continue creating a PDF file?")
;
3020 eOption = SvtSecurityOptions::EOption::DocWarnCreatePdf;
3021 break;
3022 }
3023 default:
3024 assert(false)(static_cast <bool> (false) ? void (0) : __assert_fail (
"false", "/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
, 3024, __extension__ __PRETTY_FUNCTION__))
; // this cannot happen
3025 }
3026
3027 if ( SvtSecurityOptions().IsOptionSet( eOption ) )
3028 {
3029 OUString sMessage( SfxResId(STR_HIDDENINFO_CONTAINSreinterpret_cast<char const *>("STR_HIDDENINFO_CONTAINS"
"\004" u8"This document contains:\n\n")
) );
3030 HiddenInformation nWantedStates = HiddenInformation::RECORDEDCHANGES | HiddenInformation::NOTES;
3031 if ( eFact != HiddenWarningFact::WhenPrinting )
3032 nWantedStates |= HiddenInformation::DOCUMENTVERSIONS;
3033 HiddenInformation nStates = GetHiddenInformationState( nWantedStates );
3034 bool bWarning = false;
3035
3036 if ( nStates & HiddenInformation::RECORDEDCHANGES )
3037 {
3038 sMessage += SfxResId(STR_HIDDENINFO_RECORDCHANGESreinterpret_cast<char const *>("STR_HIDDENINFO_RECORDCHANGES"
"\004" u8"Recorded changes")
) + "\n";
3039 bWarning = true;
3040 }
3041 if ( nStates & HiddenInformation::NOTES )
3042 {
3043 sMessage += SfxResId(STR_HIDDENINFO_NOTESreinterpret_cast<char const *>("STR_HIDDENINFO_NOTES" "\004"
u8"Notes")
) + "\n";
3044 bWarning = true;
3045 }
3046 if ( nStates & HiddenInformation::DOCUMENTVERSIONS )
3047 {
3048 sMessage += SfxResId(STR_HIDDENINFO_DOCVERSIONSreinterpret_cast<char const *>("STR_HIDDENINFO_DOCVERSIONS"
"\004" u8"Document versions")
) + "\n";
3049 bWarning = true;
3050 }
3051
3052 if ( bWarning )
3053 {
3054 sMessage += "\n" + SfxResId(pResId);
3055 std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(pParent,
3056 VclMessageType::Warning, VclButtonsType::YesNo, sMessage));
3057 xWarn->set_default_response(RET_NO);
3058 nRet = xWarn->run();
3059 }
3060 }
3061
3062 return nRet;
3063}
3064
3065bool SfxObjectShell::IsSecurityOptOpenReadOnly() const
3066{
3067 return IsLoadReadonly();
3068}
3069
3070void SfxObjectShell::SetSecurityOptOpenReadOnly( bool _b )
3071{
3072 SetLoadReadonly( _b );
3073}
3074
3075bool SfxObjectShell::LoadOwnFormat( SfxMedium& rMedium )
3076{
3077 SAL_INFO( "sfx.doc", "loading \" " << rMedium.GetName() << "\"" )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() << "loading \" " <<
rMedium.GetName() << "\"") == 1) { ::sal_detail_log( (
::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "3077" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "loading \" " << rMedium.GetName
() << "\""), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "loading \" " << rMedium.GetName
() << "\""; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "3077" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "loading \" " << rMedium.GetName() <<
"\"") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "3077" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "loading \" " << rMedium.GetName
() << "\""), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "loading \" " << rMedium.GetName
() << "\""; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "3077" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
3078
3079 uno::Reference< embed::XStorage > xStorage = rMedium.GetStorage();
3080 if ( xStorage.is() )
3081 {
3082 // Password
3083 const SfxStringItem* pPasswdItem = SfxItemSet::GetItem<SfxStringItem>(rMedium.GetItemSet(), SID_PASSWORD(((((10000 + 1499) + 1) + 499) + 1) + 36), false);
3084 if ( pPasswdItem || ERRCODE_IO_ABORTErrCode( ErrCodeArea::Io, ErrCodeClass::Abort, 27 ) != CheckPasswd_Impl( this, pMedium ) )
3085 {
3086 uno::Sequence< beans::NamedValue > aEncryptionData;
3087 if ( GetEncryptionData_Impl(pMedium->GetItemSet(), aEncryptionData) )
3088 {
3089 try
3090 {
3091 // the following code must throw an exception in case of failure
3092 ::comphelper::OStorageHelper::SetCommonStorageEncryptionData( xStorage, aEncryptionData );
3093 }
3094 catch( uno::Exception& )
3095 {
3096 // TODO/LATER: handle the error code
3097 }
3098 }
3099
3100 // load document
3101 return Load( rMedium );
3102 }
3103 return false;
3104 }
3105 else
3106 return false;
3107}
3108
3109bool SfxObjectShell::SaveAsOwnFormat( SfxMedium& rMedium )
3110{
3111 uno::Reference< embed::XStorage > xStorage = rMedium.GetStorage();
3112 if( xStorage.is() )
3113 {
3114 sal_Int32 nVersion = rMedium.GetFilter()->GetVersion();
3115
3116 // OASIS templates have own mediatypes (SO7 also actually, but it is too late to use them here)
3117 const bool bTemplate = rMedium.GetFilter()->IsOwnTemplateFormat()
3118 && nVersion > SOFFICE_FILEFORMAT_606200;
3119
3120 SetupStorage( xStorage, nVersion, bTemplate );
3121#if HAVE_FEATURE_SCRIPTING1
3122 if ( HasBasic() )
3123 {
3124 // Initialize Basic
3125 GetBasicManager();
3126
3127 // Save dialog/script container
3128 pImpl->aBasicManager.storeLibrariesToStorage( xStorage );
3129 }
3130#endif
3131 return SaveAs( rMedium );
3132 }
3133 else return false;
3134}
3135
3136uno::Reference< embed::XStorage > const & SfxObjectShell::GetStorage()
3137{
3138 if ( !pImpl->m_xDocStorage.is() )
3139 {
3140 OSL_ENSURE( pImpl->m_bCreateTempStor, "The storage must exist already!" )do { if (true && (!(pImpl->m_bCreateTempStor))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "3140" ": "), "%s", "The storage must exist already!"); }
} while (false)
;
3141 try {
3142 // no notification is required the storage is set the first time
3143 pImpl->m_xDocStorage = ::comphelper::OStorageHelper::GetTemporaryStorage();
3144 OSL_ENSURE( pImpl->m_xDocStorage.is(), "The method must either return storage or throw exception!" )do { if (true && (!(pImpl->m_xDocStorage.is()))) {
sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "3144" ": "), "%s", "The method must either return storage or throw exception!"
); } } while (false)
;
3145
3146 SetupStorage( pImpl->m_xDocStorage, SOFFICE_FILEFORMAT_CURRENT6800, false );
3147 pImpl->m_bCreateTempStor = false;
3148 if (!utl::ConfigManager::IsFuzzing())
3149 SfxGetpApp()->NotifyEvent( SfxEventHint( SfxEventHintId::StorageChanged, GlobalEventConfig::GetEventName(GlobalEventId::STORAGECHANGED), this ) );
3150 }
3151 catch( uno::Exception& )
3152 {
3153 // TODO/LATER: error handling?
3154 TOOLS_WARN_EXCEPTION("sfx.doc", "SfxObjectShell::GetStorage")do { css::uno::Any tools_warn_exception( DbgGetCaughtException
() ); do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "sfx.doc")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "SfxObjectShell::GetStorage"
<< " " << exceptionToString(tools_warn_exception
)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), (
"sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "3154" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "SfxObjectShell::GetStorage" <<
" " << exceptionToString(tools_warn_exception)), 0); }
else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "SfxObjectShell::GetStorage" << " " << exceptionToString
(tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "3154" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "SfxObjectShell::GetStorage" << " " <<
exceptionToString(tools_warn_exception)) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "3154" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "SfxObjectShell::GetStorage" <<
" " << exceptionToString(tools_warn_exception)), 0); }
else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "SfxObjectShell::GetStorage" << " " << exceptionToString
(tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "3154" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false); } while (false)
;
3155 }
3156 }
3157
3158 OSL_ENSURE( pImpl->m_xDocStorage.is(), "The document storage must be created!" )do { if (true && (!(pImpl->m_xDocStorage.is()))) {
sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "3158" ": "), "%s", "The document storage must be created!"
); } } while (false)
;
3159 return pImpl->m_xDocStorage;
3160}
3161
3162
3163void SfxObjectShell::SaveChildren( bool bObjectsOnly )
3164{
3165 if ( pImpl->mxObjectContainer )
3166 {
3167 bool bOasis = ( SotStorage::GetVersion( GetStorage() ) > SOFFICE_FILEFORMAT_606200 );
3168 GetEmbeddedObjectContainer().StoreChildren(bOasis,bObjectsOnly);
3169 }
3170}
3171
3172bool SfxObjectShell::SaveAsChildren( SfxMedium& rMedium )
3173{
3174 uno::Reference < embed::XStorage > xStorage = rMedium.GetStorage();
3175 if ( !xStorage.is() )
3176 return false;
3177
3178 if ( xStorage == GetStorage() )
3179 {
3180 SaveChildren();
3181 return true;
3182 }
3183
3184 if ( pImpl->mxObjectContainer )
3185 {
3186 bool bOasis = ( SotStorage::GetVersion( xStorage ) > SOFFICE_FILEFORMAT_606200 );
3187 GetEmbeddedObjectContainer().StoreAsChildren(bOasis,SfxObjectCreateMode::EMBEDDED == eCreateMode,xStorage);
3188 }
3189
3190 uno::Sequence<OUString> aExceptions;
3191 if (const SfxBoolItem* pNoEmbDS
3192 = SfxItemSet::GetItem(rMedium.GetItemSet(), SID_NO_EMBEDDED_DSTypedWhichId<SfxBoolItem>(5000 + 1731), false))
3193 {
3194 // Don't save data source in case a temporary is being saved for preview in MM wizard
3195 if (pNoEmbDS->GetValue())
3196 aExceptions = uno::Sequence<OUString>{ "EmbeddedDatabase" };
3197 }
3198
3199 return CopyStoragesOfUnknownMediaType(GetStorage(), xStorage, aExceptions);
3200}
3201
3202bool SfxObjectShell::SaveCompletedChildren()
3203{
3204 bool bResult = true;
3205
3206 if ( pImpl->mxObjectContainer )
3207 {
3208 const uno::Sequence < OUString > aNames = GetEmbeddedObjectContainer().GetObjectNames();
3209 for ( const auto& rName : aNames )
3210 {
3211 uno::Reference < embed::XEmbeddedObject > xObj = GetEmbeddedObjectContainer().GetEmbeddedObject( rName );
3212 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/objstor.cxx"
":" "3212" ": "), "%s", "An empty entry in the embedded objects list!"
); } } while (false)
;
3213 if ( xObj.is() )
3214 {
3215 uno::Reference< embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY );
3216 if ( xPersist.is() )
3217 {
3218 try
3219 {
3220 xPersist->saveCompleted( false/*bSuccess*/ );
3221 }
3222 catch( uno::Exception& )
3223 {
3224 // TODO/LATER: error handling
3225 bResult = false;
3226 break;
3227 }
3228 }
3229 }
3230 }
3231 }
3232
3233 return bResult;
3234}
3235
3236bool SfxObjectShell::SwitchChildrenPersistance( const uno::Reference< embed::XStorage >& xStorage,
3237 bool bForceNonModified )
3238{
3239 if ( !xStorage.is() )
3240 {
3241 // TODO/LATER: error handling
3242 return false;
3243 }
3244
3245 if ( pImpl->mxObjectContainer )
3246 pImpl->mxObjectContainer->SetPersistentEntries(xStorage,bForceNonModified);
3247
3248 return true;
3249}
3250
3251// Never call this method directly, always use the DoSaveCompleted call
3252bool SfxObjectShell::SaveCompleted( const uno::Reference< embed::XStorage >& xStorage )
3253{
3254 bool bResult = false;
3255 bool bSendNotification = false;
3256 uno::Reference< embed::XStorage > xOldStorageHolder;
3257
3258 // check for wrong creation of object container
3259 bool bHasContainer( pImpl->mxObjectContainer );
3260
3261 if ( !xStorage.is() || xStorage == GetStorage() )
3262 {
3263 // no persistence change
3264 bResult = SaveCompletedChildren();
3265 }
3266 else
3267 {
3268 if ( pImpl->mxObjectContainer )
3269 GetEmbeddedObjectContainer().SwitchPersistence( xStorage );
3270
3271 bResult = SwitchChildrenPersistance( xStorage, true );
3272 }
3273
3274 if ( bResult )
3275 {
3276 if ( xStorage.is() && pImpl->m_xDocStorage != xStorage )
3277 {
3278 // make sure that until the storage is assigned the object
3279 // container is not created by accident!
3280 DBG_ASSERT( bHasContainer == (pImpl->mxObjectContainer != nullptr), "Wrong storage in object container!" )do { if (true && (!(bHasContainer == (pImpl->mxObjectContainer
!= nullptr)))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "3280" ": "), "%s", "Wrong storage in object container!"
); } } while (false)
;
3281 xOldStorageHolder = pImpl->m_xDocStorage;
3282 pImpl->m_xDocStorage = xStorage;
3283 bSendNotification = true;
3284
3285 if ( IsEnableSetModified() )
3286 SetModified( false );
3287 }
3288 }
3289 else
3290 {
3291 if ( pImpl->mxObjectContainer )
3292 GetEmbeddedObjectContainer().SwitchPersistence( pImpl->m_xDocStorage );
3293
3294 // let already successfully connected objects be switched back
3295 SwitchChildrenPersistance( pImpl->m_xDocStorage, true );
3296 }
3297
3298 if ( bSendNotification )
3299 {
3300 SfxGetpApp()->NotifyEvent( SfxEventHint( SfxEventHintId::StorageChanged, GlobalEventConfig::GetEventName(GlobalEventId::STORAGECHANGED), this ) );
3301 }
3302
3303 return bResult;
3304}
3305
3306static bool StoragesOfUnknownMediaTypeAreCopied_Impl( const uno::Reference< embed::XStorage >& xSource,
3307 const uno::Reference< embed::XStorage >& xTarget )
3308{
3309 OSL_ENSURE( xSource.is() && xTarget.is(), "Source and/or target storages are not available!" )do { if (true && (!(xSource.is() && xTarget.is
()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "3309" ": "), "%s", "Source and/or target storages are not available!"
); } } while (false)
;
3310 if ( !xSource.is() || !xTarget.is() || xSource == xTarget )
3311 return true;
3312
3313 try
3314 {
3315 const uno::Sequence< OUString > aSubElements = xSource->getElementNames();
3316 for ( const auto& rSubElement : aSubElements )
3317 {
3318 if ( xSource->isStorageElement( rSubElement ) )
3319 {
3320 OUString aMediaType;
3321 const OUString aMediaTypePropName( "MediaType" );
3322 bool bGotMediaType = false;
3323
3324 try
3325 {
3326 uno::Reference< embed::XOptimizedStorage > xOptStorage( xSource, uno::UNO_QUERY_THROW );
3327 bGotMediaType =
3328 ( xOptStorage->getElementPropertyValue( rSubElement, aMediaTypePropName ) >>= aMediaType );
3329 }
3330 catch( uno::Exception& )
3331 {}
3332
3333 if ( !bGotMediaType )
3334 {
3335 uno::Reference< embed::XStorage > xSubStorage;
3336 try {
3337 xSubStorage = xSource->openStorageElement( rSubElement, embed::ElementModes::READ );
3338 } catch( uno::Exception& )
3339 {}
3340
3341 if ( !xSubStorage.is() )
3342 {
3343 xSubStorage = ::comphelper::OStorageHelper::GetTemporaryStorage();
3344 xSource->copyStorageElementLastCommitTo( rSubElement, xSubStorage );
3345 }
3346
3347 uno::Reference< beans::XPropertySet > xProps( xSubStorage, uno::UNO_QUERY_THROW );
3348 xProps->getPropertyValue( aMediaTypePropName ) >>= aMediaType;
3349 }
3350
3351 // TODO/LATER: there should be a way to detect whether an object with such a MediaType can exist
3352 // probably it should be placed in the MimeType-ClassID table or in standalone table
3353 if ( !aMediaType.isEmpty()
3354 && aMediaType != "application/vnd.sun.star.oleobject" )
3355 {
3356 css::datatransfer::DataFlavor aDataFlavor;
3357 aDataFlavor.MimeType = aMediaType;
3358 SotClipboardFormatId nFormat = SotExchange::GetFormat( aDataFlavor );
3359
3360 switch ( nFormat )
3361 {
3362 case SotClipboardFormatId::STARWRITER_60 :
3363 case SotClipboardFormatId::STARWRITERWEB_60 :
3364 case SotClipboardFormatId::STARWRITERGLOB_60 :
3365 case SotClipboardFormatId::STARDRAW_60 :
3366 case SotClipboardFormatId::STARIMPRESS_60 :
3367 case SotClipboardFormatId::STARCALC_60 :
3368 case SotClipboardFormatId::STARCHART_60 :
3369 case SotClipboardFormatId::STARMATH_60 :
3370 case SotClipboardFormatId::STARWRITER_8:
3371 case SotClipboardFormatId::STARWRITERWEB_8:
3372 case SotClipboardFormatId::STARWRITERGLOB_8:
3373 case SotClipboardFormatId::STARDRAW_8:
3374 case SotClipboardFormatId::STARIMPRESS_8:
3375 case SotClipboardFormatId::STARCALC_8:
3376 case SotClipboardFormatId::STARCHART_8:
3377 case SotClipboardFormatId::STARMATH_8:
3378 break;
3379
3380 default:
3381 {
3382 if ( !xTarget->hasByName( rSubElement ) )
3383 return false;
3384 }
3385 }
3386 }
3387 }
3388 }
3389 }
3390 catch( uno::Exception& )
3391 {
3392 SAL_WARN( "sfx.doc", "Can not check storage consistency!" )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "sfx.doc")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "Can not check storage consistency!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "3392" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Can not check storage consistency!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Can not check storage consistency!"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "3392" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Can not check storage consistency!") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "3392" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Can not check storage consistency!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Can not check storage consistency!"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "3392" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
3393 }
3394
3395 return true;
3396}
3397
3398bool SfxObjectShell::SwitchPersistance( const uno::Reference< embed::XStorage >& xStorage )
3399{
3400 bool bResult = false;
3401 // check for wrong creation of object container
3402 bool bHasContainer( pImpl->mxObjectContainer );
3403 if ( xStorage.is() )
3404 {
3405 if ( pImpl->mxObjectContainer )
3406 GetEmbeddedObjectContainer().SwitchPersistence( xStorage );
3407 bResult = SwitchChildrenPersistance( xStorage );
3408
3409 // TODO/LATER: substorages that have unknown mimetypes probably should be copied to the target storage here
3410 OSL_ENSURE( StoragesOfUnknownMediaTypeAreCopied_Impl( pImpl->m_xDocStorage, xStorage ),do { if (true && (!(StoragesOfUnknownMediaTypeAreCopied_Impl
( pImpl->m_xDocStorage, xStorage )))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "3411" ": "), "%s", "Some of substorages with unknown mimetypes is lost!"
); } } while (false)
3411 "Some of substorages with unknown mimetypes is lost!" )do { if (true && (!(StoragesOfUnknownMediaTypeAreCopied_Impl
( pImpl->m_xDocStorage, xStorage )))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "3411" ": "), "%s", "Some of substorages with unknown mimetypes is lost!"
); } } while (false)
;
3412 }
3413
3414 if ( bResult )
3415 {
3416 // make sure that until the storage is assigned the object container is not created by accident!
3417 DBG_ASSERT( bHasContainer == (pImpl->mxObjectContainer != nullptr), "Wrong storage in object container!" )do { if (true && (!(bHasContainer == (pImpl->mxObjectContainer
!= nullptr)))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "3417" ": "), "%s", "Wrong storage in object container!"
); } } while (false)
;
3418 if ( pImpl->m_xDocStorage != xStorage )
3419 DoSaveCompleted( new SfxMedium( xStorage, GetMedium()->GetBaseURL() ) );
3420
3421 if ( IsEnableSetModified() )
3422 SetModified(); // ???
3423 }
3424
3425 return bResult;
3426}
3427
3428bool SfxObjectShell::CopyStoragesOfUnknownMediaType(const uno::Reference< embed::XStorage >& xSource,
3429 const uno::Reference< embed::XStorage >& xTarget,
3430 const uno::Sequence<OUString>& rExceptions)
3431{
3432 // This method does not commit the target storage and should not do it
3433 bool bResult = true;
3434
3435 try
3436 {
3437 const css::uno::Sequence<OUString> aSubElementNames = xSource->getElementNames();
3438 for (const OUString& rSubElement : aSubElementNames)
3439 {
3440 if (std::find(rExceptions.begin(), rExceptions.end(), rSubElement) != rExceptions.end())
3441 continue;
3442
3443 if (rSubElement == "Configurations")
3444 {
3445 // The workaround for compatibility with SO7, "Configurations" substorage must be preserved
3446 if (xSource->isStorageElement(rSubElement))
3447 {
3448 OSL_ENSURE(!xTarget->hasByName(rSubElement), "The target storage is an output "do { if (true && (!(!xTarget->hasByName(rSubElement
)))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "3450" ": "), "%s", "The target storage is an output " "storage, the element should not "
"exist in the target!"); } } while (false)
3449 "storage, the element should not "do { if (true && (!(!xTarget->hasByName(rSubElement
)))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "3450" ": "), "%s", "The target storage is an output " "storage, the element should not "
"exist in the target!"); } } while (false)
3450 "exist in the target!")do { if (true && (!(!xTarget->hasByName(rSubElement
)))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "3450" ": "), "%s", "The target storage is an output " "storage, the element should not "
"exist in the target!"); } } while (false)
;
3451
3452 xSource->copyElementTo(rSubElement, xTarget, rSubElement);
3453 }
3454 }
3455 else if (xSource->isStorageElement(rSubElement))
3456 {
3457 OUString aMediaType;
3458 const OUString aMediaTypePropName( "MediaType" );
3459 bool bGotMediaType = false;
3460
3461 try
3462 {
3463 uno::Reference< embed::XOptimizedStorage > xOptStorage( xSource, uno::UNO_QUERY_THROW );
3464 bGotMediaType = (xOptStorage->getElementPropertyValue(rSubElement, aMediaTypePropName)
3465 >>= aMediaType);
3466 }
3467 catch( uno::Exception& )
3468 {}
3469
3470 if ( !bGotMediaType )
3471 {
3472 uno::Reference< embed::XStorage > xSubStorage;
3473 try {
3474 xSubStorage
3475 = xSource->openStorageElement(rSubElement, embed::ElementModes::READ);
3476 } catch( uno::Exception& )
3477 {}
3478
3479 if ( !xSubStorage.is() )
3480 {
3481 // TODO/LATER: as optimization in future a substorage of target storage could be used
3482 // instead of the temporary storage; this substorage should be removed later
3483 // if the MimeType is wrong
3484 xSubStorage = ::comphelper::OStorageHelper::GetTemporaryStorage();
3485 xSource->copyStorageElementLastCommitTo(rSubElement, xSubStorage);
3486 }
3487
3488 uno::Reference< beans::XPropertySet > xProps( xSubStorage, uno::UNO_QUERY_THROW );
3489 xProps->getPropertyValue( aMediaTypePropName ) >>= aMediaType;
3490 }
3491
3492 // TODO/LATER: there should be a way to detect whether an object with such a MediaType can exist
3493 // probably it should be placed in the MimeType-ClassID table or in standalone table
3494 if ( !aMediaType.isEmpty()
3495 && aMediaType != "application/vnd.sun.star.oleobject" )
3496 {
3497 css::datatransfer::DataFlavor aDataFlavor;
3498 aDataFlavor.MimeType = aMediaType;
3499 SotClipboardFormatId nFormat = SotExchange::GetFormat( aDataFlavor );
3500
3501 switch ( nFormat )
3502 {
3503 case SotClipboardFormatId::STARWRITER_60 :
3504 case SotClipboardFormatId::STARWRITERWEB_60 :
3505 case SotClipboardFormatId::STARWRITERGLOB_60 :
3506 case SotClipboardFormatId::STARDRAW_60 :
3507 case SotClipboardFormatId::STARIMPRESS_60 :
3508 case SotClipboardFormatId::STARCALC_60 :
3509 case SotClipboardFormatId::STARCHART_60 :
3510 case SotClipboardFormatId::STARMATH_60 :
3511 case SotClipboardFormatId::STARWRITER_8:
3512 case SotClipboardFormatId::STARWRITERWEB_8:
3513 case SotClipboardFormatId::STARWRITERGLOB_8:
3514 case SotClipboardFormatId::STARDRAW_8:
3515 case SotClipboardFormatId::STARIMPRESS_8:
3516 case SotClipboardFormatId::STARCALC_8:
3517 case SotClipboardFormatId::STARCHART_8:
3518 case SotClipboardFormatId::STARMATH_8:
3519 break;
3520
3521 default:
3522 {
3523 OSL_ENSURE(rSubElement == "Configurations2"do { if (true && (!(rSubElement == "Configurations2" ||
nFormat == SotClipboardFormatId::STARBASE_8 || !xTarget->
hasByName(rSubElement)))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "3527" ": "), "%s", "The target storage is an output storage, the element "
"should not exist in the target!"); } } while (false)
3524 || nFormat == SotClipboardFormatId::STARBASE_8do { if (true && (!(rSubElement == "Configurations2" ||
nFormat == SotClipboardFormatId::STARBASE_8 || !xTarget->
hasByName(rSubElement)))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "3527" ": "), "%s", "The target storage is an output storage, the element "
"should not exist in the target!"); } } while (false)
3525 || !xTarget->hasByName(rSubElement),do { if (true && (!(rSubElement == "Configurations2" ||
nFormat == SotClipboardFormatId::STARBASE_8 || !xTarget->
hasByName(rSubElement)))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "3527" ": "), "%s", "The target storage is an output storage, the element "
"should not exist in the target!"); } } while (false)
3526 "The target storage is an output storage, the element "do { if (true && (!(rSubElement == "Configurations2" ||
nFormat == SotClipboardFormatId::STARBASE_8 || !xTarget->
hasByName(rSubElement)))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "3527" ": "), "%s", "The target storage is an output storage, the element "
"should not exist in the target!"); } } while (false)
3527 "should not exist in the target!")do { if (true && (!(rSubElement == "Configurations2" ||
nFormat == SotClipboardFormatId::STARBASE_8 || !xTarget->
hasByName(rSubElement)))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
":" "3527" ": "), "%s", "The target storage is an output storage, the element "
"should not exist in the target!"); } } while (false)
;
3528
3529 if (!xTarget->hasByName(rSubElement))
3530 {
3531 xSource->copyElementTo(rSubElement, xTarget, rSubElement);
3532 }
3533 }
3534 }
3535 }
3536 }
3537 }
3538 }
3539 catch( uno::Exception& )
3540 {
3541 bResult = false;
3542 // TODO/LATER: a specific error could be provided
3543 }
3544
3545 return bResult;
3546}
3547
3548bool SfxObjectShell::GenerateAndStoreThumbnail(bool bEncrypted, const uno::Reference<embed::XStorage>& xStorage)
3549{
3550 //optimize thumbnail generate and store procedure to improve odt saving performance, i120030
3551 bIsInGenerateThumbnail = true;
3552
3553 bool bResult = false;
3554
3555 try
3556 {
3557 uno::Reference<embed::XStorage> xThumbnailStorage = xStorage->openStorageElement("Thumbnails", embed::ElementModes::READWRITE);
3558
3559 if (xThumbnailStorage.is())
3560 {
3561 uno::Reference<io::XStream> xStream = xThumbnailStorage->openStreamElement("thumbnail.png", embed::ElementModes::READWRITE);
3562
3563 if (xStream.is() && WriteThumbnail(bEncrypted, xStream))
3564 {
3565 uno::Reference<embed::XTransactedObject> xTransactedObject(xThumbnailStorage, uno::UNO_QUERY_THROW);
3566 xTransactedObject->commit();
3567 bResult = true;
3568 }
3569 }
3570 }
3571 catch( uno::Exception& )
3572 {
3573 }
3574
3575 //optimize thumbnail generate and store procedure to improve odt saving performance, i120030
3576 bIsInGenerateThumbnail = false;
3577
3578 return bResult;
3579}
3580
3581bool SfxObjectShell::WriteThumbnail(bool bEncrypted, const uno::Reference<io::XStream>& xStream)
3582{
3583 bool bResult = false;
3584
3585 if (!xStream.is())
3586 return false;
3587
3588 try
3589 {
3590 uno::Reference<io::XTruncate> xTruncate(xStream->getOutputStream(), uno::UNO_QUERY_THROW);
3591 xTruncate->truncate();
3592
3593 uno::Reference <beans::XPropertySet> xSet(xStream, uno::UNO_QUERY);
3594 if (xSet.is())
3595 xSet->setPropertyValue("MediaType", uno::makeAny(OUString("image/png")));
3596 if (bEncrypted)
3597 {
3598 const OUString sResID = GraphicHelper::getThumbnailReplacementIDByFactoryName_Impl(
3599 GetFactory().GetFactoryName());
3600 if (!sResID.isEmpty())
3601 bResult = GraphicHelper::getThumbnailReplacement_Impl(sResID, xStream);
3602 }
3603 else
3604 {
3605 std::shared_ptr<GDIMetaFile> xMetaFile = GetPreviewMetaFile();
3606 if (xMetaFile)
3607 {
3608 bResult = GraphicHelper::getThumbnailFormatFromGDI_Impl(xMetaFile.get(), xStream);
3609 }
3610 }
3611 }
3612 catch(uno::Exception&)
3613 {}
3614
3615 return bResult;
3616}
3617
3618void SfxObjectShell::UpdateLinks()
3619{
3620}
3621
3622bool SfxObjectShell::LoadExternal( SfxMedium& )
3623{
3624 // Not implemented. It's an error if the code path ever comes here.
3625 assert(false)(static_cast <bool> (false) ? void (0) : __assert_fail (
"false", "/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
, 3625, __extension__ __PRETTY_FUNCTION__))
;
3626 return false;
3627}
3628
3629bool SfxObjectShell::InsertGeneratedStream(SfxMedium&,
3630 uno::Reference<text::XTextRange> const&)
3631{
3632 // Not implemented. It's an error if the code path ever comes here.
3633 assert(false)(static_cast <bool> (false) ? void (0) : __assert_fail (
"false", "/home/maarten/src/libreoffice/core/sfx2/source/doc/objstor.cxx"
, 3633, __extension__ __PRETTY_FUNCTION__))
;
3634 return false;
3635}
3636
3637bool SfxObjectShell::IsConfigOptionsChecked() const
3638{
3639 return pImpl->m_bConfigOptionsChecked;
3640}
3641
3642void SfxObjectShell::SetConfigOptionsChecked( bool bChecked )
3643{
3644 pImpl->m_bConfigOptionsChecked = bChecked;
3645}
3646
3647void SfxObjectShell::SetMacroCallsSeenWhileLoading()
3648{
3649 pImpl->m_bMacroCallsSeenWhileLoading = true;
3650}
3651
3652bool SfxObjectShell::GetMacroCallsSeenWhileLoading() const
3653{
3654 if (officecfg::Office::Common::Security::Scripting::CheckDocumentEvents::get())
3655 return pImpl->m_bMacroCallsSeenWhileLoading;
3656 return false;
3657}
3658
3659bool SfxObjectShell::QuerySaveSizeExceededModules_Impl( const uno::Reference< task::XInteractionHandler >& xHandler )
3660{
3661#if !HAVE_FEATURE_SCRIPTING1
3662 (void) xHandler;
3663#else
3664 if ( !HasBasic() )
3665 return true;
3666
3667 if ( !pImpl->aBasicManager.isValid() )
3668 GetBasicManager();
3669 std::vector< OUString > sModules;
3670 if ( xHandler.is() )
3671 {
3672 if( pImpl->aBasicManager.LegacyPsswdBinaryLimitExceeded( sModules ) )
3673 {
3674 ModuleSizeExceeded* pReq = new ModuleSizeExceeded( sModules );
3675 uno::Reference< task::XInteractionRequest > xReq( pReq );
3676 xHandler->handle( xReq );
3677 return pReq->isApprove();
3678 }
3679 }
3680#endif
3681 // No interaction handler, default is to continue to save
3682 return true;
3683}
3684
3685bool SfxObjectShell::QueryAllowExoticFormat_Impl( const uno::Reference< task::XInteractionHandler >& xHandler, const OUString& rURL, const OUString& rFilterUIName )
3686{
3687 if ( SvtSecurityOptions().isTrustedLocationUri( rURL ) )
3688 {
3689 // Always load from trusted location
3690 return true;
3691 }
3692 if ( officecfg::Office::Common::Security::LoadExoticFileFormats::get() == 0 )
3693 {
3694 // Refuse loading without question
3695 return false;
3696 }
3697 else if ( officecfg::Office::Common::Security::LoadExoticFileFormats::get() == 2 )
3698 {
3699 // Always load without question
3700 return true;
3701 }
3702 else if ( officecfg::Office::Common::Security::LoadExoticFileFormats::get() == 1 && xHandler.is() )
3703 {
3704 // Display a warning and let the user decide
3705 rtl::Reference<ExoticFileLoadException> xException(new ExoticFileLoadException( rURL, rFilterUIName ));
3706 uno::Reference< task::XInteractionRequest > xReq( xException.get() );
3707 xHandler->handle( xReq );
3708 return xException->isApprove();
3709 }
3710 // No interaction handler, default is to continue to load
3711 return true;
3712}
3713
3714uno::Reference< task::XInteractionHandler > SfxObjectShell::getInteractionHandler() const
3715{
3716 uno::Reference< task::XInteractionHandler > xRet;
3717 if ( GetMedium() )
3718 xRet = GetMedium()->GetInteractionHandler();
3719 return xRet;
3720}
3721
3722OUString SfxObjectShell::getDocumentBaseURL() const
3723{
3724 return GetMedium()->GetBaseURL();
3725}
3726
3727/* vim:set shiftwidth=4 softtabstop=4 expandtab: */