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