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 {
480 SfxItemSet *pSet = GetMedium()->GetItemSet();
481 uno::Sequence< beans::PropertyValue > aArgs;
482 TransformItems( SID_OPENDOC, *pSet, 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();
581 SfxItemSet* pSet = pMedium->GetItemSet();
582 if( pImpl->nEventId == SfxEventHintId::NONE )
583 {
584 const SfxBoolItem* pTemplateItem = SfxItemSet::GetItem<SfxBoolItem>(pSet, SID_TEMPLATE, false);
586 ( pTemplateItem && pTemplateItem->GetValue() )
588 }
589
590 const SfxStringItem* pBaseItem = SfxItemSet::GetItem<SfxStringItem>(pSet, SID_BASEURL, false);
591 OUString aBaseURL;
592 const SfxStringItem* pSalvageItem = SfxItemSet::GetItem<SfxStringItem>(pMedium->GetItemSet(), 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 pSet->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 = SfxItemSet::GetItem<SfxBoolItem>(pMedium->GetItemSet(), 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 = SfxItemSet::GetItem<SfxBoolItem>(pMedium->GetItemSet(), 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 const 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 const OUStringLiteral aAuthor( u"Author" );
780 static const OUStringLiteral aKeywords( u"Keywords" );
781 static const 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 = SfxItemSet::GetItem<SfxBoolItem>(pMedium->GetItemSet(), SID_TEMPLATE, false);
826 const SfxBoolItem* pPreviewItem = SfxItemSet::GetItem<SfxBoolItem>(pMedium->GetItemSet(), SID_PREVIEW, false);
827 const SfxBoolItem* pHiddenItem = SfxItemSet::GetItem<SfxBoolItem>(pMedium->GetItemSet(), 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 = SfxItemSet::GetItem<SfxBoolItem>(pMedium->GetItemSet(), 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;
859 SfxItemSet* pSet = pMedium->GetItemSet();
860 const SfxStringItem* pOptions = SfxItemSet::GetItem<SfxStringItem>(pSet, SID_FILE_FILTEROPTIONS, false);
861 const SfxUnoAnyItem* pData = SfxItemSet::GetItem<SfxUnoAnyItem>(pSet, 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 ( pSet->GetItemState( SID_INPUTSTREAM ) < SfxItemState::SET )
897 pSet->Put( SfxUnoAnyItem( SID_INPUTSTREAM, aStreamAny ) );
898 if ( pSet->GetItemState( SID_FILE_NAME ) < SfxItemState::SET )
899 pSet->Put( SfxStringItem( SID_FILE_NAME, pMedium->GetName() ) );
900 if ( pSet->GetItemState( SID_FILTER_NAME ) < SfxItemState::SET )
901 pSet->Put( SfxStringItem( SID_FILTER_NAME, pFilter->GetName() ) );
902
903 Sequence< PropertyValue > rProperties;
904 TransformItems( SID_OPENDOC, *pSet, 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 pSet->Put( *pFilterOptions );
919
920 const SfxUnoAnyItem* pFilterData = aNewParams.GetItem<SfxUnoAnyItem>(SID_FILTER_DATA, false);
921 if ( pFilterData )
922 pSet->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 const OUStringLiteral aBasicStorageName( u"Basic" );
1048 static const 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();
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 *pMedSet = rMedium.GetItemSet();
1401 if( pMedSet )
1402 {
1403 const SfxBoolItem* pSaveToItem = SfxItemSet::GetItem<SfxBoolItem>(pMedSet, SID_SAVETO, false);
1405 (pSaveToItem && pSaveToItem->GetValue());
1406 }
1407
1408 bool bOk = false;
1409 // TODO/LATER: get rid of bOk
1410 if (bOwnTarget && pFilter && !(pFilter->GetFilterFlags() & SfxFilterFlags::STARONEFILTER))
1411 {
1412 uno::Reference< embed::XStorage > xMedStorage = rMedium.GetStorage();
1413 if ( !xMedStorage.is() )
1414 {
1415 // no saving without storage
1416 pImpl->bForbidReload = bOldStat;
1417 return false;
1418 }
1419
1420 // transfer password from the parameters to the storage
1421 uno::Sequence< beans::NamedValue > aEncryptionData;
1422 bool bPasswdProvided = false;
1423 if ( GetEncryptionData_Impl( rMedium.GetItemSet(), aEncryptionData ) )
1424 {
1425 bPasswdProvided = true;
1426 try {
1428 bOk = true;
1429 }
1430 catch( uno::Exception& )
1431 {
1432 SAL_WARN( "sfx.doc", "Setting of common encryption key failed!" );
1434 }
1435 }
1436 else
1437 bOk = true;
1438
1439 pFilter = rMedium.GetFilter();
1440
1441 const SfxStringItem *pVersionItem = !rMedium.IsInCheckIn()? SfxItemSet::GetItem<SfxStringItem>(pSet, SID_DOCINFO_COMMENTS, false): nullptr;
1442 OUString aTmpVersionURL;
1443
1444 if ( bOk )
1445 {
1446 bOk = false;
1447 // currently the case that the storage is the same should be impossible
1448 if ( xMedStorage == GetStorage() )
1449 {
1450 OSL_ENSURE( !pVersionItem, "This scenario is impossible currently!" );
1451 // usual save procedure
1452 bOk = Save();
1453 }
1454 else
1455 {
1456 // save to target
1457 bOk = SaveAsOwnFormat( rMedium );
1458 if ( bOk && pVersionItem )
1459 {
1460 aTmpVersionURL = CreateTempCopyOfStorage_Impl( xMedStorage );
1461 bOk = !aTmpVersionURL.isEmpty();
1462 }
1463 }
1464 }
1465
1466 //fdo#61320: only store thumbnail image if the corresponding option is enabled in the configuration
1467 if ( bOk && officecfg::Office::Common::Save::Document::GenerateThumbnail::get()
1468 && GetCreateMode() != SfxObjectCreateMode::EMBEDDED && !bPasswdProvided && IsUseThumbnailSave() )
1469 {
1470 // store the thumbnail representation image
1471 // the thumbnail is not stored in case of encrypted document
1472 if ( !GenerateAndStoreThumbnail( bPasswdProvided, xMedStorage ) )
1473 {
1474 // TODO: error handling
1475 SAL_WARN( "sfx.doc", "Couldn't store thumbnail representation!" );
1476 }
1477 }
1478
1479 if ( bOk )
1480 {
1481 if ( pImpl->bIsSaving || pImpl->bPreserveVersions )
1482 {
1483 try
1484 {
1485 const Sequence < util::RevisionTag > aVersions = rMedium.GetVersionList();
1486 if ( aVersions.hasElements() )
1487 {
1488 // copy the version streams
1489 static const OUStringLiteral aVersionsName( u"Versions" );
1490 uno::Reference< embed::XStorage > xNewVerStor = xMedStorage->openStorageElement(
1491 aVersionsName,
1492 embed::ElementModes::READWRITE );
1493 uno::Reference< embed::XStorage > xOldVerStor = GetStorage()->openStorageElement(
1494 aVersionsName,
1495 embed::ElementModes::READ );
1496 if ( !xNewVerStor.is() || !xOldVerStor.is() )
1497 throw uno::RuntimeException();
1498
1499 for ( const auto& rVersion : aVersions )
1500 {
1501 if ( xOldVerStor->hasByName( rVersion.Identifier ) )
1502 xOldVerStor->copyElementTo( rVersion.Identifier, xNewVerStor, rVersion.Identifier );
1503 }
1504
1505 uno::Reference< embed::XTransactedObject > xTransact( xNewVerStor, uno::UNO_QUERY );
1506 if ( xTransact.is() )
1507 xTransact->commit();
1508 }
1509 }
1510 catch( uno::Exception& )
1511 {
1512 SAL_WARN( "sfx.doc", "Couldn't copy versions!" );
1513 bOk = false;
1514 // TODO/LATER: a specific error could be set
1515 }
1516 }
1517
1518 if ( bOk && pVersionItem && !rMedium.IsInCheckIn() )
1519 {
1520 // store a version also
1521 const SfxStringItem *pAuthorItem = SfxItemSet::GetItem<SfxStringItem>(pSet, SID_DOCINFO_AUTHOR, false);
1522
1523 // version comment
1524 util::RevisionTag aInfo;
1525 aInfo.Comment = pVersionItem->GetValue();
1526
1527 // version author
1528 if ( pAuthorItem )
1529 aInfo.Author = pAuthorItem->GetValue();
1530 else
1531 // if not transferred as a parameter, get it from user settings
1532 aInfo.Author = SvtUserOptions().GetFullName();
1533
1534 DateTime aTime( DateTime::SYSTEM );
1535 aInfo.TimeStamp.Day = aTime.GetDay();
1536 aInfo.TimeStamp.Month = aTime.GetMonth();
1537 aInfo.TimeStamp.Year = aTime.GetYear();
1538 aInfo.TimeStamp.Hours = aTime.GetHour();
1539 aInfo.TimeStamp.Minutes = aTime.GetMin();
1540 aInfo.TimeStamp.Seconds = aTime.GetSec();
1541
1542 // add new version information into the versionlist and save the versionlist
1543 // the version list must have been transferred from the "old" medium before
1544 rMedium.AddVersion_Impl(aInfo);
1545 rMedium.SaveVersionList_Impl();
1546 bOk = PutURLContentsToVersionStream_Impl(aTmpVersionURL, xMedStorage,
1547 aInfo.Identifier);
1548 }
1549 else if ( bOk && ( pImpl->bIsSaving || pImpl->bPreserveVersions ) )
1550 {
1551 rMedium.SaveVersionList_Impl();
1552 }
1553 }
1554
1555 if ( !aTmpVersionURL.isEmpty() )
1556 ::utl::UCBContentHelper::Kill( aTmpVersionURL );
1557 }
1558 else
1559 {
1560 // it's a "SaveAs" in an alien format
1561 if ( rMedium.GetFilter() && ( rMedium.GetFilter()->GetFilterFlags() & SfxFilterFlags::STARONEFILTER ) )
1562 bOk = ExportTo( rMedium );
1563 else
1564 bOk = ConvertTo( rMedium );
1565
1566 // after saving the document, the temporary object storage must be updated
1567 // if the old object storage was not a temporary one, it will be updated also, because it will be used
1568 // as a source for copying the objects into the new temporary storage that will be created below
1569 // updating means: all child objects must be stored into it
1570 // ( same as on loading, where these objects are copied to the temporary storage )
1571 // but don't commit these changes, because in the case when the old object storage is not a temporary one,
1572 // all changes will be written into the original file !
1573
1574 if( bOk && !bCopyTo )
1575 // we also don't touch any graphical replacements here
1576 SaveChildren( true );
1577 }
1578
1579 if ( bOk )
1580 {
1581 // if ODF version of oasis format changes on saving the signature should not be preserved
1582 if ( bTryToPreserveScriptSignature && bNoPreserveForOasis )
1583 bTryToPreserveScriptSignature = ( SotStorage::GetVersion( rMedium.GetStorage() ) == SOFFICE_FILEFORMAT_60 );
1584
1585 uno::Reference< security::XDocumentDigitalSignatures > xDDSigns;
1586 if (bTryToPreserveScriptSignature)
1587 {
1588 // if the scripting code was not changed and it is signed the signature should be preserved
1589 // unfortunately at this point we have only information whether the basic code has changed or not
1590 // so the only way is to check the signature if the basic was not changed
1591 try
1592 {
1593 // get the ODF version of the new medium
1594 OUString aVersion;
1595 try
1596 {
1597 uno::Reference < beans::XPropertySet > xPropSet( rMedium.GetStorage(), uno::UNO_QUERY_THROW );
1598 xPropSet->getPropertyValue("Version") >>= aVersion;
1599 }
1600 catch( uno::Exception& )
1601 {
1602 }
1603
1604 xDDSigns = security::DocumentDigitalSignatures::createWithVersion(comphelper::getProcessComponentContext(), aVersion);
1605
1606 const OUString aScriptSignName = xDDSigns->getScriptingContentSignatureDefaultStreamName();
1607
1608 if ( !aScriptSignName.isEmpty() )
1609 {
1610 // target medium is still not committed, it should not be closed
1611 // commit the package storage and close it, but leave the streams open
1612 rMedium.StorageCommit_Impl();
1613 rMedium.CloseStorage();
1614
1615 uno::Reference< embed::XStorage > xReadOrig = pMedium->GetZipStorageToSign_Impl();
1616 if ( !xReadOrig.is() )
1617 throw uno::RuntimeException();
1618 uno::Reference< embed::XStorage > xMetaInf = xReadOrig->openStorageElement(
1619 "META-INF",
1620 embed::ElementModes::READ );
1621
1622 uno::Reference< embed::XStorage > xTarget = rMedium.GetZipStorageToSign_Impl( false );
1623 if ( !xTarget.is() )
1624 throw uno::RuntimeException();
1625 uno::Reference< embed::XStorage > xTargetMetaInf = xTarget->openStorageElement(
1626 "META-INF",
1627 embed::ElementModes::READWRITE );
1628
1629 if ( xMetaInf.is() && xTargetMetaInf.is() )
1630 {
1631 xMetaInf->copyElementTo( aScriptSignName, xTargetMetaInf, aScriptSignName );
1632
1633 uno::Reference< embed::XTransactedObject > xTransact( xTargetMetaInf, uno::UNO_QUERY );
1634 if ( xTransact.is() )
1635 xTransact->commit();
1636
1637 xTargetMetaInf->dispose();
1638
1639 // now check the copied signature
1640 uno::Sequence< security::DocumentSignatureInformation > aInfos =
1641 xDDSigns->verifyScriptingContentSignatures( xTarget,
1642 uno::Reference< io::XInputStream >() );
1646 {
1648
1649 // commit the ZipStorage from target medium
1650 xTransact.set( xTarget, uno::UNO_QUERY );
1651 if ( xTransact.is() )
1652 xTransact->commit();
1653 }
1654 else
1655 {
1656 // it should not happen, the copies signature is invalid!
1657 // throw the changes away
1658 SAL_WARN( "sfx.doc", "An invalid signature was copied!" );
1659 }
1660 }
1661 }
1662 }
1663 catch( uno::Exception& )
1664 {
1665 }
1666
1667 rMedium.CloseZipStorage_Impl();
1668 }
1669
1670 const OUString sName( rMedium.GetName( ) );
1671 bOk = rMedium.Commit();
1672 const OUString sNewName( rMedium.GetName( ) );
1673
1674 if ( sName != sNewName )
1675 GetMedium( )->SwitchDocumentToFile( sNewName );
1676
1677 if ( bOk )
1678 {
1679 // if the target medium is an alien format and the "old" medium was an own format and the "old" medium
1680 // has a name, the object storage must be exchanged, because now we need a new temporary storage
1681 // as object storage
1682 if ( !bCopyTo && bStorageBasedSource && !bStorageBasedTarget )
1683 {
1684 if ( bStoreToSameLocation )
1685 {
1686 // if the old medium already disconnected from document storage, the storage still must
1687 // be switched if backup file is used
1688 if ( bNeedsDisconnectionOnFail )
1689 ConnectTmpStorage_Impl( pImpl->m_xDocStorage, nullptr );
1690 }
1691 else if (!pMedium->GetName().isEmpty()
1693 {
1694 OSL_ENSURE(!pMedium->GetName().isEmpty(), "Fallback is used, the medium without name should not dispose the storage!");
1695 // copy storage of old medium to new temporary storage and take this over
1697 {
1698 SAL_WARN( "sfx.doc", "Process after storing has failed." );
1699 bOk = false;
1700 }
1701 }
1702 }
1703 }
1704 else
1705 {
1706 SAL_WARN( "sfx.doc", "Storing has failed." );
1707
1708 // in case the document storage was connected to backup temporarily it must be disconnected now
1709 if ( bNeedsDisconnectionOnFail )
1710 ConnectTmpStorage_Impl( pImpl->m_xDocStorage, nullptr );
1711 }
1712 }
1713
1714 // unlock user interface
1715 aLockUIGuard.Unlock();
1716 pImpl->bForbidReload = bOldStat;
1717
1718 if ( bOk )
1719 {
1720 try
1721 {
1723 css::uno::Reference < XPropertySetInfo > xProps = aContent.getProperties();
1724 if ( xProps.is() )
1725 {
1726 static const OUStringLiteral aAuthor( u"Author" );
1727 static const OUStringLiteral aKeywords( u"Keywords" );
1728 static const OUStringLiteral aSubject( u"Subject" );
1729
1730 uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
1731 GetModel(), uno::UNO_QUERY_THROW);
1732 uno::Reference<document::XDocumentProperties> xDocProps
1733 = xDPS->getDocumentProperties();
1734
1735 if ( xProps->hasPropertyByName( aAuthor ) )
1736 {
1737 aContent.setPropertyValue( aAuthor, Any(xDocProps->getAuthor()) );
1738 }
1739 if ( xProps->hasPropertyByName( aKeywords ) )
1740 {
1741 Any aAny;
1742 aAny <<= ::comphelper::string::convertCommaSeparated(
1743 xDocProps->getKeywords());
1744 aContent.setPropertyValue( aKeywords, aAny );
1745 }
1746 if ( xProps->hasPropertyByName( aSubject ) )
1747 {
1748 aContent.setPropertyValue( aSubject, Any(xDocProps->getSubject()) );
1749 }
1750 }
1751 }
1752 catch( Exception& )
1753 {
1754 }
1755 }
1756
1757 return bOk;
1758}
1759
1761{
1762 // this method disconnects the storage from source medium, and attaches it to the backup created by the target medium
1763
1764 uno::Reference< embed::XStorage > xStorage = rSrcMedium.GetStorage();
1765
1766 bool bResult = false;
1767 if ( xStorage == pImpl->m_xDocStorage )
1768 {
1769 try
1770 {
1771 uno::Reference< embed::XOptimizedStorage > xOptStorage( xStorage, uno::UNO_QUERY_THROW );
1772 const OUString aBackupURL = rTargetMedium.GetBackup_Impl();
1773 if ( aBackupURL.isEmpty() )
1774 {
1775 // the backup could not be created, try to disconnect the storage and close the source SfxMedium
1776 // in this case the optimization is not possible, connect storage to a temporary file
1777 rTargetMedium.ResetError();
1778 xOptStorage->writeAndAttachToStream( uno::Reference< io::XStream >() );
1779 rSrcMedium.CanDisposeStorage_Impl( false );
1780 rSrcMedium.Close();
1781
1782 // now try to create the backup
1783 rTargetMedium.GetBackup_Impl();
1784 }
1785 else
1786 {
1787 // the following call will only compare stream sizes
1788 // TODO/LATER: this is a very risky part, since if the URL contents are different from the storage
1789 // contents, the storage will be broken
1790 xOptStorage->attachToURL( aBackupURL, true );
1791
1792 // the storage is successfully attached to backup, thus it is owned by the document not by the medium
1793 rSrcMedium.CanDisposeStorage_Impl( false );
1794 bResult = true;
1795 }
1796 }
1797 catch ( uno::Exception& )
1798 {}
1799 }
1800 return bResult;
1801}
1802
1803
1805 const uno::Reference< embed::XStorage >& xStorage,
1806 SfxMedium* pMediumArg )
1807
1808/* [Description]
1809
1810 If the application operates on a temporary storage, then it may not take
1811 the temporary storage from the SaveCompleted. Therefore the new storage
1812 is connected already here in this case and SaveCompleted then does nothing.
1813*/
1814
1815{
1816 bool bResult = false;
1817
1818 if ( xStorage.is() )
1819 {
1820 try
1821 {
1822 // the empty argument means that the storage will create temporary stream itself
1823 uno::Reference< embed::XOptimizedStorage > xOptStorage( xStorage, uno::UNO_QUERY_THROW );
1824 xOptStorage->writeAndAttachToStream( uno::Reference< io::XStream >() );
1825
1826 // the storage is successfully disconnected from the original sources, thus the medium must not dispose it
1827 if ( pMediumArg )
1828 pMediumArg->CanDisposeStorage_Impl( false );
1829
1830 bResult = true;
1831 }
1832 catch( uno::Exception& )
1833 {
1834 }
1835
1836 // if switching of the storage does not work for any reason ( nonroot storage for example ) use the old method
1837 if ( !bResult ) try
1838 {
1839 uno::Reference< embed::XStorage > xTmpStorage = ::comphelper::OStorageHelper::GetTemporaryStorage();
1840
1841 DBG_ASSERT( xTmpStorage.is(), "If a storage can not be created an exception must be thrown!\n" );
1842 if ( !xTmpStorage.is() )
1843 throw uno::RuntimeException();
1844
1845 // TODO/LATER: may be it should be done in SwitchPersistence also
1846 // TODO/LATER: find faster way to copy storage; perhaps sharing with backup?!
1847 xStorage->copyToStorage( xTmpStorage );
1848 bResult = SaveCompleted( xTmpStorage );
1849
1850 if ( bResult )
1851 {
1852 pImpl->aBasicManager.setStorage( xTmpStorage );
1853
1854 // Get rid of this workaround after issue i113914 is fixed
1855 try
1856 {
1857 uno::Reference< script::XStorageBasedLibraryContainer > xBasicLibraries( pImpl->xBasicLibraries, uno::UNO_QUERY_THROW );
1858 xBasicLibraries->setRootStorage( xTmpStorage );
1859 }
1860 catch( uno::Exception& )
1861 {}
1862 try
1863 {
1864 uno::Reference< script::XStorageBasedLibraryContainer > xDialogLibraries( pImpl->xDialogLibraries, uno::UNO_QUERY_THROW );
1865 xDialogLibraries->setRootStorage( xTmpStorage );
1866 }
1867 catch( uno::Exception& )
1868 {}
1869 }
1870 }
1871 catch( uno::Exception& )
1872 {}
1873
1874 if ( !bResult )
1875 {
1876 // TODO/LATER: may need error code setting based on exception
1878 }
1879 }
1880 else if (!GetMedium()->GetFilter()->IsOwnFormat())
1881 bResult = true;
1882
1883 return bResult;
1884}
1885
1886
1887bool SfxObjectShell::DoSaveObjectAs( SfxMedium& rMedium, bool bCommit )
1888{
1889 bool bOk = false;
1890
1891 ModifyBlocker_Impl aBlock( this );
1892
1893 uno::Reference < embed::XStorage > xNewStor = rMedium.GetStorage();
1894 if ( !xNewStor.is() )
1895 return false;
1896
1897 uno::Reference < beans::XPropertySet > xPropSet( xNewStor, uno::UNO_QUERY );
1898 if ( !xPropSet.is() )
1899 return false;
1900
1901 Any a = xPropSet->getPropertyValue("MediaType");
1902 OUString aMediaType;
1903 if ( !(a>>=aMediaType) || aMediaType.isEmpty() )
1904 {
1905 SAL_WARN( "sfx.doc", "The mediatype must be set already!" );
1906 SetupStorage( xNewStor, SOFFICE_FILEFORMAT_CURRENT, false );
1907 }
1908
1909 pImpl->bIsSaving = false;
1910 bOk = SaveAsOwnFormat( rMedium );
1911
1912 if ( bCommit )
1913 {
1914 try {
1915 uno::Reference< embed::XTransactedObject > xTransact( xNewStor, uno::UNO_QUERY_THROW );
1916 xTransact->commit();
1917 }
1918 catch( uno::Exception& )
1919 {
1920 SAL_WARN( "sfx.doc", "The storage was not committed on DoSaveAs!" );
1921 }
1922 }
1923
1924 return bOk;
1925}
1926
1927
1928// TODO/LATER: may be the call must be removed completely
1930{
1931 // here only root storages are included, which are stored via temp file
1932 rMedium.CreateTempFileNoCopy();
1933 SetError(rMedium.GetErrorCode());
1934 if ( GetError() )
1935 return false;
1936
1937 // copy version list from "old" medium to target medium, so it can be used on saving
1938 if ( pImpl->bPreserveVersions )
1940
1941 bool bRet = SaveTo_Impl( rMedium, nullptr );
1942 if ( !bRet )
1943 SetError(rMedium.GetErrorCode());
1944 return bRet;
1945}
1946
1947
1948bool SfxObjectShell::DoSaveCompleted( SfxMedium* pNewMed, bool bRegisterRecent )
1949{
1950 bool bOk = true;
1951 bool bMedChanged = pNewMed && pNewMed!=pMedium;
1952
1953 DBG_ASSERT( !pNewMed || pNewMed->GetError() == ERRCODE_NONE, "DoSaveCompleted: Medium has error!" );
1954
1955 // delete Medium (and Storage!) after all notifications
1956 SfxMedium* pOld = pMedium;
1957 if ( bMedChanged )
1958 {
1959 pMedium = pNewMed;
1961 }
1962
1963 std::shared_ptr<const SfxFilter> pFilter = pMedium ? pMedium->GetFilter() : nullptr;
1964 if ( pNewMed )
1965 {
1966 if( bMedChanged )
1967 {
1968 if (!pNewMed->GetName().isEmpty())
1969 bHasName = true;
1970 Broadcast( SfxHint(SfxHintId::NameChanged) );
1971 EnableSetModified(false);
1972 getDocProperties()->setGenerator(
1975 }
1976
1977 uno::Reference< embed::XStorage > xStorage;
1978 if ( !pFilter || IsPackageStorageFormat_Impl( *pMedium ) )
1979 {
1980 uno::Reference < embed::XStorage > xOld = GetStorage();
1981
1982 // when the package based medium is broken and has no storage or if the storage
1983 // is the same as the document storage the current document storage should be preserved
1984 xStorage = pMedium->GetStorage();
1985 bOk = SaveCompleted( xStorage );
1986 if ( bOk && xStorage.is() && xOld != xStorage
1987 && (!pOld || !pOld->HasStorage_Impl() || xOld != pOld->GetStorage() ) )
1988 {
1989 // old own storage was not controlled by old Medium -> dispose it
1990 try {
1991 xOld->dispose();
1992 } catch( uno::Exception& )
1993 {
1994 // the storage is disposed already
1995 // can happen during reload scenario when the medium has
1996 // disposed it during the closing
1997 // will be fixed in one of the next milestones
1998 }
1999 }
2000 }
2001 else
2002 {
2003 if (pImpl->m_bSavingForSigning && pFilter && pFilter->GetSupportsSigning())
2004 // So that pMedium->pImpl->xStream becomes a non-empty
2005 // reference, and at the end we attempt locking again in
2006 // SfxMedium::LockOrigFileOnDemand().
2008
2009 if( pMedium->GetOpenMode() & StreamMode::WRITE )
2011 xStorage = GetStorage();
2012 }
2013
2014 // TODO/LATER: may be this code will be replaced, but not sure
2015 // Set storage in document library containers
2016 pImpl->aBasicManager.setStorage( xStorage );
2017
2018 // Get rid of this workaround after issue i113914 is fixed
2019 try
2020 {
2021 uno::Reference< script::XStorageBasedLibraryContainer > xBasicLibraries( pImpl->xBasicLibraries, uno::UNO_QUERY_THROW );
2022 xBasicLibraries->setRootStorage( xStorage );
2023 }
2024 catch( uno::Exception& )
2025 {}
2026 try
2027 {
2028 uno::Reference< script::XStorageBasedLibraryContainer > xDialogLibraries( pImpl->xDialogLibraries, uno::UNO_QUERY_THROW );
2029 xDialogLibraries->setRootStorage( xStorage );
2030 }
2031 catch( uno::Exception& )
2032 {}
2033 }
2034 else
2035 {
2036 if( pMedium )
2037 {
2038 if( pFilter && !IsPackageStorageFormat_Impl( *pMedium ) && (pMedium->GetOpenMode() & StreamMode::WRITE ))
2039 {
2040 pMedium->ReOpen();
2041 bOk = SaveCompletedChildren();
2042 }
2043 else
2044 bOk = SaveCompleted( nullptr );
2045 }
2046 // either Save or ConvertTo
2047 else
2048 bOk = SaveCompleted( nullptr );
2049 }
2050
2051 if ( bOk && pNewMed )
2052 {
2053 if( bMedChanged )
2054 {
2055 delete pOld;
2056
2057 uno::Reference< frame::XModel > xModel = GetModel();
2058 if ( xModel.is() )
2059 {
2060 const OUString& aURL {pNewMed->GetOrigURL()};
2061 uno::Sequence< beans::PropertyValue > aMediaDescr;
2062 TransformItems( SID_OPENDOC, *pNewMed->GetItemSet(), aMediaDescr );
2063 try
2064 {
2065 xModel->attachResource( aURL, aMediaDescr );
2066 }
2067 catch( uno::Exception& )
2068 {}
2069 }
2070
2071 const SfxBoolItem* pTemplateItem = SfxItemSet::GetItem<SfxBoolItem>(pMedium->GetItemSet(), SID_TEMPLATE, false);
2072 bool bTemplate = pTemplateItem && pTemplateItem->GetValue();
2073
2074 // before the title regenerated the document must lose the signatures
2075 pImpl->nDocumentSignatureState = SignatureState::NOSIGNATURES;
2076 if (!bTemplate)
2077 {
2078 pImpl->nScriptingSignatureState = pNewMed->GetCachedSignatureState_Impl();
2079 OSL_ENSURE( pImpl->nScriptingSignatureState != SignatureState::BROKEN, "The signature must not be broken at this place" );
2080
2081 // TODO/LATER: in future the medium must control own signature state, not the document
2082 pNewMed->SetCachedSignatureState_Impl( SignatureState::NOSIGNATURES ); // set the default value back
2083 }
2084 else
2085 pNewMed->SetCachedSignatureState_Impl( pImpl->nScriptingSignatureState );
2086
2087 // Set new title
2088 if (!pNewMed->GetName().isEmpty() && SfxObjectCreateMode::EMBEDDED != eCreateMode)
2090 SetModified(false); // reset only by set medium
2091 Broadcast( SfxHint(SfxHintId::ModeChanged) );
2092
2093 // this is the end of the saving process, it is possible that
2094 // the file was changed
2095 // between medium commit and this step (attributes change and so on)
2096 // so get the file date again
2097 if ( pNewMed->DocNeedsFileDateCheck() )
2098 pNewMed->GetInitFileDate( true );
2099 }
2100 }
2101
2103 pMedium->LockOrigFileOnDemand( true, false );
2104
2105 if (bRegisterRecent)
2107
2108 return bOk;
2109}
2110
2112{
2113 INetURLObject aUrl( pMedium->GetOrigURL() );
2114
2115 if ( aUrl.GetProtocol() == INetProtocol::File )
2116 {
2117 std::shared_ptr<const SfxFilter> pOrgFilter = pMedium->GetFilter();
2119 pOrgFilter ? pOrgFilter->GetMimeType() : OUString(),
2120 pOrgFilter ? pOrgFilter->GetServiceName() : OUString() );
2121 }
2122}
2123
2124
2126(
2127 SfxMedium& /*rMedium*/ /* <SfxMedium>, which describes the source file
2128 (for example file name, <SfxFilter>,
2129 Open-Modi and so on) */
2130)
2131
2132/* [Description]
2133
2134 This method is called for loading of documents over all filters which are
2135 not SfxFilterFlags::OWN or for which no clipboard format has been registered
2136 (thus no storage format that is used). In other words, with this method
2137 it is imported.
2138
2139 Files which are to be opened here should be opened through 'rMedium'
2140 to guarantee the right open modes. Especially if the format is retained
2141 (only possible with SfxFilterFlags::SIMULATE or SfxFilterFlags::OWN) file which must
2142 be opened STREAM_SHARE_DENYWRITE.
2143
2144 [Return value]
2145
2146 bool true
2147 The document could be loaded.
2148
2149 false
2150 The document could not be loaded, an error code
2151 received through <SvMedium::GetError()const>
2152
2153 [Example]
2154
2155 bool DocSh::ConvertFrom( SfxMedium &rMedium )
2156 {
2157 SvStreamRef xStream = rMedium.GetInStream();
2158 if( xStream.is() )
2159 {
2160 xStream->SetBufferSize(4096);
2161 *xStream >> ...;
2162
2163 // Do not call 'rMedium.CloseInStream()'! Keep File locked!
2164 return ERRCODE_NONE == rMedium.GetError();
2165 }
2166
2167 return false;
2168 }
2169
2170 [Cross-references]
2171
2172 <SfxObjectShell::ConvertTo(SfxMedium&)>
2173 <SfxFilterFlags::REGISTRATION>
2174*/
2175{
2176 return false;
2177}
2178
2180 css::uno::Reference<css::text::XTextRange> const& xInsertPosition)
2181{
2182 const OUString aFilterName( rMedium.GetFilter()->GetFilterName() );
2183
2184 uno::Reference< lang::XMultiServiceFactory > xMan = ::comphelper::getProcessServiceFactory();
2185 uno::Reference < lang::XMultiServiceFactory > xFilterFact (
2186 xMan->createInstance( "com.sun.star.document.FilterFactory" ), uno::UNO_QUERY );
2187
2188 uno::Sequence < beans::PropertyValue > aProps;
2189 uno::Reference < container::XNameAccess > xFilters ( xFilterFact, uno::UNO_QUERY );
2190 if ( xFilters->hasByName( aFilterName ) )
2191 {
2192 xFilters->getByName( aFilterName ) >>= aProps;
2193 rMedium.GetItemSet()->Put( SfxStringItem( SID_FILTER_NAME, aFilterName ) );
2194 }
2195
2196 OUString aFilterImplName;
2197 auto pProp = std::find_if(std::cbegin(aProps), std::cend(aProps),
2198 [](const beans::PropertyValue& rFilterProp) { return rFilterProp.Name == "FilterService"; });
2199 if (pProp != std::cend(aProps))
2200 pProp->Value >>= aFilterImplName;
2201
2202 uno::Reference< document::XFilter > xLoader;
2203 if ( !aFilterImplName.isEmpty() )
2204 {
2205 try
2206 {
2207 xLoader.set( xFilterFact->createInstanceWithArguments( aFilterName, uno::Sequence < uno::Any >() ), uno::UNO_QUERY );
2208 }
2209 catch(const uno::Exception&)
2210 {
2211 xLoader.clear();
2212 }
2213 }
2214 if ( xLoader.is() )
2215 {
2216 // it happens that xLoader does not support xImporter!
2217 try
2218 {
2219 uno::Reference< lang::XComponent > xComp( GetModel(), uno::UNO_QUERY_THROW );
2220 uno::Reference< document::XImporter > xImporter( xLoader, uno::UNO_QUERY_THROW );
2221 xImporter->setTargetDocument( xComp );
2222
2223 uno::Sequence < beans::PropertyValue > lDescriptor;
2224 rMedium.GetItemSet()->Put( SfxStringItem( SID_FILE_NAME, rMedium.GetName() ) );
2225 TransformItems( SID_OPENDOC, *rMedium.GetItemSet(), lDescriptor );
2226
2227 css::uno::Sequence < css::beans::PropertyValue > aArgs ( lDescriptor.getLength() );
2228 css::beans::PropertyValue * pNewValue = aArgs.getArray();
2229 const css::beans::PropertyValue * pOldValue = lDescriptor.getConstArray();
2230 static const OUStringLiteral sInputStream ( u"InputStream" );
2231
2232 bool bHasInputStream = false;
2233 bool bHasBaseURL = false;
2234 sal_Int32 nEnd = lDescriptor.getLength();
2235
2236 for ( sal_Int32 i = 0; i < nEnd; i++ )
2237 {
2238 pNewValue[i] = pOldValue[i];
2239 if ( pOldValue [i].Name == sInputStream )
2240 bHasInputStream = true;
2241 else if ( pOldValue[i].Name == "DocumentBaseURL" )
2242 bHasBaseURL = true;
2243 }
2244
2245 if ( !bHasInputStream )
2246 {
2247 aArgs.realloc ( ++nEnd );
2248 auto pArgs = aArgs.getArray();
2249 pArgs[nEnd-1].Name = sInputStream;
2250 pArgs[nEnd-1].Value <<= css::uno::Reference < css::io::XInputStream > ( new utl::OSeekableInputStreamWrapper ( *rMedium.GetInStream() ) );
2251 }
2252
2253 if ( !bHasBaseURL )
2254 {
2255 aArgs.realloc ( ++nEnd );
2256 auto pArgs = aArgs.getArray();
2257 pArgs[nEnd-1].Name = "DocumentBaseURL";
2258 pArgs[nEnd-1].Value <<= rMedium.GetBaseURL();
2259 }
2260
2261 if (xInsertPosition.is()) {
2262 aArgs.realloc( nEnd += 2 );
2263 auto pArgs = aArgs.getArray();
2264 pArgs[nEnd-2].Name = "InsertMode";
2265 pArgs[nEnd-2].Value <<= true;
2266 pArgs[nEnd-1].Name = "TextInsertModeRange";
2267 pArgs[nEnd-1].Value <<= xInsertPosition;
2268 }
2269
2270 // #i119492# During loading, some OLE objects like chart will be set
2271 // modified flag, so needs to reset the flag to false after loading
2272 bool bRtn = xLoader->filter(aArgs);
2273 const uno::Sequence < OUString > aNames = GetEmbeddedObjectContainer().GetObjectNames();
2274 for ( const auto& rName : aNames )
2275 {
2276 uno::Reference < embed::XEmbeddedObject > xObj = GetEmbeddedObjectContainer().GetEmbeddedObject( rName );
2277 OSL_ENSURE( xObj.is(), "An empty entry in the embedded objects list!" );
2278 if ( xObj.is() )
2279 {
2280 sal_Int32 nState = xObj->getCurrentState();
2281 if ( nState == embed::EmbedStates::LOADED || nState == embed::EmbedStates::RUNNING ) // means that the object is not active
2282 {
2283 uno::Reference< util::XModifiable > xModifiable( xObj->getComponent(), uno::UNO_QUERY );
2284 if (xModifiable.is() && xModifiable->isModified())
2285 {
2286 uno::Reference<embed::XEmbedPersist> const xPers(xObj, uno::UNO_QUERY);
2287 assert(xPers.is() && "Modified object without persistence!");
2288 // store it before resetting modified!
2289 xPers->storeOwn();
2290 xModifiable->setModified(false);
2291 }
2292 }
2293 }
2294 }
2295
2296 // tdf#107690 import custom document property _MarkAsFinal as SecurityOptOpenReadonly
2297 // (before this fix, LibreOffice opened read-only OOXML documents as editable,
2298 // also saved and exported _MarkAsFinal=true silently, resulting unintended read-only
2299 // warning info bar in MSO)
2300 uno::Reference< document::XDocumentPropertiesSupplier > xPropSupplier(GetModel(), uno::UNO_QUERY_THROW);
2301 uno::Reference<document::XDocumentProperties> xDocProps = xPropSupplier->getDocumentProperties() ;
2302 uno::Reference<beans::XPropertyContainer> xPropertyContainer = xDocProps->getUserDefinedProperties();
2303 if (xPropertyContainer.is())
2304 {
2305 uno::Reference<beans::XPropertySet> xPropertySet(xPropertyContainer, uno::UNO_QUERY);
2306 if (xPropertySet.is())
2307 {
2308 uno::Reference<beans::XPropertySetInfo> xPropertySetInfo = xPropertySet->getPropertySetInfo();
2309 if (xPropertySetInfo.is() && xPropertySetInfo->hasPropertyByName("_MarkAsFinal"))
2310 {
2311 if (xPropertySet->getPropertyValue("_MarkAsFinal").get<bool>())
2312 {
2313 uno::Reference< lang::XMultiServiceFactory > xFactory(GetModel(), uno::UNO_QUERY);
2314 uno::Reference< beans::XPropertySet > xSettings(xFactory->createInstance("com.sun.star.document.Settings"), uno::UNO_QUERY);
2315 xSettings->setPropertyValue("LoadReadonly", uno::Any(true));
2316 }
2317 xPropertyContainer->removeProperty("_MarkAsFinal");
2318 }
2319 }
2320 }
2321
2322 return bRtn;
2323 }
2324 catch (const packages::zip::ZipIOException&)
2325 {
2327 }
2328 catch (const lang::WrappedTargetRuntimeException& rWrapped)
2329 {
2330 io::WrongFormatException e;
2331 if (rWrapped.TargetException >>= e)
2332 {
2334 e.Message, DialogMask::ButtonsOk | DialogMask::MessageError ));
2335 }
2336 }
2337 catch (const css::io::IOException& e)
2338 {
2340 e.Message, DialogMask::ButtonsOk | DialogMask::MessageError ));
2341 }
2342 catch (const std::exception& e)
2343 {
2344 const char *msg = e.what();
2345 const OUString sError(msg, strlen(msg), RTL_TEXTENCODING_ASCII_US);
2346 SAL_WARN("sfx.doc", "exception importing " << sError);
2348 sError, DialogMask::ButtonsOk | DialogMask::MessageError));
2349 }
2350 catch (...)
2351 {
2352 std::abort(); // cannot happen
2353 }
2354 }
2355
2356 return false;
2357}
2358
2360{
2361 const OUString aFilterName( rMedium.GetFilter()->GetFilterName() );
2362 uno::Reference< document::XExporter > xExporter;
2363
2364 {
2365 uno::Reference< lang::XMultiServiceFactory > xMan = ::comphelper::getProcessServiceFactory();
2366 uno::Reference < lang::XMultiServiceFactory > xFilterFact (
2367 xMan->createInstance( "com.sun.star.document.FilterFactory" ), uno::UNO_QUERY );
2368
2369 uno::Sequence < beans::PropertyValue > aProps;
2370 uno::Reference < container::XNameAccess > xFilters ( xFilterFact, uno::UNO_QUERY );
2371 if ( xFilters->hasByName( aFilterName ) )
2372 xFilters->getByName( aFilterName ) >>= aProps;
2373
2374 OUString aFilterImplName;
2375 auto pProp = std::find_if(std::cbegin(aProps), std::cend(aProps),
2376 [](const beans::PropertyValue& rFilterProp) { return rFilterProp.Name == "FilterService"; });
2377 if (pProp != std::cend(aProps))
2378 pProp->Value >>= aFilterImplName;
2379
2380 if ( !aFilterImplName.isEmpty() )
2381 {
2382 try
2383 {
2384 xExporter.set( xFilterFact->createInstanceWithArguments( aFilterName, uno::Sequence < uno::Any >() ), uno::UNO_QUERY );
2385 }
2386 catch(const uno::Exception&)
2387 {
2388 xExporter.clear();
2389 }
2390 }
2391 }
2392
2393 if ( xExporter.is() )
2394 {
2395 try{
2396 uno::Reference< lang::XComponent > xComp( GetModel(), uno::UNO_QUERY_THROW );
2397 uno::Reference< document::XFilter > xFilter( xExporter, uno::UNO_QUERY_THROW );
2398 xExporter->setSourceDocument( xComp );
2399
2400 css::uno::Sequence < css::beans::PropertyValue > aOldArgs;
2401 SfxItemSet* pItems = rMedium.GetItemSet();
2402 TransformItems( SID_SAVEASDOC, *pItems, aOldArgs );
2403
2404 const css::beans::PropertyValue * pOldValue = aOldArgs.getConstArray();
2405 css::uno::Sequence < css::beans::PropertyValue > aArgs ( aOldArgs.getLength() );
2406 css::beans::PropertyValue * pNewValue = aArgs.getArray();
2407
2408 // put in the REAL file name, and copy all PropertyValues
2409 static const OUStringLiteral sOutputStream ( u"OutputStream" );
2410 static const OUStringLiteral sStream ( u"StreamForOutput" );
2411 bool bHasOutputStream = false;
2412 bool bHasStream = false;
2413 bool bHasBaseURL = false;
2414 bool bHasFilterName = false;
2415 bool bIsRedactMode = false;
2416 bool bIsPreview = false;
2417 sal_Int32 nEnd = aOldArgs.getLength();
2418
2419 for ( sal_Int32 i = 0; i < nEnd; i++ )
2420 {
2421 pNewValue[i] = pOldValue[i];
2422 if ( pOldValue[i].Name == "FileName" )
2423 pNewValue[i].Value <<= rMedium.GetName();
2424 else if ( pOldValue[i].Name == sOutputStream )
2425 bHasOutputStream = true;
2426 else if ( pOldValue[i].Name == sStream )
2427 bHasStream = true;
2428 else if ( pOldValue[i].Name == "DocumentBaseURL" )
2429 bHasBaseURL = true;
2430 else if( pOldValue[i].Name == "FilterName" )
2431 bHasFilterName = true;
2432 }
2433
2434 const css::uno::Sequence<css::beans::PropertyValue>& rMediumArgs = rMedium.GetArgs();
2435 for ( sal_Int32 i = 0; i < rMediumArgs.getLength(); i++ )
2436 {
2437 if( rMediumArgs[i].Name == "IsPreview" )
2438 rMediumArgs[i].Value >>= bIsPreview;
2439 }
2440
2441 // FIXME: Handle this inside TransformItems()
2442 if (pItems->GetItemState(SID_IS_REDACT_MODE) == SfxItemState::SET)
2443 bIsRedactMode = true;
2444
2445 if ( !bHasOutputStream )
2446 {
2447 aArgs.realloc ( ++nEnd );
2448 auto pArgs = aArgs.getArray();
2449 pArgs[nEnd-1].Name = sOutputStream;
2450 pArgs[nEnd-1].Value <<= css::uno::Reference < css::io::XOutputStream > ( new utl::OOutputStreamWrapper ( *rMedium.GetOutStream() ) );
2451 }
2452
2453 // add stream as well, for OOX export and maybe others
2454 if ( !bHasStream )
2455 {
2456 aArgs.realloc ( ++nEnd );
2457 auto pArgs = aArgs.getArray();
2458 pArgs[nEnd-1].Name = sStream;
2459 pArgs[nEnd-1].Value <<= css::uno::Reference < css::io::XStream > ( new utl::OStreamWrapper ( *rMedium.GetOutStream() ) );
2460 }
2461
2462 if ( !bHasBaseURL )
2463 {
2464 aArgs.realloc ( ++nEnd );
2465 auto pArgs = aArgs.getArray();
2466 pArgs[nEnd-1].Name = "DocumentBaseURL";
2467 pArgs[nEnd-1].Value <<= rMedium.GetBaseURL( true );
2468 }
2469
2470 if( !bHasFilterName )
2471 {
2472 aArgs.realloc( ++nEnd );
2473 auto pArgs = aArgs.getArray();
2474 pArgs[nEnd-1].Name = "FilterName";
2475 pArgs[nEnd-1].Value <<= aFilterName;
2476 }
2477
2478 if (bIsRedactMode)
2479 {
2480 aArgs.realloc( ++nEnd );
2481 auto pArgs = aArgs.getArray();
2482 pArgs[nEnd-1].Name = "IsRedactMode";
2483 pArgs[nEnd-1].Value <<= bIsRedactMode;
2484 }
2485
2486 if (bIsPreview)
2487 {
2488 aArgs.realloc( ++nEnd );
2489 auto pArgs = aArgs.getArray();
2490 pArgs[nEnd-1].Name = "IsPreview";
2491 pArgs[nEnd-1].Value <<= bIsPreview;
2492 }
2493
2494 return xFilter->filter( aArgs );
2495 }
2496 catch (const css::uno::RuntimeException&)
2497 {
2498 css::uno::Any ex(cppu::getCaughtException());
2499 TOOLS_INFO_EXCEPTION("sfx.doc", "exception: " << exceptionToString(ex));
2500 }
2501 catch (const std::exception& e)
2502 {
2503 TOOLS_INFO_EXCEPTION("sfx.doc", "exception: " << e.what());
2504 }
2505 catch(...)
2506 {
2507 TOOLS_INFO_EXCEPTION("sfx.doc", "Unknown exception!");
2508 }
2509 }
2510
2511 return false;
2512}
2513
2514
2516(
2517 SfxMedium& /*rMedium*/ /* <SfxMedium>, which describes the target file
2518 (for example file name, <SfxFilter>,
2519 Open-Modi and so on) */
2520)
2521
2522/* [Description]
2523
2524 This method is called for saving of documents over all filters which are
2525 not SfxFilterFlags::OWN or for which no clipboard format has been registered
2526 (thus no storage format that is used). In other words, with this method
2527 it is exported.
2528
2529 Files which are to be opened here should be opened through 'rMedium'
2530 to guarantee the right open modes. Especially if the format is retained
2531 (only possible with SfxFilterFlags::SIMULATE or SfxFilterFlags::OWN) file which must
2532 be opened STREAM_SHARE_DENYWRITE.
2533
2534 [Return value]
2535
2536 bool true
2537 The document could be saved.
2538
2539 false
2540 The document could not be saved, an error code is
2541 received by <SvMedium::GetError()const>
2542
2543
2544 [Example]
2545
2546 bool DocSh::ConvertTo( SfxMedium &rMedium )
2547 {
2548 SvStreamRef xStream = rMedium.GetOutStream();
2549 if ( xStream.is() )
2550 {
2551 xStream->SetBufferSize(4096);
2552 *xStream << ...;
2553
2554 rMedium.CloseOutStream(); // opens the InStream automatically
2555 return ERRCODE_NONE == rMedium.GetError();
2556 }
2557 return false ;
2558 }
2559
2560 [Cross-references]
2561
2562 <SfxObjectShell::ConvertFrom(SfxMedium&)>
2563 <SfxFilterFlags::REGISTRATION>
2564*/
2565
2566{
2567 return false;
2568}
2569
2570
2572{
2573 SfxMedium* pRetrMedium = GetMedium();
2574 std::shared_ptr<const SfxFilter> pFilter = pRetrMedium->GetFilter();
2575
2576 // copy the original itemset, but remove the "version" item, because pMediumTmp
2577 // is a new medium "from scratch", so no version should be stored into it
2578 std::shared_ptr<SfxItemSet> pSet = std::make_shared<SfxAllItemSet>(*pRetrMedium->GetItemSet());
2579 pSet->ClearItem( SID_VERSION );
2580 pSet->ClearItem( SID_DOC_BASEURL );
2581
2582 // copy the version comment and major items for the checkin only
2583 if ( pRetrMedium->IsInCheckIn( ) )
2584 {
2585 const SfxPoolItem* pMajor = pArgs->GetItem( SID_DOCINFO_MAJOR );
2586 if ( pMajor )
2587 pSet->Put( *pMajor );
2588
2589 const SfxPoolItem* pComments = pArgs->GetItem( SID_DOCINFO_COMMENTS );
2590 if ( pComments )
2591 pSet->Put( *pComments );
2592 }
2593
2594 // create a medium as a copy; this medium is only for writing, because it
2595 // uses the same name as the original one writing is done through a copy,
2596 // that will be transferred to the target (of course after calling HandsOff)
2597 SfxMedium* pMediumTmp = new SfxMedium( pRetrMedium->GetName(), pRetrMedium->GetOpenMode(), pFilter, std::move(pSet) );
2598 pMediumTmp->SetInCheckIn( pRetrMedium->IsInCheckIn( ) );
2599 pMediumTmp->SetLongName( pRetrMedium->GetLongName() );
2600 if ( pMediumTmp->GetErrorCode() != ERRCODE_NONE )
2601 {
2602 SetError(pMediumTmp->GetError());
2603 delete pMediumTmp;
2604 return false;
2605 }
2606
2607 // copy version list from "old" medium to target medium, so it can be used on saving
2608 pMediumTmp->TransferVersionList_Impl( *pRetrMedium );
2609
2610 // an interaction handler here can acquire only in case of GUI Saving
2611 // and should be removed after the saving is done
2612 css::uno::Reference< XInteractionHandler > xInteract;
2613 const SfxUnoAnyItem* pxInteractionItem = SfxItemSet::GetItem<SfxUnoAnyItem>(pArgs, SID_INTERACTIONHANDLER, false);
2614 if ( pxInteractionItem && ( pxInteractionItem->GetValue() >>= xInteract ) && xInteract.is() )
2615 pMediumTmp->GetItemSet()->Put( SfxUnoAnyItem( SID_INTERACTIONHANDLER, Any( xInteract ) ) );
2616
2617 const SfxBoolItem* pNoFileSync = pArgs->GetItem<SfxBoolItem>(SID_NO_FILE_SYNC, false);
2618 if (pNoFileSync && pNoFileSync->GetValue())
2619 pMediumTmp->DisableFileSync(true);
2620
2621 bool bSaved = false;
2622 if( !GetError() && SaveTo_Impl( *pMediumTmp, pArgs ) )
2623 {
2624 bSaved = true;
2625
2626 if( pMediumTmp->GetItemSet() )
2627 {
2628 pMediumTmp->GetItemSet()->ClearItem( SID_INTERACTIONHANDLER );
2629 pMediumTmp->GetItemSet()->ClearItem( SID_PROGRESS_STATUSBAR_CONTROL );
2630 }
2631
2632 SetError(pMediumTmp->GetErrorCode());
2633
2634 bool bOpen = DoSaveCompleted( pMediumTmp );
2635
2636 DBG_ASSERT(bOpen,"Error handling for DoSaveCompleted not implemented");
2637 }
2638 else
2639 {
2640 // transfer error code from medium to objectshell
2641 ErrCode errCode = pMediumTmp->GetError();
2642 SetError(errCode);
2643
2644 if (errCode == ERRCODE_ABORT)
2645 {
2646 // avoid doing DoSaveCompleted() which updates the SfxMedium timestamp values
2647 // and prevents subsequent filedate checks from being accurate
2648 delete pMediumTmp;
2649 return false;
2650 }
2651
2652 // reconnect to object storage
2654
2655 if( pRetrMedium->GetItemSet() )
2656 {
2657 pRetrMedium->GetItemSet()->ClearItem( SID_INTERACTIONHANDLER );
2658 pRetrMedium->GetItemSet()->ClearItem( SID_PROGRESS_STATUSBAR_CONTROL );
2659 }
2660
2661 delete pMediumTmp;
2662 }
2663
2664 SetModified( !bSaved );
2665 return bSaved;
2666}
2667
2668
2670{
2671 if ( IsReadOnly() )
2672 {
2674 return false;
2675 }
2676
2677 pImpl->bIsSaving = true;
2678 bool bSaved = false;
2679 const SfxStringItem* pSalvageItem = SfxItemSet::GetItem<SfxStringItem>(GetMedium()->GetItemSet(), SID_DOC_SALVAGE, false);
2680 if ( pSalvageItem )
2681 {
2682 const SfxStringItem* pFilterItem = SfxItemSet::GetItem<SfxStringItem>(GetMedium()->GetItemSet(), SID_FILTER_NAME, false);
2683 std::shared_ptr<const SfxFilter> pFilter;
2684 if ( pFilterItem )
2685 pFilter = SfxFilterMatcher( GetFactory().GetFactoryName() ).GetFilter4FilterName( OUString() );
2686
2687 SfxMedium *pMed = new SfxMedium(
2688 pSalvageItem->GetValue(), StreamMode::READWRITE | StreamMode::SHARE_DENYWRITE | StreamMode::TRUNC, pFilter );
2689
2690 const SfxStringItem* pPasswordItem = SfxItemSet::GetItem<SfxStringItem>(GetMedium()->GetItemSet(), SID_PASSWORD, false);
2691 if ( pPasswordItem )
2692 pMed->GetItemSet()->Put( *pPasswordItem );
2693
2694 bSaved = DoSaveAs( *pMed );
2695 if ( bSaved )
2696 bSaved = DoSaveCompleted( pMed );
2697 else
2698 delete pMed;
2699 }
2700 else
2701 bSaved = DoSave_Impl( pSet );
2702 return bSaved;
2703}
2704
2705bool SfxObjectShell::CommonSaveAs_Impl(const INetURLObject& aURL, const OUString& aFilterName,
2706 SfxItemSet& rItemSet,
2707 const uno::Sequence<beans::PropertyValue>& rArgs)
2708{
2709 if( aURL.HasError() )
2710 {
2712 return false;
2713 }
2714
2715 if ( aURL != INetURLObject( u"private:stream" ) )
2716 {
2717 // Is there already a Document with this name?
2718 SfxObjectShell* pDoc = nullptr;
2720 pTmp && !pDoc;
2721 pTmp = SfxObjectShell::GetNext(*pTmp) )
2722 {
2723 if( ( pTmp != this ) && pTmp->GetMedium() )
2724 {
2725 INetURLObject aCompare( pTmp->GetMedium()->GetName() );
2726 if ( aCompare == aURL )
2727 pDoc = pTmp;
2728 }
2729 }
2730 if ( pDoc )
2731 {
2732 // Then error message: "already opened"
2734 return false;
2735 }
2736 }
2737
2738 DBG_ASSERT( aURL.GetProtocol() != INetProtocol::NotValid, "Illegal URL!" );
2739 DBG_ASSERT( rItemSet.Count() != 0, "Incorrect Parameter");
2740
2741 const SfxBoolItem* pSaveToItem = rItemSet.GetItem<SfxBoolItem>(SID_SAVETO, false);
2742 bool bSaveTo = pSaveToItem && pSaveToItem->GetValue();
2743
2744 std::shared_ptr<const SfxFilter> pFilter = GetFactory().GetFilterContainer()->GetFilter4FilterName( aFilterName );
2745 if ( !pFilter
2746 || !pFilter->CanExport()
2747 || (!bSaveTo && !pFilter->CanImport()) )
2748 {
2750 return false;
2751 }
2752
2753
2754 const SfxBoolItem* pCopyStreamItem = rItemSet.GetItem(SID_COPY_STREAM_IF_POSSIBLE, false);
2755 if ( bSaveTo && pCopyStreamItem && pCopyStreamItem->GetValue() && !IsModified() )
2756 {
2758 return true;
2759 }
2760 rItemSet.ClearItem( SID_COPY_STREAM_IF_POSSIBLE );
2761
2762 SfxMedium *pActMed = GetMedium();
2763 const INetURLObject aActName(pActMed->GetName());
2764
2765 bool bWasReadonly = IsReadOnly();
2766
2767 if ( aURL == aActName && aURL != INetURLObject( u"private:stream" )
2768 && IsReadOnly() )
2769 {
2771 return false;
2772 }
2773
2774 if (SfxItemState::SET != rItemSet.GetItemState(SID_UNPACK) && officecfg::Office::Common::Save::Document::Unpacked::get())
2775 rItemSet.Put(SfxBoolItem(SID_UNPACK, false));
2776
2777#if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
2778 OUString aTempFileURL;
2779 if ( IsDocShared() )
2781#endif
2782
2783 if (PreDoSaveAs_Impl(aURL.GetMainURL(INetURLObject::DecodeMechanism::NONE), aFilterName,
2784 rItemSet, rArgs))
2785 {
2786 // Update Data on media
2787 SfxItemSet *pSet = GetMedium()->GetItemSet();
2788 pSet->ClearItem( SID_INTERACTIONHANDLER );
2789 pSet->ClearItem( SID_PROGRESS_STATUSBAR_CONTROL );
2790 pSet->ClearItem( SID_STANDARD_DIR );
2791 pSet->ClearItem( SID_PATH );
2792
2793 if ( !bSaveTo )
2794 {
2795 pSet->ClearItem( SID_REFERER );
2796 pSet->ClearItem( SID_POSTDATA );
2797 pSet->ClearItem( SID_TEMPLATE );
2798 pSet->ClearItem( SID_DOC_READONLY );
2799 pSet->ClearItem( SID_CONTENTTYPE );
2800 pSet->ClearItem( SID_CHARSET );
2801 pSet->ClearItem( SID_FILTER_NAME );
2802 pSet->ClearItem( SID_OPTIONS );
2803 pSet->ClearItem( SID_VERSION );
2804 pSet->ClearItem( SID_EDITDOC );
2805 pSet->ClearItem( SID_OVERWRITE );
2806 pSet->ClearItem( SID_DEFAULTFILEPATH );
2807 pSet->ClearItem( SID_DEFAULTFILENAME );
2808
2809 const SfxStringItem* pFilterItem = rItemSet.GetItem<SfxStringItem>(SID_FILTER_NAME, false);
2810 if ( pFilterItem )
2811 pSet->Put( *pFilterItem );
2812
2813 const SfxStringItem* pOptionsItem = rItemSet.GetItem<SfxStringItem>(SID_OPTIONS, false);
2814 if ( pOptionsItem )
2815 pSet->Put( *pOptionsItem );
2816
2817 const SfxStringItem* pFilterOptItem = rItemSet.GetItem<SfxStringItem>(SID_FILE_FILTEROPTIONS, false);
2818 if ( pFilterOptItem )
2819 pSet->Put( *pFilterOptItem );
2820
2821#if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
2822 if ( IsDocShared() && !aTempFileURL.isEmpty() )
2823 {
2824 // this is a shared document that has to be disconnected from the old location
2825 FreeSharedFile( aTempFileURL );
2826
2827 if ( pFilter->IsOwnFormat()
2828 && pFilter->UsesStorage()
2829 && pFilter->GetVersion() >= SOFFICE_FILEFORMAT_60 )
2830 {
2831 // the target format is the own format
2832 // the target document must be shared
2833 SwitchToShared( true, false );
2834 }
2835 }
2836#endif
2837 }
2838
2839 if ( bWasReadonly && !bSaveTo )
2840 Broadcast( SfxHint(SfxHintId::ModeChanged) );
2841
2842 return true;
2843 }
2844 else
2845 return false;
2846}
2847
2848bool SfxObjectShell::PreDoSaveAs_Impl(const OUString& rFileName, const OUString& aFilterName,
2849 SfxItemSet const& rItemSet,
2850 const uno::Sequence<beans::PropertyValue>& rArgs)
2851{
2852 // copy all items stored in the itemset of the current medium
2853 std::shared_ptr<SfxAllItemSet> xMergedParams = std::make_shared<SfxAllItemSet>( *pMedium->GetItemSet() );
2854
2855 // in "SaveAs" title and password will be cleared ( maybe the new itemset contains new values, otherwise they will be empty )
2856 // #i119366# - As the SID_ENCRYPTIONDATA and SID_PASSWORD are using for setting password together, we need to clear them both.
2857 // Also, ( maybe the new itemset contains new values, otherwise they will be empty )
2858 if (xMergedParams->HasItem(SID_ENCRYPTIONDATA))
2859 {
2860 bool bPasswordProtected = true;
2861 const SfxUnoAnyItem* pEncryptionDataItem
2862 = xMergedParams->GetItem<SfxUnoAnyItem>(SID_ENCRYPTIONDATA, false);
2863 if (pEncryptionDataItem)
2864 {
2865 uno::Sequence<beans::NamedValue> aEncryptionData;
2866 pEncryptionDataItem->GetValue() >>= aEncryptionData;
2867 for (const auto& rItem : std::as_const(aEncryptionData))
2868 {
2869 if (rItem.Name == "CryptoType")
2870 {
2871 OUString aValue;
2872 rItem.Value >>= aValue;
2873 if (aValue != "StrongEncryptionDataSpace")
2874 {
2875 // This is not just a password protected document. Let's keep encryption data as is.
2876 bPasswordProtected = false;
2877 }
2878 break;
2879 }
2880 }
2881 }
2882 if (bPasswordProtected)
2883 {
2884 // For password protected documents remove encryption data during "Save as..."
2885 xMergedParams->ClearItem(SID_PASSWORD);
2886 xMergedParams->ClearItem(SID_ENCRYPTIONDATA);
2887 }
2888 }
2889
2890 xMergedParams->ClearItem( SID_DOCINFO_TITLE );
2891
2892 xMergedParams->ClearItem( SID_INPUTSTREAM );
2893 xMergedParams->ClearItem( SID_STREAM );
2894 xMergedParams->ClearItem( SID_CONTENT );
2895 xMergedParams->ClearItem( SID_DOC_READONLY );
2896 xMergedParams->ClearItem( SID_DOC_BASEURL );
2897
2898 xMergedParams->ClearItem( SID_REPAIRPACKAGE );
2899
2900 // "SaveAs" will never store any version information - it's a complete new file !
2901 xMergedParams->ClearItem( SID_VERSION );
2902
2903 // merge the new parameters into the copy
2904 // all values present in both itemsets will be overwritten by the new parameters
2905 xMergedParams->Put(rItemSet);
2906
2907 SAL_WARN_IF( xMergedParams->GetItemState( SID_DOC_SALVAGE) >= SfxItemState::SET,
2908 "sfx.doc","Salvage item present in Itemset, check the parameters!");
2909
2910 // should be unnecessary - too hot to handle!
2911 xMergedParams->ClearItem( SID_DOC_SALVAGE );
2912
2913 // create a medium for the target URL
2914 SfxMedium *pNewFile = new SfxMedium( rFileName, StreamMode::READWRITE | StreamMode::SHARE_DENYWRITE | StreamMode::TRUNC, nullptr, xMergedParams );
2915 pNewFile->SetArgs(rArgs);
2916
2917 const SfxBoolItem* pNoFileSync = xMergedParams->GetItem<SfxBoolItem>(SID_NO_FILE_SYNC, false);
2918 if (pNoFileSync && pNoFileSync->GetValue())
2919 pNewFile->DisableFileSync(true);
2920
2921 bool bUseThumbnailSave = IsUseThumbnailSave();
2922 comphelper::ScopeGuard aThumbnailGuard(
2923 [this, bUseThumbnailSave] { this->SetUseThumbnailSave(bUseThumbnailSave); });
2924 const SfxBoolItem* pNoThumbnail = xMergedParams->GetItem<SfxBoolItem>(SID_NO_THUMBNAIL, false);
2925 if (pNoThumbnail)
2926 // Thumbnail generation should be avoided just for this save.
2927 SetUseThumbnailSave(!pNoThumbnail->GetValue());
2928 else
2929 aThumbnailGuard.dismiss();
2930
2931 // set filter; if no filter is given, take the default filter of the factory
2932 if ( !aFilterName.isEmpty() )
2933 {
2934 pNewFile->SetFilter( GetFactory().GetFilterContainer()->GetFilter4FilterName( aFilterName ) );
2935
2936 if(aFilterName == "writer_pdf_Export" && pNewFile->GetItemSet())
2937 {
2938 uno::Sequence< beans::PropertyValue > aSaveToFilterDataOptions(2);
2939 auto pSaveToFilterDataOptions = aSaveToFilterDataOptions.getArray();
2940 bool bRet = false;
2941
2942 for(int i = 0 ; i< rArgs.getLength() ; ++i)
2943 {
2944 auto aProp = rArgs[i];
2945 if(aProp.Name == "EncryptFile")
2946 {
2947 pSaveToFilterDataOptions[0].Name = aProp.Name;
2948 pSaveToFilterDataOptions[0].Value = aProp.Value;
2949 bRet = true;
2950 }
2951 if(aProp.Name == "DocumentOpenPassword")
2952 {
2953 pSaveToFilterDataOptions[1].Name = aProp.Name;
2954 pSaveToFilterDataOptions[1].Value = aProp.Value;
2955 bRet = true;
2956 }
2957 }
2958
2959 if( bRet )
2960 pNewFile->GetItemSet()->Put( SfxUnoAnyItem(SID_FILTER_DATA, uno::Any(aSaveToFilterDataOptions)));
2961 }
2962 }
2963 else
2964 pNewFile->SetFilter( GetFactory().GetFilterContainer()->GetAnyFilter( SfxFilterFlags::IMPORT | SfxFilterFlags::EXPORT ) );
2965
2966 if ( pNewFile->GetErrorCode() != ERRCODE_NONE )
2967 {
2968 // creating temporary file failed ( f.e. floppy disk not inserted! )
2969 SetError(pNewFile->GetError());
2970 delete pNewFile;
2971 return false;
2972 }
2973
2975 {
2976 // Before saving, commit in-flight changes.
2978 }
2979
2980 // check if a "SaveTo" is wanted, no "SaveAs"
2981 const SfxBoolItem* pSaveToItem = xMergedParams->GetItem<SfxBoolItem>(SID_SAVETO, false);
2982 bool bCopyTo = GetCreateMode() == SfxObjectCreateMode::EMBEDDED || (pSaveToItem && pSaveToItem->GetValue());
2983
2984 // distinguish between "Save" and "SaveAs"
2985 pImpl->bIsSaving = false;
2986
2987 // copy version list from "old" medium to target medium, so it can be used on saving
2988 if ( pImpl->bPreserveVersions )
2989 pNewFile->TransferVersionList_Impl( *pMedium );
2990
2991 // Save the document ( first as temporary file, then transfer to the target URL by committing the medium )
2992 bool bOk = false;
2993 if ( !pNewFile->GetErrorCode() && SaveTo_Impl( *pNewFile, nullptr ) )
2994 {
2995 // transfer a possible error from the medium to the document
2996 SetError(pNewFile->GetErrorCode());
2997
2998 // notify the document that saving was done successfully
2999 if ( !bCopyTo )
3000 {
3001 bOk = DoSaveCompleted( pNewFile );
3002 }
3003 else
3004 bOk = DoSaveCompleted();
3005
3006 if( bOk )
3007 {
3008 if( !bCopyTo )
3009 SetModified( false );
3010 }
3011 else
3012 {
3013 // TODO/LATER: the code below must be dead since the storage commit makes all the stuff
3014 // and the DoSaveCompleted call should not be able to fail in general
3015
3016 DBG_ASSERT( !bCopyTo, "Error while reconnecting to medium, can't be handled!");
3017 SetError(pNewFile->GetErrorCode());
3018
3019 if ( !bCopyTo )
3020 {
3021 // reconnect to the old medium
3022 bool bRet = DoSaveCompleted( pMedium );
3023 DBG_ASSERT( bRet, "Error in DoSaveCompleted, can't be handled!");
3024 }
3025
3026 // TODO/LATER: disconnect the new file from the storage for the case when pure saving is done
3027 // if storing has corrupted the file, probably it must be restored either here or
3028 // by the storage
3029 delete pNewFile;
3030 pNewFile = nullptr;
3031 }
3032 }
3033 else
3034 {
3035 SetError(pNewFile->GetErrorCode());
3036
3037 // reconnect to the old storage
3039
3040 delete pNewFile;
3041 pNewFile = nullptr;
3042 }
3043
3044 if ( bCopyTo )
3045 delete pNewFile;
3046 else if( !bOk )
3047 SetModified();
3048
3049 return bOk;
3050}
3051
3052
3054{
3055 SAL_WARN( "sfx.doc", "Base implementation, must not be called in general!" );
3056 return true;
3057}
3058
3059
3061
3062/* [Description]
3063
3064 Internal method for determining whether a reload of the document
3065 (as RevertToSaved or last known version) is possible.
3066*/
3067
3068{
3069 return pMedium && HasName() && !IsInModalMode() && !pImpl->bForbidReload;
3070}
3071
3072
3074{
3077 {
3078 if ( GetMedium()->GetVersionList().hasElements() )
3080 }
3081
3082 return nState;
3083}
3084
3086{
3087 sal_Int16 nRet = RET_YES;
3088 TranslateId pResId;
3090
3091 switch ( eFact )
3092 {
3094 {
3095 pResId = STR_HIDDENINFO_CONTINUE_SAVING;
3097 break;
3098 }
3100 {
3101 pResId = STR_HIDDENINFO_CONTINUE_PRINTING;
3103 break;
3104 }
3106 {
3107 pResId = STR_HIDDENINFO_CONTINUE_SIGNING;
3109 break;
3110 }
3112 {
3113 pResId = STR_HIDDENINFO_CONTINUE_CREATEPDF;
3115 break;
3116 }
3117 default:
3118 assert(false); // this cannot happen
3119 }
3120
3121 if ( SvtSecurityOptions::IsOptionSet( eOption ) )
3122 {
3123 OUString sMessage( SfxResId(STR_HIDDENINFO_CONTAINS) );
3125 if ( eFact != HiddenWarningFact::WhenPrinting )
3126 nWantedStates |= HiddenInformation::DOCUMENTVERSIONS;
3127 HiddenInformation nStates = GetHiddenInformationState( nWantedStates );
3128 bool bWarning = false;
3129
3130 if ( nStates & HiddenInformation::RECORDEDCHANGES )
3131 {
3132 sMessage += SfxResId(STR_HIDDENINFO_RECORDCHANGES) + "\n";
3133 bWarning = true;
3134 }
3135 if ( nStates & HiddenInformation::NOTES )
3136 {
3137 sMessage += SfxResId(STR_HIDDENINFO_NOTES) + "\n";
3138 bWarning = true;
3139 }
3141 {
3142 sMessage += SfxResId(STR_HIDDENINFO_DOCVERSIONS) + "\n";
3143 bWarning = true;
3144 }
3145
3146 if ( bWarning )
3147 {
3148 sMessage += "\n" + SfxResId(pResId);
3149 std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(pParent,
3150 VclMessageType::Warning, VclButtonsType::YesNo, sMessage));
3151 xWarn->set_default_response(RET_NO);
3152 nRet = xWarn->run();
3153 }
3154 }
3155
3156 return nRet;
3157}
3158
3160{
3161 return IsLoadReadonly();
3162}
3163
3165{
3166 SetLoadReadonly( _b );
3167}
3168
3170{
3171 SAL_INFO( "sfx.doc", "loading \" " << rMedium.GetName() << "\"" );
3172
3173 uno::Reference< embed::XStorage > xStorage = rMedium.GetStorage();
3174 if ( xStorage.is() )
3175 {
3176 // Password
3177 const SfxStringItem* pPasswdItem = SfxItemSet::GetItem<SfxStringItem>(rMedium.GetItemSet(), SID_PASSWORD, false);
3178 if ( pPasswdItem || ERRCODE_IO_ABORT != CheckPasswd_Impl( this, pMedium ) )
3179 {
3180 uno::Sequence< beans::NamedValue > aEncryptionData;
3181 if ( GetEncryptionData_Impl(pMedium->GetItemSet(), aEncryptionData) )
3182 {
3183 try
3184 {
3185 // the following code must throw an exception in case of failure
3187 }
3188 catch( uno::Exception& )
3189 {
3190 // TODO/LATER: handle the error code
3191 }
3192 }
3193
3194 // load document
3195 return Load( rMedium );
3196 }
3197 return false;
3198 }
3199 else
3200 return false;
3201}
3202
3204{
3205 uno::Reference< embed::XStorage > xStorage = rMedium.GetStorage();
3206 if( xStorage.is() )
3207 {
3208 sal_Int32 nVersion = rMedium.GetFilter()->GetVersion();
3209
3210 // OASIS templates have own mediatypes (SO7 also actually, but it is too late to use them here)
3211 const bool bTemplate = rMedium.GetFilter()->IsOwnTemplateFormat()
3213
3214 SetupStorage( xStorage, nVersion, bTemplate );
3215#if HAVE_FEATURE_SCRIPTING
3216 if ( HasBasic() )
3217 {
3218 // Initialize Basic
3220
3221 // Save dialog/script container
3222 pImpl->aBasicManager.storeLibrariesToStorage( xStorage );
3223 }
3224#endif
3225
3227 {
3228 // Because XMLTextFieldExport::ExportFieldDeclarations (called from SwXMLExport)
3229 // calls SwXTextFieldMasters::getByName, which in turn maps property names by
3230 // calling SwStyleNameMapper::GetTextUINameArray, which uses
3231 // SvtSysLocale().GetUILanguageTag() to do the mapping, saving indirectly depends
3232 // on the UI language. This is an unfortunate dependency. Here we use the loader's language.
3234 const LanguageTag loadLanguage = SfxLokHelper::getLoadLanguage();
3235
3236 // Use the default language for saving and restore later if necessary.
3237 bool restoreLanguage = false;
3238 if (viewLanguage != loadLanguage)
3239 {
3240 restoreLanguage = true;
3242 }
3243
3244 // Restore the view's original language automatically and as necessary.
3245 const ::comphelper::ScopeGuard aGuard(
3246 [&viewLanguage, restoreLanguage]()
3247 {
3248 if (restoreLanguage
3249 && viewLanguage != comphelper::LibreOfficeKit::getLanguageTag())
3251 });
3252
3253 return SaveAs(rMedium);
3254 }
3255
3256 return SaveAs( rMedium );
3257 }
3258 else return false;
3259}
3260
3261uno::Reference< embed::XStorage > const & SfxObjectShell::GetStorage()
3262{
3263 if ( !pImpl->m_xDocStorage.is() )
3264 {
3265 OSL_ENSURE( pImpl->m_bCreateTempStor, "The storage must exist already!" );
3266 try {
3267 // no notification is required the storage is set the first time
3269 OSL_ENSURE( pImpl->m_xDocStorage.is(), "The method must either return storage or throw exception!" );
3270
3271 SetupStorage( pImpl->m_xDocStorage, SOFFICE_FILEFORMAT_CURRENT, false );
3272 pImpl->m_bCreateTempStor = false;
3275 }
3276 catch( uno::Exception& )
3277 {
3278 // TODO/LATER: error handling?
3279 TOOLS_WARN_EXCEPTION("sfx.doc", "SfxObjectShell::GetStorage");
3280 }
3281 }
3282
3283 OSL_ENSURE( pImpl->m_xDocStorage.is(), "The document storage must be created!" );
3284 return pImpl->m_xDocStorage;
3285}
3286
3287
3288void SfxObjectShell::SaveChildren( bool bObjectsOnly )
3289{
3290 if ( pImpl->mxObjectContainer )
3291 {
3293 GetEmbeddedObjectContainer().StoreChildren(bOasis,bObjectsOnly);
3294 }
3295}
3296
3298{
3299 uno::Reference < embed::XStorage > xStorage = rMedium.GetStorage();
3300 if ( !xStorage.is() )
3301 return false;
3302
3303 if ( xStorage == GetStorage() )
3304 {
3305 SaveChildren();
3306 return true;
3307 }
3308
3309 bool AutoSaveEvent = false;
3310 utl::MediaDescriptor lArgs(rMedium.GetArgs());
3311 lArgs[utl::MediaDescriptor::PROP_AUTOSAVEEVENT] >>= AutoSaveEvent;
3312
3313 if ( pImpl->mxObjectContainer )
3314 {
3315 bool bOasis = ( SotStorage::GetVersion( xStorage ) > SOFFICE_FILEFORMAT_60 );
3317 }
3318
3319 uno::Sequence<OUString> aExceptions;
3320 if (const SfxBoolItem* pNoEmbDS
3321 = SfxItemSet::GetItem(rMedium.GetItemSet(), SID_NO_EMBEDDED_DS, false))
3322 {
3323 // Don't save data source in case a temporary is being saved for preview in MM wizard
3324 if (pNoEmbDS->GetValue())
3325 aExceptions = uno::Sequence<OUString>{ "EmbeddedDatabase" };
3326 }
3327
3328 return CopyStoragesOfUnknownMediaType(GetStorage(), xStorage, aExceptions);
3329}
3330
3332{
3333 bool bResult = true;
3334
3335 if ( pImpl->mxObjectContainer )
3336 {
3337 const uno::Sequence < OUString > aNames = GetEmbeddedObjectContainer().GetObjectNames();
3338 for ( const auto& rName : aNames )
3339 {
3340 uno::Reference < embed::XEmbeddedObject > xObj = GetEmbeddedObjectContainer().GetEmbeddedObject( rName );
3341 OSL_ENSURE( xObj.is(), "An empty entry in the embedded objects list!" );
3342 if ( xObj.is() )
3343 {
3344 uno::Reference< embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY );
3345 if ( xPersist.is() )
3346 {
3347 try
3348 {
3349 xPersist->saveCompleted( false/*bSuccess*/ );
3350 }
3351 catch( uno::Exception& )
3352 {
3353 // TODO/LATER: error handling
3354 bResult = false;
3355 break;
3356 }
3357 }
3358 }
3359 }
3360 }
3361
3362 return bResult;
3363}
3364
3365bool SfxObjectShell::SwitchChildrenPersistence( const uno::Reference< embed::XStorage >& xStorage,
3366 bool bForceNonModified )
3367{
3368 if ( !xStorage.is() )
3369 {
3370 // TODO/LATER: error handling
3371 return false;
3372 }
3373
3374 if ( pImpl->mxObjectContainer )
3375 pImpl->mxObjectContainer->SetPersistentEntries(xStorage,bForceNonModified);
3376
3377 return true;
3378}
3379
3380// Never call this method directly, always use the DoSaveCompleted call
3381bool SfxObjectShell::SaveCompleted( const uno::Reference< embed::XStorage >& xStorage )
3382{
3383 bool bResult = false;
3384 bool bSendNotification = false;
3385 uno::Reference< embed::XStorage > xOldStorageHolder;
3386
3387 // check for wrong creation of object container
3388 bool bHasContainer( pImpl->mxObjectContainer );
3389
3390 if ( !xStorage.is() || xStorage == GetStorage() )
3391 {
3392 // no persistence change
3393 bResult = SaveCompletedChildren();
3394 }
3395 else
3396 {
3397 if ( pImpl->mxObjectContainer )
3399
3400 bResult = SwitchChildrenPersistence( xStorage, true );
3401 }
3402
3403 if ( bResult )
3404 {
3405 if ( xStorage.is() && pImpl->m_xDocStorage != xStorage )
3406 {
3407 // make sure that until the storage is assigned the object
3408 // container is not created by accident!
3409 DBG_ASSERT( bHasContainer == (pImpl->mxObjectContainer != nullptr), "Wrong storage in object container!" );
3410 xOldStorageHolder = pImpl->m_xDocStorage;
3411 pImpl->m_xDocStorage = xStorage;
3412 bSendNotification = true;
3413
3414 if ( IsEnableSetModified() )
3415 SetModified( false );
3416 }
3417 }
3418 else
3419 {
3420 if ( pImpl->mxObjectContainer )
3422
3423 // let already successfully connected objects be switched back
3424 SwitchChildrenPersistence( pImpl->m_xDocStorage, true );
3425 }
3426
3427 if ( bSendNotification )
3428 {
3430 }
3431
3432 return bResult;
3433}
3434
3435static bool StoragesOfUnknownMediaTypeAreCopied_Impl( const uno::Reference< embed::XStorage >& xSource,
3436 const uno::Reference< embed::XStorage >& xTarget )
3437{
3438 OSL_ENSURE( xSource.is() && xTarget.is(), "Source and/or target storages are not available!" );
3439 if ( !xSource.is() || !xTarget.is() || xSource == xTarget )
3440 return true;
3441
3442 try
3443 {
3444 const uno::Sequence< OUString > aSubElements = xSource->getElementNames();
3445 for ( const auto& rSubElement : aSubElements )
3446 {
3447 if ( xSource->isStorageElement( rSubElement ) )
3448 {
3449 OUString aMediaType;
3450 static const OUStringLiteral aMediaTypePropName( u"MediaType" );
3451 bool bGotMediaType = false;
3452
3453 try
3454 {
3455 uno::Reference< embed::XOptimizedStorage > xOptStorage( xSource, uno::UNO_QUERY_THROW );
3456 bGotMediaType =
3457 ( xOptStorage->getElementPropertyValue( rSubElement, aMediaTypePropName ) >>= aMediaType );
3458 }
3459 catch( uno::Exception& )
3460 {}
3461
3462 if ( !bGotMediaType )
3463 {
3464 uno::Reference< embed::XStorage > xSubStorage;
3465 try {
3466 xSubStorage = xSource->openStorageElement( rSubElement, embed::ElementModes::READ );
3467 } catch( uno::Exception& )
3468 {}
3469
3470 if ( !xSubStorage.is() )
3471 {
3473 xSource->copyStorageElementLastCommitTo( rSubElement, xSubStorage );
3474 }
3475
3476 uno::Reference< beans::XPropertySet > xProps( xSubStorage, uno::UNO_QUERY_THROW );
3477 xProps->getPropertyValue( aMediaTypePropName ) >>= aMediaType;
3478 }
3479
3480 // TODO/LATER: there should be a way to detect whether an object with such a MediaType can exist
3481 // probably it should be placed in the MimeType-ClassID table or in standalone table
3482 if ( !aMediaType.isEmpty()
3483 && aMediaType != "application/vnd.sun.star.oleobject" )
3484 {
3485 css::datatransfer::DataFlavor aDataFlavor;
3486 aDataFlavor.MimeType = aMediaType;
3487 SotClipboardFormatId nFormat = SotExchange::GetFormat( aDataFlavor );
3488
3489 switch ( nFormat )
3490 {
3491 case SotClipboardFormatId::STARWRITER_60 :
3492 case SotClipboardFormatId::STARWRITERWEB_60 :
3493 case SotClipboardFormatId::STARWRITERGLOB_60 :
3494 case SotClipboardFormatId::STARDRAW_60 :
3495 case SotClipboardFormatId::STARIMPRESS_60 :
3496 case SotClipboardFormatId::STARCALC_60 :
3497 case SotClipboardFormatId::STARCHART_60 :
3498 case SotClipboardFormatId::STARMATH_60 :
3499 case SotClipboardFormatId::STARWRITER_8:
3500 case SotClipboardFormatId::STARWRITERWEB_8:
3501 case SotClipboardFormatId::STARWRITERGLOB_8:
3502 case SotClipboardFormatId::STARDRAW_8:
3503 case SotClipboardFormatId::STARIMPRESS_8:
3504 case SotClipboardFormatId::STARCALC_8:
3505 case SotClipboardFormatId::STARCHART_8:
3506 case SotClipboardFormatId::STARMATH_8:
3507 break;
3508
3509 default:
3510 {
3511 if ( !xTarget->hasByName( rSubElement ) )
3512 return false;
3513 }
3514 }
3515 }
3516 }
3517 }
3518 }
3519 catch( uno::Exception& )
3520 {
3521 SAL_WARN( "sfx.doc", "Can not check storage consistency!" );
3522 }
3523
3524 return true;
3525}
3526
3527bool SfxObjectShell::SwitchPersistence( const uno::Reference< embed::XStorage >& xStorage )
3528{
3529 bool bResult = false;
3530 // check for wrong creation of object container
3531 bool bHasContainer( pImpl->mxObjectContainer );
3532 if ( xStorage.is() )
3533 {
3534 if ( pImpl->mxObjectContainer )
3536 bResult = SwitchChildrenPersistence( xStorage );
3537
3538 // TODO/LATER: substorages that have unknown mimetypes probably should be copied to the target storage here
3539 OSL_ENSURE( StoragesOfUnknownMediaTypeAreCopied_Impl( pImpl->m_xDocStorage, xStorage ),
3540 "Some of substorages with unknown mimetypes is lost!" );
3541 }
3542
3543 if ( bResult )
3544 {
3545 // make sure that until the storage is assigned the object container is not created by accident!
3546 DBG_ASSERT( bHasContainer == (pImpl->mxObjectContainer != nullptr), "Wrong storage in object container!" );
3547 if ( pImpl->m_xDocStorage != xStorage )
3548 DoSaveCompleted( new SfxMedium( xStorage, GetMedium()->GetBaseURL() ) );
3549
3550 if ( IsEnableSetModified() )
3551 SetModified(); // ???
3552 }
3553
3554 return bResult;
3555}
3556
3557bool SfxObjectShell::CopyStoragesOfUnknownMediaType(const uno::Reference< embed::XStorage >& xSource,
3558 const uno::Reference< embed::XStorage >& xTarget,
3559 const uno::Sequence<OUString>& rExceptions)
3560{
3561 if (!xSource.is())
3562 {
3563 SAL_WARN( "sfx.doc", "SfxObjectShell::GetStorage() failed");
3564 return false;
3565 }
3566
3567 // This method does not commit the target storage and should not do it
3568 bool bResult = true;
3569
3570 try
3571 {
3572 const css::uno::Sequence<OUString> aSubElementNames = xSource->getElementNames();
3573 for (const OUString& rSubElement : aSubElementNames)
3574 {
3575 if (std::find(rExceptions.begin(), rExceptions.end(), rSubElement) != rExceptions.end())
3576 continue;
3577
3578 if (rSubElement == "Configurations")
3579 {
3580 // The workaround for compatibility with SO7, "Configurations" substorage must be preserved
3581 if (xSource->isStorageElement(rSubElement))
3582 {
3583 OSL_ENSURE(!xTarget->hasByName(rSubElement), "The target storage is an output "
3584 "storage, the element should not "
3585 "exist in the target!");
3586
3587 xSource->copyElementTo(rSubElement, xTarget, rSubElement);
3588 }
3589 }
3590 else if (xSource->isStorageElement(rSubElement))
3591 {
3592 OUString aMediaType;
3593 static const OUStringLiteral aMediaTypePropName( u"MediaType" );
3594 bool bGotMediaType = false;
3595
3596 try
3597 {
3598 uno::Reference< embed::XOptimizedStorage > xOptStorage( xSource, uno::UNO_QUERY_THROW );
3599 bGotMediaType = (xOptStorage->getElementPropertyValue(rSubElement, aMediaTypePropName)
3600 >>= aMediaType);
3601 }
3602 catch( uno::Exception& )
3603 {}
3604
3605 if ( !bGotMediaType )
3606 {
3607 uno::Reference< embed::XStorage > xSubStorage;
3608 try {
3609 xSubStorage
3610 = xSource->openStorageElement(rSubElement, embed::ElementModes::READ);
3611 } catch( uno::Exception& )
3612 {}
3613
3614 if ( !xSubStorage.is() )
3615 {
3616 // TODO/LATER: as optimization in future a substorage of target storage could be used
3617 // instead of the temporary storage; this substorage should be removed later
3618 // if the MimeType is wrong
3620 xSource->copyStorageElementLastCommitTo(rSubElement, xSubStorage);
3621 }
3622
3623 uno::Reference< beans::XPropertySet > xProps( xSubStorage, uno::UNO_QUERY_THROW );
3624 xProps->getPropertyValue( aMediaTypePropName ) >>= aMediaType;
3625 }
3626
3627 // TODO/LATER: there should be a way to detect whether an object with such a MediaType can exist
3628 // probably it should be placed in the MimeType-ClassID table or in standalone table
3629 if ( !aMediaType.isEmpty()
3630 && aMediaType != "application/vnd.sun.star.oleobject" )
3631 {
3632 css::datatransfer::DataFlavor aDataFlavor;
3633 aDataFlavor.MimeType = aMediaType;
3634 SotClipboardFormatId nFormat = SotExchange::GetFormat( aDataFlavor );
3635
3636 switch ( nFormat )
3637 {
3638 case SotClipboardFormatId::STARWRITER_60 :
3639 case SotClipboardFormatId::STARWRITERWEB_60 :
3640 case SotClipboardFormatId::STARWRITERGLOB_60 :
3641 case SotClipboardFormatId::STARDRAW_60 :
3642 case SotClipboardFormatId::STARIMPRESS_60 :
3643 case SotClipboardFormatId::STARCALC_60 :
3644 case SotClipboardFormatId::STARCHART_60 :
3645 case SotClipboardFormatId::STARMATH_60 :
3646 case SotClipboardFormatId::STARWRITER_8:
3647 case SotClipboardFormatId::STARWRITERWEB_8:
3648 case SotClipboardFormatId::STARWRITERGLOB_8:
3649 case SotClipboardFormatId::STARDRAW_8:
3650 case SotClipboardFormatId::STARIMPRESS_8:
3651 case SotClipboardFormatId::STARCALC_8:
3652 case SotClipboardFormatId::STARCHART_8:
3653 case SotClipboardFormatId::STARMATH_8:
3654 break;
3655
3656 default:
3657 {
3658 OSL_ENSURE(rSubElement == "Configurations2"
3659 || nFormat == SotClipboardFormatId::STARBASE_8
3660 || !xTarget->hasByName(rSubElement),
3661 "The target storage is an output storage, the element "
3662 "should not exist in the target!");
3663
3664 if (!xTarget->hasByName(rSubElement))
3665 {
3666 xSource->copyElementTo(rSubElement, xTarget, rSubElement);
3667 }
3668 }
3669 }
3670 }
3671 }
3672 }
3673 }
3674 catch( uno::Exception& )
3675 {
3676 bResult = false;
3677 // TODO/LATER: a specific error could be provided
3678 }
3679
3680 return bResult;
3681}
3682
3683bool SfxObjectShell::GenerateAndStoreThumbnail(bool bEncrypted, const uno::Reference<embed::XStorage>& xStorage)
3684{
3685 //optimize thumbnail generate and store procedure to improve odt saving performance, i120030
3687
3688 bool bResult = false;
3689
3690 try
3691 {
3692 uno::Reference<embed::XStorage> xThumbnailStorage = xStorage->openStorageElement("Thumbnails", embed::ElementModes::READWRITE);
3693
3694 if (xThumbnailStorage.is())
3695 {
3696 uno::Reference<io::XStream> xStream = xThumbnailStorage->openStreamElement("thumbnail.png", embed::ElementModes::READWRITE);
3697
3698 if (xStream.is() && WriteThumbnail(bEncrypted, xStream))
3699 {
3700 uno::Reference<embed::XTransactedObject> xTransactedObject(xThumbnailStorage, uno::UNO_QUERY_THROW);
3701 xTransactedObject->commit();
3702 bResult = true;
3703 }
3704 }
3705 }
3706 catch( uno::Exception& )
3707 {
3708 }
3709
3710 //optimize thumbnail generate and store procedure to improve odt saving performance, i120030
3711 bIsInGenerateThumbnail = false;
3712
3713 return bResult;
3714}
3715
3716bool SfxObjectShell::WriteThumbnail(bool bEncrypted, const uno::Reference<io::XStream>& xStream)
3717{
3718 bool bResult = false;
3719
3720 if (!xStream.is())
3721 return false;
3722
3723 try
3724 {
3725 uno::Reference<io::XTruncate> xTruncate(xStream->getOutputStream(), uno::UNO_QUERY_THROW);
3726 xTruncate->truncate();
3727
3728 uno::Reference <beans::XPropertySet> xSet(xStream, uno::UNO_QUERY);
3729 if (xSet.is())
3730 xSet->setPropertyValue("MediaType", uno::Any(OUString("image/png")));
3731 if (bEncrypted)
3732 {
3733 const OUString sResID = GraphicHelper::getThumbnailReplacementIDByFactoryName_Impl(
3734 GetFactory().GetFactoryName());
3735 if (!sResID.isEmpty())
3736 bResult = GraphicHelper::getThumbnailReplacement_Impl(sResID, xStream);
3737 }
3738 else
3739 {
3740 BitmapEx bitmap = GetPreviewBitmap();
3741 if (!bitmap.IsEmpty())
3742 {
3743 bResult = GraphicHelper::getThumbnailFormatFromBitmap_Impl(bitmap, xStream);
3744 }
3745 }
3746 }
3747 catch(uno::Exception&)
3748 {}
3749
3750 return bResult;
3751}
3752
3754{
3755}
3756
3758{
3759 // Not implemented. It's an error if the code path ever comes here.
3760 assert(false);
3761 return false;
3762}
3763
3765 uno::Reference<text::XTextRange> const&)
3766{
3767 // Not implemented. It's an error if the code path ever comes here.
3768 assert(false);
3769 return false;
3770}
3771
3773{
3774 return pImpl->m_bConfigOptionsChecked;
3775}
3776
3778{
3779 pImpl->m_bConfigOptionsChecked = bChecked;
3780}
3781
3783{
3784 pImpl->m_bMacroCallsSeenWhileLoading = true;
3785}
3786
3788{
3789 if (officecfg::Office::Common::Security::Scripting::CheckDocumentEvents::get())
3790 return pImpl->m_bMacroCallsSeenWhileLoading;
3791 return false;
3792}
3793
3794bool SfxObjectShell::QuerySaveSizeExceededModules_Impl( const uno::Reference< task::XInteractionHandler >& xHandler )
3795{
3796#if !HAVE_FEATURE_SCRIPTING
3797 (void) xHandler;
3798#else
3799 if ( !HasBasic() )
3800 return true;
3801
3802 if ( !pImpl->aBasicManager.isValid() )
3804 std::vector< OUString > sModules;
3805 if ( xHandler.is() )
3806 {
3807 if( pImpl->aBasicManager.LegacyPsswdBinaryLimitExceeded( sModules ) )
3808 {
3809 rtl::Reference<ModuleSizeExceeded> pReq = new ModuleSizeExceeded( sModules );
3810 xHandler->handle( pReq );
3811 return pReq->isApprove();
3812 }
3813 }
3814#endif
3815 // No interaction handler, default is to continue to save
3816 return true;
3817}
3818
3819bool SfxObjectShell::QueryAllowExoticFormat_Impl( const uno::Reference< task::XInteractionHandler >& xHandler, const OUString& rURL, const OUString& rFilterUIName )
3820{
3822 {
3823 // Always load from trusted location
3824 return true;
3825 }
3826 if ( officecfg::Office::Common::Security::LoadExoticFileFormats::get() == 0 )
3827 {
3828 // Refuse loading without question
3829 return false;
3830 }
3831 else if ( officecfg::Office::Common::Security::LoadExoticFileFormats::get() == 2 )
3832 {
3833 // Always load without question
3834 return true;
3835 }
3836 else if ( officecfg::Office::Common::Security::LoadExoticFileFormats::get() == 1 && xHandler.is() )
3837 {
3838 // Display a warning and let the user decide
3839 rtl::Reference<ExoticFileLoadException> xException(new ExoticFileLoadException( rURL, rFilterUIName ));
3840 xHandler->handle( xException );
3841 return xException->isApprove();
3842 }
3843 // No interaction handler, default is to continue to load
3844 return true;
3845}
3846
3847uno::Reference< task::XInteractionHandler > SfxObjectShell::getInteractionHandler() const
3848{
3849 uno::Reference< task::XInteractionHandler > xRet;
3850 if ( GetMedium() )
3851 xRet = GetMedium()->GetInteractionHandler();
3852 return xRet;
3853}
3854
3856{
3857 return GetMedium()->GetBaseURL();
3858}
3859
3860/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Reference< XInputStream > xStream
SfxApplication * SfxGetpApp()
Definition: app.hxx:232
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:722
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
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:3974
const std::shared_ptr< const SfxFilter > & GetFilter() const
Definition: docfile.cxx:3089
void DisableFileSync(bool bDisableFileSync)
Lets Transfer_Impl() not fsync the output file.
Definition: docfile.cxx:3144
void Close(bool bInDestruction=false)
Definition: docfile.cxx:3115
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:4301
SAL_DLLPRIVATE void DoBackup_Impl()
Definition: docfile.cxx:2637
const INetURLObject & GetURLObject() const
Definition: docfile.cxx:3575
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:3619
void CloseAndRelease()
Definition: docfile.cxx:3127
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:4290
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:4513
SfxItemSet * GetItemSet() const
Definition: docfile.cxx:3625
SAL_DLLPRIVATE void SaveVersionList_Impl()
Definition: docfile.cxx:3759
ErrCode GetError() const
Definition: docfile.hxx:147
SAL_DLLPRIVATE OUString const & GetBackup_Impl()
Definition: docfile.cxx:940
SAL_DLLPRIVATE bool TransferVersionList_Impl(SfxMedium const &rMedium)
Definition: docfile.cxx:3748
StreamMode GetOpenMode() const
Definition: docfile.cxx:1957
bool IsInCheckIn() const
Definition: docfile.cxx:4518
const OUString & GetOrigURL() const
Definition: docfile.cxx:3342
SAL_DLLPRIVATE void SetLongName(const OUString &rName)
Definition: docfile.cxx:2907
const css::uno::Sequence< css::util::RevisionTag > & GetVersionList(bool _bNoReload=false)
Definition: docfile.cxx:3666
const OUString & GetName() const
Definition: docfile.cxx:3570
void DisableUnlockWebDAV(bool bDisableUnlockWebDAV=true)
Definition: docfile.cxx:3139
bool SwitchDocumentToFile(const OUString &aURL)
Definition: docfile.cxx:4462
SAL_DLLPRIVATE bool HasStorage_Impl() const
Definition: docfile.cxx:4306
void ReOpen()
Definition: docfile.cxx:3363
SAL_DLLPRIVATE bool WillDisposeStorageOnClose_Impl()
Definition: docfile.cxx:1952
SAL_DLLPRIVATE void SetCachedSignatureState_Impl(SignatureState nState)
Definition: docfile.cxx:4296
const css::uno::Sequence< css::beans::PropertyValue > & GetArgs() const
Definition: docfile.cxx:3508
SAL_DLLPRIVATE void GetMedium_Impl()
Definition: docfile.cxx:2758
SAL_DLLPRIVATE const OUString & GetLongName() const
Definition: docfile.cxx:2912
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:3084
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:3659
SAL_DLLPRIVATE void ClearBackup_Impl()
Definition: docfile.cxx:2694
SAL_DLLPRIVATE void AddVersion_Impl(css::util::RevisionTag &rVersion)
Definition: docfile.cxx:3704
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:3498
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:3054
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:2179
comphelper::EmbeddedObjectContainer & GetEmbeddedObjectContainer() const
Definition: objembed.cxx:204
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:2126
SAL_DLLPRIVATE bool CommonSaveAs_Impl(const INetURLObject &aURL, const OUString &aFilterName, SfxItemSet &rItemSet, const css::uno::Sequence< css::beans::PropertyValue > &rArgs)
Definition: objstor.cxx:2705
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:1929
void SaveChildren(bool bObjectsOnly=false)
Definition: objstor.cxx:3288
void SetConfigOptionsChecked(bool bChecked)
Definition: objstor.cxx:3777
void SetTitle(const OUString &rTitle)
Definition: objmisc.cxx:664
virtual css::uno::Reference< css::task::XInteractionHandler > getInteractionHandler() const override
Definition: objstor.cxx:3847
virtual bool DoSaveCompleted(SfxMedium *pNewStor=nullptr, bool bRegisterRecent=true)
Definition: objstor.cxx:1948
virtual bool LoadFrom(SfxMedium &rMedium)
Definition: objstor.cxx:3053
SAL_DLLPRIVATE bool CanReload_Impl()
Definition: objstor.cxx:3060
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:2669
bool IsLoadReadonly() const
Definition: objcont.cxx:640
bool IsConfigOptionsChecked() const
Definition: objstor.cxx:3772
bool SaveCompletedChildren()
Definition: objstor.cxx:3331
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:3557
static SAL_DLLPRIVATE bool QueryAllowExoticFormat_Impl(const css::uno::Reference< css::task::XInteractionHandler > &xHandler, const OUString &rURL, const OUString &rFilterUIName)
Definition: objstor.cxx:3819
SAL_DLLPRIVATE void SetInitialized_Impl(const bool i_fromInitNew)
Definition: objxtor.cxx:1064
bool IsInModalMode() const
Definition: objmisc.cxx:418
bool DoLoadExternal(SfxMedium *pMed)
Definition: objstor.cxx:850
SAL_DLLPRIVATE bool DisconnectStorage_Impl(SfxMedium &rSrcMedium, SfxMedium &rTargetMedium)
Definition: objstor.cxx:1760
bool IsReadOnlyMedium() const
Definition: objmisc.cxx:345
bool LoadOwnFormat(SfxMedium &pMedium)
Definition: objstor.cxx:3169
SAL_DLLPRIVATE bool DoSave_Impl(const SfxItemSet *pSet)
Definition: objstor.cxx:2571
static bool IsOwnStorageFormat(const SfxMedium &)
Definition: objstor.cxx:953
BasicManager * GetBasicManager() const
Definition: objxtor.cxx:636
virtual bool SaveAs(SfxMedium &rMedium)
Definition: objstor.cxx:158
bool HasName() const
Definition: objsh.hxx:261
bool IsEnableSetModified() const
Definition: objmisc.cxx:248
SfxObjectCreateMode eCreateMode
Definition: objsh.hxx:187
bool SaveAsChildren(SfxMedium &rMedium)
Definition: objstor.cxx:3297
virtual bool SaveCompleted(const css::uno::Reference< css::embed::XStorage > &xStorage)
Definition: objstor.cxx:3381
static SAL_WARN_UNUSED_RESULT SfxObjectShell * GetNext(const SfxObjectShell &rPrev, const std::function< bool(const SfxObjectShell *)> &isObjectShell=nullptr, bool bOnlyVisible=true)
Definition: objxtor.cxx:450
sal_Int16 QueryHiddenInformation(HiddenWarningFact eFact, weld::Window *pParent)
Definition: objstor.cxx:3085
virtual SfxObjectFactory & GetFactory() const =0
virtual std::unique_ptr< LockAllViewsGuard > LockAllViews()
Definition: objsh.hxx:790
bool HasBasic() const
Definition: objxtor.cxx:654
bool SwitchToShared(bool bShared, bool bSave)
bool IsReadOnly() const
Definition: objmisc.cxx:412
bool GenerateAndStoreThumbnail(bool bEncrypted, const css::uno::Reference< css::embed::XStorage > &xStor)
Definition: objstor.cxx:3683
virtual bool ConvertTo(SfxMedium &rMedium)
Definition: objstor.cxx:2516
bool IsDocShared() const
Definition: objmisc.cxx:630
bool IsSecurityOptOpenReadOnly() const
Definition: objstor.cxx:3159
virtual bool Save()
Definition: objstor.cxx:151
void AddToRecentlyUsedList()
Definition: objstor.cxx:2111
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:3365
void FinishedLoading(SfxLoadedFlags nWhich=SfxLoadedFlags::ALL)
Definition: objmisc.cxx:1069
SAL_DLLPRIVATE bool QuerySaveSizeExceededModules_Impl(const css::uno::Reference< css::task::XInteractionHandler > &xHandler)
Definition: objstor.cxx:3794
bool IsModified() const
Definition: objmisc.cxx:255
SfxMedium * pMedium
Definition: objsh.hxx:185
SAL_DLLPRIVATE bool SaveTo_Impl(SfxMedium &rMedium, const SfxItemSet *pSet)
Definition: objstor.cxx:1129
virtual bool SaveAsOwnFormat(SfxMedium &pMedium)
Definition: objstor.cxx:3203
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:3716
SfxMedium * GetMedium() const
Definition: objsh.hxx:256
void SetReadOnlyUI(bool bReadOnly=true)
Definition: objmisc.cxx:369
css::uno::Reference< css::frame::XModel3 > GetModel() const
Definition: objxtor.cxx:830
OUString GetTitle(sal_uInt16 nMaxLen=0) const
Definition: objmisc.cxx:706
SAL_DLLPRIVATE void InitOwnModel_Impl()
Definition: objmisc.cxx:1034
bool DoSaveObjectAs(SfxMedium &rNewStor, bool bCommit)
Definition: objstor.cxx:1887
virtual OUString getDocumentBaseURL() const override
Definition: objstor.cxx:3855
bool DoSave()
Definition: objstor.cxx:970
void UpdateDocInfoForSave()
Definition: objcont.cxx:207
std::unique_ptr< struct SfxObjectShell_Impl > pImpl
Definition: objsh.hxx:183
bool GetMacroCallsSeenWhileLoading() const
Definition: objstor.cxx:3787
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:3073
bool SwitchPersistence(const css::uno::Reference< css::embed::XStorage > &xStorage)
Definition: objstor.cxx:3527
css::uno::Reference< css::embed::XStorage > const & GetStorage()
Definition: objstor.cxx:3261
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:633
bool IsUseThumbnailSave() const
Definition: objcont.cxx:614
virtual bool LoadExternal(SfxMedium &rMedium)
Definition: objstor.cxx:3757
bool DoLoad(SfxMedium *pMedium)
Definition: objstor.cxx:572
void SetLoadReadonly(bool _bReadonly)
Definition: objcont.cxx:650
bool ExportTo(SfxMedium &rMedium)
Definition: objstor.cxx:2359
static SAL_WARN_UNUSED_RESULT SfxObjectShell * GetFirst(const std::function< bool(const SfxObjectShell *)> &isObjectShell=nullptr, bool bOnlyVisible=true)
Definition: objxtor.cxx:425
virtual void FillClass(SvGlobalName *pClassName, SotClipboardFormatId *pFormat, OUString *pFullTypeName, sal_Int32 nVersion, bool bTemplate=false) const =0
SfxObjectCreateMode GetCreateMode() const
Definition: objsh.hxx:479
void InvalidateName()
Definition: objmisc.cxx:835
SAL_DLLPRIVATE void PrepareSecondTryLoad_Impl()
Definition: objstor.cxx:379
void SetMacroCallsSeenWhileLoading()
Definition: objstor.cxx:3782
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:3753
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:2848
SAL_DLLPRIVATE void SetActivateEvent_Impl(SfxEventHintId)
Definition: objmisc.cxx:918
bool bIsInGenerateThumbnail
Definition: objsh.hxx:190
virtual void TerminateEditing()
Terminate any in-flight editing. Used before saving, primarily by Calc to commit cell changes.
Definition: objsh.hxx:308
SAL_DLLPRIVATE bool ConnectTmpStorage_Impl(const css::uno::Reference< css::embed::XStorage > &xStorage, SfxMedium *pMedium)
Definition: objstor.cxx:1804
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:3764
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:297
void SetSecurityOptOpenReadOnly(bool bOpenReadOnly)
Definition: objstor.cxx:3164
bool bHasName
Definition: objsh.hxx:188
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:1989
SfxDispatcher * GetDispatcher()
Definition: viewfrm.hxx:109
static SAL_WARN_UNUSED_RESULT SfxViewFrame * GetFirst(const SfxObjectShell *pDoc=nullptr, bool bOnlyVisible=true)
Definition: viewfrm.cxx:1966
void Enable(bool bEnable)
Definition: viewfrm.cxx:2083
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 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 char * sName
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:133
#define SFX_TITLE_DETECT
Definition: objsh.hxx:114
HiddenWarningFact
Definition: objsh.hxx:147
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:3435
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
SignatureState
OUString sMessage
Reference< XModel > xModel
OUString Name
RET_NO
RET_YES
sal_Int32 nLength