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