xref: /AOO41X/main/sfx2/source/doc/docfile.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 #include <sfx2/docfile.hxx>
31*cdf0e10cSrcweir #include "sfx2/signaturestate.hxx"
32*cdf0e10cSrcweir 
33*cdf0e10cSrcweir #include <uno/mapping.hxx>
34*cdf0e10cSrcweir #include <com/sun/star/task/XInteractionHandler.hpp>
35*cdf0e10cSrcweir #include <com/sun/star/uno/Reference.h>
36*cdf0e10cSrcweir #include <com/sun/star/ucb/XContent.hpp>
37*cdf0e10cSrcweir #include <com/sun/star/document/XDocumentRevisionListPersistence.hpp>
38*cdf0e10cSrcweir #include <com/sun/star/document/LockedDocumentRequest.hpp>
39*cdf0e10cSrcweir #include <com/sun/star/document/OwnLockOnDocumentRequest.hpp>
40*cdf0e10cSrcweir #include <com/sun/star/document/LockedOnSavingRequest.hpp>
41*cdf0e10cSrcweir #include <com/sun/star/document/LockFileIgnoreRequest.hpp>
42*cdf0e10cSrcweir #include <com/sun/star/document/ChangedByOthersRequest.hpp>
43*cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp>
44*cdf0e10cSrcweir #include <com/sun/star/embed/XTransactedObject.hpp>
45*cdf0e10cSrcweir #include <com/sun/star/embed/ElementModes.hpp>
46*cdf0e10cSrcweir #include <com/sun/star/embed/UseBackupException.hpp>
47*cdf0e10cSrcweir #include <com/sun/star/embed/XOptimizedStorage.hpp>
48*cdf0e10cSrcweir #include <com/sun/star/ucb/InteractiveIOException.hpp>
49*cdf0e10cSrcweir #include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
50*cdf0e10cSrcweir #include <com/sun/star/ucb/CommandFailedException.hpp>
51*cdf0e10cSrcweir #include <com/sun/star/ucb/CommandAbortedException.hpp>
52*cdf0e10cSrcweir #include <com/sun/star/ucb/XCommandEnvironment.hpp>
53*cdf0e10cSrcweir #include <com/sun/star/ucb/XContentIdentifierFactory.hpp>
54*cdf0e10cSrcweir #include <com/sun/star/ucb/XContentProvider.hpp>
55*cdf0e10cSrcweir #include <com/sun/star/ucb/XProgressHandler.hpp>
56*cdf0e10cSrcweir #include <com/sun/star/ucb/XCommandInfo.hpp>
57*cdf0e10cSrcweir #include <com/sun/star/util/XArchiver.hpp>
58*cdf0e10cSrcweir #include <com/sun/star/io/XOutputStream.hpp>
59*cdf0e10cSrcweir #include <com/sun/star/io/XInputStream.hpp>
60*cdf0e10cSrcweir #include <com/sun/star/io/XTruncate.hpp>
61*cdf0e10cSrcweir #include <com/sun/star/io/XStreamListener.hpp>
62*cdf0e10cSrcweir #include <com/sun/star/io/XSeekable.hpp>
63*cdf0e10cSrcweir #include <com/sun/star/ucb/XSimpleFileAccess.hpp>
64*cdf0e10cSrcweir #include <com/sun/star/lang/XInitialization.hpp>
65*cdf0e10cSrcweir #include <com/sun/star/ucb/InsertCommandArgument.hpp>
66*cdf0e10cSrcweir #include <com/sun/star/ucb/NameClash.hpp>
67*cdf0e10cSrcweir #include <com/sun/star/ucb/TransferInfo.hpp>
68*cdf0e10cSrcweir #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
69*cdf0e10cSrcweir #include <com/sun/star/ucb/OpenMode.hpp>
70*cdf0e10cSrcweir #include <com/sun/star/ucb/NameClashException.hpp>
71*cdf0e10cSrcweir #include <com/sun/star/logging/XSimpleLogRing.hpp>
72*cdf0e10cSrcweir #include <cppuhelper/implbase1.hxx>
73*cdf0e10cSrcweir #include <com/sun/star/beans/PropertyValue.hpp>
74*cdf0e10cSrcweir #ifndef _COM_SUN_STAR_SECURITY_DOCUMENTSIGNATURESINFORMATION_HPP_
75*cdf0e10cSrcweir #include <com/sun/star/security/DocumentSignatureInformation.hpp>
76*cdf0e10cSrcweir #endif
77*cdf0e10cSrcweir #include <com/sun/star/security/XDocumentDigitalSignatures.hpp>
78*cdf0e10cSrcweir #include <tools/zcodec.hxx>
79*cdf0e10cSrcweir #include <tools/cachestr.hxx>
80*cdf0e10cSrcweir #include <tools/urlobj.hxx>
81*cdf0e10cSrcweir #include <unotools/tempfile.hxx>
82*cdf0e10cSrcweir #include <comphelper/processfactory.hxx>
83*cdf0e10cSrcweir #include <comphelper/componentcontext.hxx>
84*cdf0e10cSrcweir #include <comphelper/interaction.hxx>
85*cdf0e10cSrcweir #include <framework/interaction.hxx>
86*cdf0e10cSrcweir #include <unotools/streamhelper.hxx>
87*cdf0e10cSrcweir #include <unotools/localedatawrapper.hxx>
88*cdf0e10cSrcweir #ifndef _MSGBOX_HXX //autogen
89*cdf0e10cSrcweir #include <vcl/msgbox.hxx>
90*cdf0e10cSrcweir #endif
91*cdf0e10cSrcweir #include <svl/stritem.hxx>
92*cdf0e10cSrcweir #include <svl/eitem.hxx>
93*cdf0e10cSrcweir #include <svl/lckbitem.hxx>
94*cdf0e10cSrcweir #include <svtools/sfxecode.hxx>
95*cdf0e10cSrcweir #include <svl/itemset.hxx>
96*cdf0e10cSrcweir #include <svl/intitem.hxx>
97*cdf0e10cSrcweir #include <svtools/svparser.hxx> // SvKeyValue
98*cdf0e10cSrcweir #include <cppuhelper/weakref.hxx>
99*cdf0e10cSrcweir #include <cppuhelper/implbase1.hxx>
100*cdf0e10cSrcweir 
101*cdf0e10cSrcweir #define _SVSTDARR_ULONGS
102*cdf0e10cSrcweir #define _SVSTDARR_STRINGSDTOR
103*cdf0e10cSrcweir #include <svl/svstdarr.hxx>
104*cdf0e10cSrcweir 
105*cdf0e10cSrcweir #include <unotools/streamwrap.hxx>
106*cdf0e10cSrcweir 
107*cdf0e10cSrcweir #include <rtl/logfile.hxx>
108*cdf0e10cSrcweir #include <osl/file.hxx>
109*cdf0e10cSrcweir 
110*cdf0e10cSrcweir using namespace ::com::sun::star;
111*cdf0e10cSrcweir using namespace ::com::sun::star::uno;
112*cdf0e10cSrcweir using namespace ::com::sun::star::ucb;
113*cdf0e10cSrcweir using namespace ::com::sun::star::beans;
114*cdf0e10cSrcweir using namespace ::com::sun::star::io;
115*cdf0e10cSrcweir 
116*cdf0e10cSrcweir #include <comphelper/storagehelper.hxx>
117*cdf0e10cSrcweir #include <comphelper/mediadescriptor.hxx>
118*cdf0e10cSrcweir #include <comphelper/configurationhelper.hxx>
119*cdf0e10cSrcweir #include <comphelper/docpasswordhelper.hxx>
120*cdf0e10cSrcweir #include <tools/urlobj.hxx>
121*cdf0e10cSrcweir #include <tools/inetmime.hxx>
122*cdf0e10cSrcweir #include <unotools/ucblockbytes.hxx>
123*cdf0e10cSrcweir #include <unotools/pathoptions.hxx>
124*cdf0e10cSrcweir #include <svtools/asynclink.hxx>
125*cdf0e10cSrcweir #include <svl/inettype.hxx>
126*cdf0e10cSrcweir #include <ucbhelper/contentbroker.hxx>
127*cdf0e10cSrcweir #include <ucbhelper/commandenvironment.hxx>
128*cdf0e10cSrcweir #include <unotools/localfilehelper.hxx>
129*cdf0e10cSrcweir #include <unotools/ucbstreamhelper.hxx>
130*cdf0e10cSrcweir #include <unotools/ucbhelper.hxx>
131*cdf0e10cSrcweir #include <unotools/progresshandlerwrap.hxx>
132*cdf0e10cSrcweir #include <ucbhelper/content.hxx>
133*cdf0e10cSrcweir #include <ucbhelper/interactionrequest.hxx>
134*cdf0e10cSrcweir #include <sot/stg.hxx>
135*cdf0e10cSrcweir #include <unotools/saveopt.hxx>
136*cdf0e10cSrcweir #include <svl/documentlockfile.hxx>
137*cdf0e10cSrcweir 
138*cdf0e10cSrcweir #include "helper.hxx"
139*cdf0e10cSrcweir #include <sfx2/request.hxx>      // SFX_ITEMSET_SET
140*cdf0e10cSrcweir #include <sfx2/app.hxx>          // GetFilterMatcher
141*cdf0e10cSrcweir #include <sfx2/frame.hxx>        // LoadTargetFrame
142*cdf0e10cSrcweir #include "fltfnc.hxx"       // SfxFilterMatcher
143*cdf0e10cSrcweir #include <sfx2/docfilt.hxx>      // SfxFilter
144*cdf0e10cSrcweir #include <sfx2/objsh.hxx>        // CheckOpenMode
145*cdf0e10cSrcweir #include <sfx2/docfac.hxx>       // GetFilterContainer
146*cdf0e10cSrcweir #include "doc.hrc"
147*cdf0e10cSrcweir #include "openflag.hxx"     // SFX_STREAM_READONLY etc.
148*cdf0e10cSrcweir #include "sfx2/sfxresid.hxx"
149*cdf0e10cSrcweir #include <sfx2/appuno.hxx>
150*cdf0e10cSrcweir 
151*cdf0e10cSrcweir //#include "xmlversion.hxx"
152*cdf0e10cSrcweir 
153*cdf0e10cSrcweir #define MAX_REDIRECT 5
154*cdf0e10cSrcweir 
155*cdf0e10cSrcweir 
156*cdf0e10cSrcweir sal_Bool IsReadonlyAccordingACL( const sal_Unicode* pFilePath );
157*cdf0e10cSrcweir 
158*cdf0e10cSrcweir //==========================================================
159*cdf0e10cSrcweir namespace {
160*cdf0e10cSrcweir 
161*cdf0e10cSrcweir static const sal_Int8 LOCK_UI_NOLOCK = 0;
162*cdf0e10cSrcweir static const sal_Int8 LOCK_UI_SUCCEEDED = 1;
163*cdf0e10cSrcweir static const sal_Int8 LOCK_UI_TRY = 2;
164*cdf0e10cSrcweir 
165*cdf0e10cSrcweir //----------------------------------------------------------------
166*cdf0e10cSrcweir sal_Bool IsSystemFileLockingUsed()
167*cdf0e10cSrcweir {
168*cdf0e10cSrcweir     // check whether system file locking has been used, the default value is false
169*cdf0e10cSrcweir     sal_Bool bUseSystemLock = sal_False;
170*cdf0e10cSrcweir     try
171*cdf0e10cSrcweir     {
172*cdf0e10cSrcweir 
173*cdf0e10cSrcweir         uno::Reference< uno::XInterface > xCommonConfig = ::comphelper::ConfigurationHelper::openConfig(
174*cdf0e10cSrcweir                             ::comphelper::getProcessServiceFactory(),
175*cdf0e10cSrcweir                             ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Common" ) ),
176*cdf0e10cSrcweir                             ::comphelper::ConfigurationHelper::E_STANDARD );
177*cdf0e10cSrcweir         if ( !xCommonConfig.is() )
178*cdf0e10cSrcweir             throw uno::RuntimeException();
179*cdf0e10cSrcweir 
180*cdf0e10cSrcweir         ::comphelper::ConfigurationHelper::readRelativeKey(
181*cdf0e10cSrcweir                 xCommonConfig,
182*cdf0e10cSrcweir                 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Misc/" ) ),
183*cdf0e10cSrcweir                 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UseDocumentSystemFileLocking" ) ) ) >>= bUseSystemLock;
184*cdf0e10cSrcweir     }
185*cdf0e10cSrcweir     catch( const uno::Exception& )
186*cdf0e10cSrcweir     {
187*cdf0e10cSrcweir     }
188*cdf0e10cSrcweir 
189*cdf0e10cSrcweir     return bUseSystemLock;
190*cdf0e10cSrcweir }
191*cdf0e10cSrcweir 
192*cdf0e10cSrcweir //----------------------------------------------------------------
193*cdf0e10cSrcweir sal_Bool IsOOoLockFileUsed()
194*cdf0e10cSrcweir {
195*cdf0e10cSrcweir     // check whether system file locking has been used, the default value is false
196*cdf0e10cSrcweir     sal_Bool bOOoLockFileUsed = sal_False;
197*cdf0e10cSrcweir     try
198*cdf0e10cSrcweir     {
199*cdf0e10cSrcweir 
200*cdf0e10cSrcweir         uno::Reference< uno::XInterface > xCommonConfig = ::comphelper::ConfigurationHelper::openConfig(
201*cdf0e10cSrcweir                             ::comphelper::getProcessServiceFactory(),
202*cdf0e10cSrcweir                             ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Common" ) ),
203*cdf0e10cSrcweir                             ::comphelper::ConfigurationHelper::E_STANDARD );
204*cdf0e10cSrcweir         if ( !xCommonConfig.is() )
205*cdf0e10cSrcweir             throw uno::RuntimeException();
206*cdf0e10cSrcweir 
207*cdf0e10cSrcweir         ::comphelper::ConfigurationHelper::readRelativeKey(
208*cdf0e10cSrcweir                 xCommonConfig,
209*cdf0e10cSrcweir                 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Misc/" ) ),
210*cdf0e10cSrcweir                 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UseDocumentOOoLockFile" ) ) ) >>= bOOoLockFileUsed;
211*cdf0e10cSrcweir     }
212*cdf0e10cSrcweir     catch( const uno::Exception& )
213*cdf0e10cSrcweir     {
214*cdf0e10cSrcweir     }
215*cdf0e10cSrcweir 
216*cdf0e10cSrcweir     return bOOoLockFileUsed;
217*cdf0e10cSrcweir }
218*cdf0e10cSrcweir 
219*cdf0e10cSrcweir } // anonymous namespace
220*cdf0e10cSrcweir //==========================================================
221*cdf0e10cSrcweir 
222*cdf0e10cSrcweir 
223*cdf0e10cSrcweir //----------------------------------------------------------------
224*cdf0e10cSrcweir class SfxMediumHandler_Impl : public ::cppu::WeakImplHelper1< com::sun::star::task::XInteractionHandler >
225*cdf0e10cSrcweir {
226*cdf0e10cSrcweir     com::sun::star::uno::Reference< com::sun::star::task::XInteractionHandler > m_xInter;
227*cdf0e10cSrcweir 
228*cdf0e10cSrcweir public:
229*cdf0e10cSrcweir     virtual void SAL_CALL handle( const com::sun::star::uno::Reference< com::sun::star::task::XInteractionRequest >& xRequest )
230*cdf0e10cSrcweir             throw( com::sun::star::uno::RuntimeException );
231*cdf0e10cSrcweir 
232*cdf0e10cSrcweir     SfxMediumHandler_Impl( com::sun::star::uno::Reference< com::sun::star::task::XInteractionHandler > xInteraction )
233*cdf0e10cSrcweir         : m_xInter( xInteraction )
234*cdf0e10cSrcweir         {}
235*cdf0e10cSrcweir 
236*cdf0e10cSrcweir     ~SfxMediumHandler_Impl();
237*cdf0e10cSrcweir };
238*cdf0e10cSrcweir 
239*cdf0e10cSrcweir //----------------------------------------------------------------
240*cdf0e10cSrcweir SfxMediumHandler_Impl::~SfxMediumHandler_Impl()
241*cdf0e10cSrcweir {
242*cdf0e10cSrcweir }
243*cdf0e10cSrcweir 
244*cdf0e10cSrcweir //----------------------------------------------------------------
245*cdf0e10cSrcweir void SAL_CALL SfxMediumHandler_Impl::handle( const com::sun::star::uno::Reference< com::sun::star::task::XInteractionRequest >& xRequest )
246*cdf0e10cSrcweir         throw( com::sun::star::uno::RuntimeException )
247*cdf0e10cSrcweir {
248*cdf0e10cSrcweir 	if( !m_xInter.is() )
249*cdf0e10cSrcweir 		return;
250*cdf0e10cSrcweir 
251*cdf0e10cSrcweir     com::sun::star::uno::Any aRequest = xRequest->getRequest();
252*cdf0e10cSrcweir     com::sun::star::ucb::InteractiveIOException aIoException;
253*cdf0e10cSrcweir     com::sun::star::ucb::UnsupportedDataSinkException aSinkException;
254*cdf0e10cSrcweir     if ( (aRequest >>= aIoException) && ( aIoException.Code == IOErrorCode_ACCESS_DENIED || aIoException.Code == IOErrorCode_LOCKING_VIOLATION ) )
255*cdf0e10cSrcweir         return;
256*cdf0e10cSrcweir     else
257*cdf0e10cSrcweir     if ( aRequest >>= aSinkException )
258*cdf0e10cSrcweir         return;
259*cdf0e10cSrcweir     else
260*cdf0e10cSrcweir         m_xInter->handle( xRequest );
261*cdf0e10cSrcweir }
262*cdf0e10cSrcweir 
263*cdf0e10cSrcweir //----------------------------------------------------------------
264*cdf0e10cSrcweir class SfxMedium_Impl : public SvCompatWeakBase
265*cdf0e10cSrcweir {
266*cdf0e10cSrcweir public:
267*cdf0e10cSrcweir     ::ucbhelper::Content aContent;
268*cdf0e10cSrcweir     sal_Bool bUpdatePickList : 1;
269*cdf0e10cSrcweir     sal_Bool bIsTemp        : 1;
270*cdf0e10cSrcweir     sal_Bool bForceSynchron : 1;
271*cdf0e10cSrcweir     sal_Bool bDownloadDone          : 1;
272*cdf0e10cSrcweir     sal_Bool bDontCallDoneLinkOnSharingError : 1;
273*cdf0e10cSrcweir     sal_Bool bIsStorage: 1;
274*cdf0e10cSrcweir     sal_Bool bUseInteractionHandler: 1;
275*cdf0e10cSrcweir     sal_Bool bAllowDefaultIntHdl: 1;
276*cdf0e10cSrcweir     sal_Bool bIsCharsetInitialized: 1;
277*cdf0e10cSrcweir     sal_Bool bDisposeStorage: 1;
278*cdf0e10cSrcweir     sal_Bool bStorageBasedOnInStream: 1;
279*cdf0e10cSrcweir     sal_Bool m_bSalvageMode: 1;
280*cdf0e10cSrcweir     sal_Bool m_bVersionsAlreadyLoaded: 1;
281*cdf0e10cSrcweir     sal_Bool m_bLocked: 1;
282*cdf0e10cSrcweir     sal_Bool m_bGotDateTime: 1;
283*cdf0e10cSrcweir 
284*cdf0e10cSrcweir     uno::Reference < embed::XStorage > xStorage;
285*cdf0e10cSrcweir 
286*cdf0e10cSrcweir     SfxMedium*       pAntiImpl;
287*cdf0e10cSrcweir 
288*cdf0e10cSrcweir     long             nFileVersion;
289*cdf0e10cSrcweir 
290*cdf0e10cSrcweir     const SfxFilter* pOrigFilter;
291*cdf0e10cSrcweir     String           aOrigURL;
292*cdf0e10cSrcweir     String           aPreRedirectionURL;
293*cdf0e10cSrcweir     String           aReferer;
294*cdf0e10cSrcweir     DateTime         aExpireTime;
295*cdf0e10cSrcweir     SfxFrameWeak     wLoadTargetFrame;
296*cdf0e10cSrcweir     SvKeyValueIteratorRef xAttributes;
297*cdf0e10cSrcweir 
298*cdf0e10cSrcweir     svtools::AsynchronLink  aDoneLink;
299*cdf0e10cSrcweir     svtools::AsynchronLink  aAvailableLink;
300*cdf0e10cSrcweir 
301*cdf0e10cSrcweir     uno::Sequence < util::RevisionTag > aVersions;
302*cdf0e10cSrcweir 
303*cdf0e10cSrcweir     ::utl::TempFile*           pTempFile;
304*cdf0e10cSrcweir 
305*cdf0e10cSrcweir     uno::Reference < embed::XStorage > m_xZipStorage;
306*cdf0e10cSrcweir     Reference < XInputStream > xInputStream;
307*cdf0e10cSrcweir     Reference < XStream > xStream;
308*cdf0e10cSrcweir 
309*cdf0e10cSrcweir     uno::Reference< io::XStream > m_xLockingStream;
310*cdf0e10cSrcweir 
311*cdf0e10cSrcweir 	sal_uInt32					nLastStorageError;
312*cdf0e10cSrcweir 	::rtl::OUString				aCharset;
313*cdf0e10cSrcweir 
314*cdf0e10cSrcweir     ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler > xInteraction;
315*cdf0e10cSrcweir 
316*cdf0e10cSrcweir 	sal_Bool 		m_bRemoveBackup;
317*cdf0e10cSrcweir 	::rtl::OUString m_aBackupURL;
318*cdf0e10cSrcweir 
319*cdf0e10cSrcweir 	// the following member is changed and makes sence only during saving
320*cdf0e10cSrcweir 	// TODO/LATER: in future the signature state should be controlled by the medium not by the document
321*cdf0e10cSrcweir 	//             in this case the member will hold this information
322*cdf0e10cSrcweir 	sal_uInt16		m_nSignatureState;
323*cdf0e10cSrcweir 
324*cdf0e10cSrcweir     util::DateTime m_aDateTime;
325*cdf0e10cSrcweir 
326*cdf0e10cSrcweir     uno::Reference< logging::XSimpleLogRing > m_xLogRing;
327*cdf0e10cSrcweir 
328*cdf0e10cSrcweir     SfxMedium_Impl( SfxMedium* pAntiImplP );
329*cdf0e10cSrcweir     ~SfxMedium_Impl();
330*cdf0e10cSrcweir };
331*cdf0e10cSrcweir 
332*cdf0e10cSrcweir void SfxMedium::DataAvailable_Impl()
333*cdf0e10cSrcweir {
334*cdf0e10cSrcweir     pImp->aAvailableLink.ClearPendingCall();
335*cdf0e10cSrcweir     pImp->aAvailableLink.Call( NULL );
336*cdf0e10cSrcweir }
337*cdf0e10cSrcweir 
338*cdf0e10cSrcweir void SfxMedium::Cancel_Impl()
339*cdf0e10cSrcweir {
340*cdf0e10cSrcweir     SetError( ERRCODE_IO_GENERAL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
341*cdf0e10cSrcweir }
342*cdf0e10cSrcweir 
343*cdf0e10cSrcweir //------------------------------------------------------------------
344*cdf0e10cSrcweir SfxMedium_Impl::SfxMedium_Impl( SfxMedium* pAntiImplP )
345*cdf0e10cSrcweir  :  SvCompatWeakBase( pAntiImplP ),
346*cdf0e10cSrcweir     bUpdatePickList(sal_True),
347*cdf0e10cSrcweir     bIsTemp( sal_False ),
348*cdf0e10cSrcweir     bForceSynchron( sal_False ),
349*cdf0e10cSrcweir     bDownloadDone( sal_True ),
350*cdf0e10cSrcweir     bDontCallDoneLinkOnSharingError( sal_False ),
351*cdf0e10cSrcweir     bIsStorage( sal_False ),
352*cdf0e10cSrcweir     bUseInteractionHandler( sal_True ),
353*cdf0e10cSrcweir     bAllowDefaultIntHdl( sal_False ),
354*cdf0e10cSrcweir     bIsCharsetInitialized( sal_False ),
355*cdf0e10cSrcweir     bStorageBasedOnInStream( sal_False ),
356*cdf0e10cSrcweir     m_bSalvageMode( sal_False ),
357*cdf0e10cSrcweir     m_bVersionsAlreadyLoaded( sal_False ),
358*cdf0e10cSrcweir     m_bLocked( sal_False ),
359*cdf0e10cSrcweir     m_bGotDateTime( sal_False ),
360*cdf0e10cSrcweir     pAntiImpl( pAntiImplP ),
361*cdf0e10cSrcweir     nFileVersion( 0 ),
362*cdf0e10cSrcweir     pOrigFilter( 0 ),
363*cdf0e10cSrcweir     aExpireTime( Date() + 10, Time() ),
364*cdf0e10cSrcweir     pTempFile( NULL ),
365*cdf0e10cSrcweir     nLastStorageError( 0 ),
366*cdf0e10cSrcweir     m_bRemoveBackup( sal_False ),
367*cdf0e10cSrcweir     m_nSignatureState( SIGNATURESTATE_NOSIGNATURES )
368*cdf0e10cSrcweir {
369*cdf0e10cSrcweir     aDoneLink.CreateMutex();
370*cdf0e10cSrcweir }
371*cdf0e10cSrcweir 
372*cdf0e10cSrcweir //------------------------------------------------------------------
373*cdf0e10cSrcweir SfxMedium_Impl::~SfxMedium_Impl()
374*cdf0e10cSrcweir {
375*cdf0e10cSrcweir 
376*cdf0e10cSrcweir     aDoneLink.ClearPendingCall();
377*cdf0e10cSrcweir     aAvailableLink.ClearPendingCall();
378*cdf0e10cSrcweir 
379*cdf0e10cSrcweir     if ( pTempFile )
380*cdf0e10cSrcweir         delete pTempFile;
381*cdf0e10cSrcweir }
382*cdf0e10cSrcweir 
383*cdf0e10cSrcweir //================================================================
384*cdf0e10cSrcweir 
385*cdf0e10cSrcweir #define IMPL_CTOR(rootVal,URLVal)			\
386*cdf0e10cSrcweir      eError( SVSTREAM_OK ),                 \
387*cdf0e10cSrcweir                                             \
388*cdf0e10cSrcweir      bDirect( sal_False ),                  \
389*cdf0e10cSrcweir      bRoot( rootVal ),						\
390*cdf0e10cSrcweir      bSetFilter( sal_False ),               \
391*cdf0e10cSrcweir      bTriedStorage( sal_False ),            \
392*cdf0e10cSrcweir                                             \
393*cdf0e10cSrcweir      nStorOpenMode( SFX_STREAM_READWRITE ), \
394*cdf0e10cSrcweir      pURLObj( URLVal ),						\
395*cdf0e10cSrcweir      pInStream(0),                          \
396*cdf0e10cSrcweir      pOutStream( 0 )
397*cdf0e10cSrcweir 
398*cdf0e10cSrcweir //------------------------------------------------------------------
399*cdf0e10cSrcweir void SfxMedium::ResetError()
400*cdf0e10cSrcweir {
401*cdf0e10cSrcweir     eError = SVSTREAM_OK;
402*cdf0e10cSrcweir     if( pInStream )
403*cdf0e10cSrcweir         pInStream->ResetError();
404*cdf0e10cSrcweir     if( pOutStream )
405*cdf0e10cSrcweir         pOutStream->ResetError();
406*cdf0e10cSrcweir }
407*cdf0e10cSrcweir 
408*cdf0e10cSrcweir //------------------------------------------------------------------
409*cdf0e10cSrcweir sal_uInt32 SfxMedium::GetLastStorageCreationState()
410*cdf0e10cSrcweir {
411*cdf0e10cSrcweir 	return pImp->nLastStorageError;
412*cdf0e10cSrcweir }
413*cdf0e10cSrcweir 
414*cdf0e10cSrcweir //------------------------------------------------------------------
415*cdf0e10cSrcweir void SfxMedium::AddLog( const ::rtl::OUString& aMessage )
416*cdf0e10cSrcweir {
417*cdf0e10cSrcweir     if ( !pImp->m_xLogRing.is() )
418*cdf0e10cSrcweir     {
419*cdf0e10cSrcweir         try
420*cdf0e10cSrcweir         {
421*cdf0e10cSrcweir             ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() );
422*cdf0e10cSrcweir             if ( aContext.is() )
423*cdf0e10cSrcweir                 pImp->m_xLogRing.set( aContext.getSingleton( "com.sun.star.logging.DocumentIOLogRing" ), UNO_QUERY_THROW );
424*cdf0e10cSrcweir         }
425*cdf0e10cSrcweir         catch( uno::Exception& )
426*cdf0e10cSrcweir         {}
427*cdf0e10cSrcweir     }
428*cdf0e10cSrcweir 
429*cdf0e10cSrcweir     if ( pImp->m_xLogRing.is() )
430*cdf0e10cSrcweir         pImp->m_xLogRing->logString( aMessage );
431*cdf0e10cSrcweir }
432*cdf0e10cSrcweir 
433*cdf0e10cSrcweir //------------------------------------------------------------------
434*cdf0e10cSrcweir void SfxMedium::SetError( sal_uInt32 nError, const ::rtl::OUString& aLogMessage )
435*cdf0e10cSrcweir {
436*cdf0e10cSrcweir     eError = nError;
437*cdf0e10cSrcweir     if ( eError != ERRCODE_NONE && aLogMessage.getLength() )
438*cdf0e10cSrcweir         AddLog( aLogMessage );
439*cdf0e10cSrcweir }
440*cdf0e10cSrcweir 
441*cdf0e10cSrcweir //------------------------------------------------------------------
442*cdf0e10cSrcweir sal_uInt32 SfxMedium::GetErrorCode() const
443*cdf0e10cSrcweir {
444*cdf0e10cSrcweir     sal_uInt32 lError=eError;
445*cdf0e10cSrcweir     if(!lError && pInStream)
446*cdf0e10cSrcweir         lError=pInStream->GetErrorCode();
447*cdf0e10cSrcweir     if(!lError && pOutStream)
448*cdf0e10cSrcweir         lError=pOutStream->GetErrorCode();
449*cdf0e10cSrcweir     return lError;
450*cdf0e10cSrcweir }
451*cdf0e10cSrcweir 
452*cdf0e10cSrcweir //------------------------------------------------------------------
453*cdf0e10cSrcweir void SfxMedium::CheckFileDate( const util::DateTime& aInitDate )
454*cdf0e10cSrcweir {
455*cdf0e10cSrcweir     GetInitFileDate( sal_True );
456*cdf0e10cSrcweir     if ( pImp->m_aDateTime.Seconds != aInitDate.Seconds
457*cdf0e10cSrcweir       || pImp->m_aDateTime.Minutes != aInitDate.Minutes
458*cdf0e10cSrcweir       || pImp->m_aDateTime.Hours != aInitDate.Hours
459*cdf0e10cSrcweir       || pImp->m_aDateTime.Day != aInitDate.Day
460*cdf0e10cSrcweir       || pImp->m_aDateTime.Month != aInitDate.Month
461*cdf0e10cSrcweir       || pImp->m_aDateTime.Year != aInitDate.Year )
462*cdf0e10cSrcweir     {
463*cdf0e10cSrcweir         uno::Reference< task::XInteractionHandler > xHandler = GetInteractionHandler();
464*cdf0e10cSrcweir 
465*cdf0e10cSrcweir         if ( xHandler.is() )
466*cdf0e10cSrcweir         {
467*cdf0e10cSrcweir             try
468*cdf0e10cSrcweir             {
469*cdf0e10cSrcweir                 ::rtl::Reference< ::ucbhelper::InteractionRequest > xInteractionRequestImpl = new ::ucbhelper::InteractionRequest( uno::makeAny(
470*cdf0e10cSrcweir                     document::ChangedByOthersRequest() ) );
471*cdf0e10cSrcweir                 uno::Sequence< uno::Reference< task::XInteractionContinuation > > aContinuations( 3 );
472*cdf0e10cSrcweir                 aContinuations[0] = new ::ucbhelper::InteractionAbort( xInteractionRequestImpl.get() );
473*cdf0e10cSrcweir                 aContinuations[1] = new ::ucbhelper::InteractionApprove( xInteractionRequestImpl.get() );
474*cdf0e10cSrcweir                 xInteractionRequestImpl->setContinuations( aContinuations );
475*cdf0e10cSrcweir 
476*cdf0e10cSrcweir                 xHandler->handle( xInteractionRequestImpl.get() );
477*cdf0e10cSrcweir 
478*cdf0e10cSrcweir                 ::rtl::Reference< ::ucbhelper::InteractionContinuation > xSelected = xInteractionRequestImpl->getSelection();
479*cdf0e10cSrcweir                 if ( uno::Reference< task::XInteractionAbort >( xSelected.get(), uno::UNO_QUERY ).is() )
480*cdf0e10cSrcweir                 {
481*cdf0e10cSrcweir                     SetError( ERRCODE_ABORT, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
482*cdf0e10cSrcweir                 }
483*cdf0e10cSrcweir             }
484*cdf0e10cSrcweir             catch ( uno::Exception& )
485*cdf0e10cSrcweir             {}
486*cdf0e10cSrcweir         }
487*cdf0e10cSrcweir     }
488*cdf0e10cSrcweir }
489*cdf0e10cSrcweir 
490*cdf0e10cSrcweir //------------------------------------------------------------------
491*cdf0e10cSrcweir sal_Bool SfxMedium::DocNeedsFileDateCheck()
492*cdf0e10cSrcweir {
493*cdf0e10cSrcweir     return ( !IsReadOnly() && ::utl::LocalFileHelper::IsLocalFile( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ) );
494*cdf0e10cSrcweir }
495*cdf0e10cSrcweir 
496*cdf0e10cSrcweir //------------------------------------------------------------------
497*cdf0e10cSrcweir util::DateTime SfxMedium::GetInitFileDate( sal_Bool bIgnoreOldValue )
498*cdf0e10cSrcweir {
499*cdf0e10cSrcweir     if ( ( bIgnoreOldValue || !pImp->m_bGotDateTime ) && aLogicName.Len() )
500*cdf0e10cSrcweir     {
501*cdf0e10cSrcweir         try
502*cdf0e10cSrcweir         {
503*cdf0e10cSrcweir             uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > xDummyEnv;
504*cdf0e10cSrcweir             ::ucbhelper::Content aContent( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv );
505*cdf0e10cSrcweir 
506*cdf0e10cSrcweir             aContent.getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "DateModified" )) ) >>= pImp->m_aDateTime;
507*cdf0e10cSrcweir             pImp->m_bGotDateTime = sal_True;
508*cdf0e10cSrcweir         }
509*cdf0e10cSrcweir         catch ( ::com::sun::star::uno::Exception& )
510*cdf0e10cSrcweir         {
511*cdf0e10cSrcweir         }
512*cdf0e10cSrcweir     }
513*cdf0e10cSrcweir 
514*cdf0e10cSrcweir     return pImp->m_aDateTime;
515*cdf0e10cSrcweir }
516*cdf0e10cSrcweir 
517*cdf0e10cSrcweir //------------------------------------------------------------------
518*cdf0e10cSrcweir Reference < XContent > SfxMedium::GetContent() const
519*cdf0e10cSrcweir {
520*cdf0e10cSrcweir     if ( !pImp->aContent.get().is() )
521*cdf0e10cSrcweir     {
522*cdf0e10cSrcweir 		Reference < ::com::sun::star::ucb::XContent > xContent;
523*cdf0e10cSrcweir 	    Reference < ::com::sun::star::ucb::XCommandEnvironment > xEnv;
524*cdf0e10cSrcweir 
525*cdf0e10cSrcweir         SFX_ITEMSET_ARG( pSet, pItem, SfxUnoAnyItem, SID_CONTENT, sal_False);
526*cdf0e10cSrcweir         if ( pItem )
527*cdf0e10cSrcweir             pItem->GetValue() >>= xContent;
528*cdf0e10cSrcweir 
529*cdf0e10cSrcweir 		if ( xContent.is() )
530*cdf0e10cSrcweir 		{
531*cdf0e10cSrcweir 			try
532*cdf0e10cSrcweir 			{
533*cdf0e10cSrcweir 				pImp->aContent = ::ucbhelper::Content( xContent, xEnv );
534*cdf0e10cSrcweir 			}
535*cdf0e10cSrcweir 			catch ( Exception& )
536*cdf0e10cSrcweir 			{
537*cdf0e10cSrcweir 			}
538*cdf0e10cSrcweir 		}
539*cdf0e10cSrcweir 		else
540*cdf0e10cSrcweir 		{
541*cdf0e10cSrcweir 			// TODO: DBG_ERROR("SfxMedium::GetContent()\nCreate Content? This code exists as fallback only. Please clarify, why its used.");
542*cdf0e10cSrcweir 			String aURL;
543*cdf0e10cSrcweir 	        if ( aName.Len() )
544*cdf0e10cSrcweir 	        	::utl::LocalFileHelper::ConvertPhysicalNameToURL( aName, aURL );
545*cdf0e10cSrcweir 	        else if ( aLogicName.Len() )
546*cdf0e10cSrcweir 	            aURL = GetURLObject().GetMainURL( INetURLObject::NO_DECODE );
547*cdf0e10cSrcweir 			if ( aURL.Len() )
548*cdf0e10cSrcweir 	            ::ucbhelper::Content::create( aURL, xEnv, pImp->aContent );
549*cdf0e10cSrcweir 		}
550*cdf0e10cSrcweir     }
551*cdf0e10cSrcweir 
552*cdf0e10cSrcweir     return pImp->aContent.get();
553*cdf0e10cSrcweir }
554*cdf0e10cSrcweir 
555*cdf0e10cSrcweir //------------------------------------------------------------------
556*cdf0e10cSrcweir ::rtl::OUString SfxMedium::GetBaseURL( bool bForSaving )
557*cdf0e10cSrcweir {
558*cdf0e10cSrcweir     ::rtl::OUString aBaseURL;
559*cdf0e10cSrcweir     const SfxStringItem* pBaseURLItem = static_cast<const SfxStringItem*>( GetItemSet()->GetItem(SID_DOC_BASEURL) );
560*cdf0e10cSrcweir     if ( pBaseURLItem )
561*cdf0e10cSrcweir         aBaseURL = pBaseURLItem->GetValue();
562*cdf0e10cSrcweir     else if ( GetContent().is() )
563*cdf0e10cSrcweir     {
564*cdf0e10cSrcweir         try
565*cdf0e10cSrcweir         {
566*cdf0e10cSrcweir             Any aAny = pImp->aContent.getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("BaseURI" )) );
567*cdf0e10cSrcweir             aAny >>= aBaseURL;
568*cdf0e10cSrcweir         }
569*cdf0e10cSrcweir         catch ( ::com::sun::star::uno::Exception& )
570*cdf0e10cSrcweir         {
571*cdf0e10cSrcweir         }
572*cdf0e10cSrcweir 
573*cdf0e10cSrcweir         if ( !aBaseURL.getLength() )
574*cdf0e10cSrcweir             aBaseURL = GetURLObject().GetMainURL( INetURLObject::NO_DECODE );
575*cdf0e10cSrcweir     }
576*cdf0e10cSrcweir 
577*cdf0e10cSrcweir     if ( bForSaving )
578*cdf0e10cSrcweir     {
579*cdf0e10cSrcweir         SvtSaveOptions aOpt;
580*cdf0e10cSrcweir         sal_Bool bIsRemote = IsRemote();
581*cdf0e10cSrcweir         if( (bIsRemote && !aOpt.IsSaveRelINet()) || (!bRemote && !aOpt.IsSaveRelFSys()) )
582*cdf0e10cSrcweir             return ::rtl::OUString();
583*cdf0e10cSrcweir     }
584*cdf0e10cSrcweir 
585*cdf0e10cSrcweir     return aBaseURL;
586*cdf0e10cSrcweir }
587*cdf0e10cSrcweir 
588*cdf0e10cSrcweir //------------------------------------------------------------------
589*cdf0e10cSrcweir SvStream* SfxMedium::GetInStream()
590*cdf0e10cSrcweir {
591*cdf0e10cSrcweir     if ( pInStream )
592*cdf0e10cSrcweir         return pInStream;
593*cdf0e10cSrcweir 
594*cdf0e10cSrcweir     if ( pImp->pTempFile )
595*cdf0e10cSrcweir     {
596*cdf0e10cSrcweir         pInStream = new SvFileStream( aName, nStorOpenMode );
597*cdf0e10cSrcweir 
598*cdf0e10cSrcweir         eError = pInStream->GetError();
599*cdf0e10cSrcweir 
600*cdf0e10cSrcweir         if( !eError && (nStorOpenMode & STREAM_WRITE)
601*cdf0e10cSrcweir                     && ! pInStream->IsWritable() )
602*cdf0e10cSrcweir         {
603*cdf0e10cSrcweir             eError = ERRCODE_IO_ACCESSDENIED;
604*cdf0e10cSrcweir             delete pInStream;
605*cdf0e10cSrcweir             pInStream = NULL;
606*cdf0e10cSrcweir         }
607*cdf0e10cSrcweir         else
608*cdf0e10cSrcweir             return pInStream;
609*cdf0e10cSrcweir     }
610*cdf0e10cSrcweir 
611*cdf0e10cSrcweir     GetMedium_Impl();
612*cdf0e10cSrcweir 
613*cdf0e10cSrcweir     if ( GetError() )
614*cdf0e10cSrcweir         return NULL;
615*cdf0e10cSrcweir 
616*cdf0e10cSrcweir     return pInStream;
617*cdf0e10cSrcweir }
618*cdf0e10cSrcweir 
619*cdf0e10cSrcweir //------------------------------------------------------------------
620*cdf0e10cSrcweir void SfxMedium::CloseInStream()
621*cdf0e10cSrcweir {
622*cdf0e10cSrcweir     CloseInStream_Impl();
623*cdf0e10cSrcweir }
624*cdf0e10cSrcweir 
625*cdf0e10cSrcweir void SfxMedium::CloseInStream_Impl()
626*cdf0e10cSrcweir {
627*cdf0e10cSrcweir     // if there is a storage based on the InStream, we have to
628*cdf0e10cSrcweir     // close the storage, too, because otherwise the storage
629*cdf0e10cSrcweir     // would use an invalid ( deleted ) stream.
630*cdf0e10cSrcweir     if ( pInStream && pImp->xStorage.is() )
631*cdf0e10cSrcweir     {
632*cdf0e10cSrcweir     	if ( pImp->bStorageBasedOnInStream )
633*cdf0e10cSrcweir             CloseStorage();
634*cdf0e10cSrcweir     }
635*cdf0e10cSrcweir 
636*cdf0e10cSrcweir     if ( pInStream && !GetContent().is() )
637*cdf0e10cSrcweir     {
638*cdf0e10cSrcweir         CreateTempFile( sal_True );
639*cdf0e10cSrcweir         return;
640*cdf0e10cSrcweir     }
641*cdf0e10cSrcweir 
642*cdf0e10cSrcweir     DELETEZ( pInStream );
643*cdf0e10cSrcweir     if ( pSet )
644*cdf0e10cSrcweir         pSet->ClearItem( SID_INPUTSTREAM );
645*cdf0e10cSrcweir 
646*cdf0e10cSrcweir 	CloseZipStorage_Impl();
647*cdf0e10cSrcweir 	pImp->xInputStream = uno::Reference< io::XInputStream >();
648*cdf0e10cSrcweir 
649*cdf0e10cSrcweir 	if ( !pOutStream )
650*cdf0e10cSrcweir 	{
651*cdf0e10cSrcweir 		// output part of the stream is not used so the whole stream can be closed
652*cdf0e10cSrcweir         // TODO/LATER: is it correct?
653*cdf0e10cSrcweir 		pImp->xStream = uno::Reference< io::XStream >();
654*cdf0e10cSrcweir 		if ( pSet )
655*cdf0e10cSrcweir 			pSet->ClearItem( SID_STREAM );
656*cdf0e10cSrcweir 	}
657*cdf0e10cSrcweir }
658*cdf0e10cSrcweir 
659*cdf0e10cSrcweir //------------------------------------------------------------------
660*cdf0e10cSrcweir SvStream* SfxMedium::GetOutStream()
661*cdf0e10cSrcweir {
662*cdf0e10cSrcweir     if ( !pOutStream )
663*cdf0e10cSrcweir     {
664*cdf0e10cSrcweir         // Create a temp. file if there is none because we always
665*cdf0e10cSrcweir         // need one.
666*cdf0e10cSrcweir         CreateTempFile( sal_False );
667*cdf0e10cSrcweir 
668*cdf0e10cSrcweir         if ( pImp->pTempFile )
669*cdf0e10cSrcweir         {
670*cdf0e10cSrcweir             pOutStream = new SvFileStream( aName, STREAM_STD_READWRITE );
671*cdf0e10cSrcweir             CloseStorage();
672*cdf0e10cSrcweir         }
673*cdf0e10cSrcweir     }
674*cdf0e10cSrcweir 
675*cdf0e10cSrcweir     return pOutStream;
676*cdf0e10cSrcweir }
677*cdf0e10cSrcweir 
678*cdf0e10cSrcweir //------------------------------------------------------------------
679*cdf0e10cSrcweir sal_Bool SfxMedium::CloseOutStream()
680*cdf0e10cSrcweir {
681*cdf0e10cSrcweir     CloseOutStream_Impl();
682*cdf0e10cSrcweir     return sal_True;
683*cdf0e10cSrcweir }
684*cdf0e10cSrcweir 
685*cdf0e10cSrcweir sal_Bool SfxMedium::CloseOutStream_Impl()
686*cdf0e10cSrcweir {
687*cdf0e10cSrcweir     if ( pOutStream )
688*cdf0e10cSrcweir     {
689*cdf0e10cSrcweir         // if there is a storage based on the OutStream, we have to
690*cdf0e10cSrcweir         // close the storage, too, because otherwise the storage
691*cdf0e10cSrcweir         // would use an invalid ( deleted ) stream.
692*cdf0e10cSrcweir         //TODO/MBA: how to deal with this?!
693*cdf0e10cSrcweir         //maybe we need a new flag when the storage was created from the outstream
694*cdf0e10cSrcweir         if ( pImp->xStorage.is() )
695*cdf0e10cSrcweir         {
696*cdf0e10cSrcweir             //const SvStream *pStorage = aStorage->GetSvStream();
697*cdf0e10cSrcweir             //if ( pStorage == pOutStream )
698*cdf0e10cSrcweir                 CloseStorage();
699*cdf0e10cSrcweir         }
700*cdf0e10cSrcweir 
701*cdf0e10cSrcweir         delete pOutStream;
702*cdf0e10cSrcweir         pOutStream = NULL;
703*cdf0e10cSrcweir     }
704*cdf0e10cSrcweir 
705*cdf0e10cSrcweir 	if ( !pInStream )
706*cdf0e10cSrcweir 	{
707*cdf0e10cSrcweir 		// input part of the stream is not used so the whole stream can be closed
708*cdf0e10cSrcweir         // TODO/LATER: is it correct?
709*cdf0e10cSrcweir 		pImp->xStream = uno::Reference< io::XStream >();
710*cdf0e10cSrcweir     	if ( pSet )
711*cdf0e10cSrcweir 			pSet->ClearItem( SID_STREAM );
712*cdf0e10cSrcweir 	}
713*cdf0e10cSrcweir 
714*cdf0e10cSrcweir     return sal_True;
715*cdf0e10cSrcweir }
716*cdf0e10cSrcweir 
717*cdf0e10cSrcweir //------------------------------------------------------------------
718*cdf0e10cSrcweir const String& SfxMedium::GetPhysicalName() const
719*cdf0e10cSrcweir {
720*cdf0e10cSrcweir     if ( !aName.Len() && aLogicName.Len() )
721*cdf0e10cSrcweir         (( SfxMedium*)this)->CreateFileStream();
722*cdf0e10cSrcweir 
723*cdf0e10cSrcweir     // return the name then
724*cdf0e10cSrcweir     return aName;
725*cdf0e10cSrcweir }
726*cdf0e10cSrcweir 
727*cdf0e10cSrcweir //------------------------------------------------------------------
728*cdf0e10cSrcweir void SfxMedium::CreateFileStream()
729*cdf0e10cSrcweir {
730*cdf0e10cSrcweir     ForceSynchronStream_Impl( sal_True );
731*cdf0e10cSrcweir     GetInStream();
732*cdf0e10cSrcweir     if( pInStream )
733*cdf0e10cSrcweir     {
734*cdf0e10cSrcweir         CreateTempFile( sal_False );
735*cdf0e10cSrcweir         pImp->bIsTemp = sal_True;
736*cdf0e10cSrcweir         CloseInStream_Impl();
737*cdf0e10cSrcweir     }
738*cdf0e10cSrcweir }
739*cdf0e10cSrcweir 
740*cdf0e10cSrcweir //------------------------------------------------------------------
741*cdf0e10cSrcweir sal_Bool SfxMedium::Commit()
742*cdf0e10cSrcweir {
743*cdf0e10cSrcweir     if( pImp->xStorage.is() )
744*cdf0e10cSrcweir 		StorageCommit_Impl();
745*cdf0e10cSrcweir     else if( pOutStream  )
746*cdf0e10cSrcweir         pOutStream->Flush();
747*cdf0e10cSrcweir     else if( pInStream  )
748*cdf0e10cSrcweir         pInStream->Flush();
749*cdf0e10cSrcweir 
750*cdf0e10cSrcweir     if ( GetError() == SVSTREAM_OK )
751*cdf0e10cSrcweir 	{
752*cdf0e10cSrcweir 		// does something only in case there is a temporary file ( means aName points to different location than aLogicName )
753*cdf0e10cSrcweir         Transfer_Impl();
754*cdf0e10cSrcweir 	}
755*cdf0e10cSrcweir 
756*cdf0e10cSrcweir     sal_Bool bResult = ( GetError() == SVSTREAM_OK );
757*cdf0e10cSrcweir 
758*cdf0e10cSrcweir     if ( bResult && DocNeedsFileDateCheck() )
759*cdf0e10cSrcweir         GetInitFileDate( sal_True );
760*cdf0e10cSrcweir 
761*cdf0e10cSrcweir     // remove truncation mode from the flags
762*cdf0e10cSrcweir     nStorOpenMode &= (~STREAM_TRUNC);
763*cdf0e10cSrcweir     return bResult;
764*cdf0e10cSrcweir }
765*cdf0e10cSrcweir 
766*cdf0e10cSrcweir //------------------------------------------------------------------
767*cdf0e10cSrcweir sal_Bool SfxMedium::IsStorage()
768*cdf0e10cSrcweir {
769*cdf0e10cSrcweir     if ( pImp->xStorage.is() )
770*cdf0e10cSrcweir         return sal_True;
771*cdf0e10cSrcweir 
772*cdf0e10cSrcweir     if ( bTriedStorage )
773*cdf0e10cSrcweir         return pImp->bIsStorage;
774*cdf0e10cSrcweir 
775*cdf0e10cSrcweir     if ( pImp->pTempFile )
776*cdf0e10cSrcweir     {
777*cdf0e10cSrcweir 		String aURL;
778*cdf0e10cSrcweir 		if ( !::utl::LocalFileHelper::ConvertPhysicalNameToURL( aName, aURL ) )
779*cdf0e10cSrcweir         {
780*cdf0e10cSrcweir 			DBG_ERROR("Physical name not convertable!");
781*cdf0e10cSrcweir         }
782*cdf0e10cSrcweir         pImp->bIsStorage = SotStorage::IsStorageFile( aURL ) && !SotStorage::IsOLEStorage( aURL);
783*cdf0e10cSrcweir         if ( !pImp->bIsStorage )
784*cdf0e10cSrcweir             bTriedStorage = sal_True;
785*cdf0e10cSrcweir     }
786*cdf0e10cSrcweir     else if ( GetInStream() )
787*cdf0e10cSrcweir     {
788*cdf0e10cSrcweir         pImp->bIsStorage = SotStorage::IsStorageFile( pInStream ) && !SotStorage::IsOLEStorage( pInStream );
789*cdf0e10cSrcweir         if ( !pInStream->GetError() && !pImp->bIsStorage )
790*cdf0e10cSrcweir             bTriedStorage = sal_True;
791*cdf0e10cSrcweir     }
792*cdf0e10cSrcweir 
793*cdf0e10cSrcweir     return pImp->bIsStorage;
794*cdf0e10cSrcweir }
795*cdf0e10cSrcweir 
796*cdf0e10cSrcweir //------------------------------------------------------------------
797*cdf0e10cSrcweir Link SfxMedium::GetDataAvailableLink() const
798*cdf0e10cSrcweir {
799*cdf0e10cSrcweir     return pImp->aAvailableLink.GetLink();
800*cdf0e10cSrcweir }
801*cdf0e10cSrcweir 
802*cdf0e10cSrcweir //------------------------------------------------------------------
803*cdf0e10cSrcweir Link SfxMedium::GetDoneLink() const
804*cdf0e10cSrcweir {
805*cdf0e10cSrcweir     return pImp->aDoneLink.GetLink();
806*cdf0e10cSrcweir }
807*cdf0e10cSrcweir 
808*cdf0e10cSrcweir //------------------------------------------------------------------
809*cdf0e10cSrcweir sal_Bool SfxMedium::IsPreview_Impl()
810*cdf0e10cSrcweir {
811*cdf0e10cSrcweir     sal_Bool bPreview = sal_False;
812*cdf0e10cSrcweir     SFX_ITEMSET_ARG( GetItemSet(), pPreview, SfxBoolItem, SID_PREVIEW, sal_False);
813*cdf0e10cSrcweir     if ( pPreview )
814*cdf0e10cSrcweir         bPreview = pPreview->GetValue();
815*cdf0e10cSrcweir     else
816*cdf0e10cSrcweir     {
817*cdf0e10cSrcweir         SFX_ITEMSET_ARG( GetItemSet(), pFlags, SfxStringItem, SID_OPTIONS, sal_False);
818*cdf0e10cSrcweir         if ( pFlags )
819*cdf0e10cSrcweir         {
820*cdf0e10cSrcweir             String aFileFlags = pFlags->GetValue();
821*cdf0e10cSrcweir             aFileFlags.ToUpperAscii();
822*cdf0e10cSrcweir             if ( STRING_NOTFOUND != aFileFlags.Search( 'B' ) )
823*cdf0e10cSrcweir                 bPreview = sal_True;
824*cdf0e10cSrcweir         }
825*cdf0e10cSrcweir     }
826*cdf0e10cSrcweir 
827*cdf0e10cSrcweir     return bPreview;
828*cdf0e10cSrcweir }
829*cdf0e10cSrcweir 
830*cdf0e10cSrcweir //------------------------------------------------------------------
831*cdf0e10cSrcweir void SfxMedium::StorageBackup_Impl()
832*cdf0e10cSrcweir {
833*cdf0e10cSrcweir 	::ucbhelper::Content aOriginalContent;
834*cdf0e10cSrcweir 	Reference< ::com::sun::star::ucb::XCommandEnvironment > xDummyEnv;
835*cdf0e10cSrcweir 
836*cdf0e10cSrcweir     sal_Bool bBasedOnOriginalFile = ( !pImp->pTempFile && !( aLogicName.Len() && pImp->m_bSalvageMode )
837*cdf0e10cSrcweir         && GetURLObject().GetMainURL( INetURLObject::NO_DECODE ).getLength()
838*cdf0e10cSrcweir         && ::utl::LocalFileHelper::IsLocalFile( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) )
839*cdf0e10cSrcweir         && ::utl::UCBContentHelper::IsDocument( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ) );
840*cdf0e10cSrcweir 
841*cdf0e10cSrcweir 	if ( bBasedOnOriginalFile && !pImp->m_aBackupURL.getLength()
842*cdf0e10cSrcweir 	  && ::ucbhelper::Content::create( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv, aOriginalContent ) )
843*cdf0e10cSrcweir 	{
844*cdf0e10cSrcweir 		DoInternalBackup_Impl( aOriginalContent );
845*cdf0e10cSrcweir 		if( !pImp->m_aBackupURL.getLength() )
846*cdf0e10cSrcweir 			SetError( ERRCODE_SFX_CANTCREATEBACKUP, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
847*cdf0e10cSrcweir 	}
848*cdf0e10cSrcweir }
849*cdf0e10cSrcweir 
850*cdf0e10cSrcweir //------------------------------------------------------------------
851*cdf0e10cSrcweir ::rtl::OUString SfxMedium::GetBackup_Impl()
852*cdf0e10cSrcweir {
853*cdf0e10cSrcweir 	if ( !pImp->m_aBackupURL.getLength() )
854*cdf0e10cSrcweir 		StorageBackup_Impl();
855*cdf0e10cSrcweir 
856*cdf0e10cSrcweir 	return pImp->m_aBackupURL;
857*cdf0e10cSrcweir }
858*cdf0e10cSrcweir 
859*cdf0e10cSrcweir //------------------------------------------------------------------
860*cdf0e10cSrcweir uno::Reference < embed::XStorage > SfxMedium::GetOutputStorage()
861*cdf0e10cSrcweir {
862*cdf0e10cSrcweir 	if ( GetError() )
863*cdf0e10cSrcweir 		return uno::Reference< embed::XStorage >();
864*cdf0e10cSrcweir 
865*cdf0e10cSrcweir     // if the medium was constructed with a Storage: use this one, not a temp. storage
866*cdf0e10cSrcweir     // if a temporary storage already exists: use it
867*cdf0e10cSrcweir     if ( pImp->xStorage.is() && ( !aLogicName.Len() || pImp->pTempFile ) )
868*cdf0e10cSrcweir         return pImp->xStorage;
869*cdf0e10cSrcweir 
870*cdf0e10cSrcweir     // if necessary close stream that was used for reading
871*cdf0e10cSrcweir     if ( pInStream && !pInStream->IsWritable() )
872*cdf0e10cSrcweir         CloseInStream();
873*cdf0e10cSrcweir 
874*cdf0e10cSrcweir     DBG_ASSERT( !pOutStream, "OutStream in a readonly Medium?!" );
875*cdf0e10cSrcweir 
876*cdf0e10cSrcweir     // TODO/LATER: The current solution is to store the document temporary and then copy it to the target location;
877*cdf0e10cSrcweir     // in future it should be stored directly and then copied to the temporary location, since in this case no
878*cdf0e10cSrcweir     // file attributes have to be preserved and system copying mechanics could be used instead of streaming.
879*cdf0e10cSrcweir     CreateTempFileNoCopy();
880*cdf0e10cSrcweir 
881*cdf0e10cSrcweir     return GetStorage();
882*cdf0e10cSrcweir }
883*cdf0e10cSrcweir 
884*cdf0e10cSrcweir //------------------------------------------------------------------
885*cdf0e10cSrcweir void SfxMedium::SetEncryptionDataToStorage_Impl()
886*cdf0e10cSrcweir {
887*cdf0e10cSrcweir 	// in case media-descriptor contains password it should be used on opening
888*cdf0e10cSrcweir 	if ( pImp->xStorage.is() && pSet )
889*cdf0e10cSrcweir 	{
890*cdf0e10cSrcweir         uno::Sequence< beans::NamedValue > aEncryptionData;
891*cdf0e10cSrcweir 		if ( GetEncryptionData_Impl( pSet, aEncryptionData ) )
892*cdf0e10cSrcweir 		{
893*cdf0e10cSrcweir             // replace the password with encryption data
894*cdf0e10cSrcweir             pSet->ClearItem( SID_PASSWORD );
895*cdf0e10cSrcweir             pSet->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( aEncryptionData ) ) );
896*cdf0e10cSrcweir 
897*cdf0e10cSrcweir 			try
898*cdf0e10cSrcweir 			{
899*cdf0e10cSrcweir 				::comphelper::OStorageHelper::SetCommonStorageEncryptionData( pImp->xStorage, aEncryptionData );
900*cdf0e10cSrcweir 			}
901*cdf0e10cSrcweir 			catch( uno::Exception& )
902*cdf0e10cSrcweir 			{
903*cdf0e10cSrcweir 				OSL_ENSURE( sal_False, "It must be possible to set a common password for the storage" );
904*cdf0e10cSrcweir 				// TODO/LATER: set the error code in case of problem
905*cdf0e10cSrcweir 				// SetError( ERRCODE_IO_GENERAL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
906*cdf0e10cSrcweir 			}
907*cdf0e10cSrcweir 		}
908*cdf0e10cSrcweir 	}
909*cdf0e10cSrcweir }
910*cdf0e10cSrcweir 
911*cdf0e10cSrcweir //------------------------------------------------------------------
912*cdf0e10cSrcweir sal_Int8 SfxMedium::ShowLockedDocumentDialog( const uno::Sequence< ::rtl::OUString >& aData, sal_Bool bIsLoading, sal_Bool bOwnLock )
913*cdf0e10cSrcweir {
914*cdf0e10cSrcweir     sal_Int8 nResult = LOCK_UI_NOLOCK;
915*cdf0e10cSrcweir 
916*cdf0e10cSrcweir     // show the interaction regarding the document opening
917*cdf0e10cSrcweir     uno::Reference< task::XInteractionHandler > xHandler = GetInteractionHandler();
918*cdf0e10cSrcweir 
919*cdf0e10cSrcweir     if ( ::svt::DocumentLockFile::IsInteractionAllowed() && xHandler.is() && ( bIsLoading || bOwnLock ) )
920*cdf0e10cSrcweir     {
921*cdf0e10cSrcweir         ::rtl::OUString aDocumentURL = GetURLObject().GetLastName();
922*cdf0e10cSrcweir         ::rtl::OUString aInfo;
923*cdf0e10cSrcweir         ::rtl::Reference< ::ucbhelper::InteractionRequest > xInteractionRequestImpl;
924*cdf0e10cSrcweir 
925*cdf0e10cSrcweir         if ( bOwnLock )
926*cdf0e10cSrcweir         {
927*cdf0e10cSrcweir             if ( aData.getLength() > LOCKFILE_EDITTIME_ID )
928*cdf0e10cSrcweir                 aInfo = aData[LOCKFILE_EDITTIME_ID];
929*cdf0e10cSrcweir 
930*cdf0e10cSrcweir             xInteractionRequestImpl = new ::ucbhelper::InteractionRequest( uno::makeAny(
931*cdf0e10cSrcweir                 document::OwnLockOnDocumentRequest( ::rtl::OUString(), uno::Reference< uno::XInterface >(), aDocumentURL, aInfo, !bIsLoading ) ) );
932*cdf0e10cSrcweir         }
933*cdf0e10cSrcweir         else
934*cdf0e10cSrcweir         {
935*cdf0e10cSrcweir             if ( aData.getLength() > LOCKFILE_EDITTIME_ID )
936*cdf0e10cSrcweir             {
937*cdf0e10cSrcweir                 if ( aData[LOCKFILE_OOOUSERNAME_ID].getLength() )
938*cdf0e10cSrcweir                     aInfo = aData[LOCKFILE_OOOUSERNAME_ID];
939*cdf0e10cSrcweir                 else
940*cdf0e10cSrcweir                     aInfo = aData[LOCKFILE_SYSUSERNAME_ID];
941*cdf0e10cSrcweir 
942*cdf0e10cSrcweir                 if ( aInfo.getLength() && aData[LOCKFILE_EDITTIME_ID].getLength() )
943*cdf0e10cSrcweir                 {
944*cdf0e10cSrcweir                     aInfo += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " ( " ) );
945*cdf0e10cSrcweir                     aInfo += aData[LOCKFILE_EDITTIME_ID];
946*cdf0e10cSrcweir                     aInfo += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " )" ) );
947*cdf0e10cSrcweir                 }
948*cdf0e10cSrcweir             }
949*cdf0e10cSrcweir 
950*cdf0e10cSrcweir             if ( bIsLoading )
951*cdf0e10cSrcweir             {
952*cdf0e10cSrcweir                 xInteractionRequestImpl = new ::ucbhelper::InteractionRequest( uno::makeAny(
953*cdf0e10cSrcweir                     document::LockedDocumentRequest( ::rtl::OUString(), uno::Reference< uno::XInterface >(), aDocumentURL, aInfo ) ) );
954*cdf0e10cSrcweir             }
955*cdf0e10cSrcweir             else
956*cdf0e10cSrcweir             {
957*cdf0e10cSrcweir                 xInteractionRequestImpl = new ::ucbhelper::InteractionRequest( uno::makeAny(
958*cdf0e10cSrcweir                     document::LockedOnSavingRequest( ::rtl::OUString(), uno::Reference< uno::XInterface >(), aDocumentURL, aInfo ) ) );
959*cdf0e10cSrcweir 
960*cdf0e10cSrcweir             }
961*cdf0e10cSrcweir         }
962*cdf0e10cSrcweir 
963*cdf0e10cSrcweir         uno::Sequence< uno::Reference< task::XInteractionContinuation > > aContinuations( 3 );
964*cdf0e10cSrcweir         aContinuations[0] = new ::ucbhelper::InteractionAbort( xInteractionRequestImpl.get() );
965*cdf0e10cSrcweir         aContinuations[1] = new ::ucbhelper::InteractionApprove( xInteractionRequestImpl.get() );
966*cdf0e10cSrcweir         aContinuations[2] = new ::ucbhelper::InteractionDisapprove( xInteractionRequestImpl.get() );
967*cdf0e10cSrcweir         xInteractionRequestImpl->setContinuations( aContinuations );
968*cdf0e10cSrcweir 
969*cdf0e10cSrcweir         xHandler->handle( xInteractionRequestImpl.get() );
970*cdf0e10cSrcweir 
971*cdf0e10cSrcweir         ::rtl::Reference< ::ucbhelper::InteractionContinuation > xSelected = xInteractionRequestImpl->getSelection();
972*cdf0e10cSrcweir         if ( uno::Reference< task::XInteractionAbort >( xSelected.get(), uno::UNO_QUERY ).is() )
973*cdf0e10cSrcweir         {
974*cdf0e10cSrcweir             SetError( ERRCODE_ABORT, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
975*cdf0e10cSrcweir         }
976*cdf0e10cSrcweir         else if ( uno::Reference< task::XInteractionDisapprove >( xSelected.get(), uno::UNO_QUERY ).is() )
977*cdf0e10cSrcweir         {
978*cdf0e10cSrcweir             // own lock on loading, user has selected to ignore the lock
979*cdf0e10cSrcweir             // own lock on saving, user has selected to ignore the lock
980*cdf0e10cSrcweir             // alien lock on loading, user has selected to edit a copy of document
981*cdf0e10cSrcweir             // TODO/LATER: alien lock on saving, user has selected to do SaveAs to different location
982*cdf0e10cSrcweir             if ( bIsLoading && !bOwnLock )
983*cdf0e10cSrcweir             {
984*cdf0e10cSrcweir                 // means that a copy of the document should be opened
985*cdf0e10cSrcweir                 GetItemSet()->Put( SfxBoolItem( SID_TEMPLATE, sal_True ) );
986*cdf0e10cSrcweir             }
987*cdf0e10cSrcweir             else if ( bOwnLock )
988*cdf0e10cSrcweir                 nResult = LOCK_UI_SUCCEEDED;
989*cdf0e10cSrcweir         }
990*cdf0e10cSrcweir         else // if ( XSelected == aContinuations[1] )
991*cdf0e10cSrcweir         {
992*cdf0e10cSrcweir             // own lock on loading, user has selected to open readonly
993*cdf0e10cSrcweir             // own lock on saving, user has selected to open readonly
994*cdf0e10cSrcweir             // alien lock on loading, user has selected to retry saving
995*cdf0e10cSrcweir             // TODO/LATER: alien lock on saving, user has selected to retry saving
996*cdf0e10cSrcweir 
997*cdf0e10cSrcweir             if ( bIsLoading )
998*cdf0e10cSrcweir                 GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY, sal_True ) );
999*cdf0e10cSrcweir             else
1000*cdf0e10cSrcweir                 nResult = LOCK_UI_TRY;
1001*cdf0e10cSrcweir         }
1002*cdf0e10cSrcweir     }
1003*cdf0e10cSrcweir     else
1004*cdf0e10cSrcweir     {
1005*cdf0e10cSrcweir         if ( bIsLoading )
1006*cdf0e10cSrcweir         {
1007*cdf0e10cSrcweir             // if no interaction handler is provided the default answer is open readonly
1008*cdf0e10cSrcweir             // that usually happens in case the document is loaded per API
1009*cdf0e10cSrcweir             // so the document must be opened readonly for backward compatibility
1010*cdf0e10cSrcweir             GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY, sal_True ) );
1011*cdf0e10cSrcweir         }
1012*cdf0e10cSrcweir         else
1013*cdf0e10cSrcweir             SetError( ERRCODE_IO_ACCESSDENIED, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
1014*cdf0e10cSrcweir 
1015*cdf0e10cSrcweir     }
1016*cdf0e10cSrcweir 
1017*cdf0e10cSrcweir     return nResult;
1018*cdf0e10cSrcweir }
1019*cdf0e10cSrcweir 
1020*cdf0e10cSrcweir //------------------------------------------------------------------
1021*cdf0e10cSrcweir sal_Bool SfxMedium::LockOrigFileOnDemand( sal_Bool bLoading, sal_Bool bNoUI )
1022*cdf0e10cSrcweir {
1023*cdf0e10cSrcweir     // returns true if the document can be opened for editing ( even if it should be a copy )
1024*cdf0e10cSrcweir     // otherwise the document should be opened readonly
1025*cdf0e10cSrcweir     // if user cancel the loading the ERROR_ABORT is set
1026*cdf0e10cSrcweir 
1027*cdf0e10cSrcweir     if ( pImp->m_bLocked && bLoading && ::utl::LocalFileHelper::IsLocalFile( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ) )
1028*cdf0e10cSrcweir     {
1029*cdf0e10cSrcweir         // if the document is already locked the system locking might be temporarely off after storing
1030*cdf0e10cSrcweir         // check whether the system file locking should be taken again
1031*cdf0e10cSrcweir         GetLockingStream_Impl();
1032*cdf0e10cSrcweir     }
1033*cdf0e10cSrcweir 
1034*cdf0e10cSrcweir     sal_Bool bResult = pImp->m_bLocked;
1035*cdf0e10cSrcweir 
1036*cdf0e10cSrcweir     if ( !bResult )
1037*cdf0e10cSrcweir     {
1038*cdf0e10cSrcweir         // no read-write access is necessary on loading if the document is explicitly opened as copy
1039*cdf0e10cSrcweir         SFX_ITEMSET_ARG( GetItemSet(), pTemplateItem, SfxBoolItem, SID_TEMPLATE, sal_False);
1040*cdf0e10cSrcweir         bResult = ( bLoading && pTemplateItem && pTemplateItem->GetValue() );
1041*cdf0e10cSrcweir     }
1042*cdf0e10cSrcweir 
1043*cdf0e10cSrcweir     if ( !bResult && !IsReadOnly() )
1044*cdf0e10cSrcweir     {
1045*cdf0e10cSrcweir         sal_Bool bContentReadonly = sal_False;
1046*cdf0e10cSrcweir         if ( bLoading && ::utl::LocalFileHelper::IsLocalFile( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ) )
1047*cdf0e10cSrcweir         {
1048*cdf0e10cSrcweir             // let the original document be opened to check the possibility to open it for editing
1049*cdf0e10cSrcweir             // and to let the writable stream stay open to hold the lock on the document
1050*cdf0e10cSrcweir             GetLockingStream_Impl();
1051*cdf0e10cSrcweir         }
1052*cdf0e10cSrcweir 
1053*cdf0e10cSrcweir         // "IsReadOnly" property does not allow to detect whether the file is readonly always
1054*cdf0e10cSrcweir         // so we try always to open the file for editing
1055*cdf0e10cSrcweir         // the file is readonly only in case the read-write stream can not be opened
1056*cdf0e10cSrcweir         if ( bLoading && !pImp->m_xLockingStream.is() )
1057*cdf0e10cSrcweir         {
1058*cdf0e10cSrcweir             try
1059*cdf0e10cSrcweir             {
1060*cdf0e10cSrcweir                 // MediaDescriptor does this check also, the duplication should be avoided in future
1061*cdf0e10cSrcweir                 Reference< ::com::sun::star::ucb::XCommandEnvironment > xDummyEnv;
1062*cdf0e10cSrcweir                 ::ucbhelper::Content aContent( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv );
1063*cdf0e10cSrcweir                 aContent.getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ) ) ) >>= bContentReadonly;
1064*cdf0e10cSrcweir             }
1065*cdf0e10cSrcweir             catch( uno::Exception )
1066*cdf0e10cSrcweir             {}
1067*cdf0e10cSrcweir 
1068*cdf0e10cSrcweir             if ( !bContentReadonly )
1069*cdf0e10cSrcweir             {
1070*cdf0e10cSrcweir                 // the file is not readonly, check the ACL
1071*cdf0e10cSrcweir 
1072*cdf0e10cSrcweir                 String aPhysPath;
1073*cdf0e10cSrcweir                 if ( ::utl::LocalFileHelper::ConvertURLToPhysicalName( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ), aPhysPath ) )
1074*cdf0e10cSrcweir                     bContentReadonly = IsReadonlyAccordingACL( aPhysPath.GetBuffer() );
1075*cdf0e10cSrcweir             }
1076*cdf0e10cSrcweir         }
1077*cdf0e10cSrcweir 
1078*cdf0e10cSrcweir         // do further checks only if the file not readonly in fs
1079*cdf0e10cSrcweir         if ( !bContentReadonly )
1080*cdf0e10cSrcweir         {
1081*cdf0e10cSrcweir             // the special file locking should be used only for file URLs
1082*cdf0e10cSrcweir             if ( ::utl::LocalFileHelper::IsLocalFile( aLogicName ) )
1083*cdf0e10cSrcweir             {
1084*cdf0e10cSrcweir 
1085*cdf0e10cSrcweir                 // in case of storing the document should request the output before locking
1086*cdf0e10cSrcweir                 if ( bLoading )
1087*cdf0e10cSrcweir                 {
1088*cdf0e10cSrcweir                     // let the stream be opened to check the system file locking
1089*cdf0e10cSrcweir                     GetMedium_Impl();
1090*cdf0e10cSrcweir                 }
1091*cdf0e10cSrcweir 
1092*cdf0e10cSrcweir                 sal_Int8 bUIStatus = LOCK_UI_NOLOCK;
1093*cdf0e10cSrcweir 
1094*cdf0e10cSrcweir                 // check whether system file locking has been used, the default value is false
1095*cdf0e10cSrcweir                 sal_Bool bUseSystemLock = IsSystemFileLockingUsed();
1096*cdf0e10cSrcweir 
1097*cdf0e10cSrcweir                 // TODO/LATER: This implementation does not allow to detect the system lock on saving here, actually this is no big problem
1098*cdf0e10cSrcweir                 // if system lock is used the writeable stream should be available
1099*cdf0e10cSrcweir                 sal_Bool bHandleSysLocked = ( bLoading && bUseSystemLock && !pImp->xStream.is() && !pOutStream );
1100*cdf0e10cSrcweir 
1101*cdf0e10cSrcweir                 do
1102*cdf0e10cSrcweir                 {
1103*cdf0e10cSrcweir                     try
1104*cdf0e10cSrcweir                     {
1105*cdf0e10cSrcweir                         ::svt::DocumentLockFile aLockFile( aLogicName );
1106*cdf0e10cSrcweir                         if ( !bHandleSysLocked )
1107*cdf0e10cSrcweir                         {
1108*cdf0e10cSrcweir                             try
1109*cdf0e10cSrcweir                             {
1110*cdf0e10cSrcweir                                 bResult = aLockFile.CreateOwnLockFile();
1111*cdf0e10cSrcweir                             }
1112*cdf0e10cSrcweir                             catch ( ucb::InteractiveIOException& e )
1113*cdf0e10cSrcweir                             {
1114*cdf0e10cSrcweir                                 // exception means that the lock file can not be successfuly accessed
1115*cdf0e10cSrcweir                                 // in this case it should be ignored if system file locking is anyway active
1116*cdf0e10cSrcweir                                 if ( bUseSystemLock || !IsOOoLockFileUsed() )
1117*cdf0e10cSrcweir                                 {
1118*cdf0e10cSrcweir                                     bResult = sal_True;
1119*cdf0e10cSrcweir                                     // take the ownership over the lock file
1120*cdf0e10cSrcweir                                     aLockFile.OverwriteOwnLockFile();
1121*cdf0e10cSrcweir                                 }
1122*cdf0e10cSrcweir                                 else if ( e.Code == IOErrorCode_INVALID_PARAMETER )
1123*cdf0e10cSrcweir                                 {
1124*cdf0e10cSrcweir                                     // system file locking is not active, ask user whether he wants to open the document without any locking
1125*cdf0e10cSrcweir                                     uno::Reference< task::XInteractionHandler > xHandler = GetInteractionHandler();
1126*cdf0e10cSrcweir 
1127*cdf0e10cSrcweir                                     if ( xHandler.is() )
1128*cdf0e10cSrcweir                                     {
1129*cdf0e10cSrcweir                                         ::rtl::Reference< ::ucbhelper::InteractionRequest > xIgnoreRequestImpl
1130*cdf0e10cSrcweir                                             = new ::ucbhelper::InteractionRequest( uno::makeAny( document::LockFileIgnoreRequest() ) );
1131*cdf0e10cSrcweir 
1132*cdf0e10cSrcweir                                         uno::Sequence< uno::Reference< task::XInteractionContinuation > > aContinuations( 2 );
1133*cdf0e10cSrcweir                                         aContinuations[0] = new ::ucbhelper::InteractionAbort( xIgnoreRequestImpl.get() );
1134*cdf0e10cSrcweir                                         aContinuations[1] = new ::ucbhelper::InteractionApprove( xIgnoreRequestImpl.get() );
1135*cdf0e10cSrcweir                                         xIgnoreRequestImpl->setContinuations( aContinuations );
1136*cdf0e10cSrcweir 
1137*cdf0e10cSrcweir                                         xHandler->handle( xIgnoreRequestImpl.get() );
1138*cdf0e10cSrcweir 
1139*cdf0e10cSrcweir                                         ::rtl::Reference< ::ucbhelper::InteractionContinuation > xSelected = xIgnoreRequestImpl->getSelection();
1140*cdf0e10cSrcweir                                         bResult = (  uno::Reference< task::XInteractionApprove >( xSelected.get(), uno::UNO_QUERY ).is() );
1141*cdf0e10cSrcweir                                     }
1142*cdf0e10cSrcweir                                 }
1143*cdf0e10cSrcweir                             }
1144*cdf0e10cSrcweir                             catch ( uno::Exception& )
1145*cdf0e10cSrcweir                             {
1146*cdf0e10cSrcweir                                 // exception means that the lock file can not be successfuly accessed
1147*cdf0e10cSrcweir                                 // in this case it should be ignored if system file locking is anyway active
1148*cdf0e10cSrcweir                                 if ( bUseSystemLock || !IsOOoLockFileUsed() )
1149*cdf0e10cSrcweir                                 {
1150*cdf0e10cSrcweir                                     bResult = sal_True;
1151*cdf0e10cSrcweir                                     // take the ownership over the lock file
1152*cdf0e10cSrcweir                                     aLockFile.OverwriteOwnLockFile();
1153*cdf0e10cSrcweir                                 }
1154*cdf0e10cSrcweir                             }
1155*cdf0e10cSrcweir 
1156*cdf0e10cSrcweir                             // in case OOo locking is turned off the lock file is still written if possible
1157*cdf0e10cSrcweir                             // but it is ignored while deciding whether the document should be opened for editing or not
1158*cdf0e10cSrcweir                             if ( !bResult && !IsOOoLockFileUsed() )
1159*cdf0e10cSrcweir                             {
1160*cdf0e10cSrcweir                                 bResult = sal_True;
1161*cdf0e10cSrcweir                                 // take the ownership over the lock file
1162*cdf0e10cSrcweir                                 aLockFile.OverwriteOwnLockFile();
1163*cdf0e10cSrcweir                             }
1164*cdf0e10cSrcweir                         }
1165*cdf0e10cSrcweir 
1166*cdf0e10cSrcweir 
1167*cdf0e10cSrcweir                         if ( !bResult )
1168*cdf0e10cSrcweir                         {
1169*cdf0e10cSrcweir                             uno::Sequence< ::rtl::OUString > aData;
1170*cdf0e10cSrcweir                             try
1171*cdf0e10cSrcweir                             {
1172*cdf0e10cSrcweir                                 // impossibility to get data is no real problem
1173*cdf0e10cSrcweir                                 aData = aLockFile.GetLockData();
1174*cdf0e10cSrcweir                             }
1175*cdf0e10cSrcweir                             catch( uno::Exception ) {}
1176*cdf0e10cSrcweir 
1177*cdf0e10cSrcweir                             sal_Bool bOwnLock = sal_False;
1178*cdf0e10cSrcweir 
1179*cdf0e10cSrcweir                             if ( !bHandleSysLocked )
1180*cdf0e10cSrcweir                             {
1181*cdf0e10cSrcweir                                 uno::Sequence< ::rtl::OUString > aOwnData = aLockFile.GenerateOwnEntry();
1182*cdf0e10cSrcweir                                 bOwnLock = ( aData.getLength() > LOCKFILE_USERURL_ID
1183*cdf0e10cSrcweir                                           && aOwnData.getLength() > LOCKFILE_USERURL_ID
1184*cdf0e10cSrcweir                                           && aOwnData[LOCKFILE_SYSUSERNAME_ID].equals( aData[LOCKFILE_SYSUSERNAME_ID] ) );
1185*cdf0e10cSrcweir 
1186*cdf0e10cSrcweir                                 if ( bOwnLock
1187*cdf0e10cSrcweir                                   && aOwnData[LOCKFILE_LOCALHOST_ID].equals( aData[LOCKFILE_LOCALHOST_ID] )
1188*cdf0e10cSrcweir                                   && aOwnData[LOCKFILE_USERURL_ID].equals( aData[LOCKFILE_USERURL_ID] ) )
1189*cdf0e10cSrcweir                                 {
1190*cdf0e10cSrcweir                                     // this is own lock from the same installation, it could remain because of crash
1191*cdf0e10cSrcweir                                     bResult = sal_True;
1192*cdf0e10cSrcweir                                 }
1193*cdf0e10cSrcweir                             }
1194*cdf0e10cSrcweir 
1195*cdf0e10cSrcweir                             if ( !bResult && !bNoUI )
1196*cdf0e10cSrcweir                             {
1197*cdf0e10cSrcweir                                 bUIStatus = ShowLockedDocumentDialog( aData, bLoading, bOwnLock );
1198*cdf0e10cSrcweir                                 if ( bUIStatus == LOCK_UI_SUCCEEDED )
1199*cdf0e10cSrcweir                                 {
1200*cdf0e10cSrcweir                                     // take the ownership over the lock file
1201*cdf0e10cSrcweir                                     bResult = aLockFile.OverwriteOwnLockFile();
1202*cdf0e10cSrcweir                                 }
1203*cdf0e10cSrcweir                             }
1204*cdf0e10cSrcweir 
1205*cdf0e10cSrcweir                             bHandleSysLocked = sal_False;
1206*cdf0e10cSrcweir                         }
1207*cdf0e10cSrcweir                     }
1208*cdf0e10cSrcweir                     catch( uno::Exception& )
1209*cdf0e10cSrcweir                     {
1210*cdf0e10cSrcweir                     }
1211*cdf0e10cSrcweir                 } while( !bResult && bUIStatus == LOCK_UI_TRY );
1212*cdf0e10cSrcweir 
1213*cdf0e10cSrcweir                 pImp->m_bLocked = bResult;
1214*cdf0e10cSrcweir             }
1215*cdf0e10cSrcweir             else
1216*cdf0e10cSrcweir             {
1217*cdf0e10cSrcweir                 // this is no file URL, check whether the file is readonly
1218*cdf0e10cSrcweir                 bResult = !bContentReadonly;
1219*cdf0e10cSrcweir             }
1220*cdf0e10cSrcweir         }
1221*cdf0e10cSrcweir     }
1222*cdf0e10cSrcweir 
1223*cdf0e10cSrcweir     if ( !bResult && GetError() == ERRCODE_NONE )
1224*cdf0e10cSrcweir     {
1225*cdf0e10cSrcweir         // the error should be set in case it is storing process
1226*cdf0e10cSrcweir         // or the document has been opened for editing explicitly
1227*cdf0e10cSrcweir 
1228*cdf0e10cSrcweir         SFX_ITEMSET_ARG( pSet, pReadOnlyItem, SfxBoolItem, SID_DOC_READONLY, sal_False );
1229*cdf0e10cSrcweir         if ( !bLoading || (pReadOnlyItem && !pReadOnlyItem->GetValue()) )
1230*cdf0e10cSrcweir             SetError( ERRCODE_IO_ACCESSDENIED, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
1231*cdf0e10cSrcweir         else
1232*cdf0e10cSrcweir             GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY, sal_True ) );
1233*cdf0e10cSrcweir     }
1234*cdf0e10cSrcweir 
1235*cdf0e10cSrcweir     // when the file is locked, get the current file date
1236*cdf0e10cSrcweir     if ( bResult && DocNeedsFileDateCheck() )
1237*cdf0e10cSrcweir         GetInitFileDate( sal_True );
1238*cdf0e10cSrcweir 
1239*cdf0e10cSrcweir     return bResult;
1240*cdf0e10cSrcweir }
1241*cdf0e10cSrcweir 
1242*cdf0e10cSrcweir //------------------------------------------------------------------
1243*cdf0e10cSrcweir uno::Reference < embed::XStorage > SfxMedium::GetStorage( sal_Bool bCreateTempIfNo )
1244*cdf0e10cSrcweir {
1245*cdf0e10cSrcweir     if ( pImp->xStorage.is() || bTriedStorage )
1246*cdf0e10cSrcweir         return pImp->xStorage;
1247*cdf0e10cSrcweir 
1248*cdf0e10cSrcweir     uno::Sequence< uno::Any > aArgs( 2 );
1249*cdf0e10cSrcweir 
1250*cdf0e10cSrcweir     // the medium should be retrieved before temporary file creation
1251*cdf0e10cSrcweir     // to let the MediaDescriptor be filled with the streams
1252*cdf0e10cSrcweir     GetMedium_Impl();
1253*cdf0e10cSrcweir 
1254*cdf0e10cSrcweir     if ( bCreateTempIfNo )
1255*cdf0e10cSrcweir         CreateTempFile( sal_False );
1256*cdf0e10cSrcweir 
1257*cdf0e10cSrcweir     GetMedium_Impl();
1258*cdf0e10cSrcweir 
1259*cdf0e10cSrcweir     if ( GetError() )
1260*cdf0e10cSrcweir         return pImp->xStorage;
1261*cdf0e10cSrcweir 
1262*cdf0e10cSrcweir     SFX_ITEMSET_ARG( GetItemSet(), pRepairItem, SfxBoolItem, SID_REPAIRPACKAGE, sal_False);
1263*cdf0e10cSrcweir     if ( pRepairItem && pRepairItem->GetValue() )
1264*cdf0e10cSrcweir     {
1265*cdf0e10cSrcweir         // the storage should be created for repairing mode
1266*cdf0e10cSrcweir         CreateTempFile( sal_False );
1267*cdf0e10cSrcweir         GetMedium_Impl();
1268*cdf0e10cSrcweir 
1269*cdf0e10cSrcweir         Reference< ::com::sun::star::ucb::XProgressHandler > xProgressHandler;
1270*cdf0e10cSrcweir         Reference< ::com::sun::star::task::XStatusIndicator > xStatusIndicator;
1271*cdf0e10cSrcweir 
1272*cdf0e10cSrcweir         SFX_ITEMSET_ARG( GetItemSet(), pxProgressItem, SfxUnoAnyItem, SID_PROGRESS_STATUSBAR_CONTROL, sal_False );
1273*cdf0e10cSrcweir         if( pxProgressItem && ( pxProgressItem->GetValue() >>= xStatusIndicator ) )
1274*cdf0e10cSrcweir             xProgressHandler = Reference< ::com::sun::star::ucb::XProgressHandler >(
1275*cdf0e10cSrcweir                                     new utl::ProgressHandlerWrap( xStatusIndicator ) );
1276*cdf0e10cSrcweir 
1277*cdf0e10cSrcweir         uno::Sequence< beans::PropertyValue > aAddProps( 2 );
1278*cdf0e10cSrcweir         aAddProps[0].Name = ::rtl::OUString::createFromAscii( "RepairPackage" );
1279*cdf0e10cSrcweir         aAddProps[0].Value <<= (sal_Bool)sal_True;
1280*cdf0e10cSrcweir         aAddProps[1].Name = ::rtl::OUString::createFromAscii( "StatusIndicator" );
1281*cdf0e10cSrcweir         aAddProps[1].Value <<= xProgressHandler;
1282*cdf0e10cSrcweir 
1283*cdf0e10cSrcweir         // the first arguments will be filled later
1284*cdf0e10cSrcweir         aArgs.realloc( 3 );
1285*cdf0e10cSrcweir         aArgs[2] <<= aAddProps;
1286*cdf0e10cSrcweir     }
1287*cdf0e10cSrcweir 
1288*cdf0e10cSrcweir     if ( pImp->xStream.is() )
1289*cdf0e10cSrcweir     {
1290*cdf0e10cSrcweir         // since the storage is based on temporary stream we open it always read-write
1291*cdf0e10cSrcweir         aArgs[0] <<= pImp->xStream;
1292*cdf0e10cSrcweir         aArgs[1] <<= embed::ElementModes::READWRITE;
1293*cdf0e10cSrcweir         pImp->bStorageBasedOnInStream = sal_True;
1294*cdf0e10cSrcweir     }
1295*cdf0e10cSrcweir     else if ( pImp->xInputStream.is() )
1296*cdf0e10cSrcweir     {
1297*cdf0e10cSrcweir         // since the storage is based on temporary stream we open it always read-write
1298*cdf0e10cSrcweir         aArgs[0] <<= pImp->xInputStream;
1299*cdf0e10cSrcweir         aArgs[1] <<= embed::ElementModes::READ;
1300*cdf0e10cSrcweir         pImp->bStorageBasedOnInStream = sal_True;
1301*cdf0e10cSrcweir     }
1302*cdf0e10cSrcweir     else
1303*cdf0e10cSrcweir     {
1304*cdf0e10cSrcweir         CloseStreams_Impl();
1305*cdf0e10cSrcweir         aArgs[0] <<= ::rtl::OUString( aName );
1306*cdf0e10cSrcweir         aArgs[1] <<= embed::ElementModes::READ;
1307*cdf0e10cSrcweir         pImp->bStorageBasedOnInStream = sal_False;
1308*cdf0e10cSrcweir     }
1309*cdf0e10cSrcweir 
1310*cdf0e10cSrcweir     try
1311*cdf0e10cSrcweir     {
1312*cdf0e10cSrcweir         pImp->xStorage = uno::Reference< embed::XStorage >(
1313*cdf0e10cSrcweir                             ::comphelper::OStorageHelper::GetStorageFactory()->createInstanceWithArguments( aArgs ),
1314*cdf0e10cSrcweir                             uno::UNO_QUERY );
1315*cdf0e10cSrcweir     }
1316*cdf0e10cSrcweir     catch( uno::Exception& )
1317*cdf0e10cSrcweir     {
1318*cdf0e10cSrcweir         // impossibility to create the storage is no error
1319*cdf0e10cSrcweir     }
1320*cdf0e10cSrcweir 
1321*cdf0e10cSrcweir     if( ( pImp->nLastStorageError = GetError() ) != SVSTREAM_OK )
1322*cdf0e10cSrcweir     {
1323*cdf0e10cSrcweir         pImp->xStorage = 0;
1324*cdf0e10cSrcweir         if ( pInStream )
1325*cdf0e10cSrcweir             pInStream->Seek(0);
1326*cdf0e10cSrcweir         return uno::Reference< embed::XStorage >();
1327*cdf0e10cSrcweir     }
1328*cdf0e10cSrcweir 
1329*cdf0e10cSrcweir     bTriedStorage = sal_True;
1330*cdf0e10cSrcweir 
1331*cdf0e10cSrcweir     // TODO/LATER: Get versionlist on demand
1332*cdf0e10cSrcweir     if ( pImp->xStorage.is() )
1333*cdf0e10cSrcweir 	{
1334*cdf0e10cSrcweir         SetEncryptionDataToStorage_Impl();
1335*cdf0e10cSrcweir         GetVersionList();
1336*cdf0e10cSrcweir 	}
1337*cdf0e10cSrcweir 
1338*cdf0e10cSrcweir     SFX_ITEMSET_ARG( pSet, pVersion, SfxInt16Item, SID_VERSION, sal_False);
1339*cdf0e10cSrcweir 
1340*cdf0e10cSrcweir     sal_Bool bResetStorage = sal_False;
1341*cdf0e10cSrcweir     if ( pVersion && pVersion->GetValue() )
1342*cdf0e10cSrcweir     {
1343*cdf0e10cSrcweir         // Alle verf"ugbaren Versionen einlesen
1344*cdf0e10cSrcweir         if ( pImp->aVersions.getLength() )
1345*cdf0e10cSrcweir         {
1346*cdf0e10cSrcweir             // Die zum Kommentar passende Version suchen
1347*cdf0e10cSrcweir             // Die Versionen sind von 1 an durchnumeriert, mit negativen
1348*cdf0e10cSrcweir             // Versionsnummern werden die Versionen von der aktuellen aus
1349*cdf0e10cSrcweir             // r"uckw"arts gez"ahlt
1350*cdf0e10cSrcweir             short nVersion = pVersion ? pVersion->GetValue() : 0;
1351*cdf0e10cSrcweir             if ( nVersion<0 )
1352*cdf0e10cSrcweir                 nVersion = ( (short) pImp->aVersions.getLength() ) + nVersion;
1353*cdf0e10cSrcweir             else if ( nVersion )
1354*cdf0e10cSrcweir                 nVersion--;
1355*cdf0e10cSrcweir 
1356*cdf0e10cSrcweir             util::RevisionTag& rTag = pImp->aVersions[nVersion];
1357*cdf0e10cSrcweir             {
1358*cdf0e10cSrcweir                 // SubStorage f"ur alle Versionen "offnen
1359*cdf0e10cSrcweir                 uno::Reference < embed::XStorage > xSub = pImp->xStorage->openStorageElement( DEFINE_CONST_UNICODE( "Versions" ),
1360*cdf0e10cSrcweir                         embed::ElementModes::READ );
1361*cdf0e10cSrcweir 
1362*cdf0e10cSrcweir                 DBG_ASSERT( xSub.is(), "Versionsliste, aber keine Versionen!" );
1363*cdf0e10cSrcweir 
1364*cdf0e10cSrcweir                 // Dort ist die Version als gepackter Stream gespeichert
1365*cdf0e10cSrcweir                 uno::Reference < io::XStream > xStr = xSub->openStreamElement( rTag.Identifier, embed::ElementModes::READ );
1366*cdf0e10cSrcweir                 SvStream* pStream = utl::UcbStreamHelper::CreateStream( xStr );
1367*cdf0e10cSrcweir                 if ( pStream && pStream->GetError() == SVSTREAM_OK )
1368*cdf0e10cSrcweir                 {
1369*cdf0e10cSrcweir                     // Stream ins TempDir auspacken
1370*cdf0e10cSrcweir                     ::utl::TempFile aTempFile;
1371*cdf0e10cSrcweir                     String          aTmpName = aTempFile.GetURL();
1372*cdf0e10cSrcweir                     SvFileStream    aTmpStream( aTmpName, SFX_STREAM_READWRITE );
1373*cdf0e10cSrcweir 
1374*cdf0e10cSrcweir                     *pStream >> aTmpStream;
1375*cdf0e10cSrcweir                     aTmpStream.Close();
1376*cdf0e10cSrcweir 
1377*cdf0e10cSrcweir                     // Datei als Storage "offnen
1378*cdf0e10cSrcweir                     nStorOpenMode = SFX_STREAM_READONLY;
1379*cdf0e10cSrcweir                     pImp->xStorage = comphelper::OStorageHelper::GetStorageFromURL( aTmpName, embed::ElementModes::READ );
1380*cdf0e10cSrcweir                     pImp->bStorageBasedOnInStream = sal_False;
1381*cdf0e10cSrcweir                     String aTemp;
1382*cdf0e10cSrcweir                     ::utl::LocalFileHelper::ConvertURLToPhysicalName( aTmpName, aTemp );
1383*cdf0e10cSrcweir                     SetPhysicalName_Impl( aTemp );
1384*cdf0e10cSrcweir 
1385*cdf0e10cSrcweir                     pImp->bIsTemp = sal_True;
1386*cdf0e10cSrcweir                     GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY, sal_True ) );
1387*cdf0e10cSrcweir                     // TODO/MBA
1388*cdf0e10cSrcweir                     pImp->aVersions.realloc(0);
1389*cdf0e10cSrcweir                 }
1390*cdf0e10cSrcweir                 else
1391*cdf0e10cSrcweir                     bResetStorage = sal_True;
1392*cdf0e10cSrcweir             }
1393*cdf0e10cSrcweir         }
1394*cdf0e10cSrcweir         else
1395*cdf0e10cSrcweir             bResetStorage = sal_True;
1396*cdf0e10cSrcweir     }
1397*cdf0e10cSrcweir 
1398*cdf0e10cSrcweir     if ( bResetStorage )
1399*cdf0e10cSrcweir     {
1400*cdf0e10cSrcweir         pImp->xStorage = 0;
1401*cdf0e10cSrcweir         if ( pInStream )
1402*cdf0e10cSrcweir             pInStream->Seek( 0L );
1403*cdf0e10cSrcweir     }
1404*cdf0e10cSrcweir 
1405*cdf0e10cSrcweir     pImp->bIsStorage = pImp->xStorage.is();
1406*cdf0e10cSrcweir     return pImp->xStorage;
1407*cdf0e10cSrcweir }
1408*cdf0e10cSrcweir 
1409*cdf0e10cSrcweir //------------------------------------------------------------------
1410*cdf0e10cSrcweir uno::Reference< embed::XStorage > SfxMedium::GetZipStorageToSign_Impl( sal_Bool bReadOnly )
1411*cdf0e10cSrcweir {
1412*cdf0e10cSrcweir     if ( !GetError() && !pImp->m_xZipStorage.is() )
1413*cdf0e10cSrcweir     {
1414*cdf0e10cSrcweir         // very careful!!!
1415*cdf0e10cSrcweir         // if bReadOnly == sal_False and there is no temporary file the original file might be used
1416*cdf0e10cSrcweir         GetMedium_Impl();
1417*cdf0e10cSrcweir 
1418*cdf0e10cSrcweir         try
1419*cdf0e10cSrcweir         {
1420*cdf0e10cSrcweir             // we can not sign document if there is no stream
1421*cdf0e10cSrcweir             // should it be possible at all?
1422*cdf0e10cSrcweir             if ( !bReadOnly && pImp->xStream.is() )
1423*cdf0e10cSrcweir             {
1424*cdf0e10cSrcweir                 pImp->m_xZipStorage = ::comphelper::OStorageHelper::GetStorageOfFormatFromStream( ZIP_STORAGE_FORMAT_STRING, pImp->xStream, embed::ElementModes::READWRITE );
1425*cdf0e10cSrcweir             }
1426*cdf0e10cSrcweir             else if ( pImp->xInputStream.is() )
1427*cdf0e10cSrcweir             {
1428*cdf0e10cSrcweir                 pImp->m_xZipStorage = ::comphelper::OStorageHelper::GetStorageOfFormatFromInputStream( ZIP_STORAGE_FORMAT_STRING, pImp->xInputStream );
1429*cdf0e10cSrcweir             }
1430*cdf0e10cSrcweir         }
1431*cdf0e10cSrcweir         catch( uno::Exception& )
1432*cdf0e10cSrcweir         {
1433*cdf0e10cSrcweir             OSL_ENSURE( sal_False, "No possibility to get readonly version of storage from medium!\n" );
1434*cdf0e10cSrcweir         }
1435*cdf0e10cSrcweir 
1436*cdf0e10cSrcweir         if ( GetError() ) // do not remove warnings
1437*cdf0e10cSrcweir             ResetError();
1438*cdf0e10cSrcweir     }
1439*cdf0e10cSrcweir 
1440*cdf0e10cSrcweir     return pImp->m_xZipStorage;
1441*cdf0e10cSrcweir }
1442*cdf0e10cSrcweir 
1443*cdf0e10cSrcweir //------------------------------------------------------------------
1444*cdf0e10cSrcweir void SfxMedium::CloseZipStorage_Impl()
1445*cdf0e10cSrcweir {
1446*cdf0e10cSrcweir 	if ( pImp->m_xZipStorage.is() )
1447*cdf0e10cSrcweir 	{
1448*cdf0e10cSrcweir 		try {
1449*cdf0e10cSrcweir 			pImp->m_xZipStorage->dispose();
1450*cdf0e10cSrcweir 		} catch( uno::Exception& )
1451*cdf0e10cSrcweir 		{}
1452*cdf0e10cSrcweir 
1453*cdf0e10cSrcweir 		pImp->m_xZipStorage = uno::Reference< embed::XStorage >();
1454*cdf0e10cSrcweir 	}
1455*cdf0e10cSrcweir }
1456*cdf0e10cSrcweir 
1457*cdf0e10cSrcweir //------------------------------------------------------------------
1458*cdf0e10cSrcweir void SfxMedium::CloseStorage()
1459*cdf0e10cSrcweir {
1460*cdf0e10cSrcweir     if ( pImp->xStorage.is() )
1461*cdf0e10cSrcweir     {
1462*cdf0e10cSrcweir         uno::Reference < lang::XComponent > xComp( pImp->xStorage, uno::UNO_QUERY );
1463*cdf0e10cSrcweir 		// in the salvage mode the medium does not own the storage
1464*cdf0e10cSrcweir         if ( pImp->bDisposeStorage && !pImp->m_bSalvageMode )
1465*cdf0e10cSrcweir 		{
1466*cdf0e10cSrcweir 			try {
1467*cdf0e10cSrcweir             	xComp->dispose();
1468*cdf0e10cSrcweir 			} catch( uno::Exception& )
1469*cdf0e10cSrcweir 			{
1470*cdf0e10cSrcweir 				OSL_ENSURE( sal_False, "Medium's storage is already disposed!\n" );
1471*cdf0e10cSrcweir 			}
1472*cdf0e10cSrcweir 		}
1473*cdf0e10cSrcweir 
1474*cdf0e10cSrcweir         pImp->xStorage = 0;
1475*cdf0e10cSrcweir     	pImp->bStorageBasedOnInStream = sal_False;
1476*cdf0e10cSrcweir     }
1477*cdf0e10cSrcweir 
1478*cdf0e10cSrcweir     bTriedStorage = sal_False;
1479*cdf0e10cSrcweir     pImp->bIsStorage = sal_False;
1480*cdf0e10cSrcweir }
1481*cdf0e10cSrcweir 
1482*cdf0e10cSrcweir void SfxMedium::CanDisposeStorage_Impl( sal_Bool bDisposeStorage )
1483*cdf0e10cSrcweir {
1484*cdf0e10cSrcweir     pImp->bDisposeStorage = bDisposeStorage;
1485*cdf0e10cSrcweir }
1486*cdf0e10cSrcweir 
1487*cdf0e10cSrcweir sal_Bool SfxMedium::WillDisposeStorageOnClose_Impl()
1488*cdf0e10cSrcweir {
1489*cdf0e10cSrcweir 	return pImp->bDisposeStorage;
1490*cdf0e10cSrcweir }
1491*cdf0e10cSrcweir 
1492*cdf0e10cSrcweir //------------------------------------------------------------------
1493*cdf0e10cSrcweir void SfxMedium::SetOpenMode( StreamMode nStorOpen,
1494*cdf0e10cSrcweir                              sal_Bool bDirectP,
1495*cdf0e10cSrcweir                              sal_Bool bDontClose )
1496*cdf0e10cSrcweir {
1497*cdf0e10cSrcweir     if ( nStorOpenMode != nStorOpen )
1498*cdf0e10cSrcweir     {
1499*cdf0e10cSrcweir         nStorOpenMode = nStorOpen;
1500*cdf0e10cSrcweir 
1501*cdf0e10cSrcweir         if( !bDontClose )
1502*cdf0e10cSrcweir         {
1503*cdf0e10cSrcweir             if ( pImp->xStorage.is() )
1504*cdf0e10cSrcweir                 CloseStorage();
1505*cdf0e10cSrcweir 
1506*cdf0e10cSrcweir             CloseStreams_Impl();
1507*cdf0e10cSrcweir         }
1508*cdf0e10cSrcweir     }
1509*cdf0e10cSrcweir 
1510*cdf0e10cSrcweir     bDirect     = bDirectP;
1511*cdf0e10cSrcweir     bSetFilter  = sal_False;
1512*cdf0e10cSrcweir }
1513*cdf0e10cSrcweir 
1514*cdf0e10cSrcweir //------------------------------------------------------------------
1515*cdf0e10cSrcweir sal_Bool SfxMedium::UseBackupToRestore_Impl( ::ucbhelper::Content& aOriginalContent,
1516*cdf0e10cSrcweir 											const Reference< ::com::sun::star::ucb::XCommandEnvironment >& xComEnv )
1517*cdf0e10cSrcweir {
1518*cdf0e10cSrcweir 	try
1519*cdf0e10cSrcweir 	{
1520*cdf0e10cSrcweir 		::ucbhelper::Content aTransactCont( pImp->m_aBackupURL, xComEnv );
1521*cdf0e10cSrcweir 
1522*cdf0e10cSrcweir 		Reference< XInputStream > aOrigInput = aTransactCont.openStream();
1523*cdf0e10cSrcweir 		aOriginalContent.writeStream( aOrigInput, sal_True );
1524*cdf0e10cSrcweir 		return sal_True;
1525*cdf0e10cSrcweir 	}
1526*cdf0e10cSrcweir 	catch( Exception& )
1527*cdf0e10cSrcweir 	{
1528*cdf0e10cSrcweir 		// in case of failure here the backup file should not be removed
1529*cdf0e10cSrcweir 		// TODO/LATER: a message should be used to let user know about the backup
1530*cdf0e10cSrcweir 		pImp->m_bRemoveBackup = sal_False;
1531*cdf0e10cSrcweir 		// TODO/LATER: needs a specific error code
1532*cdf0e10cSrcweir 		eError = ERRCODE_IO_GENERAL;
1533*cdf0e10cSrcweir 	}
1534*cdf0e10cSrcweir 
1535*cdf0e10cSrcweir 	return sal_False;
1536*cdf0e10cSrcweir }
1537*cdf0e10cSrcweir 
1538*cdf0e10cSrcweir //------------------------------------------------------------------
1539*cdf0e10cSrcweir sal_Bool SfxMedium::StorageCommit_Impl()
1540*cdf0e10cSrcweir {
1541*cdf0e10cSrcweir 	sal_Bool bResult = sal_False;
1542*cdf0e10cSrcweir 	Reference< ::com::sun::star::ucb::XCommandEnvironment > xDummyEnv;
1543*cdf0e10cSrcweir 	::ucbhelper::Content aOriginalContent;
1544*cdf0e10cSrcweir 
1545*cdf0e10cSrcweir 	if ( pImp->xStorage.is() )
1546*cdf0e10cSrcweir 	{
1547*cdf0e10cSrcweir 		if ( !GetError() )
1548*cdf0e10cSrcweir 		{
1549*cdf0e10cSrcweir         	uno::Reference < embed::XTransactedObject > xTrans( pImp->xStorage, uno::UNO_QUERY );
1550*cdf0e10cSrcweir         	if ( xTrans.is() )
1551*cdf0e10cSrcweir         	{
1552*cdf0e10cSrcweir             	try
1553*cdf0e10cSrcweir             	{
1554*cdf0e10cSrcweir                 	xTrans->commit();
1555*cdf0e10cSrcweir 					CloseZipStorage_Impl();
1556*cdf0e10cSrcweir 					bResult = sal_True;
1557*cdf0e10cSrcweir             	}
1558*cdf0e10cSrcweir 				catch ( embed::UseBackupException& aBackupExc )
1559*cdf0e10cSrcweir 				{
1560*cdf0e10cSrcweir                     // since the temporary file is created always now, the scenario is close to be impossible
1561*cdf0e10cSrcweir 					if ( !pImp->pTempFile )
1562*cdf0e10cSrcweir 					{
1563*cdf0e10cSrcweir 						OSL_ENSURE( pImp->m_aBackupURL.getLength(), "No backup on storage commit!\n" );
1564*cdf0e10cSrcweir 						if ( pImp->m_aBackupURL.getLength()
1565*cdf0e10cSrcweir 							&& ::ucbhelper::Content::create( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ),
1566*cdf0e10cSrcweir 														xDummyEnv,
1567*cdf0e10cSrcweir 														aOriginalContent ) )
1568*cdf0e10cSrcweir 						{
1569*cdf0e10cSrcweir 							// use backup to restore the file
1570*cdf0e10cSrcweir 							// the storage has already disconnected from original location
1571*cdf0e10cSrcweir 							CloseAndReleaseStreams_Impl();
1572*cdf0e10cSrcweir 							if ( !UseBackupToRestore_Impl( aOriginalContent, xDummyEnv ) )
1573*cdf0e10cSrcweir 							{
1574*cdf0e10cSrcweir 								// connect the medium to the temporary file of the storage
1575*cdf0e10cSrcweir             					pImp->aContent = ::ucbhelper::Content();
1576*cdf0e10cSrcweir         						aName = aBackupExc.TemporaryFileURL;
1577*cdf0e10cSrcweir 								OSL_ENSURE( aName.Len(), "The exception _must_ contain the temporary URL!\n" );
1578*cdf0e10cSrcweir 							}
1579*cdf0e10cSrcweir 						}
1580*cdf0e10cSrcweir 
1581*cdf0e10cSrcweir 						if ( !GetError() )
1582*cdf0e10cSrcweir         					SetError( ERRCODE_IO_GENERAL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
1583*cdf0e10cSrcweir 					}
1584*cdf0e10cSrcweir 				}
1585*cdf0e10cSrcweir             	catch ( uno::Exception& )
1586*cdf0e10cSrcweir             	{
1587*cdf0e10cSrcweir                 	//TODO/LATER: improve error handling
1588*cdf0e10cSrcweir         			SetError( ERRCODE_IO_GENERAL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
1589*cdf0e10cSrcweir             	}
1590*cdf0e10cSrcweir         	}
1591*cdf0e10cSrcweir 		}
1592*cdf0e10cSrcweir 	}
1593*cdf0e10cSrcweir 
1594*cdf0e10cSrcweir 	return bResult;
1595*cdf0e10cSrcweir }
1596*cdf0e10cSrcweir 
1597*cdf0e10cSrcweir //------------------------------------------------------------------
1598*cdf0e10cSrcweir sal_Bool SfxMedium::TransactedTransferForFS_Impl( const INetURLObject& aSource,
1599*cdf0e10cSrcweir 											 	const INetURLObject& aDest,
1600*cdf0e10cSrcweir 											 	const Reference< ::com::sun::star::ucb::XCommandEnvironment >& xComEnv )
1601*cdf0e10cSrcweir {
1602*cdf0e10cSrcweir 	sal_Bool bResult = sal_False;
1603*cdf0e10cSrcweir 	Reference< ::com::sun::star::ucb::XCommandEnvironment > xDummyEnv;
1604*cdf0e10cSrcweir 	Reference< XOutputStream > aDestStream;
1605*cdf0e10cSrcweir 	::ucbhelper::Content aOriginalContent;
1606*cdf0e10cSrcweir 
1607*cdf0e10cSrcweir     try
1608*cdf0e10cSrcweir     {
1609*cdf0e10cSrcweir         aOriginalContent = ::ucbhelper::Content( aDest.GetMainURL( INetURLObject::NO_DECODE ), xComEnv );
1610*cdf0e10cSrcweir     }
1611*cdf0e10cSrcweir     catch ( ::com::sun::star::ucb::CommandAbortedException& )
1612*cdf0e10cSrcweir     {
1613*cdf0e10cSrcweir         eError = ERRCODE_ABORT;
1614*cdf0e10cSrcweir     }
1615*cdf0e10cSrcweir     catch ( ::com::sun::star::ucb::CommandFailedException& )
1616*cdf0e10cSrcweir     {
1617*cdf0e10cSrcweir         eError = ERRCODE_ABORT;
1618*cdf0e10cSrcweir     }
1619*cdf0e10cSrcweir     catch (const ::com::sun::star::ucb::ContentCreationException& ex)
1620*cdf0e10cSrcweir     {
1621*cdf0e10cSrcweir         eError = ERRCODE_IO_GENERAL;
1622*cdf0e10cSrcweir         if (
1623*cdf0e10cSrcweir             (ex.eError == ::com::sun::star::ucb::ContentCreationError_NO_CONTENT_PROVIDER    ) ||
1624*cdf0e10cSrcweir             (ex.eError == ::com::sun::star::ucb::ContentCreationError_CONTENT_CREATION_FAILED)
1625*cdf0e10cSrcweir            )
1626*cdf0e10cSrcweir         {
1627*cdf0e10cSrcweir             eError = ERRCODE_IO_NOTEXISTSPATH;
1628*cdf0e10cSrcweir         }
1629*cdf0e10cSrcweir     }
1630*cdf0e10cSrcweir     catch (const ::com::sun::star::uno::Exception&)
1631*cdf0e10cSrcweir     {
1632*cdf0e10cSrcweir        eError = ERRCODE_IO_GENERAL;
1633*cdf0e10cSrcweir     }
1634*cdf0e10cSrcweir 
1635*cdf0e10cSrcweir     if( !eError || (eError & ERRCODE_WARNING_MASK) )
1636*cdf0e10cSrcweir 	{
1637*cdf0e10cSrcweir         if ( pImp->xStorage.is() )
1638*cdf0e10cSrcweir             CloseStorage();
1639*cdf0e10cSrcweir 
1640*cdf0e10cSrcweir         CloseStreams_Impl();
1641*cdf0e10cSrcweir 
1642*cdf0e10cSrcweir 		::ucbhelper::Content aTempCont;
1643*cdf0e10cSrcweir 		if( ::ucbhelper::Content::create( aSource.GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv, aTempCont ) )
1644*cdf0e10cSrcweir 		{
1645*cdf0e10cSrcweir 			sal_Bool bTransactStarted = sal_False;
1646*cdf0e10cSrcweir 			SFX_ITEMSET_ARG( GetItemSet(), pOverWrite, SfxBoolItem, SID_OVERWRITE, sal_False );
1647*cdf0e10cSrcweir    			SFX_ITEMSET_ARG( GetItemSet(), pRename, SfxBoolItem, SID_RENAME, sal_False );
1648*cdf0e10cSrcweir 			sal_Bool bRename = pRename ? pRename->GetValue() : sal_False;
1649*cdf0e10cSrcweir 			sal_Bool bOverWrite = pOverWrite ? pOverWrite->GetValue() : !bRename;
1650*cdf0e10cSrcweir 
1651*cdf0e10cSrcweir 			try
1652*cdf0e10cSrcweir 			{
1653*cdf0e10cSrcweir 				if( bOverWrite && ::utl::UCBContentHelper::IsDocument( aDest.GetMainURL( INetURLObject::NO_DECODE ) ) )
1654*cdf0e10cSrcweir 				{
1655*cdf0e10cSrcweir 					if( ! pImp->m_aBackupURL.getLength() )
1656*cdf0e10cSrcweir 						DoInternalBackup_Impl( aOriginalContent );
1657*cdf0e10cSrcweir 
1658*cdf0e10cSrcweir 					if( pImp->m_aBackupURL.getLength() )
1659*cdf0e10cSrcweir 					{
1660*cdf0e10cSrcweir 						Reference< XInputStream > aTempInput = aTempCont.openStream();
1661*cdf0e10cSrcweir 						bTransactStarted = sal_True;
1662*cdf0e10cSrcweir 						aOriginalContent.setPropertyValue( ::rtl::OUString::createFromAscii( "Size" ),
1663*cdf0e10cSrcweir 															uno::makeAny( (sal_Int64)0 ) );
1664*cdf0e10cSrcweir 						aOriginalContent.writeStream( aTempInput, bOverWrite );
1665*cdf0e10cSrcweir 						bResult = sal_True;
1666*cdf0e10cSrcweir 					}
1667*cdf0e10cSrcweir 					else
1668*cdf0e10cSrcweir 					{
1669*cdf0e10cSrcweir 						eError = ERRCODE_SFX_CANTCREATEBACKUP;
1670*cdf0e10cSrcweir 					}
1671*cdf0e10cSrcweir 				}
1672*cdf0e10cSrcweir 				else
1673*cdf0e10cSrcweir 				{
1674*cdf0e10cSrcweir 					Reference< XInputStream > aTempInput = aTempCont.openStream();
1675*cdf0e10cSrcweir 					aOriginalContent.writeStream( aTempInput, bOverWrite );
1676*cdf0e10cSrcweir 					bResult = sal_True;
1677*cdf0e10cSrcweir 				}
1678*cdf0e10cSrcweir 			}
1679*cdf0e10cSrcweir 			catch ( ::com::sun::star::ucb::CommandAbortedException& )
1680*cdf0e10cSrcweir 			{
1681*cdf0e10cSrcweir 				eError = ERRCODE_ABORT;
1682*cdf0e10cSrcweir 			}
1683*cdf0e10cSrcweir 			catch ( ::com::sun::star::ucb::CommandFailedException& )
1684*cdf0e10cSrcweir 			{
1685*cdf0e10cSrcweir 				eError = ERRCODE_ABORT;
1686*cdf0e10cSrcweir 			}
1687*cdf0e10cSrcweir 			catch ( ::com::sun::star::ucb::InteractiveIOException& r )
1688*cdf0e10cSrcweir 			{
1689*cdf0e10cSrcweir 				if ( r.Code == IOErrorCode_ACCESS_DENIED )
1690*cdf0e10cSrcweir 					eError = ERRCODE_IO_ACCESSDENIED;
1691*cdf0e10cSrcweir 				else if ( r.Code == IOErrorCode_NOT_EXISTING )
1692*cdf0e10cSrcweir 					eError = ERRCODE_IO_NOTEXISTS;
1693*cdf0e10cSrcweir 				else if ( r.Code == IOErrorCode_CANT_READ )
1694*cdf0e10cSrcweir 					eError = ERRCODE_IO_CANTREAD;
1695*cdf0e10cSrcweir 				else
1696*cdf0e10cSrcweir 					eError = ERRCODE_IO_GENERAL;
1697*cdf0e10cSrcweir 			}
1698*cdf0e10cSrcweir             catch ( ::com::sun::star::uno::Exception& )
1699*cdf0e10cSrcweir 			{
1700*cdf0e10cSrcweir 				eError = ERRCODE_IO_GENERAL;
1701*cdf0e10cSrcweir 			}
1702*cdf0e10cSrcweir 
1703*cdf0e10cSrcweir    			if ( bResult )
1704*cdf0e10cSrcweir    			{
1705*cdf0e10cSrcweir 				if ( pImp->pTempFile )
1706*cdf0e10cSrcweir 				{
1707*cdf0e10cSrcweir 					pImp->pTempFile->EnableKillingFile( sal_True );
1708*cdf0e10cSrcweir    					delete pImp->pTempFile;
1709*cdf0e10cSrcweir    					pImp->pTempFile = NULL;
1710*cdf0e10cSrcweir 				}
1711*cdf0e10cSrcweir    			}
1712*cdf0e10cSrcweir 			else if ( bTransactStarted )
1713*cdf0e10cSrcweir 			{
1714*cdf0e10cSrcweir 				UseBackupToRestore_Impl( aOriginalContent, xDummyEnv );
1715*cdf0e10cSrcweir 			}
1716*cdf0e10cSrcweir 		}
1717*cdf0e10cSrcweir 		else
1718*cdf0e10cSrcweir 			eError = ERRCODE_IO_CANTREAD;
1719*cdf0e10cSrcweir 	}
1720*cdf0e10cSrcweir 
1721*cdf0e10cSrcweir 	return bResult;
1722*cdf0e10cSrcweir }
1723*cdf0e10cSrcweir 
1724*cdf0e10cSrcweir //------------------------------------------------------------------
1725*cdf0e10cSrcweir sal_Bool SfxMedium::TryDirectTransfer( const ::rtl::OUString& aURL, SfxItemSet& aTargetSet )
1726*cdf0e10cSrcweir {
1727*cdf0e10cSrcweir     if ( GetError() )
1728*cdf0e10cSrcweir         return sal_False;
1729*cdf0e10cSrcweir 
1730*cdf0e10cSrcweir 	// if the document had no password it should be stored without password
1731*cdf0e10cSrcweir 	// if the document had password it should be stored with the same password
1732*cdf0e10cSrcweir 	// otherwise the stream copying can not be done
1733*cdf0e10cSrcweir     SFX_ITEMSET_ARG( &aTargetSet, pNewPassItem, SfxStringItem, SID_PASSWORD, sal_False );
1734*cdf0e10cSrcweir     SFX_ITEMSET_ARG( GetItemSet(), pOldPassItem, SfxStringItem, SID_PASSWORD, sal_False );
1735*cdf0e10cSrcweir 	if ( ( !pNewPassItem && !pOldPassItem )
1736*cdf0e10cSrcweir 	  || ( pNewPassItem && pOldPassItem && pNewPassItem->GetValue().Equals( pOldPassItem->GetValue() ) ) )
1737*cdf0e10cSrcweir 	{
1738*cdf0e10cSrcweir 		// the filter must be the same
1739*cdf0e10cSrcweir 		SFX_ITEMSET_ARG( &aTargetSet, pNewFilterItem, SfxStringItem, SID_FILTER_NAME, sal_False );
1740*cdf0e10cSrcweir     	SFX_ITEMSET_ARG( GetItemSet(), pOldFilterItem, SfxStringItem, SID_FILTER_NAME, sal_False );
1741*cdf0e10cSrcweir 		if ( pNewFilterItem && pOldFilterItem && pNewFilterItem->GetValue().Equals( pOldFilterItem->GetValue() ) )
1742*cdf0e10cSrcweir 		{
1743*cdf0e10cSrcweir 			// get the input stream and copy it
1744*cdf0e10cSrcweir 			// in case of success return true
1745*cdf0e10cSrcweir 			uno::Reference< io::XInputStream > xInStream = GetInputStream();
1746*cdf0e10cSrcweir 
1747*cdf0e10cSrcweir             ResetError();
1748*cdf0e10cSrcweir 			if ( xInStream.is() )
1749*cdf0e10cSrcweir 			{
1750*cdf0e10cSrcweir 				try
1751*cdf0e10cSrcweir 				{
1752*cdf0e10cSrcweir 					uno::Reference< io::XSeekable > xSeek( xInStream, uno::UNO_QUERY );
1753*cdf0e10cSrcweir 					sal_Int64 nPos = 0;
1754*cdf0e10cSrcweir 					if ( xSeek.is() )
1755*cdf0e10cSrcweir 					{
1756*cdf0e10cSrcweir 						nPos = xSeek->getPosition();
1757*cdf0e10cSrcweir 						xSeek->seek( 0 );
1758*cdf0e10cSrcweir 					}
1759*cdf0e10cSrcweir 
1760*cdf0e10cSrcweir         			uno::Reference < ::com::sun::star::ucb::XCommandEnvironment > xEnv;
1761*cdf0e10cSrcweir 					::ucbhelper::Content aTargetContent( aURL, xEnv );
1762*cdf0e10cSrcweir 
1763*cdf0e10cSrcweir             		InsertCommandArgument aInsertArg;
1764*cdf0e10cSrcweir             		aInsertArg.Data = xInStream;
1765*cdf0e10cSrcweir                		SFX_ITEMSET_ARG( &aTargetSet, pRename, SfxBoolItem, SID_RENAME, sal_False );
1766*cdf0e10cSrcweir                		SFX_ITEMSET_ARG( &aTargetSet, pOverWrite, SfxBoolItem, SID_OVERWRITE, sal_False );
1767*cdf0e10cSrcweir                		if ( (pOverWrite && !pOverWrite->GetValue()) // argument says: never overwrite
1768*cdf0e10cSrcweir                		  || (pRename && pRename->GetValue()) ) // argument says: rename file
1769*cdf0e10cSrcweir             			aInsertArg.ReplaceExisting = sal_False;
1770*cdf0e10cSrcweir                		else
1771*cdf0e10cSrcweir             			aInsertArg.ReplaceExisting = sal_True; // default is overwrite existing files
1772*cdf0e10cSrcweir 
1773*cdf0e10cSrcweir     				Any aCmdArg;
1774*cdf0e10cSrcweir             		aCmdArg <<= aInsertArg;
1775*cdf0e10cSrcweir 					aTargetContent.executeCommand( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "insert" ) ),
1776*cdf0e10cSrcweir 													aCmdArg );
1777*cdf0e10cSrcweir 
1778*cdf0e10cSrcweir 					if ( xSeek.is() )
1779*cdf0e10cSrcweir 						xSeek->seek( nPos );
1780*cdf0e10cSrcweir 
1781*cdf0e10cSrcweir 					return sal_True;
1782*cdf0e10cSrcweir 				}
1783*cdf0e10cSrcweir 				catch( uno::Exception& )
1784*cdf0e10cSrcweir 				{}
1785*cdf0e10cSrcweir 			}
1786*cdf0e10cSrcweir 		}
1787*cdf0e10cSrcweir 	}
1788*cdf0e10cSrcweir 
1789*cdf0e10cSrcweir 	return sal_False;
1790*cdf0e10cSrcweir }
1791*cdf0e10cSrcweir 
1792*cdf0e10cSrcweir //------------------------------------------------------------------
1793*cdf0e10cSrcweir void SfxMedium::Transfer_Impl()
1794*cdf0e10cSrcweir {
1795*cdf0e10cSrcweir 	// The transfer is required only in two cases: either if there is a temporary file or if there is a salvage item
1796*cdf0e10cSrcweir 	String aNameURL;
1797*cdf0e10cSrcweir 	if ( pImp->pTempFile )
1798*cdf0e10cSrcweir 		aNameURL = pImp->pTempFile->GetURL();
1799*cdf0e10cSrcweir 	else if ( aLogicName.Len() && pImp->m_bSalvageMode )
1800*cdf0e10cSrcweir 	{
1801*cdf0e10cSrcweir 		// makes sence only in case logic name is set
1802*cdf0e10cSrcweir 		if ( !::utl::LocalFileHelper::ConvertPhysicalNameToURL( aName, aNameURL ) )
1803*cdf0e10cSrcweir 			OSL_ENSURE( sal_False, "The medium name is not convertable!\n" );
1804*cdf0e10cSrcweir 	}
1805*cdf0e10cSrcweir 
1806*cdf0e10cSrcweir     if ( aNameURL.Len() && ( !eError || (eError & ERRCODE_WARNING_MASK) ) )
1807*cdf0e10cSrcweir     {
1808*cdf0e10cSrcweir 		RTL_LOGFILE_CONTEXT( aLog, "sfx2 (mv76033) SfxMedium::Transfer_Impl, copying to target" );
1809*cdf0e10cSrcweir 
1810*cdf0e10cSrcweir         Reference < ::com::sun::star::ucb::XCommandEnvironment > xEnv;
1811*cdf0e10cSrcweir 		Reference< XOutputStream > rOutStream;
1812*cdf0e10cSrcweir 
1813*cdf0e10cSrcweir 		// in case an output stream is provided from outside and the URL is correct
1814*cdf0e10cSrcweir 		// commit to the stream
1815*cdf0e10cSrcweir         if( aLogicName.CompareToAscii( "private:stream", 14 ) == COMPARE_EQUAL )
1816*cdf0e10cSrcweir 		{
1817*cdf0e10cSrcweir 			// TODO/LATER: support storing to SID_STREAM
1818*cdf0e10cSrcweir 	   		SFX_ITEMSET_ARG( pSet, pOutStreamItem, SfxUnoAnyItem, SID_OUTPUTSTREAM, sal_False);
1819*cdf0e10cSrcweir 	 		if( pOutStreamItem && ( pOutStreamItem->GetValue() >>= rOutStream ) )
1820*cdf0e10cSrcweir 			{
1821*cdf0e10cSrcweir                 if ( pImp->xStorage.is() )
1822*cdf0e10cSrcweir                     CloseStorage();
1823*cdf0e10cSrcweir 
1824*cdf0e10cSrcweir                 CloseStreams_Impl();
1825*cdf0e10cSrcweir 
1826*cdf0e10cSrcweir     		    INetURLObject aSource( aNameURL );
1827*cdf0e10cSrcweir 				::ucbhelper::Content aTempCont;
1828*cdf0e10cSrcweir 				if( ::ucbhelper::Content::create( aSource.GetMainURL( INetURLObject::NO_DECODE ), xEnv, aTempCont ) )
1829*cdf0e10cSrcweir 				{
1830*cdf0e10cSrcweir 					try
1831*cdf0e10cSrcweir 					{
1832*cdf0e10cSrcweir 						sal_Int32 nRead;
1833*cdf0e10cSrcweir 						sal_Int32 nBufferSize = 32767;
1834*cdf0e10cSrcweir 						Sequence < sal_Int8 > aSequence ( nBufferSize );
1835*cdf0e10cSrcweir 						Reference< XInputStream > aTempInput = aTempCont.openStream();
1836*cdf0e10cSrcweir 
1837*cdf0e10cSrcweir 						do
1838*cdf0e10cSrcweir 						{
1839*cdf0e10cSrcweir 							nRead = aTempInput->readBytes ( aSequence, nBufferSize );
1840*cdf0e10cSrcweir 							if ( nRead < nBufferSize )
1841*cdf0e10cSrcweir 							{
1842*cdf0e10cSrcweir 								Sequence < sal_Int8 > aTempBuf ( aSequence.getConstArray(), nRead );
1843*cdf0e10cSrcweir 								rOutStream->writeBytes ( aTempBuf );
1844*cdf0e10cSrcweir 							}
1845*cdf0e10cSrcweir 							else
1846*cdf0e10cSrcweir 								rOutStream->writeBytes ( aSequence );
1847*cdf0e10cSrcweir 						}
1848*cdf0e10cSrcweir 						while ( nRead == nBufferSize );
1849*cdf0e10cSrcweir 
1850*cdf0e10cSrcweir 						// remove temporary file
1851*cdf0e10cSrcweir 						if ( pImp->pTempFile )
1852*cdf0e10cSrcweir 						{
1853*cdf0e10cSrcweir             				pImp->pTempFile->EnableKillingFile( sal_True );
1854*cdf0e10cSrcweir             				delete pImp->pTempFile;
1855*cdf0e10cSrcweir             				pImp->pTempFile = NULL;
1856*cdf0e10cSrcweir 						}
1857*cdf0e10cSrcweir 					}
1858*cdf0e10cSrcweir 					catch( Exception& )
1859*cdf0e10cSrcweir 					{}
1860*cdf0e10cSrcweir 				}
1861*cdf0e10cSrcweir        		}
1862*cdf0e10cSrcweir 			else
1863*cdf0e10cSrcweir 			{
1864*cdf0e10cSrcweir 				DBG_ERROR( "Illegal Output stream parameter!\n" );
1865*cdf0e10cSrcweir         		SetError( ERRCODE_IO_GENERAL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
1866*cdf0e10cSrcweir 			}
1867*cdf0e10cSrcweir 
1868*cdf0e10cSrcweir 			// free the reference
1869*cdf0e10cSrcweir     		if ( pSet )
1870*cdf0e10cSrcweir 				pSet->ClearItem( SID_OUTPUTSTREAM );
1871*cdf0e10cSrcweir 
1872*cdf0e10cSrcweir 			return;
1873*cdf0e10cSrcweir 		}
1874*cdf0e10cSrcweir 
1875*cdf0e10cSrcweir         GetContent();
1876*cdf0e10cSrcweir         if ( !pImp->aContent.get().is() )
1877*cdf0e10cSrcweir         {
1878*cdf0e10cSrcweir             eError = ERRCODE_IO_NOTEXISTS;
1879*cdf0e10cSrcweir             return;
1880*cdf0e10cSrcweir         }
1881*cdf0e10cSrcweir 
1882*cdf0e10cSrcweir         SFX_ITEMSET_ARG( GetItemSet(), pSegmentSize, SfxInt32Item, SID_SEGMENTSIZE, sal_False);
1883*cdf0e10cSrcweir         if ( pSegmentSize )
1884*cdf0e10cSrcweir         {
1885*cdf0e10cSrcweir             // this file must be stored into a disk spanned package
1886*cdf0e10cSrcweir             try
1887*cdf0e10cSrcweir             {
1888*cdf0e10cSrcweir                 uno::Reference < embed::XStorage > xStor = comphelper::OStorageHelper::GetStorageFromURL( GetName(),
1889*cdf0e10cSrcweir                         embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
1890*cdf0e10cSrcweir 
1891*cdf0e10cSrcweir                 // set segment size property; package will automatically be divided in pieces fitting
1892*cdf0e10cSrcweir                 // into this size
1893*cdf0e10cSrcweir                 ::com::sun::star::uno::Any aAny;
1894*cdf0e10cSrcweir                 aAny <<= pSegmentSize->GetValue();
1895*cdf0e10cSrcweir 
1896*cdf0e10cSrcweir                 uno::Reference < beans::XPropertySet > xSet( pImp->xStorage, uno::UNO_QUERY );
1897*cdf0e10cSrcweir                 xSet->setPropertyValue( String::CreateFromAscii("SegmentSize"), aAny );
1898*cdf0e10cSrcweir 
1899*cdf0e10cSrcweir                 // copy the temporary storage into the disk spanned package
1900*cdf0e10cSrcweir                 GetStorage()->copyToStorage( xStor );
1901*cdf0e10cSrcweir                 uno::Reference < embed::XTransactedObject > xTrans( pImp->xStorage, uno::UNO_QUERY );
1902*cdf0e10cSrcweir                 if ( xTrans.is() )
1903*cdf0e10cSrcweir                     xTrans->commit();
1904*cdf0e10cSrcweir 
1905*cdf0e10cSrcweir             }
1906*cdf0e10cSrcweir             catch ( uno::Exception& )
1907*cdf0e10cSrcweir             {
1908*cdf0e10cSrcweir                 //TODO/MBA: error handling
1909*cdf0e10cSrcweir             }
1910*cdf0e10cSrcweir             return;
1911*cdf0e10cSrcweir         }
1912*cdf0e10cSrcweir 
1913*cdf0e10cSrcweir         INetURLObject aDest( GetURLObject() );
1914*cdf0e10cSrcweir 
1915*cdf0e10cSrcweir         // source is the temp file written so far
1916*cdf0e10cSrcweir         INetURLObject aSource( aNameURL );
1917*cdf0e10cSrcweir 
1918*cdf0e10cSrcweir 		// a special case, an interaction handler should be used for
1919*cdf0e10cSrcweir 		// authentication in case it is available
1920*cdf0e10cSrcweir 		Reference< ::com::sun::star::ucb::XCommandEnvironment > xComEnv;
1921*cdf0e10cSrcweir        	Reference< ::com::sun::star::task::XInteractionHandler > xInteractionHandler = GetInteractionHandler();
1922*cdf0e10cSrcweir         if (xInteractionHandler.is())
1923*cdf0e10cSrcweir 			xComEnv = new ::ucbhelper::CommandEnvironment( xInteractionHandler,
1924*cdf0e10cSrcweir 													  Reference< ::com::sun::star::ucb::XProgressHandler >() );
1925*cdf0e10cSrcweir 
1926*cdf0e10cSrcweir         if ( ::utl::LocalFileHelper::IsLocalFile( aDest.GetMainURL( INetURLObject::NO_DECODE ) ) || !aDest.removeSegment() )
1927*cdf0e10cSrcweir 		{
1928*cdf0e10cSrcweir 			TransactedTransferForFS_Impl( aSource, aDest, xComEnv );
1929*cdf0e10cSrcweir 		}
1930*cdf0e10cSrcweir 		else
1931*cdf0e10cSrcweir         {
1932*cdf0e10cSrcweir             // create content for the parent folder and call transfer on that content with the source content
1933*cdf0e10cSrcweir             // and the destination file name as parameters
1934*cdf0e10cSrcweir             ::ucbhelper::Content aSourceContent;
1935*cdf0e10cSrcweir             ::ucbhelper::Content aTransferContent;
1936*cdf0e10cSrcweir 
1937*cdf0e10cSrcweir             String aFileName = GetLongName();
1938*cdf0e10cSrcweir             if ( !aFileName.Len() )
1939*cdf0e10cSrcweir                 aFileName = GetURLObject().getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
1940*cdf0e10cSrcweir 
1941*cdf0e10cSrcweir 			try
1942*cdf0e10cSrcweir 			{
1943*cdf0e10cSrcweir 				aTransferContent = ::ucbhelper::Content( aDest.GetMainURL( INetURLObject::NO_DECODE ), xComEnv );
1944*cdf0e10cSrcweir 			}
1945*cdf0e10cSrcweir 			catch (const ::com::sun::star::ucb::ContentCreationException& ex)
1946*cdf0e10cSrcweir             {
1947*cdf0e10cSrcweir 				eError = ERRCODE_IO_GENERAL;
1948*cdf0e10cSrcweir 				if (
1949*cdf0e10cSrcweir 					(ex.eError == ::com::sun::star::ucb::ContentCreationError_NO_CONTENT_PROVIDER    ) ||
1950*cdf0e10cSrcweir 					(ex.eError == ::com::sun::star::ucb::ContentCreationError_CONTENT_CREATION_FAILED)
1951*cdf0e10cSrcweir 				   )
1952*cdf0e10cSrcweir 				{
1953*cdf0e10cSrcweir 					eError = ERRCODE_IO_NOTEXISTSPATH;
1954*cdf0e10cSrcweir 				}
1955*cdf0e10cSrcweir             }
1956*cdf0e10cSrcweir             catch (const ::com::sun::star::uno::Exception&)
1957*cdf0e10cSrcweir             {
1958*cdf0e10cSrcweir                 eError = ERRCODE_IO_GENERAL;
1959*cdf0e10cSrcweir             }
1960*cdf0e10cSrcweir 
1961*cdf0e10cSrcweir             if ( !eError || (eError & ERRCODE_WARNING_MASK) )
1962*cdf0e10cSrcweir             {
1963*cdf0e10cSrcweir                 // free resources, otherwise the transfer may fail
1964*cdf0e10cSrcweir                 if ( pImp->xStorage.is() )
1965*cdf0e10cSrcweir                     CloseStorage();
1966*cdf0e10cSrcweir 
1967*cdf0e10cSrcweir                 CloseStreams_Impl();
1968*cdf0e10cSrcweir 
1969*cdf0e10cSrcweir                 ::ucbhelper::Content::create( aSource.GetMainURL( INetURLObject::NO_DECODE ), xEnv, aSourceContent );
1970*cdf0e10cSrcweir 
1971*cdf0e10cSrcweir                 // check for external parameters that may customize the handling of NameClash situations
1972*cdf0e10cSrcweir                 SFX_ITEMSET_ARG( GetItemSet(), pRename, SfxBoolItem, SID_RENAME, sal_False );
1973*cdf0e10cSrcweir                 SFX_ITEMSET_ARG( GetItemSet(), pOverWrite, SfxBoolItem, SID_OVERWRITE, sal_False );
1974*cdf0e10cSrcweir                 sal_Int32 nNameClash;
1975*cdf0e10cSrcweir                 if ( pOverWrite && !pOverWrite->GetValue() )
1976*cdf0e10cSrcweir                     // argument says: never overwrite
1977*cdf0e10cSrcweir                     nNameClash = NameClash::ERROR;
1978*cdf0e10cSrcweir                 else if ( pRename && pRename->GetValue() )
1979*cdf0e10cSrcweir                     // argument says: rename file
1980*cdf0e10cSrcweir                     nNameClash = NameClash::RENAME;
1981*cdf0e10cSrcweir                 else
1982*cdf0e10cSrcweir                     // default is overwrite existing files
1983*cdf0e10cSrcweir                     nNameClash = NameClash::OVERWRITE;
1984*cdf0e10cSrcweir 
1985*cdf0e10cSrcweir                 try
1986*cdf0e10cSrcweir                 {
1987*cdf0e10cSrcweir                     if (!aTransferContent.transferContent( aSourceContent, ::ucbhelper::InsertOperation_COPY, aFileName, nNameClash ))
1988*cdf0e10cSrcweir 						eError = ERRCODE_IO_GENERAL;
1989*cdf0e10cSrcweir                 }
1990*cdf0e10cSrcweir                 catch ( ::com::sun::star::ucb::CommandAbortedException& )
1991*cdf0e10cSrcweir                 {
1992*cdf0e10cSrcweir                     eError = ERRCODE_ABORT;
1993*cdf0e10cSrcweir                 }
1994*cdf0e10cSrcweir                 catch ( ::com::sun::star::ucb::CommandFailedException& )
1995*cdf0e10cSrcweir                 {
1996*cdf0e10cSrcweir                     eError = ERRCODE_ABORT;
1997*cdf0e10cSrcweir                 }
1998*cdf0e10cSrcweir                 catch ( ::com::sun::star::ucb::InteractiveIOException& r )
1999*cdf0e10cSrcweir                 {
2000*cdf0e10cSrcweir                     if ( r.Code == IOErrorCode_ACCESS_DENIED )
2001*cdf0e10cSrcweir                         eError = ERRCODE_IO_ACCESSDENIED;
2002*cdf0e10cSrcweir                     else if ( r.Code == IOErrorCode_NOT_EXISTING )
2003*cdf0e10cSrcweir                         eError = ERRCODE_IO_NOTEXISTS;
2004*cdf0e10cSrcweir                     else if ( r.Code == IOErrorCode_CANT_READ )
2005*cdf0e10cSrcweir                         eError = ERRCODE_IO_CANTREAD;
2006*cdf0e10cSrcweir                     else
2007*cdf0e10cSrcweir                         eError = ERRCODE_IO_GENERAL;
2008*cdf0e10cSrcweir                 }
2009*cdf0e10cSrcweir                 catch ( ::com::sun::star::uno::Exception& )
2010*cdf0e10cSrcweir                 {
2011*cdf0e10cSrcweir                     eError = ERRCODE_IO_GENERAL;
2012*cdf0e10cSrcweir                 }
2013*cdf0e10cSrcweir 
2014*cdf0e10cSrcweir 				// do not switch from temporary file in case of nonfile protocol
2015*cdf0e10cSrcweir 	    	}
2016*cdf0e10cSrcweir 		}
2017*cdf0e10cSrcweir 
2018*cdf0e10cSrcweir         if ( ( !eError || (eError & ERRCODE_WARNING_MASK) ) && !pImp->pTempFile )
2019*cdf0e10cSrcweir 		{
2020*cdf0e10cSrcweir 			// without a TempFile the physical and logical name should be the same after successful transfer
2021*cdf0e10cSrcweir   			::utl::LocalFileHelper::ConvertURLToPhysicalName( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ),
2022*cdf0e10cSrcweir 														  	aName );
2023*cdf0e10cSrcweir 			pImp->m_bSalvageMode = sal_False;
2024*cdf0e10cSrcweir 		}
2025*cdf0e10cSrcweir     }
2026*cdf0e10cSrcweir }
2027*cdf0e10cSrcweir 
2028*cdf0e10cSrcweir //------------------------------------------------------------------
2029*cdf0e10cSrcweir void SfxMedium::DoInternalBackup_Impl( const ::ucbhelper::Content& aOriginalContent,
2030*cdf0e10cSrcweir 									   const String& aPrefix,
2031*cdf0e10cSrcweir 									   const String& aExtension,
2032*cdf0e10cSrcweir 									   const String& aDestDir )
2033*cdf0e10cSrcweir {
2034*cdf0e10cSrcweir 	RTL_LOGFILE_CONTEXT( aLog, "sfx2 (mv76033) SfxMedium::DoInternalBackup_Impl( with destdir )" );
2035*cdf0e10cSrcweir 
2036*cdf0e10cSrcweir 	if ( pImp->m_aBackupURL.getLength() )
2037*cdf0e10cSrcweir 		return; // the backup was done already
2038*cdf0e10cSrcweir 
2039*cdf0e10cSrcweir 	::utl::TempFile aTransactTemp( aPrefix, &aExtension, &aDestDir );
2040*cdf0e10cSrcweir 	aTransactTemp.EnableKillingFile( sal_False );
2041*cdf0e10cSrcweir 
2042*cdf0e10cSrcweir 	INetURLObject aBackObj( aTransactTemp.GetURL() );
2043*cdf0e10cSrcweir 	::rtl::OUString aBackupName = aBackObj.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
2044*cdf0e10cSrcweir 
2045*cdf0e10cSrcweir 	Reference < ::com::sun::star::ucb::XCommandEnvironment > xDummyEnv;
2046*cdf0e10cSrcweir 	::ucbhelper::Content aBackupCont;
2047*cdf0e10cSrcweir 	if( ::ucbhelper::Content::create( aDestDir, xDummyEnv, aBackupCont ) )
2048*cdf0e10cSrcweir 	{
2049*cdf0e10cSrcweir 		try
2050*cdf0e10cSrcweir 		{
2051*cdf0e10cSrcweir 			if( aBackupCont.transferContent( aOriginalContent,
2052*cdf0e10cSrcweir 											::ucbhelper::InsertOperation_COPY,
2053*cdf0e10cSrcweir 											aBackupName,
2054*cdf0e10cSrcweir 											NameClash::OVERWRITE ) )
2055*cdf0e10cSrcweir 			{
2056*cdf0e10cSrcweir 				pImp->m_aBackupURL = aBackObj.GetMainURL( INetURLObject::NO_DECODE );
2057*cdf0e10cSrcweir 				pImp->m_bRemoveBackup = sal_True;
2058*cdf0e10cSrcweir 			}
2059*cdf0e10cSrcweir 		}
2060*cdf0e10cSrcweir 		catch( Exception& )
2061*cdf0e10cSrcweir 		{}
2062*cdf0e10cSrcweir 	}
2063*cdf0e10cSrcweir 
2064*cdf0e10cSrcweir 	if ( !pImp->m_aBackupURL.getLength() )
2065*cdf0e10cSrcweir 		aTransactTemp.EnableKillingFile( sal_True );
2066*cdf0e10cSrcweir }
2067*cdf0e10cSrcweir 
2068*cdf0e10cSrcweir //------------------------------------------------------------------
2069*cdf0e10cSrcweir void SfxMedium::DoInternalBackup_Impl( const ::ucbhelper::Content& aOriginalContent )
2070*cdf0e10cSrcweir {
2071*cdf0e10cSrcweir 	if ( pImp->m_aBackupURL.getLength() )
2072*cdf0e10cSrcweir 		return; // the backup was done already
2073*cdf0e10cSrcweir 
2074*cdf0e10cSrcweir 	::rtl::OUString aFileName =  GetURLObject().getName( INetURLObject::LAST_SEGMENT,
2075*cdf0e10cSrcweir 														true,
2076*cdf0e10cSrcweir 														INetURLObject::NO_DECODE );
2077*cdf0e10cSrcweir 
2078*cdf0e10cSrcweir 	sal_Int32 nPrefixLen = aFileName.lastIndexOf( '.' );
2079*cdf0e10cSrcweir 	String aPrefix = ( nPrefixLen == -1 ) ? aFileName : aFileName.copy( 0, nPrefixLen );
2080*cdf0e10cSrcweir 	String aExtension = ( nPrefixLen == -1 ) ? String() : String(aFileName.copy( nPrefixLen ));
2081*cdf0e10cSrcweir    	String aBakDir = SvtPathOptions().GetBackupPath();
2082*cdf0e10cSrcweir 
2083*cdf0e10cSrcweir 	DoInternalBackup_Impl( aOriginalContent, aPrefix, aExtension, aBakDir );
2084*cdf0e10cSrcweir 
2085*cdf0e10cSrcweir 	if ( !pImp->m_aBackupURL.getLength() )
2086*cdf0e10cSrcweir 	{
2087*cdf0e10cSrcweir 		// the copiing to the backup catalog failed ( for example because
2088*cdf0e10cSrcweir 		// of using an encrypted partition as target catalog )
2089*cdf0e10cSrcweir 		// since the user did not specify to make backup explicitly
2090*cdf0e10cSrcweir 		// office should try to make backup in another place,
2091*cdf0e10cSrcweir 		// target catalog does not look bad for this case ( and looks
2092*cdf0e10cSrcweir 		// to be the only way for encrypted partitions )
2093*cdf0e10cSrcweir 
2094*cdf0e10cSrcweir 		INetURLObject aDest = GetURLObject();
2095*cdf0e10cSrcweir 		if ( aDest.removeSegment() )
2096*cdf0e10cSrcweir 			DoInternalBackup_Impl( aOriginalContent, aPrefix, aExtension, aDest.GetMainURL( INetURLObject::NO_DECODE ) );
2097*cdf0e10cSrcweir 	}
2098*cdf0e10cSrcweir }
2099*cdf0e10cSrcweir 
2100*cdf0e10cSrcweir 
2101*cdf0e10cSrcweir //------------------------------------------------------------------
2102*cdf0e10cSrcweir void SfxMedium::DoBackup_Impl()
2103*cdf0e10cSrcweir {
2104*cdf0e10cSrcweir 	RTL_LOGFILE_CONTEXT( aLog, "sfx2 (mv76033) SfxMedium::DoBackup_Impl" );
2105*cdf0e10cSrcweir 
2106*cdf0e10cSrcweir    	// source file name is the logical name of this medium
2107*cdf0e10cSrcweir     INetURLObject aSource( GetURLObject() );
2108*cdf0e10cSrcweir 
2109*cdf0e10cSrcweir 	// there is nothing to backup in case source file does not exist
2110*cdf0e10cSrcweir 	if ( !::utl::UCBContentHelper::IsDocument( aSource.GetMainURL( INetURLObject::NO_DECODE ) ) )
2111*cdf0e10cSrcweir 		return;
2112*cdf0e10cSrcweir 
2113*cdf0e10cSrcweir     sal_Bool        bSuccess = sal_False;
2114*cdf0e10cSrcweir 
2115*cdf0e10cSrcweir     // get path for backups
2116*cdf0e10cSrcweir     String aBakDir = SvtPathOptions().GetBackupPath();
2117*cdf0e10cSrcweir     if( aBakDir.Len() )
2118*cdf0e10cSrcweir     {
2119*cdf0e10cSrcweir         // create content for the parent folder ( = backup folder )
2120*cdf0e10cSrcweir         ::ucbhelper::Content  aContent;
2121*cdf0e10cSrcweir         Reference < ::com::sun::star::ucb::XCommandEnvironment > xEnv;
2122*cdf0e10cSrcweir         if( ::ucbhelper::Content::create( aBakDir, xEnv, aContent ) )
2123*cdf0e10cSrcweir 		{
2124*cdf0e10cSrcweir         	// save as ".bak" file
2125*cdf0e10cSrcweir         	INetURLObject aDest( aBakDir );
2126*cdf0e10cSrcweir         	aDest.insertName( aSource.getName() );
2127*cdf0e10cSrcweir         	aDest.setExtension( DEFINE_CONST_UNICODE( "bak" ) );
2128*cdf0e10cSrcweir         	String aFileName = aDest.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
2129*cdf0e10cSrcweir 
2130*cdf0e10cSrcweir         	// create a content for the source file
2131*cdf0e10cSrcweir         	::ucbhelper::Content aSourceContent;
2132*cdf0e10cSrcweir         	if ( ::ucbhelper::Content::create( aSource.GetMainURL( INetURLObject::NO_DECODE ), xEnv, aSourceContent ) )
2133*cdf0e10cSrcweir         	{
2134*cdf0e10cSrcweir             	try
2135*cdf0e10cSrcweir             	{
2136*cdf0e10cSrcweir                 	// do the transfer ( copy source file to backup dir )
2137*cdf0e10cSrcweir                 	bSuccess = aContent.transferContent( aSourceContent,
2138*cdf0e10cSrcweir 														::ucbhelper::InsertOperation_COPY,
2139*cdf0e10cSrcweir 														aFileName,
2140*cdf0e10cSrcweir 														NameClash::OVERWRITE );
2141*cdf0e10cSrcweir 					if( bSuccess )
2142*cdf0e10cSrcweir 					{
2143*cdf0e10cSrcweir 						pImp->m_aBackupURL = aDest.GetMainURL( INetURLObject::NO_DECODE );
2144*cdf0e10cSrcweir 						pImp->m_bRemoveBackup = sal_False;
2145*cdf0e10cSrcweir 					}
2146*cdf0e10cSrcweir             	}
2147*cdf0e10cSrcweir             	catch ( ::com::sun::star::uno::Exception& )
2148*cdf0e10cSrcweir             	{
2149*cdf0e10cSrcweir             	}
2150*cdf0e10cSrcweir         	}
2151*cdf0e10cSrcweir     	}
2152*cdf0e10cSrcweir 	}
2153*cdf0e10cSrcweir 
2154*cdf0e10cSrcweir     if ( !bSuccess )
2155*cdf0e10cSrcweir 	{
2156*cdf0e10cSrcweir 		eError = ERRCODE_SFX_CANTCREATEBACKUP;
2157*cdf0e10cSrcweir 	}
2158*cdf0e10cSrcweir }
2159*cdf0e10cSrcweir 
2160*cdf0e10cSrcweir //------------------------------------------------------------------
2161*cdf0e10cSrcweir void SfxMedium::ClearBackup_Impl()
2162*cdf0e10cSrcweir {
2163*cdf0e10cSrcweir 	if( pImp->m_bRemoveBackup )
2164*cdf0e10cSrcweir 	{
2165*cdf0e10cSrcweir 		// currently a document is always stored in a new medium,
2166*cdf0e10cSrcweir 		// thus if a backup can not be removed the backup URL should not be cleaned
2167*cdf0e10cSrcweir 		if ( pImp->m_aBackupURL.getLength() )
2168*cdf0e10cSrcweir 		{
2169*cdf0e10cSrcweir 			if ( ::utl::UCBContentHelper::Kill( pImp->m_aBackupURL ) )
2170*cdf0e10cSrcweir 			  // || !::utl::UCBContentHelper::IsDocument( pImp->m_aBackupURL ) );
2171*cdf0e10cSrcweir 			{
2172*cdf0e10cSrcweir 				pImp->m_bRemoveBackup = sal_False;
2173*cdf0e10cSrcweir 				pImp->m_aBackupURL = ::rtl::OUString();
2174*cdf0e10cSrcweir 			}
2175*cdf0e10cSrcweir 			else
2176*cdf0e10cSrcweir 			{
2177*cdf0e10cSrcweir 
2178*cdf0e10cSrcweir 				DBG_ERROR("Couldn't remove backup file!");
2179*cdf0e10cSrcweir 			}
2180*cdf0e10cSrcweir 		}
2181*cdf0e10cSrcweir 	}
2182*cdf0e10cSrcweir 	else
2183*cdf0e10cSrcweir 		pImp->m_aBackupURL = ::rtl::OUString();
2184*cdf0e10cSrcweir }
2185*cdf0e10cSrcweir 
2186*cdf0e10cSrcweir //----------------------------------------------------------------
2187*cdf0e10cSrcweir void SfxMedium::GetLockingStream_Impl()
2188*cdf0e10cSrcweir {
2189*cdf0e10cSrcweir     if ( ::utl::LocalFileHelper::IsLocalFile( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) )
2190*cdf0e10cSrcweir       && !pImp->m_xLockingStream.is() )
2191*cdf0e10cSrcweir     {
2192*cdf0e10cSrcweir         SFX_ITEMSET_ARG( pSet, pWriteStreamItem, SfxUnoAnyItem, SID_STREAM, sal_False);
2193*cdf0e10cSrcweir         if ( pWriteStreamItem )
2194*cdf0e10cSrcweir             pWriteStreamItem->GetValue() >>= pImp->m_xLockingStream;
2195*cdf0e10cSrcweir 
2196*cdf0e10cSrcweir         if ( !pImp->m_xLockingStream.is() )
2197*cdf0e10cSrcweir         {
2198*cdf0e10cSrcweir             // open the original document
2199*cdf0e10cSrcweir             uno::Sequence< beans::PropertyValue > xProps;
2200*cdf0e10cSrcweir             TransformItems( SID_OPENDOC, *GetItemSet(), xProps );
2201*cdf0e10cSrcweir             comphelper::MediaDescriptor aMedium( xProps );
2202*cdf0e10cSrcweir 
2203*cdf0e10cSrcweir             aMedium.addInputStreamOwnLock();
2204*cdf0e10cSrcweir 
2205*cdf0e10cSrcweir             uno::Reference< io::XInputStream > xInputStream;
2206*cdf0e10cSrcweir             aMedium[comphelper::MediaDescriptor::PROP_STREAM()] >>= pImp->m_xLockingStream;
2207*cdf0e10cSrcweir             aMedium[comphelper::MediaDescriptor::PROP_INPUTSTREAM()] >>= xInputStream;
2208*cdf0e10cSrcweir 
2209*cdf0e10cSrcweir             if ( !pImp->pTempFile && !aName.Len() )
2210*cdf0e10cSrcweir             {
2211*cdf0e10cSrcweir                 // the medium is still based on the original file, it makes sence to initialize the streams
2212*cdf0e10cSrcweir                 if ( pImp->m_xLockingStream.is() )
2213*cdf0e10cSrcweir                     pImp->xStream = pImp->m_xLockingStream;
2214*cdf0e10cSrcweir 
2215*cdf0e10cSrcweir                 if ( xInputStream.is() )
2216*cdf0e10cSrcweir                     pImp->xInputStream = xInputStream;
2217*cdf0e10cSrcweir 
2218*cdf0e10cSrcweir                 if ( !pImp->xInputStream.is() && pImp->xStream.is() )
2219*cdf0e10cSrcweir                     pImp->xInputStream = pImp->xStream->getInputStream();
2220*cdf0e10cSrcweir             }
2221*cdf0e10cSrcweir         }
2222*cdf0e10cSrcweir     }
2223*cdf0e10cSrcweir }
2224*cdf0e10cSrcweir 
2225*cdf0e10cSrcweir //----------------------------------------------------------------
2226*cdf0e10cSrcweir void SfxMedium::GetMedium_Impl()
2227*cdf0e10cSrcweir {
2228*cdf0e10cSrcweir     if ( !pInStream )
2229*cdf0e10cSrcweir     {
2230*cdf0e10cSrcweir         pImp->bDownloadDone = sal_False;
2231*cdf0e10cSrcweir         Reference< ::com::sun::star::task::XInteractionHandler > xInteractionHandler = GetInteractionHandler();
2232*cdf0e10cSrcweir 
2233*cdf0e10cSrcweir         //TODO/MBA: need support for SID_STREAM
2234*cdf0e10cSrcweir         SFX_ITEMSET_ARG( pSet, pWriteStreamItem, SfxUnoAnyItem, SID_STREAM, sal_False);
2235*cdf0e10cSrcweir         SFX_ITEMSET_ARG( pSet, pInStreamItem, SfxUnoAnyItem, SID_INPUTSTREAM, sal_False);
2236*cdf0e10cSrcweir         if ( pWriteStreamItem )
2237*cdf0e10cSrcweir         {
2238*cdf0e10cSrcweir             pWriteStreamItem->GetValue() >>= pImp->xStream;
2239*cdf0e10cSrcweir 
2240*cdf0e10cSrcweir             if ( pInStreamItem )
2241*cdf0e10cSrcweir                 pInStreamItem->GetValue() >>= pImp->xInputStream;
2242*cdf0e10cSrcweir 
2243*cdf0e10cSrcweir             if ( !pImp->xInputStream.is() && pImp->xStream.is() )
2244*cdf0e10cSrcweir                 pImp->xInputStream = pImp->xStream->getInputStream();
2245*cdf0e10cSrcweir         }
2246*cdf0e10cSrcweir         else if ( pInStreamItem )
2247*cdf0e10cSrcweir         {
2248*cdf0e10cSrcweir             pInStreamItem->GetValue() >>= pImp->xInputStream;
2249*cdf0e10cSrcweir         }
2250*cdf0e10cSrcweir         else
2251*cdf0e10cSrcweir         {
2252*cdf0e10cSrcweir             uno::Sequence < beans::PropertyValue > xProps;
2253*cdf0e10cSrcweir             String aFileName;
2254*cdf0e10cSrcweir             if ( aName.Len() )
2255*cdf0e10cSrcweir             {
2256*cdf0e10cSrcweir                 if ( !::utl::LocalFileHelper::ConvertPhysicalNameToURL( aName, aFileName ) )
2257*cdf0e10cSrcweir                 {
2258*cdf0e10cSrcweir                     DBG_ERROR("Physical name not convertable!");
2259*cdf0e10cSrcweir                 }
2260*cdf0e10cSrcweir             }
2261*cdf0e10cSrcweir             else
2262*cdf0e10cSrcweir                 aFileName = GetName();
2263*cdf0e10cSrcweir 
2264*cdf0e10cSrcweir             // in case the temporary file exists the streams should be initialized from it,
2265*cdf0e10cSrcweir             // but the original MediaDescriptor should not be changed
2266*cdf0e10cSrcweir             sal_Bool bFromTempFile = ( pImp->pTempFile != NULL );
2267*cdf0e10cSrcweir 
2268*cdf0e10cSrcweir             if ( !bFromTempFile )
2269*cdf0e10cSrcweir             {
2270*cdf0e10cSrcweir                 GetItemSet()->Put( SfxStringItem( SID_FILE_NAME, aFileName ) );
2271*cdf0e10cSrcweir                 if( !(nStorOpenMode & STREAM_WRITE ) )
2272*cdf0e10cSrcweir                     GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY, sal_True ) );
2273*cdf0e10cSrcweir                 if (xInteractionHandler.is())
2274*cdf0e10cSrcweir                     GetItemSet()->Put( SfxUnoAnyItem( SID_INTERACTIONHANDLER, makeAny(xInteractionHandler) ) );
2275*cdf0e10cSrcweir             }
2276*cdf0e10cSrcweir 
2277*cdf0e10cSrcweir             if ( m_xInputStreamToLoadFrom.is() )
2278*cdf0e10cSrcweir             {
2279*cdf0e10cSrcweir                 pImp->xInputStream = m_xInputStreamToLoadFrom;
2280*cdf0e10cSrcweir                 pImp->xInputStream->skipBytes(0);
2281*cdf0e10cSrcweir                 if(m_bIsReadOnly)
2282*cdf0e10cSrcweir                     GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY, sal_True ) );
2283*cdf0e10cSrcweir 
2284*cdf0e10cSrcweir                 // m_xInputStreamToLoadFrom = 0;
2285*cdf0e10cSrcweir             }
2286*cdf0e10cSrcweir             else
2287*cdf0e10cSrcweir             {
2288*cdf0e10cSrcweir                 TransformItems( SID_OPENDOC, *GetItemSet(), xProps );
2289*cdf0e10cSrcweir                 comphelper::MediaDescriptor aMedium( xProps );
2290*cdf0e10cSrcweir 
2291*cdf0e10cSrcweir                 if ( pImp->m_xLockingStream.is() && !bFromTempFile )
2292*cdf0e10cSrcweir                 {
2293*cdf0e10cSrcweir                     // the medium is not based on the temporary file, so the original stream can be used
2294*cdf0e10cSrcweir                     pImp->xStream = pImp->m_xLockingStream;
2295*cdf0e10cSrcweir                 }
2296*cdf0e10cSrcweir                 else
2297*cdf0e10cSrcweir                 {
2298*cdf0e10cSrcweir                     if ( bFromTempFile )
2299*cdf0e10cSrcweir                     {
2300*cdf0e10cSrcweir                         aMedium[comphelper::MediaDescriptor::PROP_URL()] <<= ::rtl::OUString( aFileName );
2301*cdf0e10cSrcweir                         aMedium.erase( comphelper::MediaDescriptor::PROP_READONLY() );
2302*cdf0e10cSrcweir                         aMedium.addInputStream();
2303*cdf0e10cSrcweir                     }
2304*cdf0e10cSrcweir                     else if ( ::utl::LocalFileHelper::IsLocalFile( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ) )
2305*cdf0e10cSrcweir                     {
2306*cdf0e10cSrcweir                         // use the special locking approach only for file URLs
2307*cdf0e10cSrcweir                         aMedium.addInputStreamOwnLock();
2308*cdf0e10cSrcweir                     }
2309*cdf0e10cSrcweir                     else
2310*cdf0e10cSrcweir                         aMedium.addInputStream();
2311*cdf0e10cSrcweir 
2312*cdf0e10cSrcweir                     // the ReadOnly property set in aMedium is ignored
2313*cdf0e10cSrcweir                     // the check is done in LockOrigFileOnDemand() for file and non-file URLs
2314*cdf0e10cSrcweir 
2315*cdf0e10cSrcweir                     //TODO/MBA: what happens if property is not there?!
2316*cdf0e10cSrcweir                     aMedium[comphelper::MediaDescriptor::PROP_STREAM()] >>= pImp->xStream;
2317*cdf0e10cSrcweir                     aMedium[comphelper::MediaDescriptor::PROP_INPUTSTREAM()] >>= pImp->xInputStream;
2318*cdf0e10cSrcweir                 }
2319*cdf0e10cSrcweir 
2320*cdf0e10cSrcweir                 GetContent();
2321*cdf0e10cSrcweir                 if ( !pImp->xInputStream.is() && pImp->xStream.is() )
2322*cdf0e10cSrcweir                     pImp->xInputStream = pImp->xStream->getInputStream();
2323*cdf0e10cSrcweir             }
2324*cdf0e10cSrcweir 
2325*cdf0e10cSrcweir             if ( !bFromTempFile )
2326*cdf0e10cSrcweir             {
2327*cdf0e10cSrcweir                 //TODO/MBA: need support for SID_STREAM
2328*cdf0e10cSrcweir                 if ( pImp->xStream.is() )
2329*cdf0e10cSrcweir                     GetItemSet()->Put( SfxUsrAnyItem( SID_STREAM, makeAny( pImp->xStream ) ) );
2330*cdf0e10cSrcweir 
2331*cdf0e10cSrcweir                 GetItemSet()->Put( SfxUsrAnyItem( SID_INPUTSTREAM, makeAny( pImp->xInputStream ) ) );
2332*cdf0e10cSrcweir             }
2333*cdf0e10cSrcweir         }
2334*cdf0e10cSrcweir 
2335*cdf0e10cSrcweir         //TODO/MBA: ErrorHandling - how to transport error from MediaDescriptor
2336*cdf0e10cSrcweir         if ( !GetError() && !pImp->xStream.is() && !pImp->xInputStream.is() )
2337*cdf0e10cSrcweir             SetError( ERRCODE_IO_ACCESSDENIED, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
2338*cdf0e10cSrcweir 
2339*cdf0e10cSrcweir         if ( !GetError() )
2340*cdf0e10cSrcweir         {
2341*cdf0e10cSrcweir             if ( pImp->xStream.is() )
2342*cdf0e10cSrcweir                 pInStream = utl::UcbStreamHelper::CreateStream( pImp->xStream );
2343*cdf0e10cSrcweir             else if ( pImp->xInputStream.is() )
2344*cdf0e10cSrcweir                 pInStream = utl::UcbStreamHelper::CreateStream( pImp->xInputStream );
2345*cdf0e10cSrcweir         }
2346*cdf0e10cSrcweir 
2347*cdf0e10cSrcweir         pImp->bDownloadDone = sal_True;
2348*cdf0e10cSrcweir         pImp->aDoneLink.ClearPendingCall();
2349*cdf0e10cSrcweir         pImp->aDoneLink.Call( (void*) GetError() );
2350*cdf0e10cSrcweir     }
2351*cdf0e10cSrcweir }
2352*cdf0e10cSrcweir 
2353*cdf0e10cSrcweir //----------------------------------------------------------------
2354*cdf0e10cSrcweir sal_Bool SfxMedium::IsRemote()
2355*cdf0e10cSrcweir {
2356*cdf0e10cSrcweir     return bRemote;
2357*cdf0e10cSrcweir }
2358*cdf0e10cSrcweir 
2359*cdf0e10cSrcweir //------------------------------------------------------------------
2360*cdf0e10cSrcweir 
2361*cdf0e10cSrcweir void SfxMedium::SetUpdatePickList(sal_Bool bVal)
2362*cdf0e10cSrcweir {
2363*cdf0e10cSrcweir     if(!pImp)
2364*cdf0e10cSrcweir         pImp = new SfxMedium_Impl( this );
2365*cdf0e10cSrcweir     pImp->bUpdatePickList = bVal;
2366*cdf0e10cSrcweir }
2367*cdf0e10cSrcweir //------------------------------------------------------------------
2368*cdf0e10cSrcweir 
2369*cdf0e10cSrcweir sal_Bool SfxMedium::IsUpdatePickList() const
2370*cdf0e10cSrcweir {
2371*cdf0e10cSrcweir     return pImp? pImp->bUpdatePickList: sal_True;
2372*cdf0e10cSrcweir }
2373*cdf0e10cSrcweir //----------------------------------------------------------------
2374*cdf0e10cSrcweir 
2375*cdf0e10cSrcweir void SfxMedium::SetDoneLink( const Link& rLink )
2376*cdf0e10cSrcweir {
2377*cdf0e10cSrcweir     pImp->aDoneLink = rLink;
2378*cdf0e10cSrcweir }
2379*cdf0e10cSrcweir 
2380*cdf0e10cSrcweir //----------------------------------------------------------------
2381*cdf0e10cSrcweir 
2382*cdf0e10cSrcweir void SfxMedium::SetDataAvailableLink( const Link& rLink )
2383*cdf0e10cSrcweir {
2384*cdf0e10cSrcweir     pImp->aAvailableLink = rLink;
2385*cdf0e10cSrcweir }
2386*cdf0e10cSrcweir 
2387*cdf0e10cSrcweir //----------------------------------------------------------------
2388*cdf0e10cSrcweir void SfxMedium::StartDownload()
2389*cdf0e10cSrcweir {
2390*cdf0e10cSrcweir     GetInStream();
2391*cdf0e10cSrcweir }
2392*cdf0e10cSrcweir 
2393*cdf0e10cSrcweir void SfxMedium::DownLoad( const Link& aLink )
2394*cdf0e10cSrcweir {
2395*cdf0e10cSrcweir     SetDoneLink( aLink );
2396*cdf0e10cSrcweir     GetInStream();
2397*cdf0e10cSrcweir     if ( pInStream && !aLink.IsSet() )
2398*cdf0e10cSrcweir     {
2399*cdf0e10cSrcweir         while( !pImp->bDownloadDone )
2400*cdf0e10cSrcweir             Application::Yield();
2401*cdf0e10cSrcweir     }
2402*cdf0e10cSrcweir }
2403*cdf0e10cSrcweir 
2404*cdf0e10cSrcweir //------------------------------------------------------------------
2405*cdf0e10cSrcweir void SfxMedium::Init_Impl()
2406*cdf0e10cSrcweir /*  [Beschreibung]
2407*cdf0e10cSrcweir     Setzt in den Logischen Namen eine gueltige ::com::sun::star::util::URL (Falls zuvor ein Filename
2408*cdf0e10cSrcweir     drin war) und setzt den physikalschen Namen auf den Filenamen, falls
2409*cdf0e10cSrcweir     vorhanden.
2410*cdf0e10cSrcweir  */
2411*cdf0e10cSrcweir 
2412*cdf0e10cSrcweir {
2413*cdf0e10cSrcweir 	Reference< XOutputStream > rOutStream;
2414*cdf0e10cSrcweir 
2415*cdf0e10cSrcweir     // TODO/LATER: handle lifetime of storages
2416*cdf0e10cSrcweir     pImp->bDisposeStorage = sal_False;
2417*cdf0e10cSrcweir 
2418*cdf0e10cSrcweir     SFX_ITEMSET_ARG( pSet, pSalvageItem, SfxStringItem, SID_DOC_SALVAGE, sal_False);
2419*cdf0e10cSrcweir     if ( pSalvageItem && !pSalvageItem->GetValue().Len() )
2420*cdf0e10cSrcweir 	{
2421*cdf0e10cSrcweir 		pSalvageItem = NULL;
2422*cdf0e10cSrcweir 		pSet->ClearItem( SID_DOC_SALVAGE );
2423*cdf0e10cSrcweir 	}
2424*cdf0e10cSrcweir 
2425*cdf0e10cSrcweir     if( aLogicName.Len() )
2426*cdf0e10cSrcweir     {
2427*cdf0e10cSrcweir         INetURLObject aUrl( aLogicName );
2428*cdf0e10cSrcweir         INetProtocol eProt = aUrl.GetProtocol();
2429*cdf0e10cSrcweir         if ( eProt == INET_PROT_NOT_VALID )
2430*cdf0e10cSrcweir         {
2431*cdf0e10cSrcweir             DBG_ERROR ( "Unknown protocol!" );
2432*cdf0e10cSrcweir         }
2433*cdf0e10cSrcweir         else
2434*cdf0e10cSrcweir         {
2435*cdf0e10cSrcweir             if ( aUrl.HasMark() )
2436*cdf0e10cSrcweir             {
2437*cdf0e10cSrcweir                 aLogicName = aUrl.GetURLNoMark( INetURLObject::NO_DECODE );
2438*cdf0e10cSrcweir                 GetItemSet()->Put( SfxStringItem( SID_JUMPMARK, aUrl.GetMark() ) );
2439*cdf0e10cSrcweir             }
2440*cdf0e10cSrcweir 
2441*cdf0e10cSrcweir             // try to convert the URL into a physical name - but never change a physical name
2442*cdf0e10cSrcweir             // physical name may be set if the logical name is changed after construction
2443*cdf0e10cSrcweir             if ( !aName.Len() )
2444*cdf0e10cSrcweir                 ::utl::LocalFileHelper::ConvertURLToPhysicalName( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ), aName );
2445*cdf0e10cSrcweir             else {
2446*cdf0e10cSrcweir                 DBG_ASSERT( pSalvageItem, "Suspicious change of logical name!" );
2447*cdf0e10cSrcweir             }
2448*cdf0e10cSrcweir         }
2449*cdf0e10cSrcweir     }
2450*cdf0e10cSrcweir 
2451*cdf0e10cSrcweir     if ( pSalvageItem && pSalvageItem->GetValue().Len() )
2452*cdf0e10cSrcweir 	{
2453*cdf0e10cSrcweir         aLogicName = pSalvageItem->GetValue();
2454*cdf0e10cSrcweir 		DELETEZ( pURLObj );
2455*cdf0e10cSrcweir 		pImp->m_bSalvageMode = sal_True;
2456*cdf0e10cSrcweir 	}
2457*cdf0e10cSrcweir 
2458*cdf0e10cSrcweir 	// in case output stream is by mistake here
2459*cdf0e10cSrcweir 	// clear the reference
2460*cdf0e10cSrcweir     SFX_ITEMSET_ARG( pSet, pOutStreamItem, SfxUnoAnyItem, SID_OUTPUTSTREAM, sal_False);
2461*cdf0e10cSrcweir 	if( pOutStreamItem
2462*cdf0e10cSrcweir 	 && ( !( pOutStreamItem->GetValue() >>= rOutStream )
2463*cdf0e10cSrcweir           || !aLogicName.CompareToAscii( "private:stream", 14 ) == COMPARE_EQUAL ) )
2464*cdf0e10cSrcweir 	{
2465*cdf0e10cSrcweir 		pSet->ClearItem( SID_OUTPUTSTREAM );
2466*cdf0e10cSrcweir 		DBG_ERROR( "Unexpected Output stream parameter!\n" );
2467*cdf0e10cSrcweir 	}
2468*cdf0e10cSrcweir 
2469*cdf0e10cSrcweir     if ( aLogicName.Len() )
2470*cdf0e10cSrcweir     {
2471*cdf0e10cSrcweir         // if the logic name is set it should be set in MediaDescriptor as well
2472*cdf0e10cSrcweir         SFX_ITEMSET_ARG( pSet, pFileNameItem, SfxStringItem, SID_FILE_NAME, sal_False );
2473*cdf0e10cSrcweir         if ( !pFileNameItem )
2474*cdf0e10cSrcweir         {
2475*cdf0e10cSrcweir             // let the ItemSet be created if necessary
2476*cdf0e10cSrcweir             GetItemSet()->Put( SfxStringItem( SID_FILE_NAME, INetURLObject( aLogicName ).GetMainURL( INetURLObject::NO_DECODE ) ) );
2477*cdf0e10cSrcweir         }
2478*cdf0e10cSrcweir     }
2479*cdf0e10cSrcweir 
2480*cdf0e10cSrcweir     SetIsRemote_Impl();
2481*cdf0e10cSrcweir }
2482*cdf0e10cSrcweir 
2483*cdf0e10cSrcweir //------------------------------------------------------------------
2484*cdf0e10cSrcweir SfxMedium::SfxMedium()
2485*cdf0e10cSrcweir :   IMPL_CTOR( sal_False, 0 ),	// bRoot, pURLObj
2486*cdf0e10cSrcweir 
2487*cdf0e10cSrcweir     pFilter(0),
2488*cdf0e10cSrcweir     pSet(0),
2489*cdf0e10cSrcweir     pImp(new SfxMedium_Impl( this ))
2490*cdf0e10cSrcweir {
2491*cdf0e10cSrcweir     Init_Impl();
2492*cdf0e10cSrcweir }
2493*cdf0e10cSrcweir //------------------------------------------------------------------
2494*cdf0e10cSrcweir 
2495*cdf0e10cSrcweir SfxMedium::SfxMedium( const SfxMedium& rMedium, sal_Bool bTemporary )
2496*cdf0e10cSrcweir :   SvRefBase(),
2497*cdf0e10cSrcweir     IMPL_CTOR( sal_True,	// bRoot, pURLObj
2498*cdf0e10cSrcweir         rMedium.pURLObj ? new INetURLObject(*rMedium.pURLObj) : 0 ),
2499*cdf0e10cSrcweir     pImp(new SfxMedium_Impl( this ))
2500*cdf0e10cSrcweir {
2501*cdf0e10cSrcweir     bDirect       = rMedium.IsDirect();
2502*cdf0e10cSrcweir     nStorOpenMode = rMedium.GetOpenMode();
2503*cdf0e10cSrcweir     if ( !bTemporary )
2504*cdf0e10cSrcweir         aName = rMedium.aName;
2505*cdf0e10cSrcweir 
2506*cdf0e10cSrcweir     pImp->bIsTemp = bTemporary;
2507*cdf0e10cSrcweir     DBG_ASSERT( ! rMedium.pImp->bIsTemp, "Temporaeres Medium darf nicht kopiert werden" );
2508*cdf0e10cSrcweir     aLogicName = rMedium.aLogicName;
2509*cdf0e10cSrcweir     pSet =  rMedium.GetItemSet() ? new SfxItemSet(*rMedium.GetItemSet()) : 0;
2510*cdf0e10cSrcweir     pFilter = rMedium.pFilter;
2511*cdf0e10cSrcweir     Init_Impl();
2512*cdf0e10cSrcweir     if( bTemporary )
2513*cdf0e10cSrcweir         CreateTempFile( sal_True );
2514*cdf0e10cSrcweir }
2515*cdf0e10cSrcweir 
2516*cdf0e10cSrcweir //------------------------------------------------------------------
2517*cdf0e10cSrcweir 
2518*cdf0e10cSrcweir void SfxMedium::UseInteractionHandler( sal_Bool bUse )
2519*cdf0e10cSrcweir {
2520*cdf0e10cSrcweir     pImp->bAllowDefaultIntHdl = bUse;
2521*cdf0e10cSrcweir }
2522*cdf0e10cSrcweir 
2523*cdf0e10cSrcweir //------------------------------------------------------------------
2524*cdf0e10cSrcweir 
2525*cdf0e10cSrcweir ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >
2526*cdf0e10cSrcweir SfxMedium::GetInteractionHandler()
2527*cdf0e10cSrcweir {
2528*cdf0e10cSrcweir     // if interaction isnt allowed explicitly ... return empty reference!
2529*cdf0e10cSrcweir     if ( !pImp->bUseInteractionHandler )
2530*cdf0e10cSrcweir         return ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >();
2531*cdf0e10cSrcweir 
2532*cdf0e10cSrcweir     // search a possible existing handler inside cached item set
2533*cdf0e10cSrcweir     if ( pSet )
2534*cdf0e10cSrcweir     {
2535*cdf0e10cSrcweir         ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler > xHandler;
2536*cdf0e10cSrcweir         SFX_ITEMSET_ARG( pSet, pHandler, SfxUnoAnyItem, SID_INTERACTIONHANDLER, sal_False);
2537*cdf0e10cSrcweir         if ( pHandler && (pHandler->GetValue() >>= xHandler) && xHandler.is() )
2538*cdf0e10cSrcweir             return xHandler;
2539*cdf0e10cSrcweir     }
2540*cdf0e10cSrcweir 
2541*cdf0e10cSrcweir     // if default interaction isnt allowed explicitly ... return empty reference!
2542*cdf0e10cSrcweir     if ( !pImp->bAllowDefaultIntHdl )
2543*cdf0e10cSrcweir         return ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >();
2544*cdf0e10cSrcweir 
2545*cdf0e10cSrcweir     // otherwhise return cached default handler ... if it exist.
2546*cdf0e10cSrcweir     if ( pImp->xInteraction.is() )
2547*cdf0e10cSrcweir         return pImp->xInteraction;
2548*cdf0e10cSrcweir 
2549*cdf0e10cSrcweir     // create default handler and cache it!
2550*cdf0e10cSrcweir     ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
2551*cdf0e10cSrcweir     if ( xFactory.is() )
2552*cdf0e10cSrcweir     {
2553*cdf0e10cSrcweir         pImp->xInteraction = ::com::sun::star::uno::Reference< com::sun::star::task::XInteractionHandler >( xFactory->createInstance( DEFINE_CONST_UNICODE("com.sun.star.task.InteractionHandler") ), ::com::sun::star::uno::UNO_QUERY );
2554*cdf0e10cSrcweir         return pImp->xInteraction;
2555*cdf0e10cSrcweir     }
2556*cdf0e10cSrcweir 
2557*cdf0e10cSrcweir 	return ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >();
2558*cdf0e10cSrcweir }
2559*cdf0e10cSrcweir 
2560*cdf0e10cSrcweir //----------------------------------------------------------------
2561*cdf0e10cSrcweir 
2562*cdf0e10cSrcweir void SfxMedium::SetFilter( const SfxFilter* pFilterP, sal_Bool /*bResetOrig*/ )
2563*cdf0e10cSrcweir {
2564*cdf0e10cSrcweir     pFilter = pFilterP;
2565*cdf0e10cSrcweir     pImp->nFileVersion = 0;
2566*cdf0e10cSrcweir }
2567*cdf0e10cSrcweir 
2568*cdf0e10cSrcweir //----------------------------------------------------------------
2569*cdf0e10cSrcweir 
2570*cdf0e10cSrcweir const SfxFilter* SfxMedium::GetOrigFilter( sal_Bool bNotCurrent ) const
2571*cdf0e10cSrcweir {
2572*cdf0e10cSrcweir     return ( pImp->pOrigFilter || bNotCurrent ) ? pImp->pOrigFilter : pFilter;
2573*cdf0e10cSrcweir }
2574*cdf0e10cSrcweir 
2575*cdf0e10cSrcweir //----------------------------------------------------------------
2576*cdf0e10cSrcweir 
2577*cdf0e10cSrcweir void SfxMedium::SetOrigFilter_Impl( const SfxFilter* pOrigFilter )
2578*cdf0e10cSrcweir {
2579*cdf0e10cSrcweir     pImp->pOrigFilter = pOrigFilter;
2580*cdf0e10cSrcweir }
2581*cdf0e10cSrcweir 
2582*cdf0e10cSrcweir //------------------------------------------------------------------
2583*cdf0e10cSrcweir 
2584*cdf0e10cSrcweir sal_uInt32 SfxMedium::CreatePasswordToModifyHash( const ::rtl::OUString& aPasswd, sal_Bool bWriter )
2585*cdf0e10cSrcweir {
2586*cdf0e10cSrcweir     sal_uInt32 nHash = 0;
2587*cdf0e10cSrcweir 
2588*cdf0e10cSrcweir     if ( aPasswd.getLength() )
2589*cdf0e10cSrcweir     {
2590*cdf0e10cSrcweir         if ( bWriter )
2591*cdf0e10cSrcweir         {
2592*cdf0e10cSrcweir             nHash = ::comphelper::DocPasswordHelper::GetWordHashAsUINT32( aPasswd );
2593*cdf0e10cSrcweir         }
2594*cdf0e10cSrcweir         else
2595*cdf0e10cSrcweir         {
2596*cdf0e10cSrcweir             rtl_TextEncoding nEncoding = RTL_TEXTENCODING_UTF8;
2597*cdf0e10cSrcweir 
2598*cdf0e10cSrcweir             // if the MS-filter should be used
2599*cdf0e10cSrcweir             // use the inconsistent algorithm to find the encoding specified by MS
2600*cdf0e10cSrcweir             nEncoding = osl_getThreadTextEncoding();
2601*cdf0e10cSrcweir             switch( nEncoding )
2602*cdf0e10cSrcweir             {
2603*cdf0e10cSrcweir                 case RTL_TEXTENCODING_ISO_8859_15:
2604*cdf0e10cSrcweir                 case RTL_TEXTENCODING_MS_874:
2605*cdf0e10cSrcweir                 case RTL_TEXTENCODING_MS_1250:
2606*cdf0e10cSrcweir                 case RTL_TEXTENCODING_MS_1251:
2607*cdf0e10cSrcweir                 case RTL_TEXTENCODING_MS_1252:
2608*cdf0e10cSrcweir                 case RTL_TEXTENCODING_MS_1253:
2609*cdf0e10cSrcweir                 case RTL_TEXTENCODING_MS_1254:
2610*cdf0e10cSrcweir                 case RTL_TEXTENCODING_MS_1255:
2611*cdf0e10cSrcweir                 case RTL_TEXTENCODING_MS_1256:
2612*cdf0e10cSrcweir                 case RTL_TEXTENCODING_MS_1257:
2613*cdf0e10cSrcweir                 case RTL_TEXTENCODING_MS_1258:
2614*cdf0e10cSrcweir                 case RTL_TEXTENCODING_SHIFT_JIS:
2615*cdf0e10cSrcweir                 case RTL_TEXTENCODING_GB_2312:
2616*cdf0e10cSrcweir                 case RTL_TEXTENCODING_BIG5:
2617*cdf0e10cSrcweir                     // in case the system uses an encoding from the list above, it should be used
2618*cdf0e10cSrcweir                     break;
2619*cdf0e10cSrcweir 
2620*cdf0e10cSrcweir                 default:
2621*cdf0e10cSrcweir                     // in case other encoding is used, use one of the encodings from the list
2622*cdf0e10cSrcweir                     nEncoding = RTL_TEXTENCODING_MS_1250;
2623*cdf0e10cSrcweir                     break;
2624*cdf0e10cSrcweir             }
2625*cdf0e10cSrcweir 
2626*cdf0e10cSrcweir             nHash = ::comphelper::DocPasswordHelper::GetXLHashAsUINT16( aPasswd, nEncoding );
2627*cdf0e10cSrcweir         }
2628*cdf0e10cSrcweir     }
2629*cdf0e10cSrcweir 
2630*cdf0e10cSrcweir     return nHash;
2631*cdf0e10cSrcweir }
2632*cdf0e10cSrcweir 
2633*cdf0e10cSrcweir //------------------------------------------------------------------
2634*cdf0e10cSrcweir 
2635*cdf0e10cSrcweir void SfxMedium::Close()
2636*cdf0e10cSrcweir {
2637*cdf0e10cSrcweir     if ( pImp->xStorage.is() )
2638*cdf0e10cSrcweir     {
2639*cdf0e10cSrcweir         // don't close the streams if they belong to the
2640*cdf0e10cSrcweir         // storage
2641*cdf0e10cSrcweir         //TODO/MBA: how to?! Do we need the flag?!
2642*cdf0e10cSrcweir         /*
2643*cdf0e10cSrcweir         const SvStream *pStream = aStorage->GetSvStream();
2644*cdf0e10cSrcweir         if ( pStream && pStream == pInStream )
2645*cdf0e10cSrcweir         {
2646*cdf0e10cSrcweir 			CloseZipStorage_Impl();
2647*cdf0e10cSrcweir             pInStream = NULL;
2648*cdf0e10cSrcweir             pImp->xInputStream = Reference < XInputStream >();
2649*cdf0e10cSrcweir             pImp->xLockBytes.Clear();
2650*cdf0e10cSrcweir             if ( pSet )
2651*cdf0e10cSrcweir                 pSet->ClearItem( SID_INPUTSTREAM );
2652*cdf0e10cSrcweir             aStorage->SetDeleteStream( sal_True );
2653*cdf0e10cSrcweir         }
2654*cdf0e10cSrcweir         else if ( pStream && pStream == pOutStream )
2655*cdf0e10cSrcweir         {
2656*cdf0e10cSrcweir             pOutStream = NULL;
2657*cdf0e10cSrcweir             aStorage->SetDeleteStream( sal_True );
2658*cdf0e10cSrcweir         } */
2659*cdf0e10cSrcweir 
2660*cdf0e10cSrcweir         CloseStorage();
2661*cdf0e10cSrcweir     }
2662*cdf0e10cSrcweir 
2663*cdf0e10cSrcweir 	CloseStreams_Impl();
2664*cdf0e10cSrcweir 
2665*cdf0e10cSrcweir     UnlockFile( sal_False );
2666*cdf0e10cSrcweir }
2667*cdf0e10cSrcweir 
2668*cdf0e10cSrcweir void SfxMedium::CloseAndRelease()
2669*cdf0e10cSrcweir {
2670*cdf0e10cSrcweir     if ( pImp->xStorage.is() )
2671*cdf0e10cSrcweir     {
2672*cdf0e10cSrcweir         // don't close the streams if they belong to the
2673*cdf0e10cSrcweir         // storage
2674*cdf0e10cSrcweir         //TODO/MBA: how to?! Do we need the flag?!
2675*cdf0e10cSrcweir         /*
2676*cdf0e10cSrcweir         const SvStream *pStream = aStorage->GetSvStream();
2677*cdf0e10cSrcweir         if ( pStream && pStream == pInStream )
2678*cdf0e10cSrcweir         {
2679*cdf0e10cSrcweir 			CloseZipStorage_Impl();
2680*cdf0e10cSrcweir             pInStream = NULL;
2681*cdf0e10cSrcweir             pImp->xInputStream = Reference < XInputStream >();
2682*cdf0e10cSrcweir             pImp->xLockBytes.Clear();
2683*cdf0e10cSrcweir             if ( pSet )
2684*cdf0e10cSrcweir                 pSet->ClearItem( SID_INPUTSTREAM );
2685*cdf0e10cSrcweir             aStorage->SetDeleteStream( sal_True );
2686*cdf0e10cSrcweir         }
2687*cdf0e10cSrcweir         else if ( pStream && pStream == pOutStream )
2688*cdf0e10cSrcweir         {
2689*cdf0e10cSrcweir             pOutStream = NULL;
2690*cdf0e10cSrcweir             aStorage->SetDeleteStream( sal_True );
2691*cdf0e10cSrcweir         } */
2692*cdf0e10cSrcweir 
2693*cdf0e10cSrcweir         CloseStorage();
2694*cdf0e10cSrcweir     }
2695*cdf0e10cSrcweir 
2696*cdf0e10cSrcweir 	CloseAndReleaseStreams_Impl();
2697*cdf0e10cSrcweir 
2698*cdf0e10cSrcweir     UnlockFile( sal_True );
2699*cdf0e10cSrcweir }
2700*cdf0e10cSrcweir 
2701*cdf0e10cSrcweir void SfxMedium::UnlockFile( sal_Bool bReleaseLockStream )
2702*cdf0e10cSrcweir {
2703*cdf0e10cSrcweir     if ( pImp->m_xLockingStream.is() )
2704*cdf0e10cSrcweir     {
2705*cdf0e10cSrcweir         if ( bReleaseLockStream )
2706*cdf0e10cSrcweir         {
2707*cdf0e10cSrcweir             try
2708*cdf0e10cSrcweir             {
2709*cdf0e10cSrcweir                 uno::Reference< io::XInputStream > xInStream = pImp->m_xLockingStream->getInputStream();
2710*cdf0e10cSrcweir                 uno::Reference< io::XOutputStream > xOutStream = pImp->m_xLockingStream->getOutputStream();
2711*cdf0e10cSrcweir                 if ( xInStream.is() )
2712*cdf0e10cSrcweir                     xInStream->closeInput();
2713*cdf0e10cSrcweir                 if ( xOutStream.is() )
2714*cdf0e10cSrcweir                     xOutStream->closeOutput();
2715*cdf0e10cSrcweir             }
2716*cdf0e10cSrcweir             catch( uno::Exception& )
2717*cdf0e10cSrcweir             {}
2718*cdf0e10cSrcweir         }
2719*cdf0e10cSrcweir 
2720*cdf0e10cSrcweir         pImp->m_xLockingStream = uno::Reference< io::XStream >();
2721*cdf0e10cSrcweir     }
2722*cdf0e10cSrcweir 
2723*cdf0e10cSrcweir     if ( pImp->m_bLocked )
2724*cdf0e10cSrcweir     {
2725*cdf0e10cSrcweir         try
2726*cdf0e10cSrcweir         {
2727*cdf0e10cSrcweir             pImp->m_bLocked = sal_False;
2728*cdf0e10cSrcweir             ::svt::DocumentLockFile aLockFile( aLogicName );
2729*cdf0e10cSrcweir             // TODO/LATER: A warning could be shown in case the file is not the own one
2730*cdf0e10cSrcweir             aLockFile.RemoveFile();
2731*cdf0e10cSrcweir         }
2732*cdf0e10cSrcweir         catch( uno::Exception& )
2733*cdf0e10cSrcweir         {}
2734*cdf0e10cSrcweir     }
2735*cdf0e10cSrcweir }
2736*cdf0e10cSrcweir 
2737*cdf0e10cSrcweir void SfxMedium::CloseAndReleaseStreams_Impl()
2738*cdf0e10cSrcweir {
2739*cdf0e10cSrcweir 	CloseZipStorage_Impl();
2740*cdf0e10cSrcweir 
2741*cdf0e10cSrcweir 	uno::Reference< io::XInputStream > xInToClose = pImp->xInputStream;
2742*cdf0e10cSrcweir 	uno::Reference< io::XOutputStream > xOutToClose;
2743*cdf0e10cSrcweir 	if ( pImp->xStream.is() )
2744*cdf0e10cSrcweir     {
2745*cdf0e10cSrcweir 		xOutToClose = pImp->xStream->getOutputStream();
2746*cdf0e10cSrcweir 
2747*cdf0e10cSrcweir         // if the locking stream is closed here the related member should be cleaned
2748*cdf0e10cSrcweir         if ( pImp->xStream == pImp->m_xLockingStream )
2749*cdf0e10cSrcweir             pImp->m_xLockingStream = uno::Reference< io::XStream >();
2750*cdf0e10cSrcweir     }
2751*cdf0e10cSrcweir 
2752*cdf0e10cSrcweir 	// The probably exsisting SvStream wrappers should be closed first
2753*cdf0e10cSrcweir     CloseStreams_Impl();
2754*cdf0e10cSrcweir 
2755*cdf0e10cSrcweir     // in case of salvage mode the storage is based on the streams
2756*cdf0e10cSrcweir     if ( !pImp->m_bSalvageMode )
2757*cdf0e10cSrcweir     {
2758*cdf0e10cSrcweir         try
2759*cdf0e10cSrcweir         {
2760*cdf0e10cSrcweir             if ( xInToClose.is() )
2761*cdf0e10cSrcweir                 xInToClose->closeInput();
2762*cdf0e10cSrcweir             if ( xOutToClose.is() )
2763*cdf0e10cSrcweir                 xOutToClose->closeOutput();
2764*cdf0e10cSrcweir         }
2765*cdf0e10cSrcweir         catch ( uno::Exception& )
2766*cdf0e10cSrcweir         {
2767*cdf0e10cSrcweir         }
2768*cdf0e10cSrcweir     }
2769*cdf0e10cSrcweir }
2770*cdf0e10cSrcweir 
2771*cdf0e10cSrcweir //------------------------------------------------------------------
2772*cdf0e10cSrcweir void SfxMedium::CloseStreams_Impl()
2773*cdf0e10cSrcweir {
2774*cdf0e10cSrcweir 	CloseInStream_Impl();
2775*cdf0e10cSrcweir 	CloseOutStream_Impl();
2776*cdf0e10cSrcweir 
2777*cdf0e10cSrcweir     if ( pSet )
2778*cdf0e10cSrcweir         pSet->ClearItem( SID_CONTENT );
2779*cdf0e10cSrcweir 
2780*cdf0e10cSrcweir     pImp->aContent = ::ucbhelper::Content();
2781*cdf0e10cSrcweir }
2782*cdf0e10cSrcweir 
2783*cdf0e10cSrcweir //------------------------------------------------------------------
2784*cdf0e10cSrcweir 
2785*cdf0e10cSrcweir void SfxMedium::RefreshName_Impl()
2786*cdf0e10cSrcweir {
2787*cdf0e10cSrcweir #if 0   //(dv)
2788*cdf0e10cSrcweir     if ( pImp->aContent.get().is() )
2789*cdf0e10cSrcweir     {
2790*cdf0e10cSrcweir         String aNameP = pImp->xAnchor->GetViewURL();
2791*cdf0e10cSrcweir         pImp->aOrigURL = aNameP;
2792*cdf0e10cSrcweir         aLogicName = aNameP;
2793*cdf0e10cSrcweir         DELETEZ( pURLObj );
2794*cdf0e10cSrcweir         if (aLogicName.Len())
2795*cdf0e10cSrcweir             aLogicName = GetURLObject().GetMainURL( INetURLObject::NO_DECODE );
2796*cdf0e10cSrcweir         SetIsRemote_Impl();
2797*cdf0e10cSrcweir     }
2798*cdf0e10cSrcweir #endif  //(dv)
2799*cdf0e10cSrcweir }
2800*cdf0e10cSrcweir 
2801*cdf0e10cSrcweir void SfxMedium::SetIsRemote_Impl()
2802*cdf0e10cSrcweir {
2803*cdf0e10cSrcweir     INetURLObject aObj( GetName() );
2804*cdf0e10cSrcweir     switch( aObj.GetProtocol() )
2805*cdf0e10cSrcweir     {
2806*cdf0e10cSrcweir         case INET_PROT_FTP:
2807*cdf0e10cSrcweir         case INET_PROT_HTTP:
2808*cdf0e10cSrcweir         case INET_PROT_HTTPS:
2809*cdf0e10cSrcweir         case INET_PROT_POP3:
2810*cdf0e10cSrcweir         case INET_PROT_NEWS:
2811*cdf0e10cSrcweir         case INET_PROT_IMAP:
2812*cdf0e10cSrcweir //        case INET_PROT_OUT:
2813*cdf0e10cSrcweir         case INET_PROT_VIM:
2814*cdf0e10cSrcweir             bRemote = sal_True; break;
2815*cdf0e10cSrcweir         default:
2816*cdf0e10cSrcweir             bRemote = ( GetName().CompareToAscii( "private:msgid", 13 ) == COMPARE_EQUAL );
2817*cdf0e10cSrcweir             break;
2818*cdf0e10cSrcweir     }
2819*cdf0e10cSrcweir 
2820*cdf0e10cSrcweir     // Da Dateien, die Remote geschrieben werden zur Uebertragung auch
2821*cdf0e10cSrcweir     // gelesen werden koennen muessen
2822*cdf0e10cSrcweir     if( bRemote )
2823*cdf0e10cSrcweir         nStorOpenMode |= STREAM_READ;
2824*cdf0e10cSrcweir }
2825*cdf0e10cSrcweir 
2826*cdf0e10cSrcweir 
2827*cdf0e10cSrcweir 
2828*cdf0e10cSrcweir void SfxMedium::SetName( const String& aNameP, sal_Bool bSetOrigURL )
2829*cdf0e10cSrcweir {
2830*cdf0e10cSrcweir     if( !pImp->aOrigURL.Len() )
2831*cdf0e10cSrcweir         pImp->aOrigURL = aLogicName;
2832*cdf0e10cSrcweir     if( bSetOrigURL )
2833*cdf0e10cSrcweir         pImp->aOrigURL = aNameP;
2834*cdf0e10cSrcweir     aLogicName = aNameP;
2835*cdf0e10cSrcweir     DELETEZ( pURLObj );
2836*cdf0e10cSrcweir     pImp->aContent = ::ucbhelper::Content();
2837*cdf0e10cSrcweir     Init_Impl();
2838*cdf0e10cSrcweir }
2839*cdf0e10cSrcweir 
2840*cdf0e10cSrcweir //----------------------------------------------------------------
2841*cdf0e10cSrcweir const String& SfxMedium::GetOrigURL() const
2842*cdf0e10cSrcweir {
2843*cdf0e10cSrcweir     return !pImp->aOrigURL.Len() ? (String &)aLogicName : pImp->aOrigURL;
2844*cdf0e10cSrcweir }
2845*cdf0e10cSrcweir 
2846*cdf0e10cSrcweir //----------------------------------------------------------------
2847*cdf0e10cSrcweir 
2848*cdf0e10cSrcweir void SfxMedium::SetPhysicalName_Impl( const String& rNameP )
2849*cdf0e10cSrcweir {
2850*cdf0e10cSrcweir     if ( rNameP != aName )
2851*cdf0e10cSrcweir     {
2852*cdf0e10cSrcweir         if( pImp->pTempFile )
2853*cdf0e10cSrcweir         {
2854*cdf0e10cSrcweir             delete pImp->pTempFile;
2855*cdf0e10cSrcweir             pImp->pTempFile = NULL;
2856*cdf0e10cSrcweir         }
2857*cdf0e10cSrcweir 
2858*cdf0e10cSrcweir         if ( aName.Len() || rNameP.Len() )
2859*cdf0e10cSrcweir             pImp->aContent = ::ucbhelper::Content();
2860*cdf0e10cSrcweir 
2861*cdf0e10cSrcweir         aName = rNameP;
2862*cdf0e10cSrcweir         bTriedStorage = sal_False;
2863*cdf0e10cSrcweir         pImp->bIsStorage = sal_False;
2864*cdf0e10cSrcweir     }
2865*cdf0e10cSrcweir }
2866*cdf0e10cSrcweir 
2867*cdf0e10cSrcweir //------------------------------------------------------------------
2868*cdf0e10cSrcweir void SfxMedium::SetTemporary( sal_Bool bTemp )
2869*cdf0e10cSrcweir {
2870*cdf0e10cSrcweir     pImp->bIsTemp = bTemp;
2871*cdf0e10cSrcweir }
2872*cdf0e10cSrcweir 
2873*cdf0e10cSrcweir //------------------------------------------------------------------
2874*cdf0e10cSrcweir sal_Bool SfxMedium::IsTemporary() const
2875*cdf0e10cSrcweir {
2876*cdf0e10cSrcweir     return pImp->bIsTemp;
2877*cdf0e10cSrcweir }
2878*cdf0e10cSrcweir 
2879*cdf0e10cSrcweir //------------------------------------------------------------------
2880*cdf0e10cSrcweir 
2881*cdf0e10cSrcweir sal_Bool SfxMedium::Exists( sal_Bool /*bForceSession*/ )
2882*cdf0e10cSrcweir {
2883*cdf0e10cSrcweir     DBG_ERROR( "Not implemented!" );
2884*cdf0e10cSrcweir     return sal_True;
2885*cdf0e10cSrcweir }
2886*cdf0e10cSrcweir 
2887*cdf0e10cSrcweir //------------------------------------------------------------------
2888*cdf0e10cSrcweir 
2889*cdf0e10cSrcweir void SfxMedium::ReOpen()
2890*cdf0e10cSrcweir {
2891*cdf0e10cSrcweir     sal_Bool bUseInteractionHandler = pImp->bUseInteractionHandler;
2892*cdf0e10cSrcweir     pImp->bUseInteractionHandler = sal_False;
2893*cdf0e10cSrcweir     GetMedium_Impl();
2894*cdf0e10cSrcweir     pImp->bUseInteractionHandler = bUseInteractionHandler;
2895*cdf0e10cSrcweir }
2896*cdf0e10cSrcweir 
2897*cdf0e10cSrcweir //------------------------------------------------------------------
2898*cdf0e10cSrcweir 
2899*cdf0e10cSrcweir void SfxMedium::CompleteReOpen()
2900*cdf0e10cSrcweir {
2901*cdf0e10cSrcweir 	// do not use temporary file for reopen and in case of success throw the temporary file away
2902*cdf0e10cSrcweir     sal_Bool bUseInteractionHandler = pImp->bUseInteractionHandler;
2903*cdf0e10cSrcweir     pImp->bUseInteractionHandler = sal_False;
2904*cdf0e10cSrcweir 
2905*cdf0e10cSrcweir     ::utl::TempFile* pTmpFile = NULL;
2906*cdf0e10cSrcweir 	if ( pImp->pTempFile )
2907*cdf0e10cSrcweir 	{
2908*cdf0e10cSrcweir 		pTmpFile = pImp->pTempFile;
2909*cdf0e10cSrcweir 		pImp->pTempFile = NULL;
2910*cdf0e10cSrcweir 		aName = String();
2911*cdf0e10cSrcweir 	}
2912*cdf0e10cSrcweir 
2913*cdf0e10cSrcweir     GetMedium_Impl();
2914*cdf0e10cSrcweir 
2915*cdf0e10cSrcweir 	if ( GetError() )
2916*cdf0e10cSrcweir 	{
2917*cdf0e10cSrcweir 		if ( pImp->pTempFile )
2918*cdf0e10cSrcweir 		{
2919*cdf0e10cSrcweir     		pImp->pTempFile->EnableKillingFile( sal_True );
2920*cdf0e10cSrcweir 			delete pImp->pTempFile;
2921*cdf0e10cSrcweir 		}
2922*cdf0e10cSrcweir 		pImp->pTempFile = pTmpFile;
2923*cdf0e10cSrcweir         if ( pImp->pTempFile )
2924*cdf0e10cSrcweir             aName = pImp->pTempFile->GetFileName();
2925*cdf0e10cSrcweir 	}
2926*cdf0e10cSrcweir 	else
2927*cdf0e10cSrcweir 	{
2928*cdf0e10cSrcweir 		pTmpFile->EnableKillingFile( sal_True );
2929*cdf0e10cSrcweir 		delete pTmpFile;
2930*cdf0e10cSrcweir 
2931*cdf0e10cSrcweir 	}
2932*cdf0e10cSrcweir 
2933*cdf0e10cSrcweir     pImp->bUseInteractionHandler = bUseInteractionHandler;
2934*cdf0e10cSrcweir }
2935*cdf0e10cSrcweir 
2936*cdf0e10cSrcweir //------------------------------------------------------------------
2937*cdf0e10cSrcweir SfxMedium::SfxMedium
2938*cdf0e10cSrcweir (
2939*cdf0e10cSrcweir     const String &rName, StreamMode nOpenMode,  sal_Bool bDirectP,
2940*cdf0e10cSrcweir     const SfxFilter *pFlt, SfxItemSet *pInSet
2941*cdf0e10cSrcweir )
2942*cdf0e10cSrcweir :   IMPL_CTOR( sal_False, 0 ),	// bRoot, pURLObj
2943*cdf0e10cSrcweir     pFilter(pFlt),
2944*cdf0e10cSrcweir     pSet( pInSet ),
2945*cdf0e10cSrcweir     pImp(new SfxMedium_Impl( this ))
2946*cdf0e10cSrcweir {
2947*cdf0e10cSrcweir     aLogicName = rName;
2948*cdf0e10cSrcweir     nStorOpenMode = nOpenMode;
2949*cdf0e10cSrcweir     bDirect = bDirectP;
2950*cdf0e10cSrcweir     Init_Impl();
2951*cdf0e10cSrcweir }
2952*cdf0e10cSrcweir 
2953*cdf0e10cSrcweir 
2954*cdf0e10cSrcweir SfxMedium::SfxMedium( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aArgs )
2955*cdf0e10cSrcweir     : IMPL_CTOR( sal_False, 0 ),  // bRoot, pURLObj
2956*cdf0e10cSrcweir     pFilter(0),
2957*cdf0e10cSrcweir     pSet(0),
2958*cdf0e10cSrcweir     pImp(new SfxMedium_Impl( this ))
2959*cdf0e10cSrcweir {
2960*cdf0e10cSrcweir     SfxAllItemSet *pParams = new SfxAllItemSet( SFX_APP()->GetPool() );
2961*cdf0e10cSrcweir     pSet = pParams;
2962*cdf0e10cSrcweir     TransformParameters( SID_OPENDOC, aArgs, *pParams );
2963*cdf0e10cSrcweir 
2964*cdf0e10cSrcweir     String aFilterName;
2965*cdf0e10cSrcweir     SFX_ITEMSET_ARG( pSet, pFilterNameItem, SfxStringItem, SID_FILTER_NAME, sal_False );
2966*cdf0e10cSrcweir     if( pFilterNameItem )
2967*cdf0e10cSrcweir         aFilterName = pFilterNameItem->GetValue();
2968*cdf0e10cSrcweir     pFilter = SFX_APP()->GetFilterMatcher().GetFilter4FilterName( aFilterName );
2969*cdf0e10cSrcweir 
2970*cdf0e10cSrcweir     sal_Bool bSalvage = sal_False;
2971*cdf0e10cSrcweir     SFX_ITEMSET_ARG( pSet, pSalvageItem, SfxStringItem, SID_DOC_SALVAGE, sal_False );
2972*cdf0e10cSrcweir     if( pSalvageItem )
2973*cdf0e10cSrcweir     {
2974*cdf0e10cSrcweir         // QUESTION: there is some treatment of Salvage in Init_Impl; align!
2975*cdf0e10cSrcweir         bSalvage = sal_True;
2976*cdf0e10cSrcweir         if ( pSalvageItem->GetValue().Len() )
2977*cdf0e10cSrcweir         {
2978*cdf0e10cSrcweir             // if an URL is provided in SalvageItem that means that the FileName refers to a temporary file
2979*cdf0e10cSrcweir             // that must be copied here
2980*cdf0e10cSrcweir 
2981*cdf0e10cSrcweir             SFX_ITEMSET_ARG( pSet, pFileNameItem, SfxStringItem, SID_FILE_NAME, sal_False );
2982*cdf0e10cSrcweir             if (!pFileNameItem) throw uno::RuntimeException();
2983*cdf0e10cSrcweir             ::rtl::OUString aNewTempFileURL = SfxMedium::CreateTempCopyWithExt( pFileNameItem->GetValue() );
2984*cdf0e10cSrcweir             if ( aNewTempFileURL.getLength() )
2985*cdf0e10cSrcweir             {
2986*cdf0e10cSrcweir                 pSet->Put( SfxStringItem( SID_FILE_NAME, aNewTempFileURL ) );
2987*cdf0e10cSrcweir                 pSet->ClearItem( SID_INPUTSTREAM );
2988*cdf0e10cSrcweir                 pSet->ClearItem( SID_STREAM );
2989*cdf0e10cSrcweir                 pSet->ClearItem( SID_CONTENT );
2990*cdf0e10cSrcweir             }
2991*cdf0e10cSrcweir             else
2992*cdf0e10cSrcweir             {
2993*cdf0e10cSrcweir                 OSL_ENSURE( sal_False, "Can not create a new temporary file for crash recovery!\n" );
2994*cdf0e10cSrcweir             }
2995*cdf0e10cSrcweir         }
2996*cdf0e10cSrcweir     }
2997*cdf0e10cSrcweir 
2998*cdf0e10cSrcweir     sal_Bool bReadOnly = sal_False;
2999*cdf0e10cSrcweir     SFX_ITEMSET_ARG( pSet, pReadOnlyItem, SfxBoolItem, SID_DOC_READONLY, sal_False );
3000*cdf0e10cSrcweir     if ( pReadOnlyItem && pReadOnlyItem->GetValue() )
3001*cdf0e10cSrcweir         bReadOnly = sal_True;
3002*cdf0e10cSrcweir 
3003*cdf0e10cSrcweir     SFX_ITEMSET_ARG( pSet, pFileNameItem, SfxStringItem, SID_FILE_NAME, sal_False );
3004*cdf0e10cSrcweir     if (!pFileNameItem) throw uno::RuntimeException();
3005*cdf0e10cSrcweir     aLogicName = pFileNameItem->GetValue();
3006*cdf0e10cSrcweir     nStorOpenMode = bReadOnly ? SFX_STREAM_READONLY : SFX_STREAM_READWRITE;
3007*cdf0e10cSrcweir     bDirect = sal_False;
3008*cdf0e10cSrcweir     Init_Impl();
3009*cdf0e10cSrcweir }
3010*cdf0e10cSrcweir 
3011*cdf0e10cSrcweir 
3012*cdf0e10cSrcweir //------------------------------------------------------------------
3013*cdf0e10cSrcweir 
3014*cdf0e10cSrcweir SfxMedium::SfxMedium( const uno::Reference < embed::XStorage >& rStor, const String& rBaseURL, const SfxItemSet* p, sal_Bool bRootP )
3015*cdf0e10cSrcweir :   IMPL_CTOR( bRootP, 0 ),	// bRoot, pURLObj
3016*cdf0e10cSrcweir     pSet(0),
3017*cdf0e10cSrcweir     pImp( new SfxMedium_Impl( this ))
3018*cdf0e10cSrcweir {
3019*cdf0e10cSrcweir     String aType = SfxFilter::GetTypeFromStorage( rStor );
3020*cdf0e10cSrcweir 	pFilter = SFX_APP()->GetFilterMatcher().GetFilter4EA( aType );
3021*cdf0e10cSrcweir     DBG_ASSERT( pFilter, "No Filter for storage found!" );
3022*cdf0e10cSrcweir 
3023*cdf0e10cSrcweir     Init_Impl();
3024*cdf0e10cSrcweir     pImp->xStorage = rStor;
3025*cdf0e10cSrcweir     pImp->bDisposeStorage = sal_False;
3026*cdf0e10cSrcweir 
3027*cdf0e10cSrcweir     // always take BaseURL first, could be overwritten by ItemSet
3028*cdf0e10cSrcweir     GetItemSet()->Put( SfxStringItem( SID_DOC_BASEURL, rBaseURL ) );
3029*cdf0e10cSrcweir     if ( p )
3030*cdf0e10cSrcweir         GetItemSet()->Put( *p );
3031*cdf0e10cSrcweir }
3032*cdf0e10cSrcweir 
3033*cdf0e10cSrcweir //------------------------------------------------------------------
3034*cdf0e10cSrcweir 
3035*cdf0e10cSrcweir SfxMedium::~SfxMedium()
3036*cdf0e10cSrcweir {
3037*cdf0e10cSrcweir     /* Attention
3038*cdf0e10cSrcweir         Don't enable CancelTransfers() till you know that the writer/web has changed his asynchronous load
3039*cdf0e10cSrcweir         behaviour. Otherwhise may StyleSheets inside a html file will be loaded at the right time.
3040*cdf0e10cSrcweir         => further the help will be empty then ... #100490#
3041*cdf0e10cSrcweir      */
3042*cdf0e10cSrcweir     //CancelTransfers();
3043*cdf0e10cSrcweir 
3044*cdf0e10cSrcweir 	// if there is a requirement to clean the backup this is the last possibility to do it
3045*cdf0e10cSrcweir 	ClearBackup_Impl();
3046*cdf0e10cSrcweir 
3047*cdf0e10cSrcweir     Close();
3048*cdf0e10cSrcweir 
3049*cdf0e10cSrcweir     delete pSet;
3050*cdf0e10cSrcweir 
3051*cdf0e10cSrcweir     if( pImp->bIsTemp && aName.Len() )
3052*cdf0e10cSrcweir     {
3053*cdf0e10cSrcweir         String aTemp;
3054*cdf0e10cSrcweir         if ( !::utl::LocalFileHelper::ConvertPhysicalNameToURL( aName, aTemp ))
3055*cdf0e10cSrcweir         {
3056*cdf0e10cSrcweir 			DBG_ERROR("Physical name not convertable!");
3057*cdf0e10cSrcweir         }
3058*cdf0e10cSrcweir 
3059*cdf0e10cSrcweir         if ( !::utl::UCBContentHelper::Kill( aTemp ) )
3060*cdf0e10cSrcweir         {
3061*cdf0e10cSrcweir 			DBG_ERROR("Couldn't remove temporary file!");
3062*cdf0e10cSrcweir         }
3063*cdf0e10cSrcweir     }
3064*cdf0e10cSrcweir 
3065*cdf0e10cSrcweir     pFilter = 0;
3066*cdf0e10cSrcweir 
3067*cdf0e10cSrcweir     delete pURLObj;
3068*cdf0e10cSrcweir     delete pImp;
3069*cdf0e10cSrcweir }
3070*cdf0e10cSrcweir 
3071*cdf0e10cSrcweir //------------------------------------------------------------------
3072*cdf0e10cSrcweir void SfxMedium::SetItemSet(SfxItemSet *pNewSet)
3073*cdf0e10cSrcweir {
3074*cdf0e10cSrcweir     delete pSet;
3075*cdf0e10cSrcweir     pSet = pNewSet;
3076*cdf0e10cSrcweir }
3077*cdf0e10cSrcweir 
3078*cdf0e10cSrcweir //----------------------------------------------------------------
3079*cdf0e10cSrcweir const INetURLObject& SfxMedium::GetURLObject() const
3080*cdf0e10cSrcweir {
3081*cdf0e10cSrcweir     if( !pURLObj )
3082*cdf0e10cSrcweir     {
3083*cdf0e10cSrcweir         SfxMedium* pThis = const_cast < SfxMedium* > (this);
3084*cdf0e10cSrcweir         pThis->pURLObj = new INetURLObject( aLogicName );
3085*cdf0e10cSrcweir 		if ( pThis->pURLObj->HasMark() )
3086*cdf0e10cSrcweir 			(*pThis->pURLObj) = INetURLObject( aLogicName ).GetURLNoMark();
3087*cdf0e10cSrcweir     }
3088*cdf0e10cSrcweir 
3089*cdf0e10cSrcweir     return *pURLObj;
3090*cdf0e10cSrcweir }
3091*cdf0e10cSrcweir 
3092*cdf0e10cSrcweir //----------------------------------------------------------------
3093*cdf0e10cSrcweir 
3094*cdf0e10cSrcweir const String& SfxMedium::GetPreRedirectedURL() const
3095*cdf0e10cSrcweir {
3096*cdf0e10cSrcweir     return pImp->aPreRedirectionURL;
3097*cdf0e10cSrcweir }
3098*cdf0e10cSrcweir //----------------------------------------------------------------
3099*cdf0e10cSrcweir 
3100*cdf0e10cSrcweir sal_uInt32 SfxMedium::GetMIMEAndRedirect( String& /*rName*/ )
3101*cdf0e10cSrcweir {
3102*cdf0e10cSrcweir /* dv !!!! not needed any longer ?
3103*cdf0e10cSrcweir     INetProtocol eProt = GetURLObject().GetProtocol();
3104*cdf0e10cSrcweir     if( eProt == INET_PROT_FTP && SvBinding::ShouldUseFtpProxy( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ) )
3105*cdf0e10cSrcweir     {
3106*cdf0e10cSrcweir         Any aAny( UCB_Helper::GetProperty( GetContent(), WID_FLAG_IS_FOLDER ) );
3107*cdf0e10cSrcweir         sal_Bool bIsFolder = sal_False;
3108*cdf0e10cSrcweir         if ( ( aAny >>= bIsFolder ) && bIsFolder )
3109*cdf0e10cSrcweir             return ERRCODE_NONE;
3110*cdf0e10cSrcweir     }
3111*cdf0e10cSrcweir 
3112*cdf0e10cSrcweir     GetMedium_Impl();
3113*cdf0e10cSrcweir     if( !eError && pImp->xBinding.Is() )
3114*cdf0e10cSrcweir     {
3115*cdf0e10cSrcweir         eError = pImp->xBinding->GetMimeType( rName );
3116*cdf0e10cSrcweir 
3117*cdf0e10cSrcweir         // Wir koennen keine Parameter wie CharSets usw.
3118*cdf0e10cSrcweir         rName = rName.GetToken( 0, ';' );
3119*cdf0e10cSrcweir         if( !eError )
3120*cdf0e10cSrcweir         {
3121*cdf0e10cSrcweir             if( !pImp->aPreRedirectionURL.Len() )
3122*cdf0e10cSrcweir                 pImp->aPreRedirectionURL = aLogicName;
3123*cdf0e10cSrcweir             SetName( pImp->xBinding->GetRedirectedURL() );
3124*cdf0e10cSrcweir         }
3125*cdf0e10cSrcweir         pImp->aExpireTime = pImp->xBinding->GetExpireDateTime();
3126*cdf0e10cSrcweir     }
3127*cdf0e10cSrcweir     return eError;
3128*cdf0e10cSrcweir */
3129*cdf0e10cSrcweir     return 0;
3130*cdf0e10cSrcweir }
3131*cdf0e10cSrcweir 
3132*cdf0e10cSrcweir //----------------------------------------------------------------
3133*cdf0e10cSrcweir 
3134*cdf0e10cSrcweir void SfxMedium::SetReferer( const String& rRefer )
3135*cdf0e10cSrcweir {
3136*cdf0e10cSrcweir     pImp->aReferer = rRefer;
3137*cdf0e10cSrcweir }
3138*cdf0e10cSrcweir //----------------------------------------------------------------
3139*cdf0e10cSrcweir 
3140*cdf0e10cSrcweir const String& SfxMedium::GetReferer( ) const
3141*cdf0e10cSrcweir {
3142*cdf0e10cSrcweir     return pImp->aReferer;
3143*cdf0e10cSrcweir }
3144*cdf0e10cSrcweir 
3145*cdf0e10cSrcweir //----------------------------------------------------------------
3146*cdf0e10cSrcweir 
3147*cdf0e10cSrcweir void SfxMedium::SetExpired_Impl( const DateTime& rDateTime )
3148*cdf0e10cSrcweir {
3149*cdf0e10cSrcweir     pImp->aExpireTime = rDateTime;
3150*cdf0e10cSrcweir }
3151*cdf0e10cSrcweir //----------------------------------------------------------------
3152*cdf0e10cSrcweir 
3153*cdf0e10cSrcweir sal_Bool SfxMedium::IsExpired() const
3154*cdf0e10cSrcweir {
3155*cdf0e10cSrcweir     return pImp->aExpireTime.IsValid() && pImp->aExpireTime < DateTime();
3156*cdf0e10cSrcweir }
3157*cdf0e10cSrcweir //----------------------------------------------------------------
3158*cdf0e10cSrcweir 
3159*cdf0e10cSrcweir void SfxMedium::ForceSynchronStream_Impl( sal_Bool bForce )
3160*cdf0e10cSrcweir {
3161*cdf0e10cSrcweir     if( pInStream )
3162*cdf0e10cSrcweir     {
3163*cdf0e10cSrcweir         SvLockBytes* pBytes = pInStream->GetLockBytes();
3164*cdf0e10cSrcweir         if( pBytes )
3165*cdf0e10cSrcweir             pBytes->SetSynchronMode( bForce );
3166*cdf0e10cSrcweir     }
3167*cdf0e10cSrcweir     pImp->bForceSynchron = bForce;
3168*cdf0e10cSrcweir }
3169*cdf0e10cSrcweir 
3170*cdf0e10cSrcweir //----------------------------------------------------------------
3171*cdf0e10cSrcweir SfxFrame* SfxMedium::GetLoadTargetFrame() const
3172*cdf0e10cSrcweir {
3173*cdf0e10cSrcweir     return pImp->wLoadTargetFrame;
3174*cdf0e10cSrcweir }
3175*cdf0e10cSrcweir //----------------------------------------------------------------
3176*cdf0e10cSrcweir 
3177*cdf0e10cSrcweir void SfxMedium::SetLoadTargetFrame(SfxFrame* pFrame )
3178*cdf0e10cSrcweir {
3179*cdf0e10cSrcweir     pImp->wLoadTargetFrame = pFrame;
3180*cdf0e10cSrcweir }
3181*cdf0e10cSrcweir //----------------------------------------------------------------
3182*cdf0e10cSrcweir 
3183*cdf0e10cSrcweir void SfxMedium::SetStorage_Impl( const uno::Reference < embed::XStorage >& rStor )
3184*cdf0e10cSrcweir {
3185*cdf0e10cSrcweir     pImp->xStorage = rStor;
3186*cdf0e10cSrcweir }
3187*cdf0e10cSrcweir //----------------------------------------------------------------
3188*cdf0e10cSrcweir 
3189*cdf0e10cSrcweir SfxItemSet* SfxMedium::GetItemSet() const
3190*cdf0e10cSrcweir {
3191*cdf0e10cSrcweir 	// this method *must* return an ItemSet, returning NULL can cause crashes
3192*cdf0e10cSrcweir     if( !pSet )
3193*cdf0e10cSrcweir 		((SfxMedium*)this)->pSet = new SfxAllItemSet( SFX_APP()->GetPool() );
3194*cdf0e10cSrcweir     return pSet;
3195*cdf0e10cSrcweir }
3196*cdf0e10cSrcweir //----------------------------------------------------------------
3197*cdf0e10cSrcweir 
3198*cdf0e10cSrcweir SvKeyValueIterator* SfxMedium::GetHeaderAttributes_Impl()
3199*cdf0e10cSrcweir {
3200*cdf0e10cSrcweir     if( !pImp->xAttributes.Is() )
3201*cdf0e10cSrcweir 	{
3202*cdf0e10cSrcweir 		pImp->xAttributes = SvKeyValueIteratorRef( new SvKeyValueIterator );
3203*cdf0e10cSrcweir 
3204*cdf0e10cSrcweir 		if ( GetContent().is() )
3205*cdf0e10cSrcweir 		{
3206*cdf0e10cSrcweir 			pImp->bIsCharsetInitialized = sal_True;
3207*cdf0e10cSrcweir 
3208*cdf0e10cSrcweir 			try
3209*cdf0e10cSrcweir 			{
3210*cdf0e10cSrcweir 				Any aAny = pImp->aContent.getPropertyValue( ::rtl::OUString::createFromAscii( "MediaType" ) );
3211*cdf0e10cSrcweir 				::rtl::OUString aContentType;
3212*cdf0e10cSrcweir 				aAny >>= aContentType;
3213*cdf0e10cSrcweir 
3214*cdf0e10cSrcweir 				pImp->xAttributes->Append( SvKeyValue( ::rtl::OUString::createFromAscii( "content-type" ), aContentType ) );
3215*cdf0e10cSrcweir 			}
3216*cdf0e10cSrcweir 			catch ( ::com::sun::star::uno::Exception& )
3217*cdf0e10cSrcweir 			{
3218*cdf0e10cSrcweir 			}
3219*cdf0e10cSrcweir 		}
3220*cdf0e10cSrcweir 	}
3221*cdf0e10cSrcweir 
3222*cdf0e10cSrcweir     return pImp->xAttributes;
3223*cdf0e10cSrcweir }
3224*cdf0e10cSrcweir //----------------------------------------------------------------
3225*cdf0e10cSrcweir 
3226*cdf0e10cSrcweir SvCompatWeakHdl* SfxMedium::GetHdl()
3227*cdf0e10cSrcweir {
3228*cdf0e10cSrcweir     return pImp->GetHdl();
3229*cdf0e10cSrcweir }
3230*cdf0e10cSrcweir 
3231*cdf0e10cSrcweir sal_Bool SfxMedium::IsDownloadDone_Impl()
3232*cdf0e10cSrcweir {
3233*cdf0e10cSrcweir     return pImp->bDownloadDone;
3234*cdf0e10cSrcweir }
3235*cdf0e10cSrcweir 
3236*cdf0e10cSrcweir ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >  SfxMedium::GetInputStream()
3237*cdf0e10cSrcweir {
3238*cdf0e10cSrcweir 	if ( !pImp->xInputStream.is() )
3239*cdf0e10cSrcweir 		GetMedium_Impl();
3240*cdf0e10cSrcweir     return pImp->xInputStream;
3241*cdf0e10cSrcweir }
3242*cdf0e10cSrcweir 
3243*cdf0e10cSrcweir const uno::Sequence < util::RevisionTag >& SfxMedium::GetVersionList( bool _bNoReload )
3244*cdf0e10cSrcweir {
3245*cdf0e10cSrcweir 	// if the medium has no name, then this medium should represent a new document and can have no version info
3246*cdf0e10cSrcweir     if ( ( !_bNoReload || !pImp->m_bVersionsAlreadyLoaded ) && !pImp->aVersions.getLength() &&
3247*cdf0e10cSrcweir          ( aName.Len() || aLogicName.Len() ) && GetStorage().is() )
3248*cdf0e10cSrcweir     {
3249*cdf0e10cSrcweir         uno::Reference < document::XDocumentRevisionListPersistence > xReader( comphelper::getProcessServiceFactory()->createInstance(
3250*cdf0e10cSrcweir                 ::rtl::OUString::createFromAscii("com.sun.star.document.DocumentRevisionListPersistence") ), uno::UNO_QUERY );
3251*cdf0e10cSrcweir         if ( xReader.is() )
3252*cdf0e10cSrcweir         {
3253*cdf0e10cSrcweir             try
3254*cdf0e10cSrcweir             {
3255*cdf0e10cSrcweir                 pImp->aVersions = xReader->load( GetStorage() );
3256*cdf0e10cSrcweir             }
3257*cdf0e10cSrcweir             catch ( uno::Exception& )
3258*cdf0e10cSrcweir             {
3259*cdf0e10cSrcweir             }
3260*cdf0e10cSrcweir         }
3261*cdf0e10cSrcweir     }
3262*cdf0e10cSrcweir 
3263*cdf0e10cSrcweir     if ( !pImp->m_bVersionsAlreadyLoaded )
3264*cdf0e10cSrcweir         pImp->m_bVersionsAlreadyLoaded = sal_True;
3265*cdf0e10cSrcweir 
3266*cdf0e10cSrcweir     return pImp->aVersions;
3267*cdf0e10cSrcweir }
3268*cdf0e10cSrcweir 
3269*cdf0e10cSrcweir uno::Sequence < util::RevisionTag > SfxMedium::GetVersionList( const uno::Reference < embed::XStorage >& xStorage )
3270*cdf0e10cSrcweir {
3271*cdf0e10cSrcweir     uno::Reference < document::XDocumentRevisionListPersistence > xReader( comphelper::getProcessServiceFactory()->createInstance(
3272*cdf0e10cSrcweir             ::rtl::OUString::createFromAscii("com.sun.star.document.DocumentRevisionListPersistence") ), uno::UNO_QUERY );
3273*cdf0e10cSrcweir     if ( xReader.is() )
3274*cdf0e10cSrcweir     {
3275*cdf0e10cSrcweir         try
3276*cdf0e10cSrcweir         {
3277*cdf0e10cSrcweir             return xReader->load( xStorage );
3278*cdf0e10cSrcweir         }
3279*cdf0e10cSrcweir         catch ( uno::Exception& )
3280*cdf0e10cSrcweir         {
3281*cdf0e10cSrcweir         }
3282*cdf0e10cSrcweir     }
3283*cdf0e10cSrcweir 
3284*cdf0e10cSrcweir     return uno::Sequence < util::RevisionTag >();
3285*cdf0e10cSrcweir }
3286*cdf0e10cSrcweir 
3287*cdf0e10cSrcweir sal_uInt16 SfxMedium::AddVersion_Impl( util::RevisionTag& rRevision )
3288*cdf0e10cSrcweir {
3289*cdf0e10cSrcweir     if ( GetStorage().is() )
3290*cdf0e10cSrcweir     {
3291*cdf0e10cSrcweir         // Einen eindeutigen Namen f"ur den Stream ermitteln
3292*cdf0e10cSrcweir         SvULongs aLongs;
3293*cdf0e10cSrcweir         sal_Int32 nLength = pImp->aVersions.getLength();
3294*cdf0e10cSrcweir         for ( sal_Int32 m=0; m<nLength; m++ )
3295*cdf0e10cSrcweir         {
3296*cdf0e10cSrcweir             sal_uInt32 nVer = (sal_uInt32) String( pImp->aVersions[m].Identifier ).Copy(7).ToInt32();
3297*cdf0e10cSrcweir             sal_uInt16 n;
3298*cdf0e10cSrcweir             for ( n=0; n<aLongs.Count(); n++ )
3299*cdf0e10cSrcweir                 if ( nVer<aLongs[n] )
3300*cdf0e10cSrcweir                     break;
3301*cdf0e10cSrcweir 
3302*cdf0e10cSrcweir             aLongs.Insert( nVer, n );
3303*cdf0e10cSrcweir         }
3304*cdf0e10cSrcweir 
3305*cdf0e10cSrcweir         sal_uInt16 nKey;
3306*cdf0e10cSrcweir         for ( nKey=0; nKey<aLongs.Count(); nKey++ )
3307*cdf0e10cSrcweir             if ( aLongs[nKey] > ( sal_uIntPtr ) nKey+1 )
3308*cdf0e10cSrcweir                 break;
3309*cdf0e10cSrcweir 
3310*cdf0e10cSrcweir         String aRevName = DEFINE_CONST_UNICODE( "Version" );
3311*cdf0e10cSrcweir         aRevName += String::CreateFromInt32( nKey + 1 );
3312*cdf0e10cSrcweir         pImp->aVersions.realloc( nLength+1 );
3313*cdf0e10cSrcweir         rRevision.Identifier = aRevName;
3314*cdf0e10cSrcweir         pImp->aVersions[nLength] = rRevision;
3315*cdf0e10cSrcweir         return nKey;
3316*cdf0e10cSrcweir     }
3317*cdf0e10cSrcweir 
3318*cdf0e10cSrcweir     return 0;
3319*cdf0e10cSrcweir }
3320*cdf0e10cSrcweir 
3321*cdf0e10cSrcweir sal_Bool SfxMedium::RemoveVersion_Impl( const ::rtl::OUString& rName )
3322*cdf0e10cSrcweir {
3323*cdf0e10cSrcweir     if ( !pImp->aVersions.getLength() )
3324*cdf0e10cSrcweir         return sal_False;
3325*cdf0e10cSrcweir 
3326*cdf0e10cSrcweir     sal_Int32 nLength = pImp->aVersions.getLength();
3327*cdf0e10cSrcweir     for ( sal_Int32 n=0; n<nLength; n++ )
3328*cdf0e10cSrcweir     {
3329*cdf0e10cSrcweir         if ( pImp->aVersions[n].Identifier == rName )
3330*cdf0e10cSrcweir         {
3331*cdf0e10cSrcweir             for ( sal_Int32 m=n; m<nLength-1; m++ )
3332*cdf0e10cSrcweir                 pImp->aVersions[m] = pImp->aVersions[m+1];
3333*cdf0e10cSrcweir             pImp->aVersions.realloc(nLength-1);
3334*cdf0e10cSrcweir             return sal_True;
3335*cdf0e10cSrcweir         }
3336*cdf0e10cSrcweir     }
3337*cdf0e10cSrcweir 
3338*cdf0e10cSrcweir     return sal_False;
3339*cdf0e10cSrcweir }
3340*cdf0e10cSrcweir 
3341*cdf0e10cSrcweir sal_Bool SfxMedium::TransferVersionList_Impl( SfxMedium& rMedium )
3342*cdf0e10cSrcweir {
3343*cdf0e10cSrcweir     if ( rMedium.pImp->aVersions.getLength() )
3344*cdf0e10cSrcweir     {
3345*cdf0e10cSrcweir         pImp->aVersions = rMedium.pImp->aVersions;
3346*cdf0e10cSrcweir         return sal_True;
3347*cdf0e10cSrcweir     }
3348*cdf0e10cSrcweir 
3349*cdf0e10cSrcweir     return sal_False;
3350*cdf0e10cSrcweir }
3351*cdf0e10cSrcweir 
3352*cdf0e10cSrcweir sal_Bool SfxMedium::SaveVersionList_Impl( sal_Bool /*bUseXML*/ )
3353*cdf0e10cSrcweir {
3354*cdf0e10cSrcweir     if ( GetStorage().is() )
3355*cdf0e10cSrcweir     {
3356*cdf0e10cSrcweir         if ( !pImp->aVersions.getLength() )
3357*cdf0e10cSrcweir             return sal_True;
3358*cdf0e10cSrcweir 
3359*cdf0e10cSrcweir         uno::Reference < document::XDocumentRevisionListPersistence > xWriter( comphelper::getProcessServiceFactory()->createInstance(
3360*cdf0e10cSrcweir                 ::rtl::OUString::createFromAscii("com.sun.star.document.DocumentRevisionListPersistence") ), uno::UNO_QUERY );
3361*cdf0e10cSrcweir         if ( xWriter.is() )
3362*cdf0e10cSrcweir         {
3363*cdf0e10cSrcweir             try
3364*cdf0e10cSrcweir             {
3365*cdf0e10cSrcweir                 xWriter->store( GetStorage(), pImp->aVersions );
3366*cdf0e10cSrcweir                 return sal_True;
3367*cdf0e10cSrcweir             }
3368*cdf0e10cSrcweir             catch ( uno::Exception& )
3369*cdf0e10cSrcweir             {
3370*cdf0e10cSrcweir             }
3371*cdf0e10cSrcweir         }
3372*cdf0e10cSrcweir     }
3373*cdf0e10cSrcweir 
3374*cdf0e10cSrcweir     return sal_False;
3375*cdf0e10cSrcweir }
3376*cdf0e10cSrcweir 
3377*cdf0e10cSrcweir //----------------------------------------------------------------
3378*cdf0e10cSrcweir sal_Bool SfxMedium::IsReadOnly()
3379*cdf0e10cSrcweir {
3380*cdf0e10cSrcweir     sal_Bool bReadOnly = sal_False;
3381*cdf0e10cSrcweir 
3382*cdf0e10cSrcweir     // a) ReadOnly filter cant produce read/write contents!
3383*cdf0e10cSrcweir     bReadOnly = (
3384*cdf0e10cSrcweir                     (pFilter                                                                         ) &&
3385*cdf0e10cSrcweir                     ((pFilter->GetFilterFlags() & SFX_FILTER_OPENREADONLY) == SFX_FILTER_OPENREADONLY)
3386*cdf0e10cSrcweir                 );
3387*cdf0e10cSrcweir 
3388*cdf0e10cSrcweir     // b) if filter allow read/write contents .. check open mode of the storage
3389*cdf0e10cSrcweir     if (!bReadOnly)
3390*cdf0e10cSrcweir         bReadOnly = !( GetOpenMode() & STREAM_WRITE );
3391*cdf0e10cSrcweir 
3392*cdf0e10cSrcweir     // c) the API can force the readonly state!
3393*cdf0e10cSrcweir     if (!bReadOnly)
3394*cdf0e10cSrcweir     {
3395*cdf0e10cSrcweir         SFX_ITEMSET_ARG( GetItemSet(), pItem, SfxBoolItem, SID_DOC_READONLY, sal_False);
3396*cdf0e10cSrcweir         if (pItem)
3397*cdf0e10cSrcweir             bReadOnly = pItem->GetValue();
3398*cdf0e10cSrcweir     }
3399*cdf0e10cSrcweir 
3400*cdf0e10cSrcweir     return bReadOnly;
3401*cdf0e10cSrcweir }
3402*cdf0e10cSrcweir 
3403*cdf0e10cSrcweir //----------------------------------------------------------------
3404*cdf0e10cSrcweir sal_Bool SfxMedium::SetWritableForUserOnly( const ::rtl::OUString& aURL )
3405*cdf0e10cSrcweir {
3406*cdf0e10cSrcweir     // UCB does not allow to allow write access only for the user,
3407*cdf0e10cSrcweir     // use osl API
3408*cdf0e10cSrcweir     sal_Bool bResult = sal_False;
3409*cdf0e10cSrcweir 
3410*cdf0e10cSrcweir     ::osl::DirectoryItem aDirItem;
3411*cdf0e10cSrcweir     if ( ::osl::DirectoryItem::get( aURL, aDirItem ) == ::osl::FileBase::E_None )
3412*cdf0e10cSrcweir     {
3413*cdf0e10cSrcweir         ::osl::FileStatus aFileStatus( FileStatusMask_Attributes );
3414*cdf0e10cSrcweir         if ( aDirItem.getFileStatus( aFileStatus ) == osl::FileBase::E_None
3415*cdf0e10cSrcweir           && aFileStatus.isValid( FileStatusMask_Attributes ) )
3416*cdf0e10cSrcweir         {
3417*cdf0e10cSrcweir             sal_uInt64 nAttributes = aFileStatus.getAttributes();
3418*cdf0e10cSrcweir 
3419*cdf0e10cSrcweir             nAttributes &= ~(Attribute_OwnWrite |
3420*cdf0e10cSrcweir                              Attribute_GrpWrite |
3421*cdf0e10cSrcweir                              Attribute_OthWrite |
3422*cdf0e10cSrcweir                              Attribute_ReadOnly);
3423*cdf0e10cSrcweir             nAttributes |= Attribute_OwnWrite;
3424*cdf0e10cSrcweir 
3425*cdf0e10cSrcweir             bResult = ( osl::File::setAttributes( aURL, nAttributes ) == ::osl::FileBase::E_None );
3426*cdf0e10cSrcweir         }
3427*cdf0e10cSrcweir     }
3428*cdf0e10cSrcweir 
3429*cdf0e10cSrcweir     return bResult;
3430*cdf0e10cSrcweir }
3431*cdf0e10cSrcweir 
3432*cdf0e10cSrcweir //----------------------------------------------------------------
3433*cdf0e10cSrcweir void SfxMedium::CreateTempFile( sal_Bool bReplace )
3434*cdf0e10cSrcweir {
3435*cdf0e10cSrcweir     if ( pImp->pTempFile )
3436*cdf0e10cSrcweir 	{
3437*cdf0e10cSrcweir         if ( !bReplace )
3438*cdf0e10cSrcweir             return;
3439*cdf0e10cSrcweir 
3440*cdf0e10cSrcweir         DELETEZ( pImp->pTempFile );
3441*cdf0e10cSrcweir 		aName = String();
3442*cdf0e10cSrcweir 	}
3443*cdf0e10cSrcweir 
3444*cdf0e10cSrcweir     pImp->pTempFile = new ::utl::TempFile();
3445*cdf0e10cSrcweir     pImp->pTempFile->EnableKillingFile( sal_True );
3446*cdf0e10cSrcweir     aName = pImp->pTempFile->GetFileName();
3447*cdf0e10cSrcweir     ::rtl::OUString aTmpURL = pImp->pTempFile->GetURL();
3448*cdf0e10cSrcweir     if ( !aName.Len() || !aTmpURL.getLength() )
3449*cdf0e10cSrcweir     {
3450*cdf0e10cSrcweir         SetError( ERRCODE_IO_CANTWRITE, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
3451*cdf0e10cSrcweir         return;
3452*cdf0e10cSrcweir     }
3453*cdf0e10cSrcweir 
3454*cdf0e10cSrcweir     if ( !( nStorOpenMode & STREAM_TRUNC ) )
3455*cdf0e10cSrcweir     {
3456*cdf0e10cSrcweir         sal_Bool bTransferSuccess = sal_False;
3457*cdf0e10cSrcweir 
3458*cdf0e10cSrcweir         if ( GetContent().is()
3459*cdf0e10cSrcweir           && ::utl::LocalFileHelper::IsLocalFile( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) )
3460*cdf0e10cSrcweir           && ::utl::UCBContentHelper::IsDocument( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ) )
3461*cdf0e10cSrcweir         {
3462*cdf0e10cSrcweir             // if there is already such a document, we should copy it
3463*cdf0e10cSrcweir             // if it is a file system use OS copy process
3464*cdf0e10cSrcweir             try
3465*cdf0e10cSrcweir             {
3466*cdf0e10cSrcweir                 uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > xComEnv;
3467*cdf0e10cSrcweir                 INetURLObject aTmpURLObj( aTmpURL );
3468*cdf0e10cSrcweir                 ::rtl::OUString aFileName = aTmpURLObj.getName( INetURLObject::LAST_SEGMENT,
3469*cdf0e10cSrcweir                                                                 true,
3470*cdf0e10cSrcweir                                                                 INetURLObject::DECODE_WITH_CHARSET );
3471*cdf0e10cSrcweir                 if ( aFileName.getLength() && aTmpURLObj.removeSegment() )
3472*cdf0e10cSrcweir                 {
3473*cdf0e10cSrcweir                     ::ucbhelper::Content aTargetContent( aTmpURLObj.GetMainURL( INetURLObject::NO_DECODE ), xComEnv );
3474*cdf0e10cSrcweir                     if ( aTargetContent.transferContent( pImp->aContent, ::ucbhelper::InsertOperation_COPY, aFileName, NameClash::OVERWRITE ) )
3475*cdf0e10cSrcweir                     {
3476*cdf0e10cSrcweir                         SetWritableForUserOnly( aTmpURL );
3477*cdf0e10cSrcweir                         bTransferSuccess = sal_True;
3478*cdf0e10cSrcweir                     }
3479*cdf0e10cSrcweir                 }
3480*cdf0e10cSrcweir             }
3481*cdf0e10cSrcweir             catch( uno::Exception& )
3482*cdf0e10cSrcweir             {}
3483*cdf0e10cSrcweir 
3484*cdf0e10cSrcweir             if ( bTransferSuccess )
3485*cdf0e10cSrcweir             {
3486*cdf0e10cSrcweir                 CloseOutStream();
3487*cdf0e10cSrcweir                 CloseInStream();
3488*cdf0e10cSrcweir             }
3489*cdf0e10cSrcweir         }
3490*cdf0e10cSrcweir 
3491*cdf0e10cSrcweir         if ( !bTransferSuccess && pInStream )
3492*cdf0e10cSrcweir         {
3493*cdf0e10cSrcweir             // the case when there is no URL-access available or this is a remote protocoll
3494*cdf0e10cSrcweir             // but there is an input stream
3495*cdf0e10cSrcweir             GetOutStream();
3496*cdf0e10cSrcweir             if ( pOutStream )
3497*cdf0e10cSrcweir             {
3498*cdf0e10cSrcweir                 char        *pBuf = new char [8192];
3499*cdf0e10cSrcweir                 sal_uInt32   nErr = ERRCODE_NONE;
3500*cdf0e10cSrcweir 
3501*cdf0e10cSrcweir                 pInStream->Seek(0);
3502*cdf0e10cSrcweir                 pOutStream->Seek(0);
3503*cdf0e10cSrcweir 
3504*cdf0e10cSrcweir                 while( !pInStream->IsEof() && nErr == ERRCODE_NONE )
3505*cdf0e10cSrcweir                 {
3506*cdf0e10cSrcweir                     sal_uInt32 nRead = pInStream->Read( pBuf, 8192 );
3507*cdf0e10cSrcweir                     nErr = pInStream->GetError();
3508*cdf0e10cSrcweir                     pOutStream->Write( pBuf, nRead );
3509*cdf0e10cSrcweir                 }
3510*cdf0e10cSrcweir 
3511*cdf0e10cSrcweir                 bTransferSuccess = sal_True;
3512*cdf0e10cSrcweir                 delete[] pBuf;
3513*cdf0e10cSrcweir                 CloseInStream();
3514*cdf0e10cSrcweir             }
3515*cdf0e10cSrcweir             CloseOutStream_Impl();
3516*cdf0e10cSrcweir         }
3517*cdf0e10cSrcweir         else
3518*cdf0e10cSrcweir         {
3519*cdf0e10cSrcweir             // Quite strange design, but currently it is expected that in this case no transfer happens
3520*cdf0e10cSrcweir             // TODO/LATER: get rid of this inconsistent part of the call design
3521*cdf0e10cSrcweir             bTransferSuccess = sal_True;
3522*cdf0e10cSrcweir             CloseInStream();
3523*cdf0e10cSrcweir         }
3524*cdf0e10cSrcweir 
3525*cdf0e10cSrcweir         if ( !bTransferSuccess )
3526*cdf0e10cSrcweir         {
3527*cdf0e10cSrcweir             SetError( ERRCODE_IO_CANTWRITE, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
3528*cdf0e10cSrcweir             return;
3529*cdf0e10cSrcweir         }
3530*cdf0e10cSrcweir     }
3531*cdf0e10cSrcweir 
3532*cdf0e10cSrcweir     CloseStorage();
3533*cdf0e10cSrcweir }
3534*cdf0e10cSrcweir 
3535*cdf0e10cSrcweir //----------------------------------------------------------------
3536*cdf0e10cSrcweir void SfxMedium::CreateTempFileNoCopy()
3537*cdf0e10cSrcweir {
3538*cdf0e10cSrcweir     // this call always replaces the existing temporary file
3539*cdf0e10cSrcweir     if ( pImp->pTempFile )
3540*cdf0e10cSrcweir         delete pImp->pTempFile;
3541*cdf0e10cSrcweir 
3542*cdf0e10cSrcweir     pImp->pTempFile = new ::utl::TempFile();
3543*cdf0e10cSrcweir     pImp->pTempFile->EnableKillingFile( sal_True );
3544*cdf0e10cSrcweir     aName = pImp->pTempFile->GetFileName();
3545*cdf0e10cSrcweir     if ( !aName.Len() )
3546*cdf0e10cSrcweir     {
3547*cdf0e10cSrcweir         SetError( ERRCODE_IO_CANTWRITE, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
3548*cdf0e10cSrcweir         return;
3549*cdf0e10cSrcweir     }
3550*cdf0e10cSrcweir 
3551*cdf0e10cSrcweir     CloseOutStream_Impl();
3552*cdf0e10cSrcweir     CloseStorage();
3553*cdf0e10cSrcweir }
3554*cdf0e10cSrcweir 
3555*cdf0e10cSrcweir ::rtl::OUString SfxMedium::GetCharset()
3556*cdf0e10cSrcweir {
3557*cdf0e10cSrcweir     if( !pImp->bIsCharsetInitialized )
3558*cdf0e10cSrcweir 	{
3559*cdf0e10cSrcweir 		// Set an error in case there is no content?
3560*cdf0e10cSrcweir 		if ( GetContent().is() )
3561*cdf0e10cSrcweir 		{
3562*cdf0e10cSrcweir 			pImp->bIsCharsetInitialized = sal_True;
3563*cdf0e10cSrcweir 
3564*cdf0e10cSrcweir 			try
3565*cdf0e10cSrcweir 			{
3566*cdf0e10cSrcweir 				Any aAny = pImp->aContent.getPropertyValue( ::rtl::OUString::createFromAscii( "MediaType" ) );
3567*cdf0e10cSrcweir 				::rtl::OUString aField;
3568*cdf0e10cSrcweir 				aAny >>= aField;
3569*cdf0e10cSrcweir 
3570*cdf0e10cSrcweir 				::rtl::OString sContent = ::rtl::OUStringToOString( aField, RTL_TEXTENCODING_ASCII_US );
3571*cdf0e10cSrcweir 				ByteString sType, sSubType;
3572*cdf0e10cSrcweir 				INetContentTypeParameterList aParameters;
3573*cdf0e10cSrcweir 
3574*cdf0e10cSrcweir 				if( INetContentTypes::parse( sContent, sType, sSubType, &aParameters ) )
3575*cdf0e10cSrcweir 				{
3576*cdf0e10cSrcweir 					const INetContentTypeParameter * pCharset = aParameters.find("charset");
3577*cdf0e10cSrcweir 					if (pCharset != 0)
3578*cdf0e10cSrcweir 						pImp->aCharset = pCharset->m_sValue;
3579*cdf0e10cSrcweir 				}
3580*cdf0e10cSrcweir 			}
3581*cdf0e10cSrcweir 			catch ( ::com::sun::star::uno::Exception& )
3582*cdf0e10cSrcweir 			{
3583*cdf0e10cSrcweir 			}
3584*cdf0e10cSrcweir 		}
3585*cdf0e10cSrcweir 	}
3586*cdf0e10cSrcweir 
3587*cdf0e10cSrcweir 	return pImp->aCharset;
3588*cdf0e10cSrcweir }
3589*cdf0e10cSrcweir 
3590*cdf0e10cSrcweir void SfxMedium::SetCharset( ::rtl::OUString aChs )
3591*cdf0e10cSrcweir {
3592*cdf0e10cSrcweir 	pImp->bIsCharsetInitialized = sal_True;
3593*cdf0e10cSrcweir 	pImp->aCharset = aChs;
3594*cdf0e10cSrcweir }
3595*cdf0e10cSrcweir 
3596*cdf0e10cSrcweir sal_Bool SfxMedium::SignContents_Impl( sal_Bool bScriptingContent, const ::rtl::OUString& aODFVersion, sal_Bool bHasValidDocumentSignature )
3597*cdf0e10cSrcweir {
3598*cdf0e10cSrcweir     sal_Bool bChanges = sal_False;
3599*cdf0e10cSrcweir 
3600*cdf0e10cSrcweir     // the medium should be closed to be able to sign, the caller is responsible to close it
3601*cdf0e10cSrcweir     if ( !IsOpen() && !GetError() )
3602*cdf0e10cSrcweir     {
3603*cdf0e10cSrcweir         // The component should know if there was a valid document signature, since
3604*cdf0e10cSrcweir         // it should show a warning in this case
3605*cdf0e10cSrcweir         uno::Sequence< uno::Any > aArgs( 2 );
3606*cdf0e10cSrcweir         aArgs[0] <<= aODFVersion;
3607*cdf0e10cSrcweir         aArgs[1] <<= bHasValidDocumentSignature;
3608*cdf0e10cSrcweir         ::com::sun::star::uno::Reference< ::com::sun::star::security::XDocumentDigitalSignatures > xSigner(
3609*cdf0e10cSrcweir             comphelper::getProcessServiceFactory()->createInstanceWithArguments(
3610*cdf0e10cSrcweir                 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.security.DocumentDigitalSignatures" ) ),
3611*cdf0e10cSrcweir                 aArgs ),
3612*cdf0e10cSrcweir             ::com::sun::star::uno::UNO_QUERY );
3613*cdf0e10cSrcweir 
3614*cdf0e10cSrcweir         if ( xSigner.is() )
3615*cdf0e10cSrcweir         {
3616*cdf0e10cSrcweir             uno::Reference< embed::XStorage > xWriteableZipStor;
3617*cdf0e10cSrcweir             if ( !IsReadOnly() )
3618*cdf0e10cSrcweir             {
3619*cdf0e10cSrcweir                 // we can reuse the temporary file if there is one already
3620*cdf0e10cSrcweir                 CreateTempFile( sal_False );
3621*cdf0e10cSrcweir                 GetMedium_Impl();
3622*cdf0e10cSrcweir 
3623*cdf0e10cSrcweir                 try
3624*cdf0e10cSrcweir                 {
3625*cdf0e10cSrcweir                     if ( !pImp->xStream.is() )
3626*cdf0e10cSrcweir                         throw uno::RuntimeException();
3627*cdf0e10cSrcweir 
3628*cdf0e10cSrcweir                     xWriteableZipStor = ::comphelper::OStorageHelper::GetStorageOfFormatFromStream( ZIP_STORAGE_FORMAT_STRING, pImp->xStream );
3629*cdf0e10cSrcweir                     if ( !xWriteableZipStor.is() )
3630*cdf0e10cSrcweir                         throw uno::RuntimeException();
3631*cdf0e10cSrcweir 
3632*cdf0e10cSrcweir                     uno::Reference< embed::XStorage > xMetaInf = xWriteableZipStor->openStorageElement(
3633*cdf0e10cSrcweir                                                     ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "META-INF" ) ),
3634*cdf0e10cSrcweir                                                     embed::ElementModes::READWRITE );
3635*cdf0e10cSrcweir                     if ( !xMetaInf.is() )
3636*cdf0e10cSrcweir                         throw uno::RuntimeException();
3637*cdf0e10cSrcweir 
3638*cdf0e10cSrcweir                     if ( bScriptingContent )
3639*cdf0e10cSrcweir                     {
3640*cdf0e10cSrcweir                         // If the signature has already the document signature it will be removed
3641*cdf0e10cSrcweir                         // after the scripting signature is inserted.
3642*cdf0e10cSrcweir                         uno::Reference< io::XStream > xStream(
3643*cdf0e10cSrcweir                             xMetaInf->openStreamElement( xSigner->getScriptingContentSignatureDefaultStreamName(),
3644*cdf0e10cSrcweir                                                          embed::ElementModes::READWRITE ),
3645*cdf0e10cSrcweir                             uno::UNO_SET_THROW );
3646*cdf0e10cSrcweir 
3647*cdf0e10cSrcweir                         if ( xSigner->signScriptingContent( GetZipStorageToSign_Impl(), xStream ) )
3648*cdf0e10cSrcweir                         {
3649*cdf0e10cSrcweir                             // remove the document signature if any
3650*cdf0e10cSrcweir                             ::rtl::OUString aDocSigName = xSigner->getDocumentContentSignatureDefaultStreamName();
3651*cdf0e10cSrcweir                             if ( aDocSigName.getLength() && xMetaInf->hasByName( aDocSigName ) )
3652*cdf0e10cSrcweir                                 xMetaInf->removeElement( aDocSigName );
3653*cdf0e10cSrcweir 
3654*cdf0e10cSrcweir                             uno::Reference< embed::XTransactedObject > xTransact( xMetaInf, uno::UNO_QUERY_THROW );
3655*cdf0e10cSrcweir                             xTransact->commit();
3656*cdf0e10cSrcweir                             xTransact.set( xWriteableZipStor, uno::UNO_QUERY_THROW );
3657*cdf0e10cSrcweir                             xTransact->commit();
3658*cdf0e10cSrcweir 
3659*cdf0e10cSrcweir                             // the temporary file has been written, commit it to the original file
3660*cdf0e10cSrcweir                             Commit();
3661*cdf0e10cSrcweir                             bChanges = sal_True;
3662*cdf0e10cSrcweir                         }
3663*cdf0e10cSrcweir                     }
3664*cdf0e10cSrcweir                     else
3665*cdf0e10cSrcweir                     {
3666*cdf0e10cSrcweir                          uno::Reference< io::XStream > xStream(
3667*cdf0e10cSrcweir                             xMetaInf->openStreamElement( xSigner->getDocumentContentSignatureDefaultStreamName(),
3668*cdf0e10cSrcweir                                                          embed::ElementModes::READWRITE ),
3669*cdf0e10cSrcweir                             uno::UNO_SET_THROW );
3670*cdf0e10cSrcweir 
3671*cdf0e10cSrcweir                         if ( xSigner->signDocumentContent( GetZipStorageToSign_Impl(), xStream ) )
3672*cdf0e10cSrcweir                         {
3673*cdf0e10cSrcweir                             uno::Reference< embed::XTransactedObject > xTransact( xMetaInf, uno::UNO_QUERY_THROW );
3674*cdf0e10cSrcweir                             xTransact->commit();
3675*cdf0e10cSrcweir                             xTransact.set( xWriteableZipStor, uno::UNO_QUERY_THROW );
3676*cdf0e10cSrcweir                             xTransact->commit();
3677*cdf0e10cSrcweir 
3678*cdf0e10cSrcweir                             // the temporary file has been written, commit it to the original file
3679*cdf0e10cSrcweir                             Commit();
3680*cdf0e10cSrcweir                             bChanges = sal_True;
3681*cdf0e10cSrcweir                         }
3682*cdf0e10cSrcweir                     }
3683*cdf0e10cSrcweir                 }
3684*cdf0e10cSrcweir                 catch ( uno::Exception& )
3685*cdf0e10cSrcweir                 {
3686*cdf0e10cSrcweir                     OSL_ENSURE( sal_False, "Couldn't use signing functionality!\n" );
3687*cdf0e10cSrcweir                 }
3688*cdf0e10cSrcweir 
3689*cdf0e10cSrcweir                 CloseAndRelease();
3690*cdf0e10cSrcweir             }
3691*cdf0e10cSrcweir             else
3692*cdf0e10cSrcweir             {
3693*cdf0e10cSrcweir                 try
3694*cdf0e10cSrcweir                 {
3695*cdf0e10cSrcweir                     if ( bScriptingContent )
3696*cdf0e10cSrcweir                         xSigner->showScriptingContentSignatures( GetZipStorageToSign_Impl(), uno::Reference< io::XInputStream >() );
3697*cdf0e10cSrcweir                     else
3698*cdf0e10cSrcweir                         xSigner->showDocumentContentSignatures( GetZipStorageToSign_Impl(), uno::Reference< io::XInputStream >() );
3699*cdf0e10cSrcweir                 }
3700*cdf0e10cSrcweir                 catch( uno::Exception& )
3701*cdf0e10cSrcweir                 {
3702*cdf0e10cSrcweir                     OSL_ENSURE( sal_False, "Couldn't use signing functionality!\n" );
3703*cdf0e10cSrcweir                 }
3704*cdf0e10cSrcweir             }
3705*cdf0e10cSrcweir         }
3706*cdf0e10cSrcweir 
3707*cdf0e10cSrcweir         ResetError();
3708*cdf0e10cSrcweir     }
3709*cdf0e10cSrcweir 
3710*cdf0e10cSrcweir 	return bChanges;
3711*cdf0e10cSrcweir }
3712*cdf0e10cSrcweir 
3713*cdf0e10cSrcweir //----------------------------------------------------------------
3714*cdf0e10cSrcweir sal_uInt16 SfxMedium::GetCachedSignatureState_Impl()
3715*cdf0e10cSrcweir {
3716*cdf0e10cSrcweir 	return pImp->m_nSignatureState;
3717*cdf0e10cSrcweir }
3718*cdf0e10cSrcweir 
3719*cdf0e10cSrcweir //----------------------------------------------------------------
3720*cdf0e10cSrcweir void SfxMedium::SetCachedSignatureState_Impl( sal_uInt16 nState )
3721*cdf0e10cSrcweir {
3722*cdf0e10cSrcweir 	pImp->m_nSignatureState = nState;
3723*cdf0e10cSrcweir }
3724*cdf0e10cSrcweir 
3725*cdf0e10cSrcweir sal_Bool SfxMedium::HasStorage_Impl() const
3726*cdf0e10cSrcweir {
3727*cdf0e10cSrcweir     return pImp->xStorage.is();
3728*cdf0e10cSrcweir }
3729*cdf0e10cSrcweir 
3730*cdf0e10cSrcweir sal_Bool SfxMedium::IsOpen() const
3731*cdf0e10cSrcweir {
3732*cdf0e10cSrcweir     return pInStream || pOutStream || pImp->xStorage.is();
3733*cdf0e10cSrcweir }
3734*cdf0e10cSrcweir 
3735*cdf0e10cSrcweir ::rtl::OUString SfxMedium::CreateTempCopyWithExt( const ::rtl::OUString& aURL )
3736*cdf0e10cSrcweir {
3737*cdf0e10cSrcweir 	::rtl::OUString aResult;
3738*cdf0e10cSrcweir 
3739*cdf0e10cSrcweir 	if ( aURL.getLength() )
3740*cdf0e10cSrcweir 	{
3741*cdf0e10cSrcweir 		sal_Int32 nPrefixLen = aURL.lastIndexOf( '.' );
3742*cdf0e10cSrcweir 		String aExt = ( nPrefixLen == -1 ) ? String() : String( aURL.copy( nPrefixLen ) );
3743*cdf0e10cSrcweir 
3744*cdf0e10cSrcweir 		::rtl::OUString aNewTempFileURL = ::utl::TempFile( String(), &aExt ).GetURL();
3745*cdf0e10cSrcweir 		if ( aNewTempFileURL.getLength() )
3746*cdf0e10cSrcweir 		{
3747*cdf0e10cSrcweir 			INetURLObject aSource( aURL );
3748*cdf0e10cSrcweir 			INetURLObject aDest( aNewTempFileURL );
3749*cdf0e10cSrcweir 			::rtl::OUString aFileName = aDest.getName( INetURLObject::LAST_SEGMENT,
3750*cdf0e10cSrcweir 														true,
3751*cdf0e10cSrcweir 														INetURLObject::DECODE_WITH_CHARSET );
3752*cdf0e10cSrcweir 			if ( aFileName.getLength() && aDest.removeSegment() )
3753*cdf0e10cSrcweir 			{
3754*cdf0e10cSrcweir 				try
3755*cdf0e10cSrcweir 				{
3756*cdf0e10cSrcweir 					uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > xComEnv;
3757*cdf0e10cSrcweir 					::ucbhelper::Content aTargetContent( aDest.GetMainURL( INetURLObject::NO_DECODE ), xComEnv );
3758*cdf0e10cSrcweir 					::ucbhelper::Content aSourceContent( aSource.GetMainURL( INetURLObject::NO_DECODE ), xComEnv );
3759*cdf0e10cSrcweir 					if ( aTargetContent.transferContent( aSourceContent,
3760*cdf0e10cSrcweir 														::ucbhelper::InsertOperation_COPY,
3761*cdf0e10cSrcweir 														aFileName,
3762*cdf0e10cSrcweir 														NameClash::OVERWRITE ) )
3763*cdf0e10cSrcweir 					{
3764*cdf0e10cSrcweir 						// Success
3765*cdf0e10cSrcweir 						aResult = aNewTempFileURL;
3766*cdf0e10cSrcweir 					}
3767*cdf0e10cSrcweir 				}
3768*cdf0e10cSrcweir 				catch( uno::Exception& )
3769*cdf0e10cSrcweir 				{}
3770*cdf0e10cSrcweir 			}
3771*cdf0e10cSrcweir 		}
3772*cdf0e10cSrcweir 	}
3773*cdf0e10cSrcweir 
3774*cdf0e10cSrcweir 	return aResult;
3775*cdf0e10cSrcweir }
3776*cdf0e10cSrcweir 
3777*cdf0e10cSrcweir sal_Bool SfxMedium::CallApproveHandler( const uno::Reference< task::XInteractionHandler >& xHandler, uno::Any aRequest, sal_Bool bAllowAbort )
3778*cdf0e10cSrcweir {
3779*cdf0e10cSrcweir     sal_Bool bResult = sal_False;
3780*cdf0e10cSrcweir 
3781*cdf0e10cSrcweir     if ( xHandler.is() )
3782*cdf0e10cSrcweir     {
3783*cdf0e10cSrcweir         try
3784*cdf0e10cSrcweir         {
3785*cdf0e10cSrcweir             uno::Sequence< uno::Reference< task::XInteractionContinuation > > aContinuations( bAllowAbort ? 2 : 1 );
3786*cdf0e10cSrcweir 
3787*cdf0e10cSrcweir             ::rtl::Reference< ::comphelper::OInteractionApprove > pApprove( new ::comphelper::OInteractionApprove );
3788*cdf0e10cSrcweir             aContinuations[ 0 ] = pApprove.get();
3789*cdf0e10cSrcweir 
3790*cdf0e10cSrcweir             if ( bAllowAbort )
3791*cdf0e10cSrcweir             {
3792*cdf0e10cSrcweir                 ::rtl::Reference< ::comphelper::OInteractionAbort > pAbort( new ::comphelper::OInteractionAbort );
3793*cdf0e10cSrcweir                 aContinuations[ 1 ] = pAbort.get();
3794*cdf0e10cSrcweir             }
3795*cdf0e10cSrcweir 
3796*cdf0e10cSrcweir             xHandler->handle(::framework::InteractionRequest::CreateRequest (aRequest,aContinuations));
3797*cdf0e10cSrcweir             bResult = pApprove->wasSelected();
3798*cdf0e10cSrcweir         }
3799*cdf0e10cSrcweir         catch( const Exception& )
3800*cdf0e10cSrcweir         {
3801*cdf0e10cSrcweir         }
3802*cdf0e10cSrcweir     }
3803*cdf0e10cSrcweir 
3804*cdf0e10cSrcweir     return bResult;
3805*cdf0e10cSrcweir }
3806*cdf0e10cSrcweir 
3807*cdf0e10cSrcweir ::rtl::OUString SfxMedium::SwitchDocumentToTempFile()
3808*cdf0e10cSrcweir {
3809*cdf0e10cSrcweir     // the method returns empty string in case of failure
3810*cdf0e10cSrcweir     ::rtl::OUString aResult;
3811*cdf0e10cSrcweir     ::rtl::OUString aOrigURL = aLogicName;
3812*cdf0e10cSrcweir 
3813*cdf0e10cSrcweir     if ( aOrigURL.getLength() )
3814*cdf0e10cSrcweir     {
3815*cdf0e10cSrcweir 		sal_Int32 nPrefixLen = aOrigURL.lastIndexOf( '.' );
3816*cdf0e10cSrcweir 		String aExt = ( nPrefixLen == -1 ) ? String() : String( aOrigURL.copy( nPrefixLen ) );
3817*cdf0e10cSrcweir 		::rtl::OUString aNewURL = ::utl::TempFile( String(), &aExt ).GetURL();
3818*cdf0e10cSrcweir 
3819*cdf0e10cSrcweir         // TODO/LATER: In future the aLogicName should be set to shared folder URL
3820*cdf0e10cSrcweir         //             and a temporary file should be created. Transport_Impl should be impossible then.
3821*cdf0e10cSrcweir         if ( aNewURL.getLength() )
3822*cdf0e10cSrcweir         {
3823*cdf0e10cSrcweir             uno::Reference< embed::XStorage > xStorage = GetStorage();
3824*cdf0e10cSrcweir             uno::Reference< embed::XOptimizedStorage > xOptStorage( xStorage, uno::UNO_QUERY );
3825*cdf0e10cSrcweir 
3826*cdf0e10cSrcweir             if ( xOptStorage.is() )
3827*cdf0e10cSrcweir             {
3828*cdf0e10cSrcweir                 // TODO/LATER: reuse the pImp->pTempFile if it already exists
3829*cdf0e10cSrcweir 				CanDisposeStorage_Impl( sal_False );
3830*cdf0e10cSrcweir 				Close();
3831*cdf0e10cSrcweir                 SetPhysicalName_Impl( String() );
3832*cdf0e10cSrcweir                 SetName( aNewURL );
3833*cdf0e10cSrcweir 
3834*cdf0e10cSrcweir                 // remove the readonly state
3835*cdf0e10cSrcweir                 sal_Bool bWasReadonly = sal_False;
3836*cdf0e10cSrcweir                 nStorOpenMode = SFX_STREAM_READWRITE;
3837*cdf0e10cSrcweir                 SFX_ITEMSET_ARG( pSet, pReadOnlyItem, SfxBoolItem, SID_DOC_READONLY, sal_False );
3838*cdf0e10cSrcweir                 if ( pReadOnlyItem && pReadOnlyItem->GetValue() )
3839*cdf0e10cSrcweir                     bWasReadonly = sal_True;
3840*cdf0e10cSrcweir 				GetItemSet()->ClearItem( SID_DOC_READONLY );
3841*cdf0e10cSrcweir 
3842*cdf0e10cSrcweir                 GetMedium_Impl();
3843*cdf0e10cSrcweir 				LockOrigFileOnDemand( sal_False, sal_False );
3844*cdf0e10cSrcweir 				CreateTempFile( sal_True );
3845*cdf0e10cSrcweir 				GetMedium_Impl();
3846*cdf0e10cSrcweir 
3847*cdf0e10cSrcweir                 if ( pImp->xStream.is() )
3848*cdf0e10cSrcweir                 {
3849*cdf0e10cSrcweir                     try
3850*cdf0e10cSrcweir                     {
3851*cdf0e10cSrcweir                         xOptStorage->writeAndAttachToStream( pImp->xStream );
3852*cdf0e10cSrcweir                         pImp->xStorage = xStorage;
3853*cdf0e10cSrcweir                         aResult = aNewURL;
3854*cdf0e10cSrcweir                     }
3855*cdf0e10cSrcweir                     catch( uno::Exception& )
3856*cdf0e10cSrcweir                     {}
3857*cdf0e10cSrcweir                 }
3858*cdf0e10cSrcweir 
3859*cdf0e10cSrcweir                 if ( !aResult.getLength() )
3860*cdf0e10cSrcweir                 {
3861*cdf0e10cSrcweir                     Close();
3862*cdf0e10cSrcweir                     SetPhysicalName_Impl( String() );
3863*cdf0e10cSrcweir                     SetName( aOrigURL );
3864*cdf0e10cSrcweir                     if ( bWasReadonly )
3865*cdf0e10cSrcweir                     {
3866*cdf0e10cSrcweir                         // set the readonly state back
3867*cdf0e10cSrcweir                         nStorOpenMode = SFX_STREAM_READONLY;
3868*cdf0e10cSrcweir 						GetItemSet()->Put( SfxBoolItem(SID_DOC_READONLY, sal_True));
3869*cdf0e10cSrcweir                     }
3870*cdf0e10cSrcweir                     GetMedium_Impl();
3871*cdf0e10cSrcweir                     pImp->xStorage = xStorage;
3872*cdf0e10cSrcweir                 }
3873*cdf0e10cSrcweir             }
3874*cdf0e10cSrcweir         }
3875*cdf0e10cSrcweir     }
3876*cdf0e10cSrcweir 
3877*cdf0e10cSrcweir     return aResult;
3878*cdf0e10cSrcweir }
3879*cdf0e10cSrcweir 
3880*cdf0e10cSrcweir sal_Bool SfxMedium::SwitchDocumentToFile( ::rtl::OUString aURL )
3881*cdf0e10cSrcweir {
3882*cdf0e10cSrcweir     // the method is only for storage based documents
3883*cdf0e10cSrcweir     sal_Bool bResult = sal_False;
3884*cdf0e10cSrcweir     ::rtl::OUString aOrigURL = aLogicName;
3885*cdf0e10cSrcweir 
3886*cdf0e10cSrcweir     if ( aURL.getLength() && aOrigURL.getLength() )
3887*cdf0e10cSrcweir     {
3888*cdf0e10cSrcweir         uno::Reference< embed::XStorage > xStorage = GetStorage();
3889*cdf0e10cSrcweir         uno::Reference< embed::XOptimizedStorage > xOptStorage( xStorage, uno::UNO_QUERY );
3890*cdf0e10cSrcweir 
3891*cdf0e10cSrcweir         if ( xOptStorage.is() )
3892*cdf0e10cSrcweir         {
3893*cdf0e10cSrcweir             // TODO/LATER: reuse the pImp->pTempFile if it already exists
3894*cdf0e10cSrcweir             CanDisposeStorage_Impl( sal_False );
3895*cdf0e10cSrcweir             Close();
3896*cdf0e10cSrcweir             SetPhysicalName_Impl( String() );
3897*cdf0e10cSrcweir             SetName( aURL );
3898*cdf0e10cSrcweir 
3899*cdf0e10cSrcweir             // open the temporary file based document
3900*cdf0e10cSrcweir             GetMedium_Impl();
3901*cdf0e10cSrcweir             LockOrigFileOnDemand( sal_False, sal_False );
3902*cdf0e10cSrcweir             CreateTempFile( sal_True );
3903*cdf0e10cSrcweir             GetMedium_Impl();
3904*cdf0e10cSrcweir 
3905*cdf0e10cSrcweir             if ( pImp->xStream.is() )
3906*cdf0e10cSrcweir             {
3907*cdf0e10cSrcweir                 try
3908*cdf0e10cSrcweir                 {
3909*cdf0e10cSrcweir                     uno::Reference< io::XTruncate > xTruncate( pImp->xStream, uno::UNO_QUERY_THROW );
3910*cdf0e10cSrcweir                     if ( xTruncate.is() )
3911*cdf0e10cSrcweir                         xTruncate->truncate();
3912*cdf0e10cSrcweir 
3913*cdf0e10cSrcweir                     xOptStorage->writeAndAttachToStream( pImp->xStream );
3914*cdf0e10cSrcweir                     pImp->xStorage = xStorage;
3915*cdf0e10cSrcweir                     bResult = sal_True;
3916*cdf0e10cSrcweir                 }
3917*cdf0e10cSrcweir                 catch( uno::Exception& )
3918*cdf0e10cSrcweir                 {}
3919*cdf0e10cSrcweir             }
3920*cdf0e10cSrcweir 
3921*cdf0e10cSrcweir             if ( !bResult )
3922*cdf0e10cSrcweir             {
3923*cdf0e10cSrcweir                 Close();
3924*cdf0e10cSrcweir                 SetPhysicalName_Impl( String() );
3925*cdf0e10cSrcweir                 SetName( aOrigURL );
3926*cdf0e10cSrcweir                 GetMedium_Impl();
3927*cdf0e10cSrcweir                 pImp->xStorage = xStorage;
3928*cdf0e10cSrcweir             }
3929*cdf0e10cSrcweir         }
3930*cdf0e10cSrcweir     }
3931*cdf0e10cSrcweir 
3932*cdf0e10cSrcweir     return bResult;
3933*cdf0e10cSrcweir }
3934*cdf0e10cSrcweir 
3935