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