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