1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: docfile.cxx,v $
10 * $Revision: 1.203.50.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sfx2.hxx"
33 #include <sfx2/docfile.hxx>
34 #include "sfx2/signaturestate.hxx"
36 #include <uno/mapping.hxx>
37 #include <com/sun/star/task/XInteractionHandler.hpp>
38 #include <com/sun/star/uno/Reference.h>
39 #include <com/sun/star/ucb/XContent.hpp>
40 #include <com/sun/star/document/XDocumentRevisionListPersistence.hpp>
41 #include <com/sun/star/document/LockedDocumentRequest.hpp>
42 #include <com/sun/star/document/OwnLockOnDocumentRequest.hpp>
43 #include <com/sun/star/document/LockedOnSavingRequest.hpp>
44 #include <com/sun/star/document/LockFileIgnoreRequest.hpp>
45 #include <com/sun/star/document/ChangedByOthersRequest.hpp>
46 #include <com/sun/star/beans/XPropertySet.hpp>
47 #include <com/sun/star/embed/XTransactedObject.hpp>
48 #include <com/sun/star/embed/ElementModes.hpp>
49 #include <com/sun/star/embed/UseBackupException.hpp>
50 #include <com/sun/star/embed/XOptimizedStorage.hpp>
51 #include <com/sun/star/ucb/InteractiveIOException.hpp>
52 #include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
53 #include <com/sun/star/ucb/CommandFailedException.hpp>
54 #include <com/sun/star/ucb/CommandAbortedException.hpp>
55 #include <com/sun/star/ucb/XCommandEnvironment.hpp>
56 #include <com/sun/star/ucb/XContentIdentifierFactory.hpp>
57 #include <com/sun/star/ucb/XContentProvider.hpp>
58 #include <com/sun/star/ucb/XProgressHandler.hpp>
59 #include <com/sun/star/ucb/XCommandInfo.hpp>
60 #include <com/sun/star/util/XArchiver.hpp>
61 #include <com/sun/star/io/XOutputStream.hpp>
62 #include <com/sun/star/io/XInputStream.hpp>
63 #include <com/sun/star/io/XTruncate.hpp>
64 #include <com/sun/star/io/XStreamListener.hpp>
65 #include <com/sun/star/io/XSeekable.hpp>
66 #include <com/sun/star/ucb/XSimpleFileAccess.hpp>
67 #include <com/sun/star/lang/XInitialization.hpp>
68 #include <com/sun/star/ucb/InsertCommandArgument.hpp>
69 #include <com/sun/star/ucb/NameClash.hpp>
70 #include <com/sun/star/ucb/TransferInfo.hpp>
71 #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
72 #include <com/sun/star/ucb/OpenMode.hpp>
73 #include <com/sun/star/ucb/NameClashException.hpp>
74 #include <com/sun/star/logging/XSimpleLogRing.hpp>
75 #include <cppuhelper/implbase1.hxx>
76 #include <com/sun/star/beans/PropertyValue.hpp>
77 #ifndef _COM_SUN_STAR_SECURITY_DOCUMENTSIGNATURESINFORMATION_HPP_
78 #include <com/sun/star/security/DocumentSignatureInformation.hpp>
80 #include <com/sun/star/security/XDocumentDigitalSignatures.hpp>
81 #include <tools/zcodec.hxx>
82 #include <tools/cachestr.hxx>
83 #include <tools/urlobj.hxx>
84 #include <unotools/tempfile.hxx>
85 #include <comphelper/processfactory.hxx>
86 #include <comphelper/componentcontext.hxx>
87 #include <unotools/streamhelper.hxx>
88 #include <unotools/localedatawrapper.hxx>
89 #ifndef _MSGBOX_HXX //autogen
90 #include <vcl/msgbox.hxx>
92 #include <svtools/stritem.hxx>
93 #include <svtools/eitem.hxx>
94 #include <svtools/lckbitem.hxx>
95 #include <svtools/sfxecode.hxx>
96 #include <svtools/itemset.hxx>
97 #include <svtools/intitem.hxx>
98 #include <svtools/svparser.hxx> // SvKeyValue
99 #include <cppuhelper/weakref.hxx>
100 #include <cppuhelper/implbase1.hxx>
102 #define _SVSTDARR_ULONGS
103 #define _SVSTDARR_STRINGSDTOR
104 #include <svtools/svstdarr.hxx>
106 #include <unotools/streamwrap.hxx>
108 #include <rtl/logfile.hxx>
110 using namespace ::com::sun::star
;
111 using namespace ::com::sun::star::uno
;
112 using namespace ::com::sun::star::ucb
;
113 using namespace ::com::sun::star::beans
;
114 using namespace ::com::sun::star::io
;
116 #include <comphelper/storagehelper.hxx>
117 #include <comphelper/mediadescriptor.hxx>
118 #include <comphelper/configurationhelper.hxx>
119 #include <tools/urlobj.hxx>
120 #include <tools/inetmime.hxx>
121 #include <unotools/ucblockbytes.hxx>
122 #include <svtools/pathoptions.hxx>
123 #include <svtools/asynclink.hxx>
124 #include <svtools/inettype.hxx>
125 #include <ucbhelper/contentbroker.hxx>
126 #include <ucbhelper/commandenvironment.hxx>
127 #include <unotools/localfilehelper.hxx>
128 #include <unotools/ucbstreamhelper.hxx>
129 #include <unotools/ucbhelper.hxx>
130 #include <unotools/progresshandlerwrap.hxx>
131 #include <ucbhelper/content.hxx>
132 #include <ucbhelper/interactionrequest.hxx>
133 #include <sot/stg.hxx>
134 #include <svtools/saveopt.hxx>
135 #include <svtools/documentlockfile.hxx>
137 #include "opostponedtruncationstream.hxx"
138 #include "helper.hxx"
139 #include <sfx2/request.hxx> // SFX_ITEMSET_SET
140 #include <sfx2/app.hxx> // GetFilterMatcher
141 #include <sfx2/frame.hxx> // LoadTargetFrame
142 #include "fltfnc.hxx" // SfxFilterMatcher
143 #include <sfx2/docfilt.hxx> // SfxFilter
144 #include <sfx2/objsh.hxx> // CheckOpenMode
145 #include <sfx2/docfac.hxx> // GetFilterContainer
147 #include "openflag.hxx" // SFX_STREAM_READONLY etc.
148 #include "sfxresid.hxx"
149 #include <sfx2/appuno.hxx>
151 //#include "xmlversion.hxx"
153 #define MAX_REDIRECT 5
156 //==========================================================
159 static const sal_Int8 LOCK_UI_NOLOCK
= 0;
160 static const sal_Int8 LOCK_UI_SUCCEEDED
= 1;
161 static const sal_Int8 LOCK_UI_TRY
= 2;
163 //----------------------------------------------------------------
164 sal_Bool
IsSystemFileLockingUsed()
166 // check whether system file locking has been used, the default value is false
167 sal_Bool bUseSystemLock
= sal_False
;
171 uno::Reference
< uno::XInterface
> xCommonConfig
= ::comphelper::ConfigurationHelper::openConfig(
172 ::comphelper::getProcessServiceFactory(),
173 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Common" ) ),
174 ::comphelper::ConfigurationHelper::E_STANDARD
);
175 if ( !xCommonConfig
.is() )
176 throw uno::RuntimeException();
178 ::comphelper::ConfigurationHelper::readRelativeKey(
180 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Misc/" ) ),
181 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UseDocumentSystemFileLocking" ) ) ) >>= bUseSystemLock
;
183 catch( const uno::Exception
& )
187 return bUseSystemLock
;
190 //----------------------------------------------------------------
191 sal_Bool
IsOOoLockFileUsed()
193 // check whether system file locking has been used, the default value is false
194 sal_Bool bOOoLockFileUsed
= sal_False
;
198 uno::Reference
< uno::XInterface
> xCommonConfig
= ::comphelper::ConfigurationHelper::openConfig(
199 ::comphelper::getProcessServiceFactory(),
200 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Common" ) ),
201 ::comphelper::ConfigurationHelper::E_STANDARD
);
202 if ( !xCommonConfig
.is() )
203 throw uno::RuntimeException();
205 ::comphelper::ConfigurationHelper::readRelativeKey(
207 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Misc/" ) ),
208 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UseDocumentOOoLockFile" ) ) ) >>= bOOoLockFileUsed
;
210 catch( const uno::Exception
& )
214 return bOOoLockFileUsed
;
217 } // anonymous namespace
218 //==========================================================
221 //----------------------------------------------------------------
222 class SfxMediumHandler_Impl
: public ::cppu::WeakImplHelper1
< com::sun::star::task::XInteractionHandler
>
224 com::sun::star::uno::Reference
< com::sun::star::task::XInteractionHandler
> m_xInter
;
227 virtual void SAL_CALL
handle( const com::sun::star::uno::Reference
< com::sun::star::task::XInteractionRequest
>& xRequest
)
228 throw( com::sun::star::uno::RuntimeException
);
230 SfxMediumHandler_Impl( com::sun::star::uno::Reference
< com::sun::star::task::XInteractionHandler
> xInteraction
)
231 : m_xInter( xInteraction
)
234 ~SfxMediumHandler_Impl();
237 //----------------------------------------------------------------
238 SfxMediumHandler_Impl::~SfxMediumHandler_Impl()
242 //----------------------------------------------------------------
243 void SAL_CALL
SfxMediumHandler_Impl::handle( const com::sun::star::uno::Reference
< com::sun::star::task::XInteractionRequest
>& xRequest
)
244 throw( com::sun::star::uno::RuntimeException
)
249 com::sun::star::uno::Any aRequest
= xRequest
->getRequest();
250 com::sun::star::ucb::InteractiveIOException aIoException
;
251 com::sun::star::ucb::UnsupportedDataSinkException aSinkException
;
252 if ( (aRequest
>>= aIoException
) && ( aIoException
.Code
== IOErrorCode_ACCESS_DENIED
|| aIoException
.Code
== IOErrorCode_LOCKING_VIOLATION
) )
255 if ( aRequest
>>= aSinkException
)
258 m_xInter
->handle( xRequest
);
261 //----------------------------------------------------------------
262 class SfxPoolCancelManager_Impl
: public SfxCancelManager
,
263 public SfxCancellable
,
267 SfxCancelManagerWeak wParent
;
269 ~SfxPoolCancelManager_Impl();
271 SfxPoolCancelManager_Impl( SfxCancelManager
* pParent
, const String
& rName
);
273 virtual void Notify( SfxBroadcaster
& rBC
, const SfxHint
& rHint
);
274 using SfxCancelManager::Cancel
;
275 virtual void Cancel();
278 //----------------------------------------------------------------
279 SV_DECL_IMPL_REF( SfxPoolCancelManager_Impl
)
282 //----------------------------------------------------------------
283 SfxPoolCancelManager_Impl::SfxPoolCancelManager_Impl( SfxCancelManager
* pParent
, const String
& rName
)
284 : SfxCancelManager( pParent
),
285 SfxCancellable( pParent
? pParent
: this, rName
),
290 StartListening( *this );
295 //----------------------------------------------------------------
296 SfxPoolCancelManager_Impl::~SfxPoolCancelManager_Impl()
298 for( sal_uInt16 nPos
= GetCancellableCount(); nPos
--; )
300 // nicht an Parent uebernehmen!
301 SfxCancellable
* pCbl
= GetCancellable( nPos
);
303 pCbl
->SetManager( 0 );
308 //----------------------------------------------------------------
309 void SfxPoolCancelManager_Impl::Notify( SfxBroadcaster
& /*rBC*/, const SfxHint
& /*rHint*/ )
311 if( !GetCancellableCount() ) SetManager( 0 );
312 else if( !GetManager() )
314 if( !wParent
.Is() ) wParent
= SFX_APP()->GetCancelManager();
315 SetManager( wParent
);
319 //----------------------------------------------------------------
320 void SfxPoolCancelManager_Impl::Cancel()
322 SfxPoolCancelManager_ImplRef xThis
= this;
323 for( sal_uInt16 nPos
= GetCancellableCount(); nPos
--; )
325 SfxCancellable
* pCbl
= GetCancellable( nPos
);
326 // Wenn wir nicht im Button stehen
327 if( pCbl
&& pCbl
!= this )
329 if( GetCancellableCount() < nPos
)
330 nPos
= GetCancellableCount();
334 //----------------------------------------------------------------
335 class SfxMedium_Impl
: public SvCompatWeakBase
338 ::ucbhelper::Content aContent
;
339 sal_Bool bUpdatePickList
: 1;
340 sal_Bool bIsTemp
: 1;
341 sal_Bool bForceSynchron
: 1;
342 sal_Bool bDontCreateCancellable
: 1;
343 sal_Bool bDownloadDone
: 1;
344 sal_Bool bDontCallDoneLinkOnSharingError
: 1;
345 sal_Bool bIsStorage
: 1;
346 sal_Bool bUseInteractionHandler
: 1;
347 sal_Bool bAllowDefaultIntHdl
: 1;
348 sal_Bool bIsCharsetInitialized
: 1;
349 sal_Bool bDisposeStorage
: 1;
350 sal_Bool bStorageBasedOnInStream
: 1;
351 sal_Bool m_bSalvageMode
: 1;
352 sal_Bool m_bVersionsAlreadyLoaded
: 1;
353 sal_Bool m_bLocked
: 1;
354 sal_Bool m_bGotDateTime
: 1;
356 uno::Reference
< embed::XStorage
> xStorage
;
358 SfxPoolCancelManager_ImplRef xCancelManager
;
359 SfxMedium
* pAntiImpl
;
363 const SfxFilter
* pOrigFilter
;
365 String aPreRedirectionURL
;
367 DateTime aExpireTime
;
368 SfxFrameWeak wLoadTargetFrame
;
369 SvKeyValueIteratorRef xAttributes
;
371 svtools::AsynchronLink aDoneLink
;
372 svtools::AsynchronLink aAvailableLink
;
374 uno::Sequence
< util::RevisionTag
> aVersions
;
376 ::utl::TempFile
* pTempDir
;
377 ::utl::TempFile
* pTempFile
;
379 uno::Reference
< embed::XStorage
> m_xReadStorage
;
380 Reference
< XInputStream
> xInputStream
;
381 Reference
< XStream
> xStream
;
383 sal_uInt32 nLastStorageError
;
384 ::rtl::OUString aCharset
;
386 ::com::sun::star::uno::Reference
< ::com::sun::star::task::XInteractionHandler
> xInteraction
;
388 sal_Bool m_bRemoveBackup
;
389 ::rtl::OUString m_aBackupURL
;
391 // the following member is changed and makes sence only during saving
392 // TODO/LATER: in future the signature state should be controlled by the medium not by the document
393 // in this case the member will hold this information
394 sal_uInt16 m_nSignatureState
;
396 util::DateTime m_aDateTime
;
398 uno::Reference
< logging::XSimpleLogRing
> m_xLogRing
;
400 SfxPoolCancelManager_Impl
* GetCancelManager();
402 SfxMedium_Impl( SfxMedium
* pAntiImplP
);
406 void SfxMedium::DataAvailable_Impl()
408 pImp
->aAvailableLink
.ClearPendingCall();
409 pImp
->aAvailableLink
.Call( NULL
);
412 void SfxMedium::Cancel_Impl()
414 SetError( ERRCODE_IO_GENERAL
, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
) ) );
417 SfxPoolCancelManager_Impl
* SfxMedium_Impl::GetCancelManager()
419 if( !xCancelManager
.Is() )
421 if( !bDontCreateCancellable
)
422 xCancelManager
= new SfxPoolCancelManager_Impl(
423 wLoadTargetFrame
? wLoadTargetFrame
->GetCancelManager() :
424 SFX_APP()->GetCancelManager(),
425 pAntiImpl
->GetURLObject().GetURLNoPass() );
427 xCancelManager
= new SfxPoolCancelManager_Impl(
428 0, pAntiImpl
->GetURLObject().GetURLNoPass() );
430 return xCancelManager
;
433 //------------------------------------------------------------------
434 SfxMedium_Impl::SfxMedium_Impl( SfxMedium
* pAntiImplP
)
435 : SvCompatWeakBase( pAntiImplP
),
436 bUpdatePickList(sal_True
),
437 bIsTemp( sal_False
),
438 bForceSynchron( sal_False
),
439 bDontCreateCancellable( sal_False
),
440 bDownloadDone( sal_True
),
441 bDontCallDoneLinkOnSharingError( sal_False
),
442 bIsStorage( sal_False
),
443 bUseInteractionHandler( sal_True
),
444 bAllowDefaultIntHdl( sal_False
),
445 bIsCharsetInitialized( sal_False
),
446 bStorageBasedOnInStream( sal_False
),
447 m_bSalvageMode( sal_False
),
448 m_bVersionsAlreadyLoaded( sal_False
),
449 m_bLocked( sal_False
),
450 m_bGotDateTime( sal_False
),
451 pAntiImpl( pAntiImplP
),
454 aExpireTime( Date() + 10, Time() ),
457 nLastStorageError( 0 ),
458 m_bRemoveBackup( sal_False
),
459 m_nSignatureState( SIGNATURESTATE_NOSIGNATURES
)
461 aDoneLink
.CreateMutex();
464 //------------------------------------------------------------------
465 SfxMedium_Impl::~SfxMedium_Impl()
468 aDoneLink
.ClearPendingCall();
469 aAvailableLink
.ClearPendingCall();
478 //================================================================
480 #define IMPL_CTOR(rootVal,URLVal) \
481 eError( SVSTREAM_OK ), \
483 bDirect( sal_False ), \
485 bSetFilter( sal_False ), \
486 bTriedStorage( sal_False ), \
488 nStorOpenMode( SFX_STREAM_READWRITE ), \
493 //------------------------------------------------------------------
495 const SvGlobalName& SfxMedium::GetClassFilter()
500 if( !bSetFilter && GetStorage() )
501 SetClassFilter( GetStorage()->GetClassName() );
505 //------------------------------------------------------------------
506 void SfxMedium::ResetError()
508 eError
= SVSTREAM_OK
;
510 pInStream
->ResetError();
512 pOutStream
->ResetError();
515 //------------------------------------------------------------------
516 sal_uInt32
SfxMedium::GetLastStorageCreationState()
518 return pImp
->nLastStorageError
;
521 //------------------------------------------------------------------
522 void SfxMedium::AddLog( const ::rtl::OUString
& aMessage
)
524 if ( !pImp
->m_xLogRing
.is() )
528 ::comphelper::ComponentContext
aContext( ::comphelper::getProcessServiceFactory() );
530 pImp
->m_xLogRing
.set( aContext
.getSingleton( "com.sun.star.logging.DocumentIOLogRing" ), UNO_QUERY_THROW
);
532 catch( uno::Exception
& )
536 if ( pImp
->m_xLogRing
.is() )
537 pImp
->m_xLogRing
->logString( aMessage
);
540 //------------------------------------------------------------------
541 void SfxMedium::SetError( sal_uInt32 nError
, const ::rtl::OUString
& aLogMessage
)
544 if ( eError
!= ERRCODE_NONE
&& aLogMessage
.getLength() )
545 AddLog( aLogMessage
);
548 //------------------------------------------------------------------
549 sal_uInt32
SfxMedium::GetErrorCode() const
551 sal_uInt32 lError
=eError
;
552 if(!lError
&& pInStream
)
553 lError
=pInStream
->GetErrorCode();
554 if(!lError
&& pOutStream
)
555 lError
=pOutStream
->GetErrorCode();
559 //------------------------------------------------------------------
560 long SfxMedium::GetFileVersion() const
562 if ( !pImp
->nFileVersion
&& pFilter
)
563 return pFilter
->GetVersion();
565 return pImp
->nFileVersion
;
568 //------------------------------------------------------------------
569 void SfxMedium::CheckFileDate( const util::DateTime
& aInitDate
)
571 GetInitFileDate( sal_True
);
572 if ( pImp
->m_aDateTime
.Seconds
!= aInitDate
.Seconds
573 || pImp
->m_aDateTime
.Minutes
!= aInitDate
.Minutes
574 || pImp
->m_aDateTime
.Hours
!= aInitDate
.Hours
575 || pImp
->m_aDateTime
.Day
!= aInitDate
.Day
576 || pImp
->m_aDateTime
.Month
!= aInitDate
.Month
577 || pImp
->m_aDateTime
.Year
!= aInitDate
.Year
)
579 uno::Reference
< task::XInteractionHandler
> xHandler
= GetInteractionHandler();
585 ::rtl::Reference
< ::ucbhelper::InteractionRequest
> xInteractionRequestImpl
= new ::ucbhelper::InteractionRequest( uno::makeAny(
586 document::ChangedByOthersRequest() ) );
587 uno::Sequence
< uno::Reference
< task::XInteractionContinuation
> > aContinuations( 3 );
588 aContinuations
[0] = new ::ucbhelper::InteractionAbort( xInteractionRequestImpl
.get() );
589 aContinuations
[1] = new ::ucbhelper::InteractionApprove( xInteractionRequestImpl
.get() );
590 xInteractionRequestImpl
->setContinuations( aContinuations
);
592 xHandler
->handle( xInteractionRequestImpl
.get() );
594 ::rtl::Reference
< ::ucbhelper::InteractionContinuation
> xSelected
= xInteractionRequestImpl
->getSelection();
595 if ( uno::Reference
< task::XInteractionAbort
>( xSelected
.get(), uno::UNO_QUERY
).is() )
597 SetError( ERRCODE_ABORT
, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
) ) );
600 catch ( uno::Exception
& )
606 //------------------------------------------------------------------
607 sal_Bool
SfxMedium::DocNeedsFileDateCheck()
609 return ( !IsReadOnly() && SupportsActiveStreaming( GetURLObject().GetMainURL( INetURLObject::NO_DECODE
) ) );
612 //------------------------------------------------------------------
613 util::DateTime
SfxMedium::GetInitFileDate( sal_Bool bIgnoreOldValue
)
615 if ( ( bIgnoreOldValue
|| !pImp
->m_bGotDateTime
) && GetContent().is() )
619 pImp
->aContent
.getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "DateModified" )) ) >>= pImp
->m_aDateTime
;
620 pImp
->m_bGotDateTime
= sal_True
;
622 catch ( ::com::sun::star::uno::Exception
& )
627 return pImp
->m_aDateTime
;
630 //------------------------------------------------------------------
631 Reference
< XContent
> SfxMedium::GetContent() const
633 if ( !pImp
->aContent
.get().is() )
635 Reference
< ::com::sun::star::ucb::XContent
> xContent
;
636 Reference
< ::com::sun::star::ucb::XCommandEnvironment
> xEnv
;
638 SFX_ITEMSET_ARG( pSet
, pItem
, SfxUnoAnyItem
, SID_CONTENT
, sal_False
);
640 pItem
->GetValue() >>= xContent
;
646 pImp
->aContent
= ::ucbhelper::Content( xContent
, xEnv
);
654 // TODO: DBG_ERROR("SfxMedium::GetContent()\nCreate Content? This code exists as fallback only. Please clarify, why its used.");
657 ::utl::LocalFileHelper::ConvertPhysicalNameToURL( aName
, aURL
);
658 else if ( aLogicName
.Len() )
659 aURL
= GetURLObject().GetMainURL( INetURLObject::NO_DECODE
);
661 ::ucbhelper::Content::create( aURL
, xEnv
, pImp
->aContent
);
665 return pImp
->aContent
.get();
668 ::rtl::OUString
SfxMedium::GetBaseURL( bool bForSaving
)
670 ::rtl::OUString aBaseURL
;
671 const SfxStringItem
* pBaseURLItem
= static_cast<const SfxStringItem
*>( GetItemSet()->GetItem(SID_DOC_BASEURL
) );
673 aBaseURL
= pBaseURLItem
->GetValue();
674 else if ( GetContent().is() )
678 Any aAny
= pImp
->aContent
.getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("BaseURI" )) );
681 catch ( ::com::sun::star::uno::Exception
& )
685 if ( !aBaseURL
.getLength() )
686 aBaseURL
= GetURLObject().GetMainURL( INetURLObject::NO_DECODE
);
692 sal_Bool bIsRemote
= IsRemote();
693 if( (bIsRemote
&& !aOpt
.IsSaveRelINet()) || (!bRemote
&& !aOpt
.IsSaveRelFSys()) )
694 return ::rtl::OUString();
700 //------------------------------------------------------------------
701 SvStream
* SfxMedium::GetInStream()
706 if ( pImp
->pTempFile
|| pImp
->pTempDir
)
708 pInStream
= new SvFileStream( aName
, nStorOpenMode
);
710 eError
= pInStream
->GetError();
712 if( !eError
&& (nStorOpenMode
& STREAM_WRITE
)
713 && ! pInStream
->IsWritable() )
715 eError
= ERRCODE_IO_ACCESSDENIED
;
731 //------------------------------------------------------------------
732 void SfxMedium::CloseInStream()
734 CloseInStream_Impl();
737 void SfxMedium::CloseInStream_Impl()
739 // if there is a storage based on the InStream, we have to
740 // close the storage, too, because otherwise the storage
741 // would use an invalid ( deleted ) stream.
742 if ( pInStream
&& pImp
->xStorage
.is() )
744 if ( pImp
->bStorageBasedOnInStream
)
748 if ( pInStream
&& !GetContent().is() )
754 DELETEZ( pInStream
);
756 pSet
->ClearItem( SID_INPUTSTREAM
);
758 CloseReadStorage_Impl();
759 pImp
->xInputStream
= uno::Reference
< io::XInputStream
>();
763 // output part of the stream is not used so the whole stream can be closed
764 // TODO/LATER: is it correct?
765 pImp
->xStream
= uno::Reference
< io::XStream
>();
767 pSet
->ClearItem( SID_STREAM
);
771 //------------------------------------------------------------------
772 SvStream
* SfxMedium::GetOutStream()
776 // Create a temp. file if there is none because we always
778 if ( !pImp
->pTempFile
)
781 if ( pImp
->pTempFile
)
783 pOutStream
= new SvFileStream( aName
, STREAM_STD_READWRITE
);
791 //------------------------------------------------------------------
792 sal_Bool
SfxMedium::CloseOutStream()
794 CloseOutStream_Impl();
798 sal_Bool
SfxMedium::CloseOutStream_Impl()
802 // if there is a storage based on the OutStream, we have to
803 // close the storage, too, because otherwise the storage
804 // would use an invalid ( deleted ) stream.
805 //TODO/MBA: how to deal with this?!
806 //maybe we need a new flag when the storage was created from the outstream
807 if ( pImp
->xStorage
.is() )
809 //const SvStream *pStorage = aStorage->GetSvStream();
810 //if ( pStorage == pOutStream )
820 // input part of the stream is not used so the whole stream can be closed
821 // TODO/LATER: is it correct?
822 pImp
->xStream
= uno::Reference
< io::XStream
>();
824 pSet
->ClearItem( SID_STREAM
);
830 //------------------------------------------------------------------
831 const String
& SfxMedium::GetPhysicalName( sal_Bool bForceCreateTempIfRemote
) const
833 if ( !aName
.Len() && aLogicName
.Len() )
835 if ( bForceCreateTempIfRemote
|| !SupportsActiveStreaming( aLogicName
) )
836 (( SfxMedium
*)this)->CreateFileStream();
839 // return the name then
843 //------------------------------------------------------------------
844 void SfxMedium::CreateFileStream()
846 ForceSynchronStream_Impl( TRUE
);
850 if ( !pImp
->pTempFile
)
852 pImp
->bIsTemp
= sal_True
;
853 CloseInStream_Impl();
857 //------------------------------------------------------------------
858 sal_Bool
SfxMedium::Commit()
860 if( pImp
->xStorage
.is() )
861 StorageCommit_Impl();
862 else if( pOutStream
)
867 if ( GetError() == SVSTREAM_OK
)
869 // does something only in case there is a temporary file ( means aName points to different location than aLogicName )
873 sal_Bool bResult
= ( GetError() == SVSTREAM_OK
);
875 if ( bResult
&& DocNeedsFileDateCheck() )
876 GetInitFileDate( sal_True
);
881 //------------------------------------------------------------------
882 sal_Bool
SfxMedium::IsStorage()
884 if ( pImp
->xStorage
.is() )
888 return pImp
->bIsStorage
;
890 if ( pImp
->pTempFile
)
893 if ( !::utl::LocalFileHelper::ConvertPhysicalNameToURL( aName
, aURL
) )
895 DBG_ERROR("Physical name not convertable!");
897 pImp
->bIsStorage
= SotStorage::IsStorageFile( aURL
) && !SotStorage::IsOLEStorage( aURL
);
898 if ( !pImp
->bIsStorage
)
899 bTriedStorage
= TRUE
;
901 else if ( GetInStream() )
903 pImp
->bIsStorage
= SotStorage::IsStorageFile( pInStream
) && !SotStorage::IsOLEStorage( pInStream
);
904 if ( !pInStream
->GetError() && !pImp
->bIsStorage
)
905 bTriedStorage
= TRUE
;
908 return pImp
->bIsStorage
;
911 //------------------------------------------------------------------
912 Link
SfxMedium::GetDataAvailableLink() const
914 return pImp
->aAvailableLink
.GetLink();
917 //------------------------------------------------------------------
918 Link
SfxMedium::GetDoneLink() const
920 return pImp
->aDoneLink
.GetLink();
923 //------------------------------------------------------------------
924 sal_Bool
SfxMedium::IsPreview_Impl()
926 sal_Bool bPreview
= sal_False
;
927 SFX_ITEMSET_ARG( GetItemSet(), pPreview
, SfxBoolItem
, SID_PREVIEW
, sal_False
);
929 bPreview
= pPreview
->GetValue();
932 SFX_ITEMSET_ARG( GetItemSet(), pFlags
, SfxStringItem
, SID_OPTIONS
, sal_False
);
935 String aFileFlags
= pFlags
->GetValue();
936 aFileFlags
.ToUpperAscii();
937 if ( STRING_NOTFOUND
!= aFileFlags
.Search( 'B' ) )
945 //------------------------------------------------------------------
946 sal_Bool
SfxMedium::TryStorage()
950 if ( pImp
->xStorage
.is() )
953 // this code will be removed when binary filter components are available!
954 ::com::sun::star::uno::Reference
< ::com::sun::star::lang::XMultiServiceFactory
> xSMgr( ::comphelper::getProcessServiceFactory() );
955 ::com::sun::star::uno::Reference
< ::com::sun::star::util::XArchiver
>
956 xPacker( xSMgr
->createInstance( DEFINE_CONST_UNICODE( "com.sun.star.util.Archiver" ) ), ::com::sun::star::uno::UNO_QUERY
);
961 // extract extra data
962 ::rtl::OUString aPath
= GetURLObject().PathToFileName();
963 ::rtl::OUString aExtraData
= xPacker
->getExtraData( aPath
);
964 const ::rtl::OUString
aSig1( DEFINE_CONST_UNICODE( "private:" ) );
966 aTmp
+= String::CreateFromAscii("simpress");//pFilter->GetFilterContainer()->GetName();
967 const ::rtl::OUString
aSig2( aTmp
);
968 sal_Int32 nIndex1
= aExtraData
.indexOf( aSig1
);
969 sal_Int32 nIndex2
= aExtraData
.indexOf( aSig2
);
971 if( nIndex1
!= 0 || nIndex2
== -1 )
974 nIndex1
+= aSig1
.getLength();
975 ::rtl::OUString aTempDoku
= aExtraData
.copy( nIndex1
, nIndex2
- nIndex1
);
977 // create a temp dir to unpack to
978 pImp
->pTempDir
= new ::utl::TempFile( NULL
, sal_True
);
979 pImp
->pTempDir
->EnableKillingFile( sal_True
);
981 // unpack all files to temp dir
982 ::com::sun::star::uno::Sequence
< ::com::sun::star::beans::PropertyValue
> aArgs
;
983 com::sun::star::uno::Reference
< com::sun::star::task::XInteractionHandler
> xInteractionHandler
= GetInteractionHandler();
984 if (xInteractionHandler
.is())
987 aArgs
.getArray()[0].Name
= DEFINE_CONST_UNICODE( "InteractionHandler" );
988 aArgs
.getArray()[0].Value
<<= xInteractionHandler
;
990 ::com::sun::star::uno::Sequence
< ::rtl::OUString
> files(0);
992 if( !xPacker
->unpack( pImp
->pTempDir
->GetURL(), aPath
, files
, aArgs
) )
995 String aNewName
= pImp
->pTempDir
->GetURL();
997 aNewName
+= String( aTempDoku
);
998 CloseInStream_Impl();
1000 ::utl::LocalFileHelper::ConvertURLToPhysicalName( aNewName
, aTemp
);
1001 SetPhysicalName_Impl( aTemp
);
1004 return pImp
->xStorage
.is();
1007 //------------------------------------------------------------------
1008 sal_Bool
SfxMedium::SupportsActiveStreaming( const rtl::OUString
&rName
) const
1010 if ( ::utl::LocalFileHelper::IsLocalFile( rName
) )
1013 ::ucbhelper::Content aTmpContent
;
1014 Reference
< ::com::sun::star::ucb::XCommandEnvironment
> xDummyEnv
;
1015 if ( ::ucbhelper::Content::create( GetURLObject().GetMainURL( INetURLObject::NO_DECODE
), xDummyEnv
, aTmpContent
) )
1017 Any aAny
= aTmpContent
.getPropertyValue(
1018 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "SupportsActiveStreaming" )) );
1020 sal_Bool bSupportsStreaming
= sal_False
;
1021 return ( ( aAny
>>= bSupportsStreaming
) && bSupportsStreaming
);
1027 //------------------------------------------------------------------
1028 sal_Bool
SfxMedium::BasedOnOriginalFile_Impl()
1030 return ( !pImp
->pTempFile
&& !( aLogicName
.Len() && pImp
->m_bSalvageMode
)
1031 && GetURLObject().GetMainURL( INetURLObject::NO_DECODE
).getLength()
1032 && SupportsActiveStreaming( GetURLObject().GetMainURL( INetURLObject::NO_DECODE
) )
1033 && ::utl::UCBContentHelper::IsDocument( GetURLObject().GetMainURL( INetURLObject::NO_DECODE
) ) );
1036 //------------------------------------------------------------------
1037 void SfxMedium::StorageBackup_Impl()
1039 ::ucbhelper::Content aOriginalContent
;
1040 Reference
< ::com::sun::star::ucb::XCommandEnvironment
> xDummyEnv
;
1041 if ( BasedOnOriginalFile_Impl() && !pImp
->m_aBackupURL
.getLength()
1042 && ::ucbhelper::Content::create( GetURLObject().GetMainURL( INetURLObject::NO_DECODE
), xDummyEnv
, aOriginalContent
) )
1044 DoInternalBackup_Impl( aOriginalContent
);
1045 if( !pImp
->m_aBackupURL
.getLength() )
1046 SetError( ERRCODE_SFX_CANTCREATEBACKUP
, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
) ) );
1050 //------------------------------------------------------------------
1051 ::rtl::OUString
SfxMedium::GetBackup_Impl()
1053 if ( !pImp
->m_aBackupURL
.getLength() )
1054 StorageBackup_Impl();
1056 return pImp
->m_aBackupURL
;
1059 //------------------------------------------------------------------
1060 ::rtl::OUString
SfxMedium::GetOutputStorageURL_Impl()
1062 String aStorageName
;
1066 if ( !::utl::LocalFileHelper::ConvertPhysicalNameToURL( aName
, aStorageName
) )
1068 DBG_ERROR("Physical name not convertable!");
1073 aStorageName
= GetURLObject().GetMainURL( INetURLObject::NO_DECODE
);
1076 return aStorageName
;
1079 //------------------------------------------------------------------
1080 uno::Reference
< embed::XStorage
> SfxMedium::GetOutputStorage()
1083 return uno::Reference
< embed::XStorage
>();
1085 // if the medium was constructed with a Storage: use this one, not a temp. storage
1086 // if a temporary storage already exists: use it
1087 if ( pImp
->xStorage
.is() && ( !aLogicName
.Len() || pImp
->pTempFile
) )
1088 return pImp
->xStorage
;
1090 // if necessary close stream that was used for reading
1091 if ( pInStream
&& !pInStream
->IsWritable() )
1094 DBG_ASSERT( !pOutStream
, "OutStream in a readonly Medium?!" );
1096 // medium based on OutputStream: must work with TempFile
1097 if( aLogicName
.CompareToAscii( "private:stream", 14 ) == COMPARE_EQUAL
1098 || !::utl::LocalFileHelper::IsLocalFile( aLogicName
) )
1099 CreateTempFileNoCopy();
1100 // if Medium already contains a stream - TODO/LATER: store stream/outputstream in ImplData, not in Medium
1101 else if ( GetItemSet()->GetItemState( SID_STREAM
) < SFX_ITEM_SET
)
1103 // check whether the backup should be created
1104 StorageBackup_Impl();
1107 return uno::Reference
< embed::XStorage
>();
1109 ::rtl::OUString aOutputURL
= GetOutputStorageURL_Impl();
1111 SFX_ITEMSET_ARG( GetItemSet(), pOverWrite
, SfxBoolItem
, SID_OVERWRITE
, sal_False
);
1112 SFX_ITEMSET_ARG( GetItemSet(), pRename
, SfxBoolItem
, SID_RENAME
, sal_False
);
1113 sal_Bool bRename
= pRename
? pRename
->GetValue() : FALSE
;
1114 sal_Bool bOverWrite
= pOverWrite
? pOverWrite
->GetValue() : !bRename
;
1116 // the target file must be truncated before a storage based on it is created
1119 uno::Reference
< lang::XMultiServiceFactory
> xFactory
= ::comphelper::getProcessServiceFactory();
1120 uno::Reference
< ::com::sun::star::ucb::XSimpleFileAccess
> xSimpleFileAccess(
1121 xFactory
->createInstance( ::rtl::OUString::createFromAscii("com.sun.star.ucb.SimpleFileAccess") ),
1122 uno::UNO_QUERY_THROW
);
1124 uno::Reference
< ucb::XCommandEnvironment
> xDummyEnv
;
1125 ::ucbhelper::Content aContent
= ::ucbhelper::Content( aOutputURL
, xDummyEnv
);
1127 uno::Reference
< io::XStream
> xStream
;
1128 sal_Bool bDeleteOnFailure
= sal_False
;
1132 xStream
= aContent
.openWriteableStreamNoLock();
1136 // the stream should not exist, it should not be possible to open it
1137 if ( xStream
->getOutputStream().is() )
1138 xStream
->getOutputStream()->closeOutput();
1139 if ( xStream
->getInputStream().is() )
1140 xStream
->getInputStream()->closeInput();
1142 xStream
= uno::Reference
< io::XStream
>();
1143 SetError( ERRCODE_IO_GENERAL
, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
) ) );
1146 catch ( ucb::InteractiveIOException
const & e
)
1148 if ( e
.Code
== ucb::IOErrorCode_NOT_EXISTING
)
1151 SvMemoryStream
aStream(0,0);
1152 uno::Reference
< io::XInputStream
> xInput( new ::utl::OInputStreamWrapper( aStream
) );
1153 ucb::InsertCommandArgument aInsertArg
;
1154 aInsertArg
.Data
= xInput
;
1155 aInsertArg
.ReplaceExisting
= sal_False
;
1156 aContent
.executeCommand( rtl::OUString::createFromAscii( "insert" ), uno::makeAny( aInsertArg
) );
1158 // Try to open one more time
1159 xStream
= aContent
.openWriteableStreamNoLock();
1160 bDeleteOnFailure
= sal_True
;
1168 if ( BasedOnOriginalFile_Impl() )
1170 // the storage will be based on original file, the wrapper should be used
1171 xStream
= new OPostponedTruncationFileStream( aOutputURL
, xFactory
, xSimpleFileAccess
, xStream
, bDeleteOnFailure
);
1175 // the storage will be based on the temporary file, the stream can be truncated directly
1176 uno::Reference
< io::XOutputStream
> xOutStream
= xStream
->getOutputStream();
1177 uno::Reference
< io::XTruncate
> xTruncate( xOutStream
, uno::UNO_QUERY
);
1178 if ( !xTruncate
.is() )
1179 throw uno::RuntimeException();
1181 xTruncate
->truncate();
1182 xOutStream
->flush();
1185 pImp
->xStream
= xStream
;
1186 GetItemSet()->Put( SfxUsrAnyItem( SID_STREAM
, makeAny( xStream
) ) );
1189 catch( uno::Exception
& )
1191 // TODO/LATER: try to use the temporary file in case the target content can not be opened, it might happen in case of some FS, the copy functionality might work in this case
1192 SetError( ERRCODE_IO_GENERAL
, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
) ) );
1196 return GetStorage();
1199 //------------------------------------------------------------------
1200 void SfxMedium::SetPasswordToStorage_Impl()
1202 // in case media-descriptor contains password it should be used on opening
1203 if ( pImp
->xStorage
.is() && pSet
)
1205 ::rtl::OUString aPasswd
;
1206 if ( GetPasswd_Impl( pSet
, aPasswd
) )
1210 ::comphelper::OStorageHelper::SetCommonStoragePassword( pImp
->xStorage
, aPasswd
);
1212 catch( uno::Exception
& )
1214 OSL_ENSURE( sal_False
, "It must be possible to set a common password for the storage" );
1215 // TODO/LATER: set the error code in case of problem
1216 // SetError( ERRCODE_IO_GENERAL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
1222 //------------------------------------------------------------------
1223 sal_Int8
SfxMedium::ShowLockedDocumentDialog( const uno::Sequence
< ::rtl::OUString
>& aData
, sal_Bool bIsLoading
, sal_Bool bOwnLock
)
1225 sal_Int8 nResult
= LOCK_UI_NOLOCK
;
1227 // show the interaction regarding the document opening
1228 uno::Reference
< task::XInteractionHandler
> xHandler
= GetInteractionHandler();
1230 if ( ::svt::DocumentLockFile::IsInteractionAllowed() && xHandler
.is() && ( bIsLoading
|| bOwnLock
) )
1232 ::rtl::OUString aDocumentURL
= GetURLObject().GetLastName();
1233 ::rtl::OUString aInfo
;
1234 ::rtl::Reference
< ::ucbhelper::InteractionRequest
> xInteractionRequestImpl
;
1238 if ( aData
.getLength() > LOCKFILE_EDITTIME_ID
)
1239 aInfo
= aData
[LOCKFILE_EDITTIME_ID
];
1241 xInteractionRequestImpl
= new ::ucbhelper::InteractionRequest( uno::makeAny(
1242 document::OwnLockOnDocumentRequest( ::rtl::OUString(), uno::Reference
< uno::XInterface
>(), aDocumentURL
, aInfo
, !bIsLoading
) ) );
1246 if ( aData
.getLength() > LOCKFILE_EDITTIME_ID
)
1248 if ( aData
[LOCKFILE_OOOUSERNAME_ID
].getLength() )
1249 aInfo
= aData
[LOCKFILE_OOOUSERNAME_ID
];
1251 aInfo
= aData
[LOCKFILE_SYSUSERNAME_ID
];
1253 if ( aInfo
.getLength() && aData
[LOCKFILE_EDITTIME_ID
].getLength() )
1255 aInfo
+= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " ( " ) );
1256 aInfo
+= aData
[LOCKFILE_EDITTIME_ID
];
1257 aInfo
+= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " )" ) );
1263 xInteractionRequestImpl
= new ::ucbhelper::InteractionRequest( uno::makeAny(
1264 document::LockedDocumentRequest( ::rtl::OUString(), uno::Reference
< uno::XInterface
>(), aDocumentURL
, aInfo
) ) );
1268 xInteractionRequestImpl
= new ::ucbhelper::InteractionRequest( uno::makeAny(
1269 document::LockedOnSavingRequest( ::rtl::OUString(), uno::Reference
< uno::XInterface
>(), aDocumentURL
, aInfo
) ) );
1274 uno::Sequence
< uno::Reference
< task::XInteractionContinuation
> > aContinuations( 3 );
1275 aContinuations
[0] = new ::ucbhelper::InteractionAbort( xInteractionRequestImpl
.get() );
1276 aContinuations
[1] = new ::ucbhelper::InteractionApprove( xInteractionRequestImpl
.get() );
1277 aContinuations
[2] = new ::ucbhelper::InteractionDisapprove( xInteractionRequestImpl
.get() );
1278 xInteractionRequestImpl
->setContinuations( aContinuations
);
1280 xHandler
->handle( xInteractionRequestImpl
.get() );
1282 ::rtl::Reference
< ::ucbhelper::InteractionContinuation
> xSelected
= xInteractionRequestImpl
->getSelection();
1283 if ( uno::Reference
< task::XInteractionAbort
>( xSelected
.get(), uno::UNO_QUERY
).is() )
1285 SetError( ERRCODE_ABORT
, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
) ) );
1287 else if ( uno::Reference
< task::XInteractionDisapprove
>( xSelected
.get(), uno::UNO_QUERY
).is() )
1289 // own lock on loading, user has selected to ignore the lock
1290 // own lock on saving, user has selected to ignore the lock
1291 // alien lock on loading, user has selected to edit a copy of document
1292 // TODO/LATER: alien lock on saving, user has selected to do SaveAs to different location
1293 if ( bIsLoading
&& !bOwnLock
)
1295 // means that a copy of the document should be opened
1296 GetItemSet()->Put( SfxBoolItem( SID_TEMPLATE
, sal_True
) );
1298 else if ( bOwnLock
)
1299 nResult
= LOCK_UI_SUCCEEDED
;
1301 else // if ( XSelected == aContinuations[1] )
1303 // own lock on loading, user has selected to open readonly
1304 // own lock on saving, user has selected to open readonly
1305 // alien lock on loading, user has selected to retry saving
1306 // TODO/LATER: alien lock on saving, user has selected to retry saving
1309 GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY
, sal_True
) );
1311 nResult
= LOCK_UI_TRY
;
1318 // if no interaction handler is provided the default answer is open readonly
1319 // that usually happens in case the document is loaded per API
1320 // so the document must be opened readonly for backward compatibility
1321 GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY
, sal_True
) );
1324 SetError( ERRCODE_IO_ACCESSDENIED
, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
) ) );
1331 //------------------------------------------------------------------
1332 sal_Bool
SfxMedium::LockOrigFileOnDemand( sal_Bool bLoading
, sal_Bool bNoUI
)
1334 // returns true if the document can be opened for editing ( even if it should be a copy )
1335 // otherwise the document should be opened readonly
1336 // if user cancel the loading the ERROR_ABORT is set
1338 sal_Bool bResult
= pImp
->m_bLocked
;
1342 // no read-write access is necessary on loading if the document is explicitly opened as copy
1343 SFX_ITEMSET_ARG( GetItemSet(), pTemplateItem
, SfxBoolItem
, SID_TEMPLATE
, sal_False
);
1344 bResult
= ( bLoading
&& pTemplateItem
&& pTemplateItem
->GetValue() );
1347 if ( !bResult
&& !IsReadOnly() )
1349 // check whether the file is readonly in fs
1350 // do it only for loading, some contents still might have problems with this property, let them not affect the saving
1351 sal_Bool bContentReadonly
= sal_False
;
1356 // MediaDescriptor does this check also, the duplication should be avoided in future
1357 pImp
->aContent
.getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ) ) ) >>= bContentReadonly
;
1359 catch( uno::Exception
)
1363 if ( !bContentReadonly
)
1365 if ( ::utl::LocalFileHelper::IsLocalFile( aLogicName
) )
1367 // the special file locking should be used only for file URLs
1369 // in case of storing the document should request the output before locking
1372 // let the stream be opened to check the system file locking
1376 sal_Int8 bUIStatus
= LOCK_UI_NOLOCK
;
1378 // check whether system file locking has been used, the default value is false
1379 sal_Bool bUseSystemLock
= IsSystemFileLockingUsed();
1381 // TODO/LATER: This implementation does not allow to detect the system lock on saving here, actually this is no big problem
1382 // if system lock is used the writeable stream should be available
1383 sal_Bool bHandleSysLocked
= ( bLoading
&& bUseSystemLock
&& !pImp
->xStream
.is() && !pOutStream
);
1389 ::svt::DocumentLockFile
aLockFile( aLogicName
);
1390 if ( !bHandleSysLocked
)
1394 bResult
= aLockFile
.CreateOwnLockFile();
1396 catch ( ucb::InteractiveIOException
& e
)
1398 // exception means that the lock file can not be successfuly accessed
1399 // in this case it should be ignored if system file locking is anyway active
1400 if ( bUseSystemLock
|| !IsOOoLockFileUsed() )
1403 // take the ownership over the lock file
1404 aLockFile
.OverwriteOwnLockFile();
1406 else if ( e
.Code
== IOErrorCode_INVALID_PARAMETER
)
1408 // system file locking is not active, ask user whether he wants to open the document without any locking
1409 uno::Reference
< task::XInteractionHandler
> xHandler
= GetInteractionHandler();
1411 if ( xHandler
.is() )
1413 ::rtl::Reference
< ::ucbhelper::InteractionRequest
> xIgnoreRequestImpl
1414 = new ::ucbhelper::InteractionRequest( uno::makeAny( document::LockFileIgnoreRequest() ) );
1416 uno::Sequence
< uno::Reference
< task::XInteractionContinuation
> > aContinuations( 2 );
1417 aContinuations
[0] = new ::ucbhelper::InteractionAbort( xIgnoreRequestImpl
.get() );
1418 aContinuations
[1] = new ::ucbhelper::InteractionApprove( xIgnoreRequestImpl
.get() );
1419 xIgnoreRequestImpl
->setContinuations( aContinuations
);
1421 xHandler
->handle( xIgnoreRequestImpl
.get() );
1423 ::rtl::Reference
< ::ucbhelper::InteractionContinuation
> xSelected
= xIgnoreRequestImpl
->getSelection();
1424 bResult
= ( uno::Reference
< task::XInteractionApprove
>( xSelected
.get(), uno::UNO_QUERY
).is() );
1428 catch ( uno::Exception
& )
1430 // exception means that the lock file can not be successfuly accessed
1431 // in this case it should be ignored if system file locking is anyway active
1432 if ( bUseSystemLock
|| !IsOOoLockFileUsed() )
1435 // take the ownership over the lock file
1436 aLockFile
.OverwriteOwnLockFile();
1440 // in case OOo locking is turned off the lock file is still written if possible
1441 // but it is ignored while deciding whether the document should be opened for editing or not
1442 if ( !bResult
&& !IsOOoLockFileUsed() )
1445 // take the ownership over the lock file
1446 aLockFile
.OverwriteOwnLockFile();
1453 uno::Sequence
< ::rtl::OUString
> aData
;
1456 // impossibility to get data is no real problem
1457 aData
= aLockFile
.GetLockData();
1459 catch( uno::Exception
) {}
1461 sal_Bool bOwnLock
= sal_False
;
1463 if ( !bHandleSysLocked
)
1465 uno::Sequence
< ::rtl::OUString
> aOwnData
= aLockFile
.GenerateOwnEntry();
1466 bOwnLock
= ( aData
.getLength() > LOCKFILE_USERURL_ID
1467 && aOwnData
.getLength() > LOCKFILE_USERURL_ID
1468 && aOwnData
[LOCKFILE_SYSUSERNAME_ID
].equals( aData
[LOCKFILE_SYSUSERNAME_ID
] ) );
1471 && aOwnData
[LOCKFILE_LOCALHOST_ID
].equals( aData
[LOCKFILE_LOCALHOST_ID
] )
1472 && aOwnData
[LOCKFILE_USERURL_ID
].equals( aData
[LOCKFILE_USERURL_ID
] ) )
1474 // this is own lock from the same installation, it could remain because of crash
1479 if ( !bResult
&& !bNoUI
)
1481 bUIStatus
= ShowLockedDocumentDialog( aData
, bLoading
, bOwnLock
);
1482 if ( bUIStatus
== LOCK_UI_SUCCEEDED
)
1484 // take the ownership over the lock file
1485 bResult
= aLockFile
.OverwriteOwnLockFile();
1489 bHandleSysLocked
= sal_False
;
1492 catch( uno::Exception
& )
1495 } while( !bResult
&& bUIStatus
== LOCK_UI_TRY
);
1497 pImp
->m_bLocked
= bResult
;
1501 // this is no file URL, check whether the file is readonly
1502 bResult
= !bContentReadonly
;
1507 if ( !bResult
&& GetError() == ERRCODE_NONE
)
1509 // the error should be set in case it is storing process
1510 // or the document has been opened for editing explicitly
1512 SFX_ITEMSET_ARG( pSet
, pReadOnlyItem
, SfxBoolItem
, SID_DOC_READONLY
, FALSE
);
1513 if ( !bLoading
|| (pReadOnlyItem
&& !pReadOnlyItem
->GetValue()) )
1514 SetError( ERRCODE_IO_ACCESSDENIED
, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
) ) );
1516 GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY
, sal_True
) );
1519 // when the file is locked, get the current file date
1520 if ( bResult
&& DocNeedsFileDateCheck() )
1521 GetInitFileDate( sal_True
);
1526 //------------------------------------------------------------------
1527 uno::Reference
< embed::XStorage
> SfxMedium::GetStorage()
1529 if ( pImp
->xStorage
.is() || bTriedStorage
)
1530 return pImp
->xStorage
;
1532 uno::Sequence
< uno::Any
> aArgs( 2 );
1534 String aStorageName
;
1535 if ( pImp
->pTempFile
|| pImp
->pTempDir
)
1537 // open storage from the temporary file
1538 if ( !::utl::LocalFileHelper::ConvertPhysicalNameToURL( aName
, aStorageName
) )
1540 DBG_ERROR("Physical name not convertable!");
1544 // create the set of the streams based on the temporary file
1547 OSL_ENSURE( pImp
->xStream
.is(), "It must be possible to create read write stream access!" );
1548 if ( pImp
->xStream
.is() )
1550 aArgs
[0] <<= pImp
->xStream
;
1551 pImp
->bStorageBasedOnInStream
= sal_True
;
1555 CloseStreams_Impl();
1556 aArgs
[0] <<= ::rtl::OUString( aName
);
1557 pImp
->bStorageBasedOnInStream
= sal_False
;
1560 aArgs
[1] <<= ( nStorOpenMode
&STREAM_WRITE
? embed::ElementModes::READWRITE
: embed::ElementModes::READ
);
1564 pImp
->xStorage
= uno::Reference
< embed::XStorage
>(
1565 ::comphelper::OStorageHelper::GetStorageFactory()->createInstanceWithArguments( aArgs
),
1568 catch( uno::Exception
& )
1570 //TODO/LATER: error handling; Error and LastStorageError
1575 // open the storage from original location
1579 return pImp
->xStorage
;
1583 if ( IsReadOnly() && SupportsActiveStreaming( aLogicName
) )
1585 //TODO/LATER: performance problem if not controlled by special Mode in SfxMedium
1586 //(should be done only for permanently open storages)
1587 // create a copy, the following method will close all existing streams
1590 // create the set of the streams based on the temporary file
1593 OSL_ENSURE( pImp
->xStream
.is(), "It must be possible to create read write stream access!" );
1594 if ( pImp
->xStream
.is() )
1596 aArgs
[0] <<= pImp
->xStream
;
1597 pImp
->bStorageBasedOnInStream
= sal_True
;
1601 CloseStreams_Impl();
1602 aArgs
[0] <<= ::rtl::OUString( aName
);
1603 pImp
->bStorageBasedOnInStream
= sal_False
;
1606 aArgs
[1] <<= embed::ElementModes::READWRITE
;
1611 // there is no explicit request to open the document readonly
1613 // create a storage on the stream
1614 if ( pImp
->xStream
.is() )
1616 aArgs
[0] <<= pImp
->xStream
;
1617 aArgs
[1] <<= ( ( nStorOpenMode
& STREAM_WRITE
) ?
1618 embed::ElementModes::READWRITE
: embed::ElementModes::READ
);
1620 pImp
->bStorageBasedOnInStream
= sal_True
;
1624 // no readwrite stream, but it can be a case of http protocol
1625 sal_Bool bReadOnly
= sal_False
;
1627 if ( aLogicName
.CompareToAscii( "private:stream", 14 ) != COMPARE_EQUAL
1628 && GetContent().is() )
1630 // unfortunately the content can not always have the interaction handler
1631 // so in some cases it has to be set for some time
1632 Reference
< ::com::sun::star::ucb::XCommandEnvironment
> xEnv
;
1633 Reference
< ::com::sun::star::ucb::XCommandEnvironment
> xOldEnv
;
1634 Reference
< ::com::sun::star::task::XInteractionHandler
> xInteractionHandler
= ((SfxMedium
*)this)->GetInteractionHandler();
1635 if ( xInteractionHandler
.is() )
1636 xEnv
= new ::ucbhelper::CommandEnvironment( xInteractionHandler
,
1637 Reference
< ::com::sun::star::ucb::XProgressHandler
>() );
1641 xOldEnv
= pImp
->aContent
.getCommandEnvironment();
1642 pImp
->aContent
.setCommandEnvironment( xEnv
);
1647 Any aAny
= pImp
->aContent
.getPropertyValue(
1648 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("IsReadOnly" )) );
1650 if ( ( aAny
>>= bReadOnly
) && bReadOnly
)
1652 GetItemSet()->Put( SfxBoolItem(SID_DOC_READONLY
, sal_True
));
1653 SetOpenMode( SFX_STREAM_READONLY
, sal_False
, sal_True
);
1656 catch( uno::Exception
& )
1660 pImp
->aContent
.setCommandEnvironment( xOldEnv
);
1663 // if the document is opened as readonly the copy should be done according to selected approach
1664 // if the document is opened for editing the copy should be done to use it as a temporary location for changes before the final transfer
1665 // the following method will close all existing streams
1668 // create the set of the streams based on the temporary file
1671 OSL_ENSURE( pImp
->xStream
.is(), "It must be possible to create read write stream access!" );
1672 if ( pImp
->xStream
.is() )
1674 aArgs
[0] <<= pImp
->xStream
;
1675 pImp
->bStorageBasedOnInStream
= sal_True
;
1679 CloseStreams_Impl();
1680 aArgs
[0] <<= ::rtl::OUString( aName
);
1681 pImp
->bStorageBasedOnInStream
= sal_False
;
1685 aArgs
[1] <<= embed::ElementModes::READ
;
1687 aArgs
[1] <<= embed::ElementModes::READWRITE
;
1691 SFX_ITEMSET_ARG( GetItemSet(), pRepairItem
, SfxBoolItem
, SID_REPAIRPACKAGE
, sal_False
);
1692 if ( pRepairItem
&& pRepairItem
->GetValue() )
1694 // the storage should be created for repairing mode
1696 Reference
< ::com::sun::star::ucb::XProgressHandler
> xProgressHandler
;
1697 Reference
< ::com::sun::star::task::XStatusIndicator
> xStatusIndicator
;
1699 SFX_ITEMSET_ARG( GetItemSet(), pxProgressItem
, SfxUnoAnyItem
, SID_PROGRESS_STATUSBAR_CONTROL
, sal_False
);
1700 if( pxProgressItem
&& ( pxProgressItem
->GetValue() >>= xStatusIndicator
) )
1701 xProgressHandler
= Reference
< ::com::sun::star::ucb::XProgressHandler
>(
1702 new utl::ProgressHandlerWrap( xStatusIndicator
) );
1704 uno::Sequence
< beans::PropertyValue
> aAddProps( 2 );
1705 aAddProps
[0].Name
= ::rtl::OUString::createFromAscii( "RepairPackage" );
1706 aAddProps
[0].Value
<<= (sal_Bool
)sal_True
;
1707 aAddProps
[1].Name
= ::rtl::OUString::createFromAscii( "StatusIndicator" );
1708 aAddProps
[1].Value
<<= xProgressHandler
;
1711 aArgs
[0] <<= ::rtl::OUString( aName
);
1712 aArgs
[1] <<= embed::ElementModes::READWRITE
;
1713 aArgs
[2] <<= aAddProps
;
1715 pImp
->bStorageBasedOnInStream
= sal_False
;
1718 pImp
->xStorage
= uno::Reference
< embed::XStorage
>(
1719 ::comphelper::OStorageHelper::GetStorageFactory()->createInstanceWithArguments( aArgs
),
1722 if ( !pImp
->xStorage
.is() )
1723 throw uno::RuntimeException();
1725 if ( pRepairItem
&& pRepairItem
->GetValue() )
1727 // in repairing mode the mediatype required by filter should be used
1728 ::rtl::OUString aMediaType
;
1729 ::rtl::OUString
aMediaTypePropName( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) );
1730 uno::Reference
< beans::XPropertySet
> xPropSet( pImp
->xStorage
, uno::UNO_QUERY_THROW
);
1731 xPropSet
->getPropertyValue( aMediaTypePropName
) >>= aMediaType
;
1732 if ( !aMediaType
.getLength() && pFilter
)
1733 xPropSet
->setPropertyValue( aMediaTypePropName
,
1734 uno::makeAny( ::rtl::OUString( pFilter
->GetMimeType() ) ) );
1737 catch ( uno::Exception
& )
1739 //TODO/MBA: error handling; Error and LastStorageError
1740 pImp
->bStorageBasedOnInStream
= sal_False
;
1745 if( ( pImp
->nLastStorageError
= GetError() ) != SVSTREAM_OK
)
1753 bTriedStorage
= sal_True
;
1755 //TODO/MBA: error handling; Error and LastStorageError
1756 //if ( aStorage->GetError() == SVSTREAM_OK )
1757 if ( pImp
->xStorage
.is() )
1759 SetPasswordToStorage_Impl();
1763 SFX_ITEMSET_ARG( pSet
, pVersion
, SfxInt16Item
, SID_VERSION
, sal_False
);
1765 BOOL bResetStorage
= FALSE
;
1766 if ( pVersion
&& pVersion
->GetValue() )
1768 // Alle verf"ugbaren Versionen einlesen
1769 if ( pImp
->aVersions
.getLength() )
1771 // Die zum Kommentar passende Version suchen
1772 // Die Versionen sind von 1 an durchnumeriert, mit negativen
1773 // Versionsnummern werden die Versionen von der aktuellen aus
1774 // r"uckw"arts gez"ahlt
1775 short nVersion
= pVersion
? pVersion
->GetValue() : 0;
1777 nVersion
= ( (short) pImp
->aVersions
.getLength() ) + nVersion
;
1778 else if ( nVersion
)
1781 util::RevisionTag
& rTag
= pImp
->aVersions
[nVersion
];
1783 // SubStorage f"ur alle Versionen "offnen
1784 uno::Reference
< embed::XStorage
> xSub
= pImp
->xStorage
->openStorageElement( DEFINE_CONST_UNICODE( "Versions" ),
1785 embed::ElementModes::READ
);
1787 DBG_ASSERT( xSub
.is(), "Versionsliste, aber keine Versionen!" );
1789 // Dort ist die Version als gepackter Stream gespeichert
1790 uno::Reference
< io::XStream
> xStr
= xSub
->openStreamElement( rTag
.Identifier
, embed::ElementModes::READ
);
1791 SvStream
* pStream
= utl::UcbStreamHelper::CreateStream( xStr
);
1792 if ( pStream
&& pStream
->GetError() == SVSTREAM_OK
)
1794 // Stream ins TempDir auspacken
1795 ::utl::TempFile aTempFile
;
1796 String aTmpName
= aTempFile
.GetURL();
1797 SvFileStream
aTmpStream( aTmpName
, SFX_STREAM_READWRITE
);
1799 *pStream
>> aTmpStream
;
1802 // Datei als Storage "offnen
1803 nStorOpenMode
= SFX_STREAM_READONLY
;
1804 pImp
->xStorage
= comphelper::OStorageHelper::GetStorageFromURL( aTmpName
, embed::ElementModes::READ
);
1805 pImp
->bStorageBasedOnInStream
= sal_False
;
1807 ::utl::LocalFileHelper::ConvertURLToPhysicalName( aTmpName
, aTemp
);
1808 SetPhysicalName_Impl( aTemp
);
1810 pImp
->bIsTemp
= sal_True
;
1811 GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY
, sal_True
) );
1813 pImp
->aVersions
.realloc(0);
1816 bResetStorage
= TRUE
;
1820 bResetStorage
= TRUE
;
1823 //TODO/MBA: error handling; Error and LastStorageError
1824 if ( pImp
->xStorage
.is() )
1826 if( ( pImp->nLastStorageError = aStorage->GetError() ) != SVSTREAM_OK )
1827 bResetStorage = TRUE;
1828 else if ( GetFilter() )
1829 aStorage->SetVersion( GetFilter()->GetVersion() );*/
1832 if ( bResetStorage
)
1836 pInStream
->Seek( 0L );
1839 pImp
->bIsStorage
= pImp
->xStorage
.is();
1840 return pImp
->xStorage
;
1843 //------------------------------------------------------------------
1844 uno::Reference
< embed::XStorage
> SfxMedium::GetLastCommitReadStorage_Impl()
1846 if ( !GetError() && !pImp
->m_xReadStorage
.is() )
1852 if ( pImp
->xInputStream
.is() )
1854 uno::Sequence
< uno::Any
> aArgs( 2 );
1855 aArgs
[0] <<= pImp
->xInputStream
;
1856 aArgs
[1] <<= embed::ElementModes::READ
;
1857 pImp
->m_xReadStorage
= uno::Reference
< embed::XStorage
>(
1858 ::comphelper::OStorageHelper::GetStorageFactory()->createInstanceWithArguments( aArgs
),
1861 else if ( GetStorage().is() )
1863 uno::Reference
< embed::XStorage
> xTempStor
= ::comphelper::OStorageHelper::GetTemporaryStorage();
1864 GetStorage()->copyLastCommitTo( xTempStor
);
1865 pImp
->m_xReadStorage
= xTempStor
;
1868 catch( uno::Exception
& )
1870 OSL_ENSURE( sal_False
, "No possibility to get readonly version of storage from medium!\n" );
1873 if ( GetError() ) // do not remove warnings
1877 return pImp
->m_xReadStorage
;
1880 //------------------------------------------------------------------
1881 void SfxMedium::CloseReadStorage_Impl()
1883 if ( pImp
->m_xReadStorage
.is() )
1886 pImp
->m_xReadStorage
->dispose();
1887 } catch( uno::Exception
& )
1890 pImp
->m_xReadStorage
= uno::Reference
< embed::XStorage
>();
1894 //------------------------------------------------------------------
1895 void SfxMedium::CloseStorage()
1897 if ( pImp
->xStorage
.is() )
1899 uno::Reference
< lang::XComponent
> xComp( pImp
->xStorage
, uno::UNO_QUERY
);
1900 // in the salvage mode the medium does not own the storage
1901 if ( pImp
->bDisposeStorage
&& !pImp
->m_bSalvageMode
)
1905 } catch( uno::Exception
& )
1907 OSL_ENSURE( sal_False
, "Medium's storage is already disposed!\n" );
1912 pImp
->bStorageBasedOnInStream
= sal_False
;
1915 bTriedStorage
= sal_False
;
1916 pImp
->bIsStorage
= sal_False
;
1919 void SfxMedium::CanDisposeStorage_Impl( sal_Bool bDisposeStorage
)
1921 pImp
->bDisposeStorage
= bDisposeStorage
;
1924 sal_Bool
SfxMedium::WillDisposeStorageOnClose_Impl()
1926 return pImp
->bDisposeStorage
;
1929 //------------------------------------------------------------------
1930 void SfxMedium::SetOpenMode( StreamMode nStorOpen
,
1932 sal_Bool bDontClose
)
1934 if ( nStorOpenMode
!= nStorOpen
)
1936 nStorOpenMode
= nStorOpen
;
1940 if ( pImp
->xStorage
.is() )
1943 CloseStreams_Impl();
1948 bSetFilter
= sal_False
;
1951 //------------------------------------------------------------------
1952 sal_Bool
SfxMedium::UseBackupToRestore_Impl( ::ucbhelper::Content
& aOriginalContent
,
1953 const Reference
< ::com::sun::star::ucb::XCommandEnvironment
>& xComEnv
)
1957 ::ucbhelper::Content
aTransactCont( pImp
->m_aBackupURL
, xComEnv
);
1959 Reference
< XInputStream
> aOrigInput
= aTransactCont
.openStream();
1960 aOriginalContent
.writeStream( aOrigInput
, sal_True
);
1965 // in case of failure here the backup file should not be removed
1966 // TODO/LATER: a message should be used to let user know about the backup
1967 pImp
->m_bRemoveBackup
= sal_False
;
1968 // TODO/LATER: needs a specific error code
1969 eError
= ERRCODE_IO_GENERAL
;
1975 //------------------------------------------------------------------
1976 sal_Bool
SfxMedium::StorageCommit_Impl()
1978 sal_Bool bResult
= sal_False
;
1979 Reference
< ::com::sun::star::ucb::XCommandEnvironment
> xDummyEnv
;
1980 ::ucbhelper::Content aOriginalContent
;
1982 if ( pImp
->xStorage
.is() )
1986 uno::Reference
< embed::XTransactedObject
> xTrans( pImp
->xStorage
, uno::UNO_QUERY
);
1992 CloseReadStorage_Impl();
1995 catch ( embed::UseBackupException
& aBackupExc
)
1997 if ( !pImp
->pTempFile
)
1999 OSL_ENSURE( pImp
->m_aBackupURL
.getLength(), "No backup on storage commit!\n" );
2000 if ( pImp
->m_aBackupURL
.getLength()
2001 && ::ucbhelper::Content::create( GetURLObject().GetMainURL( INetURLObject::NO_DECODE
),
2003 aOriginalContent
) )
2005 // use backup to restore the file
2006 // the storage has already disconnected from original location
2007 CloseAndReleaseStreams_Impl();
2008 if ( !UseBackupToRestore_Impl( aOriginalContent
, xDummyEnv
) )
2010 // connect the medium to the temporary file of the storage
2011 pImp
->aContent
= ::ucbhelper::Content();
2012 aName
= aBackupExc
.TemporaryFileURL
;
2013 OSL_ENSURE( aName
.Len(), "The exception _must_ contain the temporary URL!\n" );
2018 SetError( ERRCODE_IO_GENERAL
, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
) ) );
2021 catch ( uno::Exception
& )
2023 //TODO/LATER: improve error handling
2024 SetError( ERRCODE_IO_GENERAL
, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
) ) );
2033 //------------------------------------------------------------------
2034 sal_Bool
SfxMedium::TransactedTransferForFS_Impl( const INetURLObject
& aSource
,
2035 const INetURLObject
& aDest
,
2036 const Reference
< ::com::sun::star::ucb::XCommandEnvironment
>& xComEnv
)
2038 sal_Bool bResult
= sal_False
;
2039 Reference
< ::com::sun::star::ucb::XCommandEnvironment
> xDummyEnv
;
2040 Reference
< XOutputStream
> aDestStream
;
2041 ::ucbhelper::Content aOriginalContent
;
2043 // actualy it should work even for contents different from file content
2044 // DBG_ASSERT( ::utl::LocalFileHelper::IsLocalFile( aDest.GetMainURL( INetURLObject::NO_DECODE ) ),
2045 // "SfxMedium::TransactedTransferForFS() should be used only for local contents!" );
2048 aOriginalContent
= ::ucbhelper::Content( aDest
.GetMainURL( INetURLObject::NO_DECODE
), xComEnv
);
2050 catch ( ::com::sun::star::ucb::CommandAbortedException
& )
2052 eError
= ERRCODE_ABORT
;
2054 catch ( ::com::sun::star::ucb::CommandFailedException
& )
2056 eError
= ERRCODE_ABORT
;
2058 catch (const ::com::sun::star::ucb::ContentCreationException
& ex
)
2060 eError
= ERRCODE_IO_GENERAL
;
2062 (ex
.eError
== ::com::sun::star::ucb::ContentCreationError_NO_CONTENT_PROVIDER
) ||
2063 (ex
.eError
== ::com::sun::star::ucb::ContentCreationError_CONTENT_CREATION_FAILED
)
2066 eError
= ERRCODE_IO_NOTEXISTSPATH
;
2069 catch (const ::com::sun::star::uno::Exception
&)
2071 eError
= ERRCODE_IO_GENERAL
;
2074 if( !eError
|| (eError
& ERRCODE_WARNING_MASK
) )
2076 if ( pImp
->xStorage
.is() )
2079 CloseStreams_Impl();
2081 ::ucbhelper::Content aTempCont
;
2082 if( ::ucbhelper::Content::create( aSource
.GetMainURL( INetURLObject::NO_DECODE
), xDummyEnv
, aTempCont
) )
2084 sal_Bool bTransactStarted
= sal_False
;
2085 SFX_ITEMSET_ARG( GetItemSet(), pOverWrite
, SfxBoolItem
, SID_OVERWRITE
, sal_False
);
2086 SFX_ITEMSET_ARG( GetItemSet(), pRename
, SfxBoolItem
, SID_RENAME
, sal_False
);
2087 sal_Bool bRename
= pRename
? pRename
->GetValue() : FALSE
;
2088 sal_Bool bOverWrite
= pOverWrite
? pOverWrite
->GetValue() : !bRename
;
2092 if( bOverWrite
&& ::utl::UCBContentHelper::IsDocument( aDest
.GetMainURL( INetURLObject::NO_DECODE
) ) )
2094 if( ! pImp
->m_aBackupURL
.getLength() )
2095 DoInternalBackup_Impl( aOriginalContent
);
2097 if( pImp
->m_aBackupURL
.getLength() )
2099 Reference
< XInputStream
> aTempInput
= aTempCont
.openStream();
2100 bTransactStarted
= sal_True
;
2101 aOriginalContent
.setPropertyValue( ::rtl::OUString::createFromAscii( "Size" ),
2102 uno::makeAny( (sal_Int64
)0 ) );
2103 aOriginalContent
.writeStream( aTempInput
, bOverWrite
);
2108 eError
= ERRCODE_SFX_CANTCREATEBACKUP
;
2113 Reference
< XInputStream
> aTempInput
= aTempCont
.openStream();
2114 aOriginalContent
.writeStream( aTempInput
, bOverWrite
);
2118 catch ( ::com::sun::star::ucb::CommandAbortedException
& )
2120 eError
= ERRCODE_ABORT
;
2122 catch ( ::com::sun::star::ucb::CommandFailedException
& )
2124 eError
= ERRCODE_ABORT
;
2126 catch ( ::com::sun::star::ucb::InteractiveIOException
& r
)
2128 if ( r
.Code
== IOErrorCode_ACCESS_DENIED
)
2129 eError
= ERRCODE_IO_ACCESSDENIED
;
2130 else if ( r
.Code
== IOErrorCode_NOT_EXISTING
)
2131 eError
= ERRCODE_IO_NOTEXISTS
;
2132 else if ( r
.Code
== IOErrorCode_CANT_READ
)
2133 eError
= ERRCODE_IO_CANTREAD
;
2135 eError
= ERRCODE_IO_GENERAL
;
2137 catch ( ::com::sun::star::uno::Exception
& )
2139 eError
= ERRCODE_IO_GENERAL
;
2144 if ( pImp
->pTempFile
)
2146 pImp
->pTempFile
->EnableKillingFile( sal_True
);
2147 delete pImp
->pTempFile
;
2148 pImp
->pTempFile
= NULL
;
2151 else if ( bTransactStarted
)
2153 UseBackupToRestore_Impl( aOriginalContent
, xDummyEnv
);
2157 eError
= ERRCODE_IO_CANTREAD
;
2163 //------------------------------------------------------------------
2164 sal_Bool
SfxMedium::TryDirectTransfer( const ::rtl::OUString
& aURL
, SfxItemSet
& aTargetSet
)
2169 // if the document had no password it should be stored without password
2170 // if the document had password it should be stored with the same password
2171 // otherwise the stream copying can not be done
2172 SFX_ITEMSET_ARG( &aTargetSet
, pNewPassItem
, SfxStringItem
, SID_PASSWORD
, sal_False
);
2173 SFX_ITEMSET_ARG( GetItemSet(), pOldPassItem
, SfxStringItem
, SID_PASSWORD
, sal_False
);
2174 if ( ( !pNewPassItem
&& !pOldPassItem
)
2175 || ( pNewPassItem
&& pOldPassItem
&& pNewPassItem
->GetValue().Equals( pOldPassItem
->GetValue() ) ) )
2177 // the filter must be the same
2178 SFX_ITEMSET_ARG( &aTargetSet
, pNewFilterItem
, SfxStringItem
, SID_FILTER_NAME
, sal_False
);
2179 SFX_ITEMSET_ARG( GetItemSet(), pOldFilterItem
, SfxStringItem
, SID_FILTER_NAME
, sal_False
);
2180 if ( pNewFilterItem
&& pOldFilterItem
&& pNewFilterItem
->GetValue().Equals( pOldFilterItem
->GetValue() ) )
2182 // get the input stream and copy it
2183 // in case of success return true
2184 uno::Reference
< io::XInputStream
> xInStream
= GetInputStream();
2187 if ( xInStream
.is() )
2191 uno::Reference
< io::XSeekable
> xSeek( xInStream
, uno::UNO_QUERY
);
2195 nPos
= xSeek
->getPosition();
2199 uno::Reference
< ::com::sun::star::ucb::XCommandEnvironment
> xEnv
;
2200 ::ucbhelper::Content
aTargetContent( aURL
, xEnv
);
2202 InsertCommandArgument aInsertArg
;
2203 aInsertArg
.Data
= xInStream
;
2204 SFX_ITEMSET_ARG( &aTargetSet
, pRename
, SfxBoolItem
, SID_RENAME
, sal_False
);
2205 SFX_ITEMSET_ARG( &aTargetSet
, pOverWrite
, SfxBoolItem
, SID_OVERWRITE
, sal_False
);
2206 if ( (pOverWrite
&& !pOverWrite
->GetValue()) // argument says: never overwrite
2207 || (pRename
&& pRename
->GetValue()) ) // argument says: rename file
2208 aInsertArg
.ReplaceExisting
= sal_False
;
2210 aInsertArg
.ReplaceExisting
= sal_True
; // default is overwrite existing files
2213 aCmdArg
<<= aInsertArg
;
2214 aTargetContent
.executeCommand( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "insert" ) ),
2218 xSeek
->seek( nPos
);
2222 catch( uno::Exception
& )
2231 //------------------------------------------------------------------
2232 void SfxMedium::Transfer_Impl()
2234 // The transfer is required only in two cases: either if there is a temporary file or if there is a salvage item
2236 if ( pImp
->pTempFile
)
2237 aNameURL
= pImp
->pTempFile
->GetURL();
2238 else if ( aLogicName
.Len() && pImp
->m_bSalvageMode
)
2240 // makes sence only in case logic name is set
2241 if ( !::utl::LocalFileHelper::ConvertPhysicalNameToURL( aName
, aNameURL
) )
2242 OSL_ENSURE( sal_False
, "The medium name is not convertable!\n" );
2245 if ( aNameURL
.Len() && ( !eError
|| (eError
& ERRCODE_WARNING_MASK
) ) )
2247 RTL_LOGFILE_CONTEXT( aLog
, "sfx2 (mv76033) SfxMedium::Transfer_Impl, copying to target" );
2249 Reference
< ::com::sun::star::ucb::XCommandEnvironment
> xEnv
;
2250 Reference
< XOutputStream
> rOutStream
;
2252 // in case an output stream is provided from outside and the URL is correct
2253 // commit to the stream
2254 if( aLogicName
.CompareToAscii( "private:stream", 14 ) == COMPARE_EQUAL
)
2256 // TODO/LATER: support storing to SID_STREAM
2257 SFX_ITEMSET_ARG( pSet
, pOutStreamItem
, SfxUnoAnyItem
, SID_OUTPUTSTREAM
, sal_False
);
2258 if( pOutStreamItem
&& ( pOutStreamItem
->GetValue() >>= rOutStream
) )
2260 if ( pImp
->xStorage
.is() )
2263 CloseStreams_Impl();
2265 INetURLObject
aSource( aNameURL
);
2266 ::ucbhelper::Content aTempCont
;
2267 if( ::ucbhelper::Content::create( aSource
.GetMainURL( INetURLObject::NO_DECODE
), xEnv
, aTempCont
) )
2272 sal_Int32 nBufferSize
= 32767;
2273 Sequence
< sal_Int8
> aSequence ( nBufferSize
);
2274 Reference
< XInputStream
> aTempInput
= aTempCont
.openStream();
2278 nRead
= aTempInput
->readBytes ( aSequence
, nBufferSize
);
2279 if ( nRead
< nBufferSize
)
2281 Sequence
< sal_Int8
> aTempBuf ( aSequence
.getConstArray(), nRead
);
2282 rOutStream
->writeBytes ( aTempBuf
);
2285 rOutStream
->writeBytes ( aSequence
);
2287 while ( nRead
== nBufferSize
);
2289 // remove temporary file
2290 if ( pImp
->pTempFile
)
2292 pImp
->pTempFile
->EnableKillingFile( sal_True
);
2293 delete pImp
->pTempFile
;
2294 pImp
->pTempFile
= NULL
;
2303 DBG_ERROR( "Illegal Output stream parameter!\n" );
2304 SetError( ERRCODE_IO_GENERAL
, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
) ) );
2307 // free the reference
2309 pSet
->ClearItem( SID_OUTPUTSTREAM
);
2315 if ( !pImp
->aContent
.get().is() )
2317 eError
= ERRCODE_IO_NOTEXISTS
;
2321 SFX_ITEMSET_ARG( GetItemSet(), pSegmentSize
, SfxInt32Item
, SID_SEGMENTSIZE
, sal_False
);
2324 // this file must be stored into a disk spanned package
2327 uno::Reference
< embed::XStorage
> xStor
= comphelper::OStorageHelper::GetStorageFromURL( GetName(),
2328 embed::ElementModes::READWRITE
| embed::ElementModes::TRUNCATE
);
2330 // set segment size property; package will automatically be divided in pieces fitting
2332 ::com::sun::star::uno::Any aAny
;
2333 aAny
<<= pSegmentSize
->GetValue();
2335 uno::Reference
< beans::XPropertySet
> xSet( pImp
->xStorage
, uno::UNO_QUERY
);
2336 xSet
->setPropertyValue( String::CreateFromAscii("SegmentSize"), aAny
);
2338 // copy the temporary storage into the disk spanned package
2339 GetStorage()->copyToStorage( xStor
);
2340 uno::Reference
< embed::XTransactedObject
> xTrans( pImp
->xStorage
, uno::UNO_QUERY
);
2345 catch ( uno::Exception
& )
2347 //TODO/MBA: error handling
2348 //if ( !GetError() )
2349 // SetError( xStor->GetError(, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) )) );
2354 if ( pFilter
&& SOFFICE_FILEFORMAT_60
<= pFilter
->GetVersion() )
2358 SFX_ITEMSET_ARG( GetItemSet(), pItem, SfxBoolItem, SID_UNPACK, sal_False);
2359 if ( pItem && pItem->GetValue() )
2361 // this file must be stored without packing into a JAR file
2362 // check for an existing unpacked storage
2363 SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( GetName(), STREAM_STD_READ );
2364 if ( !pStream->GetError() )
2366 String aURL = UCBStorage::GetLinkedFile( *pStream );
2368 // remove a possibly existing old folder
2369 ::utl::UCBContentHelper::Kill( aURL );
2374 // create a new folder based storage
2375 SvStorageRef xStor = new SvStorage( TRUE, GetName(), STREAM_STD_READWRITE, STORAGE_CREATE_UNPACKED );
2377 // copy package into unpacked storage
2378 if ( xStor->GetError() == ERRCODE_NONE && GetStorage()->copyToStorage( xStor ) )
2380 // commit changes, writing will happen now
2383 // take new unpacked storage as own storage
2384 if ( pImp->xStorage.is() )
2387 CloseStreams_Impl();
2389 DELETEZ( pImp->pTempFile );
2390 ::utl::LocalFileHelper::ConvertURLToPhysicalName( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ), aName );
2391 SetStorage_Impl( xStor );
2393 else if ( !GetError() )
2394 SetError( xStor->GetError(, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) )) );
2399 INetURLObject
aDest( GetURLObject() );
2401 // source is the temp file written so far
2402 INetURLObject
aSource( aNameURL
);
2404 // a special case, an interaction handler should be used for
2405 // authentication in case it is available
2406 Reference
< ::com::sun::star::ucb::XCommandEnvironment
> xComEnv
;
2407 Reference
< ::com::sun::star::task::XInteractionHandler
> xInteractionHandler
= GetInteractionHandler();
2408 if (xInteractionHandler
.is())
2409 xComEnv
= new ::ucbhelper::CommandEnvironment( xInteractionHandler
,
2410 Reference
< ::com::sun::star::ucb::XProgressHandler
>() );
2412 if ( SupportsActiveStreaming( aDest
.GetMainURL( INetURLObject::NO_DECODE
) ) || !aDest
.removeSegment() )
2414 TransactedTransferForFS_Impl( aSource
, aDest
, xComEnv
);
2418 // create content for the parent folder and call transfer on that content with the source content
2419 // and the destination file name as parameters
2420 ::ucbhelper::Content aSourceContent
;
2421 ::ucbhelper::Content aTransferContent
;
2423 String aFileName
= GetLongName();
2424 if ( !aFileName
.Len() )
2425 aFileName
= GetURLObject().getName( INetURLObject::LAST_SEGMENT
, true, INetURLObject::DECODE_WITH_CHARSET
);
2429 aTransferContent
= ::ucbhelper::Content( aDest
.GetMainURL( INetURLObject::NO_DECODE
), xComEnv
);
2431 catch (const ::com::sun::star::ucb::ContentCreationException
& ex
)
2433 eError
= ERRCODE_IO_GENERAL
;
2435 (ex
.eError
== ::com::sun::star::ucb::ContentCreationError_NO_CONTENT_PROVIDER
) ||
2436 (ex
.eError
== ::com::sun::star::ucb::ContentCreationError_CONTENT_CREATION_FAILED
)
2439 eError
= ERRCODE_IO_NOTEXISTSPATH
;
2442 catch (const ::com::sun::star::uno::Exception
&)
2444 eError
= ERRCODE_IO_GENERAL
;
2447 if ( !eError
|| (eError
& ERRCODE_WARNING_MASK
) )
2449 // free resources, otherwise the transfer may fail
2450 if ( pImp
->xStorage
.is() )
2453 CloseStreams_Impl();
2455 ::ucbhelper::Content::create( aSource
.GetMainURL( INetURLObject::NO_DECODE
), xEnv
, aSourceContent
);
2457 // check for external parameters that may customize the handling of NameClash situations
2458 SFX_ITEMSET_ARG( GetItemSet(), pRename
, SfxBoolItem
, SID_RENAME
, sal_False
);
2459 SFX_ITEMSET_ARG( GetItemSet(), pOverWrite
, SfxBoolItem
, SID_OVERWRITE
, sal_False
);
2460 sal_Int32 nNameClash
;
2461 if ( pOverWrite
&& !pOverWrite
->GetValue() )
2462 // argument says: never overwrite
2463 nNameClash
= NameClash::ERROR
;
2464 else if ( pRename
&& pRename
->GetValue() )
2465 // argument says: rename file
2466 nNameClash
= NameClash::RENAME
;
2468 // default is overwrite existing files
2469 nNameClash
= NameClash::OVERWRITE
;
2473 if (!aTransferContent
.transferContent( aSourceContent
, ::ucbhelper::InsertOperation_COPY
, aFileName
, nNameClash
))
2474 eError
= ERRCODE_IO_GENERAL
;
2476 catch ( ::com::sun::star::ucb::CommandAbortedException
& )
2478 eError
= ERRCODE_ABORT
;
2480 catch ( ::com::sun::star::ucb::CommandFailedException
& )
2482 eError
= ERRCODE_ABORT
;
2484 catch ( ::com::sun::star::ucb::InteractiveIOException
& r
)
2486 if ( r
.Code
== IOErrorCode_ACCESS_DENIED
)
2487 eError
= ERRCODE_IO_ACCESSDENIED
;
2488 else if ( r
.Code
== IOErrorCode_NOT_EXISTING
)
2489 eError
= ERRCODE_IO_NOTEXISTS
;
2490 else if ( r
.Code
== IOErrorCode_CANT_READ
)
2491 eError
= ERRCODE_IO_CANTREAD
;
2493 eError
= ERRCODE_IO_GENERAL
;
2495 catch ( ::com::sun::star::uno::Exception
& )
2497 eError
= ERRCODE_IO_GENERAL
;
2500 // do not switch from temporary file in case of nonfile protocol
2504 if ( ( !eError
|| (eError
& ERRCODE_WARNING_MASK
) ) && !pImp
->pTempFile
)
2506 // without a TempFile the physical and logical name should be the same after successful transfer
2507 ::utl::LocalFileHelper::ConvertURLToPhysicalName( GetURLObject().GetMainURL( INetURLObject::NO_DECODE
),
2509 pImp
->m_bSalvageMode
= sal_False
;
2514 //------------------------------------------------------------------
2515 void SfxMedium::DoInternalBackup_Impl( const ::ucbhelper::Content
& aOriginalContent
,
2516 const String
& aPrefix
,
2517 const String
& aExtension
,
2518 const String
& aDestDir
)
2520 RTL_LOGFILE_CONTEXT( aLog
, "sfx2 (mv76033) SfxMedium::DoInternalBackup_Impl( with destdir )" );
2522 if ( pImp
->m_aBackupURL
.getLength() )
2523 return; // the backup was done already
2525 ::rtl::OUString aBackupName
;
2526 ::rtl::OUString aBackupURL
;
2528 // a living aTransactTemp kills WebDAV with SAL_ENABLE_FILE_LOCKING=1,
2529 // because then it attempts to have 2 file handles pointing to the same
2531 ::utl::TempFile
aTransactTemp( aPrefix
, &aExtension
, &aDestDir
);
2532 aTransactTemp
.EnableKillingFile( sal_True
);
2534 INetURLObject
aBackObj( aTransactTemp
.GetURL() );
2536 aBackupName
= aBackObj
.getName( INetURLObject::LAST_SEGMENT
, true, INetURLObject::DECODE_WITH_CHARSET
);
2537 aBackupURL
= aBackObj
.GetMainURL( INetURLObject::NO_DECODE
);
2540 Reference
< ::com::sun::star::ucb::XCommandEnvironment
> xDummyEnv
;
2541 ::ucbhelper::Content aBackupCont
;
2542 if( ::ucbhelper::Content::create( aDestDir
, xDummyEnv
, aBackupCont
) )
2546 if( aBackupCont
.transferContent( aOriginalContent
,
2547 ::ucbhelper::InsertOperation_COPY
,
2549 NameClash::OVERWRITE
) )
2551 pImp
->m_aBackupURL
= aBackupURL
;
2552 pImp
->m_bRemoveBackup
= sal_True
;
2560 //------------------------------------------------------------------
2561 void SfxMedium::DoInternalBackup_Impl( const ::ucbhelper::Content
& aOriginalContent
)
2563 if ( pImp
->m_aBackupURL
.getLength() )
2564 return; // the backup was done already
2566 ::rtl::OUString aFileName
= GetURLObject().getName( INetURLObject::LAST_SEGMENT
,
2568 INetURLObject::NO_DECODE
);
2570 sal_Int32 nPrefixLen
= aFileName
.lastIndexOf( '.' );
2571 String aPrefix
= ( nPrefixLen
== -1 ) ? aFileName
: aFileName
.copy( 0, nPrefixLen
);
2572 String aExtension
= ( nPrefixLen
== -1 ) ? String() : String(aFileName
.copy( nPrefixLen
));
2573 String aBakDir
= SvtPathOptions().GetBackupPath();
2575 DoInternalBackup_Impl( aOriginalContent
, aPrefix
, aExtension
, aBakDir
);
2577 if ( !pImp
->m_aBackupURL
.getLength() )
2579 // the copiing to the backup catalog failed ( for example because
2580 // of using an encrypted partition as target catalog )
2581 // since the user did not specify to make backup explicitly
2582 // office should try to make backup in another place,
2583 // target catalog does not look bad for this case ( and looks
2584 // to be the only way for encrypted partitions )
2586 INetURLObject aDest
= GetURLObject();
2587 if ( aDest
.removeSegment() )
2588 DoInternalBackup_Impl( aOriginalContent
, aPrefix
, aExtension
, aDest
.GetMainURL( INetURLObject::NO_DECODE
) );
2593 //------------------------------------------------------------------
2594 void SfxMedium::DoBackup_Impl()
2596 RTL_LOGFILE_CONTEXT( aLog
, "sfx2 (mv76033) SfxMedium::DoBackup_Impl" );
2598 // source file name is the logical name of this medium
2599 INetURLObject
aSource( GetURLObject() );
2601 // there is nothing to backup in case source file does not exist
2602 if ( !::utl::UCBContentHelper::IsDocument( aSource
.GetMainURL( INetURLObject::NO_DECODE
) ) )
2605 sal_Bool bSuccess
= sal_False
;
2607 // get path for backups
2608 String aBakDir
= SvtPathOptions().GetBackupPath();
2611 // create content for the parent folder ( = backup folder )
2612 ::ucbhelper::Content aContent
;
2613 Reference
< ::com::sun::star::ucb::XCommandEnvironment
> xEnv
;
2614 if( ::ucbhelper::Content::create( aBakDir
, xEnv
, aContent
) )
2616 // save as ".bak" file
2617 INetURLObject
aDest( aBakDir
);
2618 aDest
.insertName( aSource
.getName() );
2619 aDest
.setExtension( DEFINE_CONST_UNICODE( "bak" ) );
2620 String aFileName
= aDest
.getName( INetURLObject::LAST_SEGMENT
, true, INetURLObject::DECODE_WITH_CHARSET
);
2622 // create a content for the source file
2623 ::ucbhelper::Content aSourceContent
;
2624 if ( ::ucbhelper::Content::create( aSource
.GetMainURL( INetURLObject::NO_DECODE
), xEnv
, aSourceContent
) )
2628 // do the transfer ( copy source file to backup dir )
2629 bSuccess
= aContent
.transferContent( aSourceContent
,
2630 ::ucbhelper::InsertOperation_COPY
,
2632 NameClash::OVERWRITE
);
2635 pImp
->m_aBackupURL
= aDest
.GetMainURL( INetURLObject::NO_DECODE
);
2636 pImp
->m_bRemoveBackup
= sal_False
;
2639 catch ( ::com::sun::star::uno::Exception
& )
2648 eError
= ERRCODE_SFX_CANTCREATEBACKUP
;
2652 //------------------------------------------------------------------
2653 void SfxMedium::ClearBackup_Impl()
2655 if( pImp
->m_bRemoveBackup
)
2657 // currently a document is always stored in a new medium,
2658 // thus if a backup can not be removed the backup URL should not be cleaned
2659 if ( pImp
->m_aBackupURL
.getLength() )
2661 if ( ::utl::UCBContentHelper::Kill( pImp
->m_aBackupURL
) )
2662 // || !::utl::UCBContentHelper::IsDocument( pImp->m_aBackupURL ) );
2664 pImp
->m_bRemoveBackup
= sal_False
;
2665 pImp
->m_aBackupURL
= ::rtl::OUString();
2670 DBG_ERROR("Couldn't remove backup file!");
2675 pImp
->m_aBackupURL
= ::rtl::OUString();
2678 //----------------------------------------------------------------
2679 void SfxMedium::GetMedium_Impl()
2683 pImp
->bDownloadDone
= sal_False
;
2684 Reference
< ::com::sun::star::task::XInteractionHandler
> xInteractionHandler
= GetInteractionHandler();
2686 //TODO/MBA: need support for SID_STREAM
2687 SFX_ITEMSET_ARG( pSet
, pWriteStreamItem
, SfxUnoAnyItem
, SID_STREAM
, sal_False
);
2688 SFX_ITEMSET_ARG( pSet
, pInStreamItem
, SfxUnoAnyItem
, SID_INPUTSTREAM
, sal_False
);
2689 if ( pWriteStreamItem
)
2691 pWriteStreamItem
->GetValue() >>= pImp
->xStream
;
2693 if ( pInStreamItem
)
2694 pInStreamItem
->GetValue() >>= pImp
->xInputStream
;
2696 if ( !pImp
->xInputStream
.is() && pImp
->xStream
.is() )
2697 pImp
->xInputStream
= pImp
->xStream
->getInputStream();
2699 else if ( pInStreamItem
)
2701 pInStreamItem
->GetValue() >>= pImp
->xInputStream
;
2705 uno::Sequence
< beans::PropertyValue
> xProps
;
2709 if ( !::utl::LocalFileHelper::ConvertPhysicalNameToURL( aName
, aFileName
) )
2711 DBG_ERROR("Physical name not convertable!");
2715 aFileName
= GetName();
2717 // in case the temporary file exists the streams should be initialized from it,
2718 // but the original MediaDescriptor should not be changed
2719 sal_Bool bFromTempFile
= ( pImp
->pTempFile
|| pImp
->pTempDir
);
2721 if ( !bFromTempFile
)
2723 GetItemSet()->Put( SfxStringItem( SID_FILE_NAME
, aFileName
) );
2724 if( !(nStorOpenMode
& STREAM_WRITE
) )
2725 GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY
, TRUE
) );
2726 if (xInteractionHandler
.is())
2727 GetItemSet()->Put( SfxUnoAnyItem( SID_INTERACTIONHANDLER
, makeAny(xInteractionHandler
) ) );
2730 if ( m_xInputStreamToLoadFrom
.is() )
2732 pImp
->xInputStream
= m_xInputStreamToLoadFrom
;
2733 pImp
->xInputStream
->skipBytes(0);
2735 GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY
, sal_True
) );
2737 // m_xInputStreamToLoadFrom = 0;
2741 TransformItems( SID_OPENDOC
, *GetItemSet(), xProps
);
2742 comphelper::MediaDescriptor
aMedium( xProps
);
2744 if ( bFromTempFile
)
2746 aMedium
[comphelper::MediaDescriptor::PROP_URL()] <<= ::rtl::OUString( aFileName
);
2747 aMedium
.erase( comphelper::MediaDescriptor::PROP_READONLY() );
2748 aMedium
.addInputStream();
2750 else if ( SupportsActiveStreaming( GetURLObject().GetMainURL( INetURLObject::NO_DECODE
) ) )
2752 // use the special locking approach only for file URLs
2753 aMedium
.addInputStreamOwnLock();
2756 aMedium
.addInputStream();
2758 // the ReadOnly property set in aMedium is ignored
2759 // the check is done in LockOrigFileOnDemand() for file and non-file URLs
2761 //TODO/MBA: what happens if property is not there?!
2763 aMedium
[comphelper::MediaDescriptor::PROP_STREAM()] >>= pImp
->xStream
;
2764 aMedium
[comphelper::MediaDescriptor::PROP_INPUTSTREAM()] >>= pImp
->xInputStream
;
2765 if ( !pImp
->xInputStream
.is() && pImp
->xStream
.is() )
2766 pImp
->xInputStream
= pImp
->xStream
->getInputStream();
2769 if ( !bFromTempFile
)
2771 //TODO/MBA: need support for SID_STREAM
2772 if ( pImp
->xStream
.is() )
2773 GetItemSet()->Put( SfxUsrAnyItem( SID_STREAM
, makeAny( pImp
->xStream
) ) );
2775 GetItemSet()->Put( SfxUsrAnyItem( SID_INPUTSTREAM
, makeAny( pImp
->xInputStream
) ) );
2779 //TODO/MBA: ErrorHandling - how to transport error from MediaDescriptor
2780 if ( !GetError() && !pImp
->xStream
.is() && !pImp
->xInputStream
.is() )
2781 SetError( ERRCODE_IO_ACCESSDENIED
, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
) ) );
2785 if ( pImp
->xStream
.is() )
2786 pInStream
= utl::UcbStreamHelper::CreateStream( pImp
->xStream
);
2787 else if ( pImp
->xInputStream
.is() )
2788 pInStream
= utl::UcbStreamHelper::CreateStream( pImp
->xInputStream
);
2791 pImp
->bDownloadDone
= sal_True
;
2792 pImp
->aDoneLink
.ClearPendingCall();
2793 pImp
->aDoneLink
.Call( (void*) GetError() );
2797 //------------------------------------------------------------------
2798 SfxPoolCancelManager_Impl
* SfxMedium::GetCancelManager_Impl() const
2800 return pImp
->GetCancelManager();
2803 //------------------------------------------------------------------
2804 void SfxMedium::SetCancelManager_Impl( SfxPoolCancelManager_Impl
* pMgr
)
2806 pImp
->xCancelManager
= pMgr
;
2809 //----------------------------------------------------------------
2810 void SfxMedium::CancelTransfers()
2812 if( pImp
->xCancelManager
.Is() )
2813 pImp
->xCancelManager
->Cancel();
2816 //----------------------------------------------------------------
2818 String SfxMedium::GetStatusString( const SvProgressArg* pArg )
2821 StringList_Impl aSL( SfxResId( RID_DLSTATUS2 ), (USHORT)pArg->eStatus );
2824 if ( pArg->eStatus == SVBINDSTATUS_ENDDOWNLOADDATA && nTotal <= 1 )
2829 INetURLObject aObj( pArg->rStatus );
2830 aString = aSL.GetString();
2831 aString.SearchAndReplaceAscii( "$(HOST)", aObj.GetHost() );
2832 String aTarget = aObj.GetFull();
2833 if( aTarget.Len() <= 1 && pArg->eStatus != SVBINDSTATUS_CONNECTING )
2834 aTarget = aObj.GetHost();
2837 aTarget += DEFINE_CONST_UNICODE( " (" );
2838 AddNumber_Impl( aTarget, pArg->nMax );
2842 aString.SearchAndReplaceAscii( "$(TARGET)",aTarget );
2844 AddNumber_Impl( aNumber, pArg->nProgress );
2847 aNumber+= DEFINE_CONST_UNICODE( " (" );
2848 AddNumber_Impl( aNumber, (ULONG)pArg->nRate );
2849 aNumber+= DEFINE_CONST_UNICODE( "/s)" );
2851 if( pArg->nMax && pArg->nProgress && pArg->nMax != pArg->nProgress )
2853 aNumber += DEFINE_CONST_UNICODE( " [" );
2854 float aPerc = pArg->nProgress / (float)pArg->nMax;
2855 aNumber += String::CreateFromInt32( (USHORT)(aPerc * 100) );
2856 aNumber += DEFINE_CONST_UNICODE( "%]" );
2858 aString.SearchAndReplaceAscii( "$(BYTE)", aNumber );
2864 sal_Bool
SfxMedium::IsRemote()
2869 //------------------------------------------------------------------
2871 void SfxMedium::SetUpdatePickList(sal_Bool bVal
)
2874 pImp
= new SfxMedium_Impl( this );
2875 pImp
->bUpdatePickList
= bVal
;
2877 //------------------------------------------------------------------
2879 sal_Bool
SfxMedium::IsUpdatePickList() const
2881 return pImp
? pImp
->bUpdatePickList
: sal_True
;
2883 //----------------------------------------------------------------
2885 void SfxMedium::SetDoneLink( const Link
& rLink
)
2887 pImp
->aDoneLink
= rLink
;
2890 //----------------------------------------------------------------
2892 void SfxMedium::SetDataAvailableLink( const Link
& rLink
)
2894 pImp
->aAvailableLink
= rLink
;
2897 //----------------------------------------------------------------
2898 void SfxMedium::StartDownload()
2903 void SfxMedium::DownLoad( const Link
& aLink
)
2905 SetDoneLink( aLink
);
2907 if ( pInStream
&& !aLink
.IsSet() )
2909 while( !pImp
->bDownloadDone
)
2910 Application::Yield();
2914 //------------------------------------------------------------------
2915 void SfxMedium::Init_Impl()
2917 Setzt in den Logischen Namen eine gueltige ::com::sun::star::util::URL (Falls zuvor ein Filename
2918 drin war) und setzt den physikalschen Namen auf den Filenamen, falls
2923 Reference
< XOutputStream
> rOutStream
;
2925 // TODO/LATER: handle lifetime of storages
2926 pImp
->bDisposeStorage
= FALSE
;
2928 SFX_ITEMSET_ARG( pSet
, pSalvageItem
, SfxStringItem
, SID_DOC_SALVAGE
, sal_False
);
2929 if ( pSalvageItem
&& !pSalvageItem
->GetValue().Len() )
2931 pSalvageItem
= NULL
;
2932 pSet
->ClearItem( SID_DOC_SALVAGE
);
2935 if( aLogicName
.Len() )
2937 INetURLObject
aUrl( aLogicName
);
2938 INetProtocol eProt
= aUrl
.GetProtocol();
2939 if ( eProt
== INET_PROT_NOT_VALID
)
2941 DBG_ERROR ( "Unknown protocol!" );
2945 if ( aUrl
.HasMark() )
2947 aLogicName
= aUrl
.GetURLNoMark( INetURLObject::NO_DECODE
);
2948 GetItemSet()->Put( SfxStringItem( SID_JUMPMARK
, aUrl
.GetMark() ) );
2951 // try to convert the URL into a physical name - but never change a physical name
2952 // physical name may be set if the logical name is changed after construction
2954 ::utl::LocalFileHelper::ConvertURLToPhysicalName( GetURLObject().GetMainURL( INetURLObject::NO_DECODE
), aName
);
2956 DBG_ASSERT( pSalvageItem
, "Suspicious change of logical name!" );
2961 if ( pSalvageItem
&& pSalvageItem
->GetValue().Len() )
2963 aLogicName
= pSalvageItem
->GetValue();
2965 pImp
->m_bSalvageMode
= sal_True
;
2968 // in case output stream is by mistake here
2969 // clear the reference
2970 SFX_ITEMSET_ARG( pSet
, pOutStreamItem
, SfxUnoAnyItem
, SID_OUTPUTSTREAM
, sal_False
);
2972 && ( !( pOutStreamItem
->GetValue() >>= rOutStream
)
2973 || !aLogicName
.CompareToAscii( "private:stream", 14 ) == COMPARE_EQUAL
) )
2975 pSet
->ClearItem( SID_OUTPUTSTREAM
);
2976 DBG_ERROR( "Unexpected Output stream parameter!\n" );
2979 if ( aLogicName
.Len() )
2981 // if the logic name is set it should be set in MediaDescriptor as well
2982 SFX_ITEMSET_ARG( pSet
, pFileNameItem
, SfxStringItem
, SID_FILE_NAME
, FALSE
);
2983 if ( !pFileNameItem
)
2985 // let the ItemSet be created if necessary
2986 GetItemSet()->Put( SfxStringItem( SID_FILE_NAME
, INetURLObject( aLogicName
).GetMainURL( INetURLObject::NO_DECODE
) ) );
2993 //------------------------------------------------------------------
2994 SfxMedium::SfxMedium()
2995 : IMPL_CTOR( sal_False
, 0 ), // bRoot, pURLObj
2999 pImp(new SfxMedium_Impl( this ))
3003 //------------------------------------------------------------------
3005 SfxMedium::SfxMedium( const SfxMedium
& rMedium
, sal_Bool bTemporary
)
3007 IMPL_CTOR( sal_True
, // bRoot, pURLObj
3008 rMedium
.pURLObj
? new INetURLObject(*rMedium
.pURLObj
) : 0 ),
3009 pImp(new SfxMedium_Impl( this ))
3011 bDirect
= rMedium
.IsDirect();
3012 nStorOpenMode
= rMedium
.GetOpenMode();
3014 aName
= rMedium
.aName
;
3016 pImp
->bIsTemp
= bTemporary
;
3017 DBG_ASSERT( ! rMedium
.pImp
->bIsTemp
, "Temporaeres Medium darf nicht kopiert werden" );
3018 aLogicName
= rMedium
.aLogicName
;
3019 pSet
= rMedium
.GetItemSet() ? new SfxItemSet(*rMedium
.GetItemSet()) : 0;
3020 pFilter
= rMedium
.pFilter
;
3026 //------------------------------------------------------------------
3028 void SfxMedium::UseInteractionHandler( BOOL bUse
)
3030 pImp
->bAllowDefaultIntHdl
= bUse
;
3033 //------------------------------------------------------------------
3035 ::com::sun::star::uno::Reference
< ::com::sun::star::task::XInteractionHandler
>
3036 SfxMedium::GetInteractionHandler()
3038 // if interaction isnt allowed explicitly ... return empty reference!
3039 if ( !pImp
->bUseInteractionHandler
)
3040 return ::com::sun::star::uno::Reference
< ::com::sun::star::task::XInteractionHandler
>();
3042 // search a possible existing handler inside cached item set
3045 ::com::sun::star::uno::Reference
< ::com::sun::star::task::XInteractionHandler
> xHandler
;
3046 SFX_ITEMSET_ARG( pSet
, pHandler
, SfxUnoAnyItem
, SID_INTERACTIONHANDLER
, sal_False
);
3047 if ( pHandler
&& (pHandler
->GetValue() >>= xHandler
) && xHandler
.is() )
3051 // if default interaction isnt allowed explicitly ... return empty reference!
3052 if ( !pImp
->bAllowDefaultIntHdl
)
3053 return ::com::sun::star::uno::Reference
< ::com::sun::star::task::XInteractionHandler
>();
3055 // otherwhise return cached default handler ... if it exist.
3056 if ( pImp
->xInteraction
.is() )
3057 return pImp
->xInteraction
;
3059 // create default handler and cache it!
3060 ::com::sun::star::uno::Reference
< ::com::sun::star::lang::XMultiServiceFactory
> xFactory
= ::comphelper::getProcessServiceFactory();
3061 if ( xFactory
.is() )
3063 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
);
3064 return pImp
->xInteraction
;
3067 return ::com::sun::star::uno::Reference
< ::com::sun::star::task::XInteractionHandler
>();
3070 //----------------------------------------------------------------
3072 void SfxMedium::SetFilter( const SfxFilter
* pFilterP
, sal_Bool
/*bResetOrig*/ )
3075 pImp
->nFileVersion
= 0;
3077 //----------------------------------------------------------------
3079 const SfxFilter
* SfxMedium::GetOrigFilter( sal_Bool bNotCurrent
) const
3081 return ( pImp
->pOrigFilter
|| bNotCurrent
) ? pImp
->pOrigFilter
: pFilter
;
3083 //----------------------------------------------------------------
3085 void SfxMedium::SetOrigFilter_Impl( const SfxFilter
* pOrigFilter
)
3087 pImp
->pOrigFilter
= pOrigFilter
;
3089 //------------------------------------------------------------------
3091 void SfxMedium::Close()
3093 if ( pImp
->xStorage
.is() )
3095 // don't close the streams if they belong to the
3097 //TODO/MBA: how to?! Do we need the flag?!
3099 const SvStream *pStream = aStorage->GetSvStream();
3100 if ( pStream && pStream == pInStream )
3102 CloseReadStorage_Impl();
3104 pImp->xInputStream = Reference < XInputStream >();
3105 pImp->xLockBytes.Clear();
3107 pSet->ClearItem( SID_INPUTSTREAM );
3108 aStorage->SetDeleteStream( TRUE );
3110 else if ( pStream && pStream == pOutStream )
3113 aStorage->SetDeleteStream( TRUE );
3119 CloseStreams_Impl();
3124 void SfxMedium::CloseAndRelease()
3126 if ( pImp
->xStorage
.is() )
3128 // don't close the streams if they belong to the
3130 //TODO/MBA: how to?! Do we need the flag?!
3132 const SvStream *pStream = aStorage->GetSvStream();
3133 if ( pStream && pStream == pInStream )
3135 CloseReadStorage_Impl();
3137 pImp->xInputStream = Reference < XInputStream >();
3138 pImp->xLockBytes.Clear();
3140 pSet->ClearItem( SID_INPUTSTREAM );
3141 aStorage->SetDeleteStream( TRUE );
3143 else if ( pStream && pStream == pOutStream )
3146 aStorage->SetDeleteStream( TRUE );
3152 CloseAndReleaseStreams_Impl();
3157 void SfxMedium::UnlockFile()
3159 if ( pImp
->m_bLocked
)
3163 pImp
->m_bLocked
= sal_False
;
3164 ::svt::DocumentLockFile
aLockFile( aLogicName
);
3165 // TODO/LATER: A warning could be shown in case the file is not the own one
3166 aLockFile
.RemoveFile();
3168 catch( uno::Exception
& )
3173 void SfxMedium::CloseAndReleaseStreams_Impl()
3175 CloseReadStorage_Impl();
3177 uno::Reference
< io::XInputStream
> xInToClose
= pImp
->xInputStream
;
3178 uno::Reference
< io::XOutputStream
> xOutToClose
;
3179 if ( pImp
->xStream
.is() )
3180 xOutToClose
= pImp
->xStream
->getOutputStream();
3182 // The probably exsisting SvStream wrappers should be closed first
3183 CloseStreams_Impl();
3185 // in case of salvage mode the storage is based on the streams
3186 if ( !pImp
->m_bSalvageMode
)
3190 if ( xInToClose
.is() )
3191 xInToClose
->closeInput();
3192 if ( xOutToClose
.is() )
3193 xOutToClose
->closeOutput();
3195 catch ( uno::Exception
& )
3201 //------------------------------------------------------------------
3202 void SfxMedium::CloseStreams_Impl()
3204 CloseInStream_Impl();
3205 CloseOutStream_Impl();
3208 pSet
->ClearItem( SID_CONTENT
);
3210 pImp
->aContent
= ::ucbhelper::Content();
3213 //------------------------------------------------------------------
3215 void SfxMedium::RefreshName_Impl()
3218 if ( pImp
->aContent
.get().is() )
3220 String aNameP
= pImp
->xAnchor
->GetViewURL();
3221 pImp
->aOrigURL
= aNameP
;
3222 aLogicName
= aNameP
;
3224 if (aLogicName
.Len())
3225 aLogicName
= GetURLObject().GetMainURL( INetURLObject::NO_DECODE
);
3231 void SfxMedium::SetIsRemote_Impl()
3233 INetURLObject
aObj( GetName() );
3234 switch( aObj
.GetProtocol() )
3237 case INET_PROT_HTTP
:
3238 case INET_PROT_HTTPS
:
3239 case INET_PROT_POP3
:
3240 case INET_PROT_NEWS
:
3241 case INET_PROT_IMAP
:
3242 // case INET_PROT_OUT:
3244 bRemote
= TRUE
; break;
3246 bRemote
= ( GetName().CompareToAscii( "private:msgid", 13 ) == COMPARE_EQUAL
);
3250 // Da Dateien, die Remote geschrieben werden zur Uebertragung auch
3251 // gelesen werden koennen muessen
3253 nStorOpenMode
|= STREAM_READ
;
3258 void SfxMedium::SetName( const String
& aNameP
, sal_Bool bSetOrigURL
)
3260 if( !pImp
->aOrigURL
.Len() )
3261 pImp
->aOrigURL
= aLogicName
;
3263 pImp
->aOrigURL
= aNameP
;
3264 aLogicName
= aNameP
;
3266 pImp
->aContent
= ::ucbhelper::Content();
3270 //----------------------------------------------------------------
3271 const String
& SfxMedium::GetOrigURL() const
3273 return !pImp
->aOrigURL
.Len() ? (String
&)aLogicName
: pImp
->aOrigURL
;
3276 //----------------------------------------------------------------
3278 void SfxMedium::SetPhysicalName_Impl( const String
& rNameP
)
3280 if ( rNameP
!= aName
)
3282 if( pImp
->pTempFile
)
3284 delete pImp
->pTempFile
;
3285 pImp
->pTempFile
= NULL
;
3288 if ( aName
.Len() || rNameP
.Len() )
3289 pImp
->aContent
= ::ucbhelper::Content();
3292 bTriedStorage
= sal_False
;
3293 pImp
->bIsStorage
= sal_False
;
3297 //----------------------------------------------------------------
3298 void SfxMedium::MoveTempTo_Impl( SfxMedium
* pMedium
)
3300 if ( pMedium
&& pMedium
!= this && pImp
->pTempFile
)
3302 if( pMedium
->pImp
->pTempFile
)
3303 delete pMedium
->pImp
->pTempFile
;
3304 pMedium
->pImp
->pTempFile
= pImp
->pTempFile
;
3306 pImp
->pTempFile
->EnableKillingFile( sal_True
);
3307 pImp
->pTempFile
= NULL
;
3309 pMedium
->aName
= pMedium
->pImp
->pTempFile
->GetFileName();
3311 pMedium
->CloseInStream();
3312 pMedium
->CloseStorage();
3313 pMedium
->pImp
->aContent
= ::ucbhelper::Content();
3317 //------------------------------------------------------------------
3318 void SfxMedium::SetTemporary( sal_Bool bTemp
)
3320 pImp
->bIsTemp
= bTemp
;
3323 //------------------------------------------------------------------
3324 sal_Bool
SfxMedium::IsTemporary() const
3326 return pImp
->bIsTemp
;
3329 //------------------------------------------------------------------
3331 sal_Bool
SfxMedium::Exists( sal_Bool
/*bForceSession*/ )
3333 DBG_ERROR( "Not implemented!" );
3337 //------------------------------------------------------------------
3339 void SfxMedium::ReOpen()
3341 BOOL bUseInteractionHandler
= pImp
->bUseInteractionHandler
;
3342 pImp
->bUseInteractionHandler
= FALSE
;
3344 pImp
->bUseInteractionHandler
= bUseInteractionHandler
;
3347 //------------------------------------------------------------------
3349 void SfxMedium::CompleteReOpen()
3351 // do not use temporary file for reopen and in case of success throw the temporary file away
3352 BOOL bUseInteractionHandler
= pImp
->bUseInteractionHandler
;
3353 pImp
->bUseInteractionHandler
= FALSE
;
3355 ::utl::TempFile
* pTmpFile
= NULL
;
3356 if ( pImp
->pTempFile
)
3358 pTmpFile
= pImp
->pTempFile
;
3359 pImp
->pTempFile
= NULL
;
3367 if ( pImp
->pTempFile
)
3369 pImp
->pTempFile
->EnableKillingFile( sal_True
);
3370 delete pImp
->pTempFile
;
3372 pImp
->pTempFile
= pTmpFile
;
3373 if ( pImp
->pTempFile
)
3374 aName
= pImp
->pTempFile
->GetFileName();
3378 pTmpFile
->EnableKillingFile( sal_True
);
3383 pImp
->bUseInteractionHandler
= bUseInteractionHandler
;
3386 //------------------------------------------------------------------
3387 SfxMedium::SfxMedium
3389 const String
&rName
, StreamMode nOpenMode
, sal_Bool bDirectP
,
3390 const SfxFilter
*pFlt
, SfxItemSet
*pInSet
3392 : IMPL_CTOR( sal_False
, 0 ), // bRoot, pURLObj
3395 pImp(new SfxMedium_Impl( this ))
3398 nStorOpenMode
= nOpenMode
;
3404 SfxMedium::SfxMedium( const ::com::sun::star::uno::Sequence
< ::com::sun::star::beans::PropertyValue
>& aArgs
)
3405 : IMPL_CTOR( sal_False
, 0 ), // bRoot, pURLObj
3408 pImp(new SfxMedium_Impl( this ))
3410 SfxAllItemSet
*pParams
= new SfxAllItemSet( SFX_APP()->GetPool() );
3412 TransformParameters( SID_OPENDOC
, aArgs
, *pParams
);
3415 SFX_ITEMSET_ARG( pSet
, pFilterNameItem
, SfxStringItem
, SID_FILTER_NAME
, sal_False
);
3416 if( pFilterNameItem
)
3417 aFilterName
= pFilterNameItem
->GetValue();
3418 pFilter
= SFX_APP()->GetFilterMatcher().GetFilter4FilterName( aFilterName
);
3420 sal_Bool bSalvage
= sal_False
;
3421 SFX_ITEMSET_ARG( pSet
, pSalvageItem
, SfxStringItem
, SID_DOC_SALVAGE
, sal_False
);
3424 // QUESTION: there is some treatment of Salvage in Init_Impl; align!
3425 bSalvage
= sal_True
;
3426 if ( pSalvageItem
->GetValue().Len() )
3428 // if an URL is provided in SalvageItem that means that the FileName refers to a temporary file
3429 // that must be copied here
3431 SFX_ITEMSET_ARG( pSet
, pFileNameItem
, SfxStringItem
, SID_FILE_NAME
, FALSE
);
3432 if (!pFileNameItem
) throw uno::RuntimeException();
3433 ::rtl::OUString aNewTempFileURL
= SfxMedium::CreateTempCopyWithExt( pFileNameItem
->GetValue() );
3434 if ( aNewTempFileURL
.getLength() )
3436 pSet
->Put( SfxStringItem( SID_FILE_NAME
, aNewTempFileURL
) );
3437 pSet
->ClearItem( SID_INPUTSTREAM
);
3438 pSet
->ClearItem( SID_STREAM
);
3439 pSet
->ClearItem( SID_CONTENT
);
3443 OSL_ENSURE( sal_False
, "Can not create a new temporary file for crash recovery!\n" );
3448 BOOL bReadOnly
= FALSE
;
3449 SFX_ITEMSET_ARG( pSet
, pReadOnlyItem
, SfxBoolItem
, SID_DOC_READONLY
, FALSE
);
3450 if ( pReadOnlyItem
&& pReadOnlyItem
->GetValue() )
3453 SFX_ITEMSET_ARG( pSet
, pFileNameItem
, SfxStringItem
, SID_FILE_NAME
, FALSE
);
3454 if (!pFileNameItem
) throw uno::RuntimeException();
3455 aLogicName
= pFileNameItem
->GetValue();
3456 nStorOpenMode
= bReadOnly
? SFX_STREAM_READONLY
: SFX_STREAM_READWRITE
;
3462 //------------------------------------------------------------------
3464 SfxMedium::SfxMedium( const uno::Reference
< embed::XStorage
>& rStor
, const String
& rBaseURL
, const SfxItemSet
* p
, sal_Bool bRootP
)
3465 : IMPL_CTOR( bRootP
, 0 ), // bRoot, pURLObj
3467 pImp( new SfxMedium_Impl( this ))
3469 String aType
= SfxFilter::GetTypeFromStorage( rStor
);
3470 pFilter
= SFX_APP()->GetFilterMatcher().GetFilter4EA( aType
);
3471 DBG_ASSERT( pFilter
, "No Filter for storage found!" );
3474 pImp
->xStorage
= rStor
;
3475 pImp
->bDisposeStorage
= FALSE
;
3477 // always take BaseURL first, could be overwritten by ItemSet
3478 GetItemSet()->Put( SfxStringItem( SID_DOC_BASEURL
, rBaseURL
) );
3480 GetItemSet()->Put( *p
);
3483 //------------------------------------------------------------------
3485 SfxMedium::~SfxMedium()
3488 Don't enable CancelTransfers() till you know that the writer/web has changed his asynchronous load
3489 behaviour. Otherwhise may StyleSheets inside a html file will be loaded at the right time.
3490 => further the help will be empty then ... #100490#
3492 //CancelTransfers();
3494 // if there is a requirement to clean the backup this is the last possibility to do it
3501 if( pImp
->bIsTemp
&& aName
.Len() )
3504 if ( !::utl::LocalFileHelper::ConvertPhysicalNameToURL( aName
, aTemp
))
3506 DBG_ERROR("Physical name not convertable!");
3509 if ( !::utl::UCBContentHelper::Kill( aTemp
) )
3511 DBG_ERROR("Couldn't remove temporary file!");
3520 //------------------------------------------------------------------
3522 void SfxMedium::SetItemSet(SfxItemSet
*pNewSet
)
3527 //------------------------------------------------------------------
3529 void SfxMedium::SetClassFilter( const SvGlobalName
& rFilterClass
)
3531 bSetFilter
= sal_True
;
3532 aFilterClass
= rFilterClass
;
3534 //----------------------------------------------------------------
3536 const INetURLObject
& SfxMedium::GetURLObject() const
3540 SfxMedium
* pThis
= const_cast < SfxMedium
* > (this);
3541 pThis
->pURLObj
= new INetURLObject( aLogicName
);
3542 if ( pThis
->pURLObj
->HasMark() )
3543 (*pThis
->pURLObj
) = INetURLObject( aLogicName
).GetURLNoMark();
3549 //----------------------------------------------------------------
3551 const String
& SfxMedium::GetPreRedirectedURL() const
3553 return pImp
->aPreRedirectionURL
;
3555 //----------------------------------------------------------------
3557 sal_uInt32
SfxMedium::GetMIMEAndRedirect( String
& /*rName*/ )
3559 /* dv !!!! not needed any longer ?
3560 INetProtocol eProt = GetURLObject().GetProtocol();
3561 if( eProt == INET_PROT_FTP && SvBinding::ShouldUseFtpProxy( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ) )
3563 Any aAny( UCB_Helper::GetProperty( GetContent(), WID_FLAG_IS_FOLDER ) );
3564 sal_Bool bIsFolder = FALSE;
3565 if ( ( aAny >>= bIsFolder ) && bIsFolder )
3566 return ERRCODE_NONE;
3570 if( !eError && pImp->xBinding.Is() )
3572 eError = pImp->xBinding->GetMimeType( rName );
3574 // Wir koennen keine Parameter wie CharSets usw.
3575 rName = rName.GetToken( 0, ';' );
3578 if( !pImp->aPreRedirectionURL.Len() )
3579 pImp->aPreRedirectionURL = aLogicName;
3580 SetName( pImp->xBinding->GetRedirectedURL() );
3582 pImp->aExpireTime = pImp->xBinding->GetExpireDateTime();
3589 //----------------------------------------------------------------
3591 void SfxMedium::SetReferer( const String
& rRefer
)
3593 pImp
->aReferer
= rRefer
;
3595 //----------------------------------------------------------------
3597 const String
& SfxMedium::GetReferer( ) const
3599 return pImp
->aReferer
;
3602 //----------------------------------------------------------------
3604 void SfxMedium::SetExpired_Impl( const DateTime
& rDateTime
)
3606 pImp
->aExpireTime
= rDateTime
;
3608 //----------------------------------------------------------------
3610 sal_Bool
SfxMedium::IsExpired() const
3612 return pImp
->aExpireTime
.IsValid() && pImp
->aExpireTime
< DateTime();
3614 //----------------------------------------------------------------
3616 void SfxMedium::ForceSynchronStream_Impl( sal_Bool bForce
)
3620 SvLockBytes
* pBytes
= pInStream
->GetLockBytes();
3622 pBytes
->SetSynchronMode( bForce
);
3624 pImp
->bForceSynchron
= bForce
;
3627 //----------------------------------------------------------------
3628 SfxFrame
* SfxMedium::GetLoadTargetFrame() const
3630 return pImp
->wLoadTargetFrame
;
3632 //----------------------------------------------------------------
3634 void SfxMedium::SetLoadTargetFrame(SfxFrame
* pFrame
)
3636 pImp
->wLoadTargetFrame
= pFrame
;
3638 //----------------------------------------------------------------
3640 void SfxMedium::SetStorage_Impl( const uno::Reference
< embed::XStorage
>& rStor
)
3642 pImp
->xStorage
= rStor
;
3644 //----------------------------------------------------------------
3646 SfxItemSet
* SfxMedium::GetItemSet() const
3648 // this method *must* return an ItemSet, returning NULL can cause crashes
3650 ((SfxMedium
*)this)->pSet
= new SfxAllItemSet( SFX_APP()->GetPool() );
3653 //----------------------------------------------------------------
3655 SvKeyValueIterator
* SfxMedium::GetHeaderAttributes_Impl()
3657 if( !pImp
->xAttributes
.Is() )
3659 pImp
->xAttributes
= SvKeyValueIteratorRef( new SvKeyValueIterator
);
3661 if ( GetContent().is() )
3663 pImp
->bIsCharsetInitialized
= sal_True
;
3667 Any aAny
= pImp
->aContent
.getPropertyValue( ::rtl::OUString::createFromAscii( "MediaType" ) );
3668 ::rtl::OUString aContentType
;
3669 aAny
>>= aContentType
;
3671 pImp
->xAttributes
->Append( SvKeyValue( ::rtl::OUString::createFromAscii( "content-type" ), aContentType
) );
3673 catch ( ::com::sun::star::uno::Exception
& )
3679 return pImp
->xAttributes
;
3681 //----------------------------------------------------------------
3683 SvCompatWeakHdl
* SfxMedium::GetHdl()
3685 return pImp
->GetHdl();
3688 sal_Bool
SfxMedium::IsDownloadDone_Impl()
3690 return pImp
->bDownloadDone
;
3693 //----------------------------------------------------------------
3695 void SfxMedium::SetDontCreateCancellable( )
3697 pImp
->bDontCreateCancellable
= sal_True
;
3700 ::com::sun::star::uno::Reference
< ::com::sun::star::io::XInputStream
> SfxMedium::GetInputStream()
3702 if ( !pImp
->xInputStream
.is() )
3704 return pImp
->xInputStream
;
3707 const uno::Sequence
< util::RevisionTag
>& SfxMedium::GetVersionList( bool _bNoReload
)
3709 // if the medium has no name, then this medium should represent a new document and can have no version info
3710 if ( ( !_bNoReload
|| !pImp
->m_bVersionsAlreadyLoaded
) && !pImp
->aVersions
.getLength() &&
3711 ( aName
.Len() || aLogicName
.Len() ) && GetStorage().is() )
3713 uno::Reference
< document::XDocumentRevisionListPersistence
> xReader( comphelper::getProcessServiceFactory()->createInstance(
3714 ::rtl::OUString::createFromAscii("com.sun.star.document.DocumentRevisionListPersistence") ), uno::UNO_QUERY
);
3719 pImp
->aVersions
= xReader
->load( GetStorage() );
3721 catch ( uno::Exception
& )
3727 if ( !pImp
->m_bVersionsAlreadyLoaded
)
3728 pImp
->m_bVersionsAlreadyLoaded
= sal_True
;
3730 return pImp
->aVersions
;
3733 uno::Sequence
< util::RevisionTag
> SfxMedium::GetVersionList( const uno::Reference
< embed::XStorage
>& xStorage
)
3735 uno::Reference
< document::XDocumentRevisionListPersistence
> xReader( comphelper::getProcessServiceFactory()->createInstance(
3736 ::rtl::OUString::createFromAscii("com.sun.star.document.DocumentRevisionListPersistence") ), uno::UNO_QUERY
);
3741 return xReader
->load( xStorage
);
3743 catch ( uno::Exception
& )
3748 return uno::Sequence
< util::RevisionTag
>();
3751 sal_uInt16
SfxMedium::AddVersion_Impl( util::RevisionTag
& rRevision
)
3753 if ( GetStorage().is() )
3755 // Einen eindeutigen Namen f"ur den Stream ermitteln
3757 sal_Int32 nLength
= pImp
->aVersions
.getLength();
3758 for ( sal_Int32 m
=0; m
<nLength
; m
++ )
3760 sal_uInt32 nVer
= (sal_uInt32
) String( pImp
->aVersions
[m
].Identifier
).Copy(7).ToInt32();
3762 for ( n
=0; n
<aLongs
.Count(); n
++ )
3763 if ( nVer
<aLongs
[n
] )
3766 aLongs
.Insert( nVer
, n
);
3770 for ( nKey
=0; nKey
<aLongs
.Count(); nKey
++ )
3771 if ( aLongs
[nKey
] > ( ULONG
) nKey
+1 )
3774 String aRevName
= DEFINE_CONST_UNICODE( "Version" );
3775 aRevName
+= String::CreateFromInt32( nKey
+ 1 );
3776 pImp
->aVersions
.realloc( nLength
+1 );
3777 rRevision
.Identifier
= aRevName
;
3778 pImp
->aVersions
[nLength
] = rRevision
;
3785 sal_Bool
SfxMedium::RemoveVersion_Impl( const ::rtl::OUString
& rName
)
3787 if ( !pImp
->aVersions
.getLength() )
3790 sal_Int32 nLength
= pImp
->aVersions
.getLength();
3791 for ( sal_Int32 n
=0; n
<nLength
; n
++ )
3793 if ( pImp
->aVersions
[n
].Identifier
== rName
)
3795 for ( sal_Int32 m
=n
; m
<nLength
-1; m
++ )
3796 pImp
->aVersions
[m
] = pImp
->aVersions
[m
+1];
3797 pImp
->aVersions
.realloc(nLength
-1);
3805 sal_Bool
SfxMedium::TransferVersionList_Impl( SfxMedium
& rMedium
)
3807 if ( rMedium
.pImp
->aVersions
.getLength() )
3809 pImp
->aVersions
= rMedium
.pImp
->aVersions
;
3816 sal_Bool
SfxMedium::SaveVersionList_Impl( sal_Bool
/*bUseXML*/ )
3818 if ( GetStorage().is() )
3820 if ( !pImp
->aVersions
.getLength() )
3823 uno::Reference
< document::XDocumentRevisionListPersistence
> xWriter( comphelper::getProcessServiceFactory()->createInstance(
3824 ::rtl::OUString::createFromAscii("com.sun.star.document.DocumentRevisionListPersistence") ), uno::UNO_QUERY
);
3829 xWriter
->store( GetStorage(), pImp
->aVersions
);
3832 catch ( uno::Exception
& )
3841 //----------------------------------------------------------------
3842 sal_Bool
SfxMedium::IsReadOnly()
3844 sal_Bool bReadOnly
= sal_False
;
3846 // a) ReadOnly filter cant produce read/write contents!
3849 ((pFilter
->GetFilterFlags() & SFX_FILTER_OPENREADONLY
) == SFX_FILTER_OPENREADONLY
)
3852 // b) if filter allow read/write contents .. check open mode of the storage
3854 bReadOnly
= !( GetOpenMode() & STREAM_WRITE
);
3856 // c) the API can force the readonly state!
3859 SFX_ITEMSET_ARG( GetItemSet(), pItem
, SfxBoolItem
, SID_DOC_READONLY
, sal_False
);
3861 bReadOnly
= pItem
->GetValue();
3867 //----------------------------------------------------------------
3868 void SfxMedium::TryToSwitchToRepairedTemp()
3870 // the medium should be opened in repair mode
3871 SFX_ITEMSET_ARG( GetItemSet(), pRepairItem
, SfxBoolItem
, SID_REPAIRPACKAGE
, FALSE
);
3872 if ( pRepairItem
&& pRepairItem
->GetValue() )
3874 DBG_ASSERT( pImp
->xStorage
.is(), "Possible performance problem" );
3875 if ( GetStorage().is() )
3877 ::utl::TempFile
* pTmpFile
= new ::utl::TempFile();
3878 pTmpFile
->EnableKillingFile( sal_True
);
3879 ::rtl::OUString aNewName
= pTmpFile
->GetFileName();
3881 if( aNewName
.getLength() )
3885 uno::Reference
< embed::XStorage
> xNewStorage
= comphelper::OStorageHelper::GetStorageFromURL( aNewName
,
3886 embed::ElementModes::READWRITE
| embed::ElementModes::TRUNCATE
);
3887 //SvStorageRef aNewStorage = new SvStorage( sal_True, aNewName, STREAM_WRITE | STREAM_TRUNC, STORAGE_TRANSACTED );
3889 pImp
->xStorage
->copyToStorage( xNewStorage
);
3890 //if ( aNewStorage->GetError() == SVSTREAM_OK )
3894 if ( pImp
->pTempFile
)
3895 DELETEZ( pImp
->pTempFile
);
3897 pImp
->pTempFile
= pTmpFile
;
3901 catch ( uno::Exception
& )
3903 //TODO/MBA: error handling
3904 //SetError( aNewStorage->GetError(, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) )) );
3908 SetError( ERRCODE_IO_CANTWRITE
, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
) ) );
3910 if (pImp
->pTempFile
!= pTmpFile
)
3914 SetError( ERRCODE_IO_CANTREAD
, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
) ) );
3918 //----------------------------------------------------------------
3919 void SfxMedium::CreateTempFile()
3921 if ( pImp
->pTempFile
)
3923 DELETEZ( pImp
->pTempFile
);
3927 StreamMode nOpenMode
= nStorOpenMode
;
3928 BOOL bCopy
= ( nStorOpenMode
== nOpenMode
&& ! ( nOpenMode
& STREAM_TRUNC
) );
3929 if ( bCopy
&& !pInStream
)
3931 if ( GetContent().is() )
3935 // make sure that the desired file exists before trying to open
3936 SvMemoryStream
aStream(0,0);
3937 ::utl::OInputStreamWrapper
* pInput
= new ::utl::OInputStreamWrapper( aStream
);
3938 Reference
< XInputStream
> xInput( pInput
);
3940 InsertCommandArgument aInsertArg
;
3941 aInsertArg
.Data
= xInput
;
3943 aInsertArg
.ReplaceExisting
= sal_False
;
3945 aCmdArg
<<= aInsertArg
;
3946 pImp
->aContent
.executeCommand( ::rtl::OUString::createFromAscii( "insert" ), aCmdArg
);
3948 catch ( Exception
& )
3950 // it is NOT an error when the stream already exists!
3956 nStorOpenMode
= nOpenMode
;
3959 pImp
->pTempFile
= new ::utl::TempFile();
3960 pImp
->pTempFile
->EnableKillingFile( sal_True
);
3961 aName
= pImp
->pTempFile
->GetFileName();
3964 SetError( ERRCODE_IO_CANTWRITE
, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
) ) );
3968 if ( bCopy
&& pInStream
)
3973 char *pBuf
= new char [8192];
3974 sal_uInt32 nErr
= ERRCODE_NONE
;
3977 pOutStream
->Seek(0);
3979 while( !pInStream
->IsEof() && nErr
== ERRCODE_NONE
)
3981 sal_uInt32 nRead
= pInStream
->Read( pBuf
, 8192 );
3982 nErr
= pInStream
->GetError();
3983 pOutStream
->Write( pBuf
, nRead
);
3989 CloseOutStream_Impl();
3997 //----------------------------------------------------------------
3998 void SfxMedium::CreateTempFileNoCopy()
4000 if ( pImp
->pTempFile
)
4001 delete pImp
->pTempFile
;
4003 pImp
->pTempFile
= new ::utl::TempFile();
4004 pImp
->pTempFile
->EnableKillingFile( sal_True
);
4005 aName
= pImp
->pTempFile
->GetFileName();
4008 SetError( ERRCODE_IO_CANTWRITE
, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
) ) );
4012 CloseOutStream_Impl();
4016 ::rtl::OUString
SfxMedium::GetCharset()
4018 if( !pImp
->bIsCharsetInitialized
)
4020 // Set an error in case there is no content?
4021 if ( GetContent().is() )
4023 pImp
->bIsCharsetInitialized
= sal_True
;
4027 Any aAny
= pImp
->aContent
.getPropertyValue( ::rtl::OUString::createFromAscii( "MediaType" ) );
4028 ::rtl::OUString aField
;
4031 ::rtl::OString sContent
= ::rtl::OUStringToOString( aField
, RTL_TEXTENCODING_ASCII_US
);
4032 ByteString sType
, sSubType
;
4033 INetContentTypeParameterList aParameters
;
4035 if( INetContentTypes::parse( sContent
, sType
, sSubType
, &aParameters
) )
4037 const INetContentTypeParameter
* pCharset
= aParameters
.find("charset");
4039 pImp
->aCharset
= pCharset
->m_sValue
;
4042 catch ( ::com::sun::star::uno::Exception
& )
4048 return pImp
->aCharset
;
4051 void SfxMedium::SetCharset( ::rtl::OUString aChs
)
4053 pImp
->bIsCharsetInitialized
= sal_True
;
4054 pImp
->aCharset
= aChs
;
4057 sal_Bool
SfxMedium::SignContents_Impl( sal_Bool bScriptingContent
)
4059 DBG_ASSERT( GetStorage().is(), "SfxMedium::SignContents_Impl - Storage doesn't exist!" );
4061 sal_Bool bChanges
= FALSE
;
4063 ::com::sun::star::uno::Reference
< ::com::sun::star::security::XDocumentDigitalSignatures
> xD(
4064 comphelper::getProcessServiceFactory()->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.security.DocumentDigitalSignatures" ) ) ), ::com::sun::star::uno::UNO_QUERY
);
4066 // TODO/LATER: error handling
4067 if ( xD
.is() && GetStorage().is() )
4069 sal_Int32 nEncrMode
= IsReadOnly() ? embed::ElementModes::READ
4070 : embed::ElementModes::READWRITE
;
4074 uno::Reference
< embed::XStorage
> xMetaInf
= GetStorage()->openStorageElement(
4075 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "META-INF" ) ),
4077 if ( !xMetaInf
.is() )
4078 throw uno::RuntimeException();
4080 if ( bScriptingContent
)
4082 if ( !IsReadOnly() )
4084 uno::Reference
< io::XStream
> xStream
= xMetaInf
->openStreamElement(
4085 xD
->getScriptingContentSignatureDefaultStreamName(),
4087 if ( !xStream
.is() )
4088 throw uno::RuntimeException();
4092 // to leave the stream unencrypted as before
4093 uno::Reference
< beans::XPropertySet
> xStrmProps( xStream
, uno::UNO_QUERY_THROW
);
4094 xStrmProps
->setPropertyValue(
4095 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UseCommonStoragePasswordEncryption" ) ),
4096 uno::makeAny( (sal_Bool
)sal_False
) );
4098 catch ( uno::Exception
& )
4101 if ( xD
->signScriptingContent( GetLastCommitReadStorage_Impl(), xStream
) )
4103 uno::Reference
< embed::XTransactedObject
> xTrans( xMetaInf
, uno::UNO_QUERY
);
4110 xD
->showScriptingContentSignatures( GetLastCommitReadStorage_Impl(), uno::Reference
< io::XInputStream
>() );
4114 if ( !IsReadOnly() )
4116 uno::Reference
< io::XStream
> xStream
= xMetaInf
->openStreamElement(
4117 xD
->getDocumentContentSignatureDefaultStreamName(),
4119 if ( !xStream
.is() )
4120 throw uno::RuntimeException();
4124 // to leave the stream unencrypted as before
4125 uno::Reference
< beans::XPropertySet
> xStrmProps( xStream
, uno::UNO_QUERY_THROW
);
4126 xStrmProps
->setPropertyValue(
4127 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UseCommonStoragePasswordEncryption" ) ),
4128 uno::makeAny( (sal_Bool
)sal_False
) );
4130 catch ( uno::Exception
& )
4133 if ( xD
->signDocumentContent( GetLastCommitReadStorage_Impl(), xStream
) )
4135 uno::Reference
< embed::XTransactedObject
> xTrans( xMetaInf
, uno::UNO_QUERY
);
4143 xD
->showDocumentContentSignatures( GetLastCommitReadStorage_Impl(), uno::Reference
< io::XInputStream
>() );
4146 catch( uno::Exception
& )
4148 OSL_ENSURE( sal_False
, "Couldn't use signing functionality!\n" );
4154 //----------------------------------------------------------------
4155 sal_uInt16
SfxMedium::GetCachedSignatureState_Impl()
4157 return pImp
->m_nSignatureState
;
4160 //----------------------------------------------------------------
4161 void SfxMedium::SetCachedSignatureState_Impl( sal_uInt16 nState
)
4163 pImp
->m_nSignatureState
= nState
;
4166 //----------------------------------------------------------------
4167 sal_Bool
SfxMedium::EqualURLs( const ::rtl::OUString
& aFirstURL
, const ::rtl::OUString
& aSecondURL
)
4169 sal_Bool bResult
= sal_False
;
4171 if ( aFirstURL
.getLength() && aSecondURL
.getLength() )
4173 INetURLObject
aFirst( aFirstURL
);
4174 INetURLObject
aSecond( aSecondURL
);
4176 if ( aFirst
.GetProtocol() != INET_PROT_NOT_VALID
&& aSecond
.GetProtocol() != INET_PROT_NOT_VALID
)
4180 ::ucbhelper::ContentBroker
* pBroker
= ::ucbhelper::ContentBroker::get();
4182 throw uno::RuntimeException();
4184 uno::Reference
< ::com::sun::star::ucb::XContentIdentifierFactory
> xIdFac
4185 = pBroker
->getContentIdentifierFactoryInterface();
4187 throw uno::RuntimeException();
4189 uno::Reference
< ::com::sun::star::ucb::XContentIdentifier
> xIdFirst
4190 = xIdFac
->createContentIdentifier( aFirst
.GetMainURL( INetURLObject::NO_DECODE
) );
4191 uno::Reference
< ::com::sun::star::ucb::XContentIdentifier
> xIdSecond
4192 = xIdFac
->createContentIdentifier( aSecond
.GetMainURL( INetURLObject::NO_DECODE
) );
4194 if ( xIdFirst
.is() && xIdSecond
.is() )
4196 uno::Reference
< ::com::sun::star::ucb::XContentProvider
> xProvider
=
4197 pBroker
->getContentProviderInterface();
4198 if ( !xProvider
.is() )
4199 throw uno::RuntimeException();
4200 bResult
= !xProvider
->compareContentIds( xIdFirst
, xIdSecond
);
4203 catch( uno::Exception
& )
4205 OSL_ENSURE( sal_False
, "Can't compare URL's, treat as different!\n" );
4213 BOOL
SfxMedium::HasStorage_Impl() const
4215 return pImp
->xStorage
.is();
4218 BOOL
SfxMedium::IsOpen() const
4220 return pInStream
|| pOutStream
|| pImp
->xStorage
.is();
4223 ::rtl::OUString
SfxMedium::CreateTempCopyWithExt( const ::rtl::OUString
& aURL
)
4225 ::rtl::OUString aResult
;
4227 if ( aURL
.getLength() )
4229 sal_Int32 nPrefixLen
= aURL
.lastIndexOf( '.' );
4230 String aExt
= ( nPrefixLen
== -1 ) ? String() : String( aURL
.copy( nPrefixLen
) );
4232 ::rtl::OUString aNewTempFileURL
= ::utl::TempFile( String(), &aExt
).GetURL();
4233 if ( aNewTempFileURL
.getLength() )
4235 INetURLObject
aSource( aURL
);
4236 INetURLObject
aDest( aNewTempFileURL
);
4237 ::rtl::OUString aFileName
= aDest
.getName( INetURLObject::LAST_SEGMENT
,
4239 INetURLObject::DECODE_WITH_CHARSET
);
4240 if ( aFileName
.getLength() && aDest
.removeSegment() )
4244 uno::Reference
< ::com::sun::star::ucb::XCommandEnvironment
> xComEnv
;
4245 ::ucbhelper::Content
aTargetContent( aDest
.GetMainURL( INetURLObject::NO_DECODE
), xComEnv
);
4246 ::ucbhelper::Content
aSourceContent( aSource
.GetMainURL( INetURLObject::NO_DECODE
), xComEnv
);
4247 if ( aTargetContent
.transferContent( aSourceContent
,
4248 ::ucbhelper::InsertOperation_COPY
,
4250 NameClash::OVERWRITE
) )
4253 aResult
= aNewTempFileURL
;
4256 catch( uno::Exception
& )
4265 ::rtl::OUString
SfxMedium::SwitchDocumentToTempFile()
4267 // the method returns empty string in case of failure
4268 ::rtl::OUString aResult
;
4269 ::rtl::OUString aOrigURL
= aLogicName
;
4271 if ( aOrigURL
.getLength() )
4273 sal_Int32 nPrefixLen
= aOrigURL
.lastIndexOf( '.' );
4274 String aExt
= ( nPrefixLen
== -1 ) ? String() : String( aOrigURL
.copy( nPrefixLen
) );
4275 ::rtl::OUString aNewURL
= ::utl::TempFile( String(), &aExt
).GetURL();
4277 // TODO/LATER: In future the aLogicName should be set to shared folder URL
4278 // and a temporary file should be created. Transport_Impl should be impossible then.
4279 if ( aNewURL
.getLength() )
4281 uno::Reference
< embed::XStorage
> xStorage
= GetStorage();
4282 uno::Reference
< embed::XOptimizedStorage
> xOptStorage( xStorage
, uno::UNO_QUERY
);
4284 if ( xOptStorage
.is() )
4286 // TODO/LATER: reuse the pImp->pTempFile if it already exists
4287 CanDisposeStorage_Impl( sal_False
);
4289 SetPhysicalName_Impl( String() );
4292 // remove the readonly state
4293 sal_Bool bWasReadonly
= sal_False
;
4294 nStorOpenMode
= SFX_STREAM_READWRITE
;
4295 SFX_ITEMSET_ARG( pSet
, pReadOnlyItem
, SfxBoolItem
, SID_DOC_READONLY
, FALSE
);
4296 if ( pReadOnlyItem
&& pReadOnlyItem
->GetValue() )
4297 bWasReadonly
= sal_True
;
4298 GetItemSet()->ClearItem( SID_DOC_READONLY
);
4301 LockOrigFileOnDemand( sal_False
, sal_False
);
4305 if ( pImp
->xStream
.is() )
4309 xOptStorage
->writeAndAttachToStream( pImp
->xStream
);
4310 pImp
->xStorage
= xStorage
;
4313 catch( uno::Exception
& )
4317 if ( !aResult
.getLength() )
4320 SetPhysicalName_Impl( String() );
4321 SetName( aOrigURL
);
4324 // set the readonly state back
4325 nStorOpenMode
= SFX_STREAM_READONLY
;
4326 GetItemSet()->Put( SfxBoolItem(SID_DOC_READONLY
, sal_True
));
4329 pImp
->xStorage
= xStorage
;
4338 sal_Bool
SfxMedium::SwitchDocumentToFile( ::rtl::OUString aURL
)
4340 // the method is only for storage based documents
4341 sal_Bool bResult
= sal_False
;
4342 ::rtl::OUString aOrigURL
= aLogicName
;
4344 if ( aURL
.getLength() && aOrigURL
.getLength() )
4346 uno::Reference
< embed::XStorage
> xStorage
= GetStorage();
4347 uno::Reference
< embed::XOptimizedStorage
> xOptStorage( xStorage
, uno::UNO_QUERY
);
4349 if ( xOptStorage
.is() )
4351 // TODO/LATER: reuse the pImp->pTempFile if it already exists
4352 CanDisposeStorage_Impl( sal_False
);
4354 SetPhysicalName_Impl( String() );
4357 // open the temporary file based document
4359 LockOrigFileOnDemand( sal_False
, sal_False
);
4363 if ( pImp
->xStream
.is() )
4367 uno::Reference
< io::XTruncate
> xTruncate( pImp
->xStream
, uno::UNO_QUERY_THROW
);
4368 if ( xTruncate
.is() )
4369 xTruncate
->truncate();
4371 xOptStorage
->writeAndAttachToStream( pImp
->xStream
);
4372 pImp
->xStorage
= xStorage
;
4375 catch( uno::Exception
& )
4382 SetPhysicalName_Impl( String() );
4383 SetName( aOrigURL
);
4385 pImp
->xStorage
= xStorage
;