LCOV - code coverage report
Current view: top level - sfx2/source/doc - objstor.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 968 1542 62.8 %
Date: 2015-06-13 12:38:46 Functions: 44 66 66.7 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11