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