LibreOffice Module embeddedobj (master) 1
persistence.cxx
Go to the documentation of this file.
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 <commonembobj.hxx>
21#include <com/sun/star/embed/Aspects.hpp>
22#include <com/sun/star/document/XStorageBasedDocument.hpp>
23#include <com/sun/star/embed/EmbedStates.hpp>
24#include <com/sun/star/embed/EntryInitModes.hpp>
25#include <com/sun/star/embed/StorageWrappedTargetException.hpp>
26#include <com/sun/star/embed/WrongStateException.hpp>
27#include <com/sun/star/embed/XStorage.hpp>
28#include <com/sun/star/embed/XOptimizedStorage.hpp>
29#include <com/sun/star/embed/ElementModes.hpp>
30#include <com/sun/star/embed/EmbedUpdateModes.hpp>
31#include <com/sun/star/embed/StorageFactory.hpp>
32#include <com/sun/star/io/IOException.hpp>
33#include <com/sun/star/io/TempFile.hpp>
34#include <com/sun/star/frame/XModel.hpp>
35#include <com/sun/star/frame/XStorable.hpp>
36#include <com/sun/star/frame/XLoadable.hpp>
37#include <com/sun/star/frame/XModule.hpp>
38#include <com/sun/star/lang/NoSupportException.hpp>
39#include <com/sun/star/lang/XSingleServiceFactory.hpp>
40#include <com/sun/star/lang/DisposedException.hpp>
41#include <com/sun/star/util/XModifiable.hpp>
42
43#include <com/sun/star/container/XNameAccess.hpp>
44#include <com/sun/star/container/XChild.hpp>
45#include <com/sun/star/util/XCloseable.hpp>
46#include <com/sun/star/beans/XPropertySet.hpp>
47#include <com/sun/star/beans/IllegalTypeException.hpp>
48#include <com/sun/star/chart2/XChartDocument.hpp>
49
50#include <com/sun/star/ucb/SimpleFileAccess.hpp>
51
58
60#include <sal/log.hxx>
62#include "persistence.hxx"
63
64using namespace ::com::sun::star;
65
66
67uno::Sequence< beans::PropertyValue > GetValuableArgs_Impl( const uno::Sequence< beans::PropertyValue >& aMedDescr,
68 bool bCanUseDocumentBaseURL )
69{
70 uno::Sequence< beans::PropertyValue > aResult;
71 sal_Int32 nResLen = 0;
72
73 for ( beans::PropertyValue const & prop : aMedDescr )
74 {
75 if ( prop.Name == "ComponentData" || prop.Name == "DocumentTitle"
76 || prop.Name == "InteractionHandler" || prop.Name == "JumpMark"
77 // || prop.Name == "Password" // makes no sense for embedded objects
78 || prop.Name == "Preview" || prop.Name == "ReadOnly"
79 || prop.Name == "StartPresentation" || prop.Name == "RepairPackage"
80 || prop.Name == "StatusIndicator" || prop.Name == "ViewData"
81 || prop.Name == "ViewId" || prop.Name == "MacroExecutionMode"
82 || prop.Name == "UpdateDocMode"
83 || (prop.Name == "DocumentBaseURL" && bCanUseDocumentBaseURL) )
84 {
85 aResult.realloc( ++nResLen );
86 aResult.getArray()[nResLen-1] = prop;
87 }
88 }
89
90 return aResult;
91}
92
93
94static uno::Sequence< beans::PropertyValue > addAsTemplate( const uno::Sequence< beans::PropertyValue >& aOrig )
95{
96 bool bAsTemplateSet = false;
97 sal_Int32 nLength = aOrig.getLength();
98 uno::Sequence< beans::PropertyValue > aResult( aOrig );
99
100 for ( sal_Int32 nInd = 0; nInd < nLength; nInd++ )
101 {
102 if ( aResult[nInd].Name == "AsTemplate" )
103 {
104 aResult.getArray()[nInd].Value <<= true;
105 bAsTemplateSet = true;
106 }
107 }
108
109 if ( !bAsTemplateSet )
110 {
111 aResult.realloc( nLength + 1 );
112 auto pResult = aResult.getArray();
113 pResult[nLength].Name = "AsTemplate";
114 pResult[nLength].Value <<= true;
115 }
116
117 return aResult;
118}
119
120
121static uno::Reference< io::XInputStream > createTempInpStreamFromStor(
122 const uno::Reference< embed::XStorage >& xStorage,
123 const uno::Reference< uno::XComponentContext >& xContext )
124{
125 SAL_WARN_IF( !xStorage.is(), "embeddedobj.common", "The storage can not be empty!" );
126
127 uno::Reference< io::XInputStream > xResult;
128
129 uno::Reference < io::XStream > xTempStream( io::TempFile::create(xContext), uno::UNO_QUERY_THROW );
130
131 uno::Reference < lang::XSingleServiceFactory > xStorageFactory( embed::StorageFactory::create(xContext) );
132
133 uno::Sequence< uno::Any > aArgs{ uno::Any(xTempStream),
134 uno::Any(embed::ElementModes::READWRITE) };
135 uno::Reference< embed::XStorage > xTempStorage( xStorageFactory->createInstanceWithArguments( aArgs ),
136 uno::UNO_QUERY_THROW );
137
138 try
139 {
140 xStorage->copyToStorage( xTempStorage );
141 } catch( const uno::Exception& )
142 {
143 css::uno::Any anyEx = cppu::getCaughtException();
144 throw embed::StorageWrappedTargetException(
145 "Can't copy storage!",
146 uno::Reference< uno::XInterface >(),
147 anyEx );
148 }
149
150 try {
151 if ( xTempStorage.is() )
152 xTempStorage->dispose();
153 }
154 catch ( const uno::Exception& )
155 {
156 }
157
158 try {
159 uno::Reference< io::XOutputStream > xTempOut = xTempStream->getOutputStream();
160 if ( xTempOut.is() )
161 xTempOut->closeOutput();
162 }
163 catch ( const uno::Exception& )
164 {
165 }
166
167 xResult = xTempStream->getInputStream();
168
169 return xResult;
170
171}
172
173
174static void TransferMediaType( const uno::Reference< embed::XStorage >& i_rSource, const uno::Reference< embed::XStorage >& i_rTarget )
175{
176 try
177 {
178 const uno::Reference< beans::XPropertySet > xSourceProps( i_rSource, uno::UNO_QUERY_THROW );
179 const uno::Reference< beans::XPropertySet > xTargetProps( i_rTarget, uno::UNO_QUERY_THROW );
180 static constexpr OUStringLiteral sMediaTypePropName( u"MediaType" );
181 xTargetProps->setPropertyValue( sMediaTypePropName, xSourceProps->getPropertyValue( sMediaTypePropName ) );
182 }
183 catch( const uno::Exception& )
184 {
185 DBG_UNHANDLED_EXCEPTION("embeddedobj.common");
186 }
187}
188
189
190static uno::Reference< util::XCloseable > CreateDocument( const uno::Reference< uno::XComponentContext >& _rxContext,
191 const OUString& _rDocumentServiceName, bool _bEmbeddedScriptSupport, const bool i_bDocumentRecoverySupport )
192{
193 static constexpr OUStringLiteral sEmbeddedObject = u"EmbeddedObject";
194 static constexpr OUStringLiteral sEmbeddedScriptSupport = u"EmbeddedScriptSupport";
195 static constexpr OUStringLiteral sDocumentRecoverySupport = u"DocumentRecoverySupport";
197 aArguments.put( sEmbeddedObject, true );
198 aArguments.put( sEmbeddedScriptSupport, _bEmbeddedScriptSupport );
199 aArguments.put( sDocumentRecoverySupport, i_bDocumentRecoverySupport );
200
201 uno::Reference< uno::XInterface > xDocument;
202 try
203 {
204 xDocument = _rxContext->getServiceManager()->createInstanceWithArgumentsAndContext(
205 _rDocumentServiceName, aArguments.getWrappedPropertyValues(), _rxContext );
206 }
207 catch( const uno::Exception& )
208 {
209 // if an embedded object implementation does not support XInitialization,
210 // the default factory from cppuhelper will throw an
211 // IllegalArgumentException when we try to create the instance with arguments.
212 // Okay, so we fall back to creating the instance without any arguments.
213 OSL_FAIL("Consider implementing interface XInitialization to avoid duplicate construction");
214 xDocument = _rxContext->getServiceManager()->createInstanceWithContext( _rDocumentServiceName, _rxContext );
215 }
216
217 SAL_WARN_IF(!xDocument.is(), "embeddedobj.common", "Service " << _rDocumentServiceName << " is not available?");
218 return uno::Reference< util::XCloseable >( xDocument, uno::UNO_QUERY );
219}
220
221
222static void SetDocToEmbedded( const uno::Reference< frame::XModel >& rDocument, const OUString& aModuleName )
223{
224 if (!rDocument.is())
225 return;
226
227 uno::Sequence< beans::PropertyValue > aSeq{ comphelper::makePropertyValue("SetEmbedded", true) };
228 rDocument->attachResource( OUString(), aSeq );
229
230 if ( !aModuleName.isEmpty() )
231 {
232 try
233 {
234 uno::Reference< frame::XModule > xModule( rDocument, uno::UNO_QUERY_THROW );
235 xModule->setIdentifier( aModuleName );
236 }
237 catch( const uno::Exception& )
238 {}
239 }
240}
241
242
243void OCommonEmbeddedObject::SwitchOwnPersistence( const uno::Reference< embed::XStorage >& xNewParentStorage,
244 const uno::Reference< embed::XStorage >& xNewObjectStorage,
245 const OUString& aNewName )
246{
247 if ( xNewParentStorage == m_xParentStorage && aNewName == m_aEntryName )
248 {
249 SAL_WARN_IF( xNewObjectStorage != m_xObjectStorage, "embeddedobj.common", "The storage must be the same!" );
250 return;
251 }
252
253 auto xOldObjectStorage = m_xObjectStorage;
254 m_xObjectStorage = xNewObjectStorage;
255 m_xParentStorage = xNewParentStorage;
256 m_aEntryName = aNewName;
257
258 // the linked document should not be switched
259 if ( !m_bIsLinkURL )
260 {
261 uno::Reference< document::XStorageBasedDocument > xDoc( m_xDocHolder->GetComponent(), uno::UNO_QUERY );
262 if ( xDoc.is() )
264 }
265
266 try {
267 if ( xOldObjectStorage.is() )
268 xOldObjectStorage->dispose();
269 }
270 catch ( const uno::Exception& )
271 {
272 }
273}
274
275
276void OCommonEmbeddedObject::SwitchOwnPersistence( const uno::Reference< embed::XStorage >& xNewParentStorage,
277 const OUString& aNewName )
278{
279 if ( xNewParentStorage == m_xParentStorage && aNewName == m_aEntryName )
280 return;
281
282 sal_Int32 nStorageMode = m_bReadOnly ? embed::ElementModes::READ : embed::ElementModes::READWRITE;
283
284 uno::Reference< embed::XStorage > xNewOwnStorage = xNewParentStorage->openStorageElement( aNewName, nStorageMode );
285 SAL_WARN_IF( !xNewOwnStorage.is(), "embeddedobj.common", "The method can not return empty reference!" );
286
287 SwitchOwnPersistence( xNewParentStorage, xNewOwnStorage, aNewName );
288}
289
290
291void OCommonEmbeddedObject::EmbedAndReparentDoc_Impl( const uno::Reference< util::XCloseable >& i_rxDocument ) const
292{
293 SetDocToEmbedded( uno::Reference< frame::XModel >( i_rxDocument, uno::UNO_QUERY ), m_aModuleName );
294
295 try
296 {
297 uno::Reference < container::XChild > xChild( i_rxDocument, uno::UNO_QUERY );
298 if ( xChild.is() )
299 xChild->setParent( m_xParent );
300 }
301 catch( const lang::NoSupportException & )
302 {
303 SAL_WARN( "embeddedobj.common", "OCommonEmbeddedObject::EmbedAndReparentDoc: cannot set parent at document!" );
304 }
305}
306
307
308uno::Reference< util::XCloseable > OCommonEmbeddedObject::InitNewDocument_Impl()
309{
310 uno::Reference< util::XCloseable > xDocument( CreateDocument( m_xContext, GetDocumentServiceName(),
312
313 uno::Reference< frame::XModel > xModel( xDocument, uno::UNO_QUERY );
314 uno::Reference< frame::XLoadable > xLoadable( xModel, uno::UNO_QUERY_THROW );
315
316 try
317 {
318 // set the document mode to embedded as the first action on document!!!
319 EmbedAndReparentDoc_Impl( xDocument );
320
321 // if we have a storage to recover the document from, do not use initNew, but instead load from that storage
322 bool bInitNew = true;
323 if ( m_xRecoveryStorage.is() )
324 {
325 uno::Reference< document::XStorageBasedDocument > xDoc( xLoadable, uno::UNO_QUERY );
326 SAL_WARN_IF( !xDoc.is(), "embeddedobj.common", "OCommonEmbeddedObject::InitNewDocument_Impl: cannot recover from a storage when the document is not storage based!" );
327 if ( xDoc.is() )
328 {
331
332 xDoc->loadFromStorage( m_xRecoveryStorage, aLoadArgs.getPropertyValues() );
334 bInitNew = false;
335 }
336 }
337
338 if ( bInitNew )
339 {
340 // init document as a new
341 xLoadable->initNew();
342 }
343 xModel->attachResource( xModel->getURL(), m_aDocMediaDescriptor );
344 }
345 catch( const uno::Exception& )
346 {
347 if ( xDocument.is() )
348 {
349 try
350 {
351 xDocument->close( true );
352 }
353 catch( const uno::Exception& )
354 {
355 }
356 }
357
358 throw; // TODO
359 }
360
361 return xDocument;
362}
363
364
365uno::Reference< util::XCloseable > OCommonEmbeddedObject::LoadLink_Impl()
366{
367 uno::Reference< util::XCloseable > xDocument( CreateDocument( m_xContext, GetDocumentServiceName(),
369
370 uno::Reference< frame::XLoadable > xLoadable( xDocument, uno::UNO_QUERY_THROW );
371
372 sal_Int32 nLen = m_bLinkHasPassword ? 3 : 2;
373 uno::Sequence< beans::PropertyValue > aArgs( m_aDocMediaDescriptor.getLength() + nLen );
374 auto pArgs = aArgs.getArray();
375
376 pArgs[0].Name = "URL";
377 if(m_aLinkTempFile.is())
378 pArgs[0].Value <<= m_aLinkTempFile->getUri();
379 else
380 pArgs[0].Value <<= m_aLinkURL;
381
382 pArgs[1].Name = "FilterName";
383 pArgs[1].Value <<= m_aLinkFilterName;
384
385 if ( m_bLinkHasPassword )
386 {
387 pArgs[2].Name = "Password";
388 pArgs[2].Value <<= m_aLinkPassword;
389 }
390
391 for ( sal_Int32 nInd = 0; nInd < m_aDocMediaDescriptor.getLength(); nInd++ )
392 {
393 pArgs[nInd+nLen].Name = m_aDocMediaDescriptor[nInd].Name;
394 pArgs[nInd+nLen].Value = m_aDocMediaDescriptor[nInd].Value;
395 }
396
397 try
398 {
400
401 // the document is not really an embedded one, it is a link
402 EmbedAndReparentDoc_Impl( xDocument );
403
404 // load the document
405 xLoadable->load( aArgs );
406
407 if ( !m_bLinkHasPassword )
408 {
409 // check if there is a password to cache
410 uno::Reference< frame::XModel > xModel( xLoadable, uno::UNO_QUERY_THROW );
411 const uno::Sequence< beans::PropertyValue > aProps = xModel->getArgs();
412 for ( beans::PropertyValue const & prop : aProps )
413 if ( prop.Name == "Password" && ( prop.Value >>= m_aLinkPassword ) )
414 {
415 m_bLinkHasPassword = true;
416 break;
417 }
418 }
419 }
420 catch( const uno::Exception& )
421 {
422 if ( xDocument.is() )
423 {
424 try
425 {
426 xDocument->close( true );
427 }
428 catch( const uno::Exception& )
429 {
430 }
431 }
432
433 throw; // TODO
434 }
435
436 return xDocument;
437
438}
439
440
441OUString OCommonEmbeddedObject::GetFilterName( sal_Int32 nVersion ) const
442{
443 OUString aFilterName = GetPresetFilterName();
444 if ( aFilterName.isEmpty() )
445 {
446 OUString sDocumentServiceName = GetDocumentServiceName();
448 sDocumentServiceName == "com.sun.star.chart2.ChartDocument")
449 {
450 return "chart8";
451 }
452 try {
454 aFilterName = aHelper.GetDefaultFilterFromServiceName(sDocumentServiceName, nVersion);
455
456 // If no filter is found, fall back to the FileFormatVersion=6200 filter, Base only has that.
457 if (aFilterName.isEmpty() && nVersion == SOFFICE_FILEFORMAT_CURRENT)
458 aFilterName = aHelper.GetDefaultFilterFromServiceName(GetDocumentServiceName(), SOFFICE_FILEFORMAT_60);
459 } catch( const uno::Exception& )
460 {}
461 }
462
463 return aFilterName;
464}
465
466
467void OCommonEmbeddedObject::FillDefaultLoadArgs_Impl( const uno::Reference< embed::XStorage >& i_rxStorage,
468 ::comphelper::NamedValueCollection& o_rLoadArgs ) const
469{
470 o_rLoadArgs.put( "DocumentBaseURL", GetBaseURL_Impl() );
471 o_rLoadArgs.put( "HierarchicalDocumentName", m_aEntryName );
472 o_rLoadArgs.put( "ReadOnly", m_bReadOnly );
473
474 OUString aFilterName = GetFilterName( ::comphelper::OStorageHelper::GetXStorageFormat( i_rxStorage ) );
475 SAL_WARN_IF( aFilterName.isEmpty(), "embeddedobj.common", "OCommonEmbeddedObject::FillDefaultLoadArgs_Impl: Wrong document service name!" );
476 if ( aFilterName.isEmpty() )
477 throw io::IOException(); // TODO: error message/code
478
479 o_rLoadArgs.put( "FilterName", aFilterName );
480}
481
482
483uno::Reference< util::XCloseable > OCommonEmbeddedObject::LoadDocumentFromStorage_Impl()
484{
485 ENSURE_OR_THROW( m_xObjectStorage.is(), "no object storage" );
486
487 const uno::Reference< embed::XStorage > xSourceStorage( m_xRecoveryStorage.is() ? m_xRecoveryStorage : m_xObjectStorage );
488
489 uno::Reference< util::XCloseable > xDocument( CreateDocument( m_xContext, GetDocumentServiceName(),
491
492 //#i103460# ODF: take the size given from the parent frame as default
493 uno::Reference< chart2::XChartDocument > xChart( xDocument, uno::UNO_QUERY );
494 if( xChart.is() )
495 {
496 uno::Reference< embed::XVisualObject > xChartVisualObject( xChart, uno::UNO_QUERY );
497 if( xChartVisualObject.is() )
498 xChartVisualObject->setVisualAreaSize( embed::Aspects::MSOLE_CONTENT, m_aDefaultSizeForChart_In_100TH_MM );
499 }
500
501 uno::Reference< frame::XLoadable > xLoadable( xDocument, uno::UNO_QUERY );
502 uno::Reference< document::XStorageBasedDocument > xDoc( xDocument, uno::UNO_QUERY );
503 if ( !xDoc.is() && !xLoadable.is() )
504 throw uno::RuntimeException();
505
507 FillDefaultLoadArgs_Impl( xSourceStorage, aLoadArgs );
508
509 uno::Reference< io::XInputStream > xTempInpStream;
510 if ( !xDoc.is() )
511 {
512 xTempInpStream = createTempInpStreamFromStor( xSourceStorage, m_xContext );
513 if ( !xTempInpStream.is() )
514 throw uno::RuntimeException();
515
516 OUString aTempFileURL;
517 try
518 {
519 // no need to let the file stay after the stream is removed since the embedded document
520 // can not be stored directly
521 uno::Reference< beans::XPropertySet > xTempStreamProps( xTempInpStream, uno::UNO_QUERY_THROW );
522 xTempStreamProps->getPropertyValue("Uri") >>= aTempFileURL;
523 }
524 catch( const uno::Exception& )
525 {
526 }
527
528 SAL_WARN_IF( aTempFileURL.isEmpty(), "embeddedobj.common", "Couldn't retrieve temporary file URL!" );
529
530 aLoadArgs.put( "URL", aTempFileURL );
531 aLoadArgs.put( "InputStream", xTempInpStream );
532 }
533
534
535 aLoadArgs.merge( m_aDocMediaDescriptor, true );
536
537 try
538 {
539 // set the document mode to embedded as the first step!!!
540 EmbedAndReparentDoc_Impl( xDocument );
541
542 if (m_bReadOnly)
543 {
544 aLoadArgs.put("ReadOnly", true);
545 }
546
547 if ( xDoc.is() )
548 {
549 xDoc->loadFromStorage( xSourceStorage, aLoadArgs.getPropertyValues() );
550 if ( xSourceStorage != m_xObjectStorage )
552 }
553 else
554 xLoadable->load( aLoadArgs.getPropertyValues() );
555 }
556 catch( const uno::Exception& )
557 {
558 if ( xDocument.is() )
559 {
560 try
561 {
562 xDocument->close( true );
563 }
564 catch( const uno::Exception& )
565 {
566 DBG_UNHANDLED_EXCEPTION("embeddedobj.common");
567 }
568 }
569
570 throw; // TODO
571 }
572
573 return xDocument;
574}
575
576
578 sal_Int32 nStorageFormat,
579 const OUString& aBaseURL,
580 const OUString& aHierarchName )
581{
582 uno::Reference < io::XOutputStream > xTempOut(
583 io::TempFile::create(m_xContext),
584 uno::UNO_QUERY_THROW );
585 uno::Reference< io::XInputStream > aResult( xTempOut, uno::UNO_QUERY_THROW );
586
587 uno::Reference< frame::XStorable > xStorable;
588 {
589 osl::MutexGuard aGuard( m_aMutex );
590 if ( m_xDocHolder.is() )
591 xStorable.set( m_xDocHolder->GetComponent(), uno::UNO_QUERY );
592 }
593
594 if( !xStorable.is() )
595 throw uno::RuntimeException("No storage is provided for storing!"); // TODO:
596
597 OUString aFilterName = GetFilterName( nStorageFormat );
598
599 SAL_WARN_IF( aFilterName.isEmpty(), "embeddedobj.common", "Wrong document service name!" );
600 if ( aFilterName.isEmpty() )
601 throw io::IOException("No filter name provided / Wrong document service name"); // TODO:
602
603 uno::Sequence< beans::PropertyValue > aArgs{
604 comphelper::makePropertyValue("FilterName", aFilterName),
605 comphelper::makePropertyValue("OutputStream", xTempOut),
606 comphelper::makePropertyValue("DocumentBaseURL", aBaseURL),
607 comphelper::makePropertyValue("HierarchicalDocumentName", aHierarchName)
608 };
609
610 xStorable->storeToURL( "private:stream", aArgs );
611 try
612 {
613 xTempOut->closeOutput();
614 }
615 catch( const uno::Exception& )
616 {
617 SAL_WARN( "embeddedobj.common", "Looks like stream was closed already" );
618 }
619
620 return aResult;
621}
622
623
625{
626 if ( !m_xClientSite.is() )
627 return;
628
629 try
630 {
631 // check whether the component is modified,
632 // if not there is no need for storing
633 uno::Reference< util::XModifiable > xModifiable( m_xDocHolder->GetComponent(), uno::UNO_QUERY );
634 if ( xModifiable.is() && !xModifiable->isModified() )
635 return;
636 }
637 catch( const uno::Exception& )
638 {}
639
640 try {
641 m_xClientSite->saveObject();
642 }
643 catch( const uno::Exception& )
644 {
645 SAL_WARN( "embeddedobj.common", "The object was not stored!" );
646 }
647}
648
649
651{
652 OUString aBaseURL;
653
654 if ( m_xClientSite.is() )
655 {
656 try
657 {
658 uno::Reference< frame::XModel > xParentModel( m_xClientSite->getComponent(), uno::UNO_QUERY_THROW );
659 const uno::Sequence< beans::PropertyValue > aModelProps = xParentModel->getArgs();
660 for ( beans::PropertyValue const & prop : aModelProps )
661 if ( prop.Name == "DocumentBaseURL" )
662 {
663 prop.Value >>= aBaseURL;
664 break;
665 }
666 }
667 catch( const uno::Exception& )
668 {}
669 }
670
671 if ( aBaseURL.isEmpty() )
672 {
673 for ( beans::PropertyValue const & prop : m_aDocMediaDescriptor )
674 if ( prop.Name == "DocumentBaseURL" )
675 {
676 prop.Value >>= aBaseURL;
677 break;
678 }
679 }
680
681 if ( aBaseURL.isEmpty() )
682 aBaseURL = m_aDefaultParentBaseURL;
683
684 return aBaseURL;
685}
686
687
689 const uno::Sequence< beans::PropertyValue >& lArguments,
690 const uno::Sequence< beans::PropertyValue >& lObjArgs )
691{
692 OUString aBaseURL;
693
694 for ( beans::PropertyValue const & prop : lArguments )
695 if ( prop.Name == "DocumentBaseURL" )
696 {
697 prop.Value >>= aBaseURL;
698 break;
699 }
700
701 if ( aBaseURL.isEmpty() )
702 {
703 for ( beans::PropertyValue const & prop : lObjArgs )
704 if ( prop.Name == "DefaultParentBaseURL" )
705 {
706 prop.Value >>= aBaseURL;
707 break;
708 }
709 }
710
711 return aBaseURL;
712}
713
714
715void OCommonEmbeddedObject::SwitchDocToStorage_Impl( const uno::Reference< document::XStorageBasedDocument >& xDoc, const uno::Reference< embed::XStorage >& xStorage )
716{
717 xDoc->switchToStorage( xStorage );
718
719 uno::Reference< util::XModifiable > xModif( xDoc, uno::UNO_QUERY );
720 if ( xModif.is() )
721 xModif->setModified( false );
722
723 if ( m_xRecoveryStorage.is() )
724 m_xRecoveryStorage.clear();
725}
726
727namespace {
728
729OUString getStringPropertyValue( const uno::Sequence<beans::PropertyValue>& rProps, std::u16string_view rName )
730{
731 OUString aStr;
732
733 for (beans::PropertyValue const & prop : rProps)
734 {
735 if (prop.Name == rName)
736 {
737 prop.Value >>= aStr;
738 break;
739 }
740 }
741
742 return aStr;
743}
744
745}
746
748 const uno::Reference<embed::XStorage>& xStorage,
749 const uno::Sequence<beans::PropertyValue>& rMediaArgs,
750 const uno::Sequence<beans::PropertyValue>& rObjArgs,
751 sal_Int32 nStorageFormat,
752 const OUString& aHierarchName,
753 bool bAttachToTheStorage )
754{
755 SAL_WARN_IF( !xStorage.is(), "embeddedobj.common", "No storage is provided for storing!" );
756
757 if ( !xStorage.is() )
758 throw uno::RuntimeException(); // TODO:
759
760 uno::Reference< document::XStorageBasedDocument > xDoc;
761 {
762 osl::MutexGuard aGuard( m_aMutex );
763 if ( m_xDocHolder.is() )
764 xDoc.set( m_xDocHolder->GetComponent(), uno::UNO_QUERY );
765 }
766
767 OUString aBaseURL = GetBaseURLFrom_Impl(rMediaArgs, rObjArgs);
768
769 if ( xDoc.is() )
770 {
771 OUString aFilterName = GetFilterName( nStorageFormat );
772
773 // No filter found? Try the older format, e.g. Base has only that.
774 if (aFilterName.isEmpty() && nStorageFormat == SOFFICE_FILEFORMAT_CURRENT)
775 aFilterName = GetFilterName( SOFFICE_FILEFORMAT_60 );
776
777 SAL_WARN_IF( aFilterName.isEmpty(), "embeddedobj.common", "Wrong document service name!" );
778 if ( aFilterName.isEmpty() )
779 throw io::IOException(); // TODO:
780
781 static constexpr OUStringLiteral sFilterName = u"FilterName";
782 static constexpr OUStringLiteral sHierarchicalDocumentName = u"HierarchicalDocumentName";
783 static constexpr OUStringLiteral sDocumentBaseURL = u"DocumentBaseURL";
784 static constexpr OUStringLiteral sSourceShellID = u"SourceShellID";
785 static constexpr OUStringLiteral sDestinationShellID = u"DestinationShellID";
786 uno::Sequence<beans::PropertyValue> aArgs{
787 comphelper::makePropertyValue(sFilterName, aFilterName),
790 comphelper::makePropertyValue(sSourceShellID,
791 getStringPropertyValue(rObjArgs, sSourceShellID)),
793 sDestinationShellID, getStringPropertyValue(rObjArgs, sDestinationShellID))
794 };
795
796 xDoc->storeToStorage( xStorage, aArgs );
797 if ( bAttachToTheStorage )
798 SwitchDocToStorage_Impl( xDoc, xStorage );
799 }
800 else
801 {
802 // store document to temporary stream based on temporary file
803 uno::Reference < io::XInputStream > xTempIn = StoreDocumentToTempStream_Impl( nStorageFormat, aBaseURL, aHierarchName );
804
805 SAL_WARN_IF( !xTempIn.is(), "embeddedobj.common", "The stream reference can not be empty!" );
806
807 // open storage based on document temporary file for reading
808 uno::Reference < lang::XSingleServiceFactory > xStorageFactory = embed::StorageFactory::create(m_xContext);
809
810 uno::Sequence< uno::Any > aArgs{ uno::Any(xTempIn) };
811 uno::Reference< embed::XStorage > xTempStorage( xStorageFactory->createInstanceWithArguments( aArgs ),
812 uno::UNO_QUERY_THROW );
813
814 // object storage must be committed automatically
815 xTempStorage->copyToStorage( xStorage );
816 }
817}
818
819
821 const uno::Sequence< beans::PropertyValue >& aMedDescr )
822{
823 uno::Reference< util::XCloseable > xDocument( CreateDocument( m_xContext, GetDocumentServiceName(),
825
826 uno::Reference< frame::XLoadable > xLoadable( xDocument, uno::UNO_QUERY_THROW );
827
828 try
829 {
830 // set the document mode to embedded as the first action on the document!!!
831 EmbedAndReparentDoc_Impl( xDocument );
832
833 xLoadable->load( addAsTemplate( aMedDescr ) );
834 }
835 catch( const uno::Exception& )
836 {
837 if ( xDocument.is() )
838 {
839 try
840 {
841 xDocument->close( true );
842 }
843 catch( const uno::Exception& )
844 {
845 }
846 }
847
848 throw; // TODO
849 }
850
851 return xDocument;
852}
853
854
855uno::Reference< util::XCloseable > OCommonEmbeddedObject::CreateTempDocFromLink_Impl()
856{
857 uno::Reference< util::XCloseable > xResult;
858
859 SAL_WARN_IF( !m_bIsLinkURL, "embeddedobj.common", "The object is not a linked one!" );
860
861 uno::Sequence< beans::PropertyValue > aTempMediaDescr;
862
863 sal_Int32 nStorageFormat = SOFFICE_FILEFORMAT_CURRENT;
864 try {
866 }
867 catch ( const beans::IllegalTypeException& )
868 {
869 // the container just has an unknown type, use current file format
870 }
871 catch ( const uno::Exception& )
872 {
873 SAL_WARN( "embeddedobj.common", "Can not retrieve storage media type!" );
874 }
875
876 if ( m_xDocHolder->GetComponent().is() )
877 {
878 aTempMediaDescr.realloc( 4 );
879
880 // TODO/LATER: may be private:stream should be used as target URL
881 OUString aTempFileURL;
882 uno::Reference< io::XInputStream > xTempStream = StoreDocumentToTempStream_Impl( SOFFICE_FILEFORMAT_CURRENT,
883 OUString(),
884 OUString() );
885 try
886 {
887 // no need to let the file stay after the stream is removed since the embedded document
888 // can not be stored directly
889 uno::Reference< beans::XPropertySet > xTempStreamProps( xTempStream, uno::UNO_QUERY_THROW );
890 xTempStreamProps->getPropertyValue("Uri") >>= aTempFileURL;
891 }
892 catch( const uno::Exception& )
893 {
894 }
895
896 SAL_WARN_IF( aTempFileURL.isEmpty(), "embeddedobj.common", "Couldn't retrieve temporary file URL!" );
897
898 aTempMediaDescr
899 = { comphelper::makePropertyValue("URL", aTempFileURL),
900 comphelper::makePropertyValue("InputStream", xTempStream),
901 comphelper::makePropertyValue("FilterName", GetFilterName( nStorageFormat )),
902 comphelper::makePropertyValue("AsTemplate", true) };
903 }
904 else
905 {
906 aTempMediaDescr = { comphelper::makePropertyValue(
907 "URL",
908 // tdf#141529 use URL of the linked TempFile if it exists
909 m_aLinkTempFile.is() ? m_aLinkTempFile->getUri() : m_aLinkURL),
911 }
912
913 xResult = CreateDocFromMediaDescr_Impl( aTempMediaDescr );
914
915 return xResult;
916}
917
918
920 const uno::Reference< embed::XStorage >& xStorage,
921 const OUString& sEntName,
922 sal_Int32 nEntryConnectionMode,
923 const uno::Sequence< beans::PropertyValue >& lArguments,
924 const uno::Sequence< beans::PropertyValue >& lObjArgs )
925{
926 // the type of the object must be already set
927 // a kind of typedetection should be done in the factory
928
929 ::osl::MutexGuard aGuard( m_aMutex );
930 if ( m_bDisposed )
931 throw lang::DisposedException(); // TODO
932
933 if ( !xStorage.is() )
934 throw lang::IllegalArgumentException( "No parent storage is provided!",
935 static_cast< ::cppu::OWeakObject* >(this),
936 1 );
937
938 if ( sEntName.isEmpty() )
939 throw lang::IllegalArgumentException( "Empty element name is provided!",
940 static_cast< ::cppu::OWeakObject* >(this),
941 2 );
942
943 // May be LOADED should be forbidden here ???
944 if ( ( m_nObjectState != -1 || nEntryConnectionMode == embed::EntryInitModes::NO_INIT )
945 && ( m_nObjectState == -1 || nEntryConnectionMode != embed::EntryInitModes::NO_INIT ) )
946 {
947 // if the object is not loaded
948 // it can not get persistent representation without initialization
949
950 // if the object is loaded
951 // it can switch persistent representation only without initialization
952
953 throw embed::WrongStateException(
954 "Can't change persistent representation of activated object!",
955 static_cast< ::cppu::OWeakObject* >(this) );
956 }
957
959 {
960 if ( nEntryConnectionMode != embed::EntryInitModes::NO_INIT )
961 throw embed::WrongStateException(
962 "The object waits for saveCompleted() call!",
963 static_cast< ::cppu::OWeakObject* >(this) );
964 // saveCompleted is expected, handle it accordingly
965 if ( m_xNewParentStorage == xStorage && m_aNewEntryName == sEntName )
966 {
967 saveCompleted( true );
968 return;
969 }
970
971 // if a completely different entry is provided, switch first back to the old persistence in saveCompleted
972 // and then switch to the target persistence
973 bool bSwitchFurther = ( m_xParentStorage != xStorage || m_aEntryName != sEntName );
974 saveCompleted( false );
975 if ( !bSwitchFurther )
976 return;
977 }
978
979 // for now support of this interface is required to allow breaking of links and converting them to normal embedded
980 // objects, so the persist name must be handled correctly ( althowgh no real persist entry is used )
981 // OSL_ENSURE( !m_bIsLinkURL, "This method implementation must not be used for links!" );
982 if ( m_bIsLinkURL )
983 {
984 m_aEntryName = sEntName;
985 return;
986 }
987
988 uno::Reference< container::XNameAccess > xNameAccess( xStorage, uno::UNO_QUERY_THROW );
989
990 // detect entry existence
991 bool bElExists = xNameAccess->hasByName( sEntName );
992
994 nEntryConnectionMode != embed::EntryInitModes::MEDIA_DESCRIPTOR_INIT );
995
996 m_bReadOnly = false;
997 for ( beans::PropertyValue const & prop : lArguments )
998 if ( prop.Name == "ReadOnly" )
999 prop.Value >>= m_bReadOnly;
1000
1001 // TODO: use lObjArgs for StoreVisualReplacement
1002 for ( beans::PropertyValue const & prop : lObjArgs )
1003 if ( prop.Name == "OutplaceDispatchInterceptor" )
1004 {
1005 uno::Reference< frame::XDispatchProviderInterceptor > xDispatchInterceptor;
1006 if ( prop.Value >>= xDispatchInterceptor )
1007 m_xDocHolder->SetOutplaceDispatchInterceptor( xDispatchInterceptor );
1008 }
1009 else if ( prop.Name == "DefaultParentBaseURL" )
1010 {
1011 prop.Value >>= m_aDefaultParentBaseURL;
1012 }
1013 else if ( prop.Name == "Parent" )
1014 {
1015 prop.Value >>= m_xParent;
1016 }
1017 else if ( prop.Name == "IndividualMiscStatus" )
1018 {
1019 sal_Int64 nMiscStatus=0;
1020 prop.Value >>= nMiscStatus;
1021 m_nMiscStatus |= nMiscStatus;
1022 }
1023 else if ( prop.Name == "CloneFrom" )
1024 {
1025 uno::Reference < embed::XEmbeddedObject > xObj;
1026 prop.Value >>= xObj;
1027 if ( xObj.is() )
1028 {
1029 m_bHasClonedSize = true;
1030 m_aClonedSize = xObj->getVisualAreaSize( embed::Aspects::MSOLE_CONTENT );
1031 m_nClonedMapUnit = xObj->getMapUnit( embed::Aspects::MSOLE_CONTENT );
1032 }
1033 }
1034 else if ( prop.Name == "OutplaceFrameProperties" )
1035 {
1036 uno::Sequence< uno::Any > aOutFrameProps;
1037 uno::Sequence< beans::NamedValue > aOutFramePropsTyped;
1038 if ( prop.Value >>= aOutFrameProps )
1039 {
1040 m_xDocHolder->SetOutplaceFrameProperties( aOutFrameProps );
1041 }
1042 else if ( prop.Value >>= aOutFramePropsTyped )
1043 {
1044 aOutFrameProps.realloc( aOutFramePropsTyped.getLength() );
1045 uno::Any* pProp = aOutFrameProps.getArray();
1046 for ( const beans::NamedValue* pTypedProp = aOutFramePropsTyped.getConstArray();
1047 pTypedProp != aOutFramePropsTyped.getConstArray() + aOutFramePropsTyped.getLength();
1048 ++pTypedProp, ++pProp
1049 )
1050 {
1051 *pProp <<= *pTypedProp;
1052 }
1053 m_xDocHolder->SetOutplaceFrameProperties( aOutFrameProps );
1054 }
1055 else
1056 SAL_WARN( "embeddedobj.common", "OCommonEmbeddedObject::setPersistentEntry: illegal type for argument 'OutplaceFrameProperties'!" );
1057 }
1058 else if ( prop.Name == "ModuleName" )
1059 {
1060 prop.Value >>= m_aModuleName;
1061 }
1062 else if ( prop.Name == "EmbeddedScriptSupport" )
1063 {
1064 OSL_VERIFY( prop.Value >>= m_bEmbeddedScriptSupport );
1065 }
1066 else if ( prop.Name == "DocumentRecoverySupport" )
1067 {
1068 OSL_VERIFY( prop.Value >>= m_bDocumentRecoverySupport );
1069 }
1070 else if ( prop.Name == "RecoveryStorage" )
1071 {
1072 OSL_VERIFY( prop.Value >>= m_xRecoveryStorage );
1073 }
1074
1075
1076 sal_Int32 nStorageMode = m_bReadOnly ? embed::ElementModes::READ : embed::ElementModes::READWRITE;
1077
1078 SwitchOwnPersistence( xStorage, sEntName );
1079
1080 if ( nEntryConnectionMode == embed::EntryInitModes::DEFAULT_INIT )
1081 {
1082 if ( bElExists )
1083 {
1084 // the initialization from existing storage allows to leave object in loaded state
1085 m_nObjectState = embed::EmbedStates::LOADED;
1086 }
1087 else
1088 {
1089 m_xDocHolder->SetComponent( InitNewDocument_Impl(), m_bReadOnly );
1090 if ( !m_xDocHolder->GetComponent().is() )
1091 throw io::IOException(); // TODO: can not create document
1092
1093 m_nObjectState = embed::EmbedStates::RUNNING;
1094 }
1095 }
1096 else
1097 {
1098 if ( ( nStorageMode & embed::ElementModes::READWRITE ) != embed::ElementModes::READWRITE )
1099 throw io::IOException();
1100
1101 if ( nEntryConnectionMode == embed::EntryInitModes::NO_INIT )
1102 {
1103 // the document just already changed its storage to store to
1104 // the links to OOo documents for now ignore this call
1105 // TODO: OOo links will have persistence so it will be switched here
1106 }
1107 else if ( nEntryConnectionMode == embed::EntryInitModes::TRUNCATE_INIT )
1108 {
1109 if ( m_xRecoveryStorage.is() )
1111
1112 // TODO:
1113 m_xDocHolder->SetComponent( InitNewDocument_Impl(), m_bReadOnly );
1114
1115 if ( !m_xDocHolder->GetComponent().is() )
1116 throw io::IOException(); // TODO: can not create document
1117
1118 m_nObjectState = embed::EmbedStates::RUNNING;
1119 }
1120 else if ( nEntryConnectionMode == embed::EntryInitModes::MEDIA_DESCRIPTOR_INIT )
1121 {
1122 m_xDocHolder->SetComponent( CreateDocFromMediaDescr_Impl( lArguments ), m_bReadOnly );
1123 m_nObjectState = embed::EmbedStates::RUNNING;
1124 }
1125 //else if ( nEntryConnectionMode == embed::EntryInitModes::TRANSFERABLE_INIT )
1126 //{
1127 //TODO:
1128 //}
1129 else
1130 throw lang::IllegalArgumentException( "Wrong connection mode is provided!",
1131 static_cast< ::cppu::OWeakObject* >(this),
1132 3 );
1133 }
1134}
1135
1136
1137void SAL_CALL OCommonEmbeddedObject::storeToEntry( const uno::Reference< embed::XStorage >& xStorage,
1138 const OUString& sEntName,
1139 const uno::Sequence< beans::PropertyValue >& lArguments,
1140 const uno::Sequence< beans::PropertyValue >& lObjArgs )
1141{
1142 ::osl::ResettableMutexGuard aGuard( m_aMutex );
1143 if ( m_bDisposed )
1144 throw lang::DisposedException(); // TODO
1145
1146 if ( m_nObjectState == -1 )
1147 {
1148 // the object is still not loaded
1149 throw embed::WrongStateException( "Can't store object without persistence!",
1150 static_cast< ::cppu::OWeakObject* >(this) );
1151 }
1152
1154 throw embed::WrongStateException(
1155 "The object waits for saveCompleted() call!",
1156 static_cast< ::cppu::OWeakObject* >(this) );
1157
1158 // for now support of this interface is required to allow breaking of links and converting them to normal embedded
1159 // objects, so the persist name must be handled correctly ( althowgh no real persist entry is used )
1160 // OSL_ENSURE( !m_bIsLinkURL, "This method implementation must not be used for links!" );
1161 if ( m_bIsLinkURL )
1162 return;
1163
1164 OSL_ENSURE( m_xParentStorage.is() && m_xObjectStorage.is(), "The object has no valid persistence!" );
1165
1166 sal_Int32 nTargetStorageFormat = SOFFICE_FILEFORMAT_CURRENT;
1167 sal_Int32 nOriginalStorageFormat = SOFFICE_FILEFORMAT_CURRENT;
1168 try {
1169 nTargetStorageFormat = ::comphelper::OStorageHelper::GetXStorageFormat( xStorage );
1170 }
1171 catch ( const beans::IllegalTypeException& )
1172 {
1173 // the container just has an unknown type, use current file format
1174 }
1175 catch ( const uno::Exception& )
1176 {
1177 SAL_WARN( "embeddedobj.common", "Can not retrieve target storage media type!" );
1178 }
1179 if (nTargetStorageFormat == SOFFICE_FILEFORMAT_60)
1180 {
1181 SAL_INFO("embeddedobj.common", "fdo#78159: Storing OOoXML as ODF");
1182 nTargetStorageFormat = SOFFICE_FILEFORMAT_CURRENT;
1183 // setting MediaType is done later anyway, no need to do it here
1184 }
1185
1186 try
1187 {
1189 }
1190 catch ( const beans::IllegalTypeException& )
1191 {
1192 // the container just has an unknown type, use current file format
1193 }
1194 catch ( const uno::Exception& )
1195 {
1196 SAL_WARN( "embeddedobj.common", "Can not retrieve own storage media type!" );
1197 }
1198
1199 bool bTryOptimization = false;
1200 for ( beans::PropertyValue const & prop : lObjArgs )
1201 {
1202 // StoreVisualReplacement and VisualReplacement args have no sense here
1203 if ( prop.Name == "CanTryOptimization" )
1204 prop.Value >>= bTryOptimization;
1205 }
1206
1207 bool bSwitchBackToLoaded = false;
1208
1209 // Storing to different format can be done only in running state.
1210 if ( m_nObjectState == embed::EmbedStates::LOADED )
1211 {
1212 // TODO/LATER: copying is not legal for documents with relative links.
1213 if ( nTargetStorageFormat == nOriginalStorageFormat )
1214 {
1215 bool bOptimizationWorks = false;
1216 if ( bTryOptimization )
1217 {
1218 try
1219 {
1220 // try to use optimized copying
1221 uno::Reference< embed::XOptimizedStorage > xSource( m_xParentStorage, uno::UNO_QUERY_THROW );
1222 uno::Reference< embed::XOptimizedStorage > xTarget( xStorage, uno::UNO_QUERY_THROW );
1223 xSource->copyElementDirectlyTo( m_aEntryName, xTarget, sEntName );
1224 bOptimizationWorks = true;
1225 }
1226 catch( const uno::Exception& )
1227 {
1228 }
1229 }
1230
1231 if ( !bOptimizationWorks )
1232 m_xParentStorage->copyElementTo( m_aEntryName, xStorage, sEntName );
1233 }
1234 else
1235 {
1236 changeState( embed::EmbedStates::RUNNING );
1237 bSwitchBackToLoaded = true;
1238 }
1239 }
1240
1241 if ( m_nObjectState == embed::EmbedStates::LOADED )
1242 return;
1243
1244 uno::Reference< embed::XStorage > xSubStorage =
1245 xStorage->openStorageElement( sEntName, embed::ElementModes::READWRITE );
1246
1247 if ( !xSubStorage.is() )
1248 throw uno::RuntimeException(); //TODO
1249
1250 aGuard.clear();
1251 // TODO/LATER: support hierarchical name for embedded objects in embedded objects
1253 xSubStorage, lArguments, lObjArgs, nTargetStorageFormat, sEntName, false );
1254 aGuard.reset();
1255
1256 if ( bSwitchBackToLoaded )
1257 changeState( embed::EmbedStates::LOADED );
1258
1259 // TODO: should the listener notification be done?
1260}
1261
1262
1263void SAL_CALL OCommonEmbeddedObject::storeAsEntry( const uno::Reference< embed::XStorage >& xStorage,
1264 const OUString& sEntName,
1265 const uno::Sequence< beans::PropertyValue >& lArguments,
1266 const uno::Sequence< beans::PropertyValue >& lObjArgs )
1267{
1268 ::osl::ResettableMutexGuard aGuard( m_aMutex );
1269 if ( m_bDisposed )
1270 throw lang::DisposedException(); // TODO
1271
1272 bool AutoSaveEvent = false;
1273 utl::MediaDescriptor lArgs(lObjArgs);
1274 lArgs[utl::MediaDescriptor::PROP_AUTOSAVEEVENT] >>= AutoSaveEvent;
1275
1276 if ( m_nObjectState == -1 )
1277 {
1278 // the object is still not loaded
1279 throw embed::WrongStateException( "Can't store object without persistence!",
1280 static_cast< ::cppu::OWeakObject* >(this) );
1281 }
1282
1284 throw embed::WrongStateException(
1285 "The object waits for saveCompleted() call!",
1286 static_cast< ::cppu::OWeakObject* >(this) );
1287
1288 // for now support of this interface is required to allow breaking of links and converting them to normal embedded
1289 // objects, so the persist name must be handled correctly ( althowgh no real persist entry is used )
1290 // OSL_ENSURE( !m_bIsLinkURL, "This method implementation must not be used for links!" );
1291 if ( m_bIsLinkURL )
1292 {
1293 m_aNewEntryName = sEntName;
1294
1295 if ( !AutoSaveEvent )
1297
1298 return;
1299 }
1300
1301 OSL_ENSURE( m_xParentStorage.is() && m_xObjectStorage.is(), "The object has no valid persistence!" );
1302
1303 sal_Int32 nTargetStorageFormat = SOFFICE_FILEFORMAT_CURRENT;
1304 sal_Int32 nOriginalStorageFormat = SOFFICE_FILEFORMAT_CURRENT;
1305 try {
1306 nTargetStorageFormat = ::comphelper::OStorageHelper::GetXStorageFormat( xStorage );
1307 }
1308 catch ( const beans::IllegalTypeException& )
1309 {
1310 // the container just has an unknown type, use current file format
1311 }
1312 catch ( const uno::Exception& )
1313 {
1314 SAL_WARN( "embeddedobj.common", "Can not retrieve target storage media type!" );
1315 }
1316 if (nTargetStorageFormat == SOFFICE_FILEFORMAT_60)
1317 {
1318 SAL_INFO("embeddedobj.common", "fdo#78159: Storing OOoXML as ODF");
1319 nTargetStorageFormat = SOFFICE_FILEFORMAT_CURRENT;
1320 // setting MediaType is done later anyway, no need to do it here
1321 }
1322
1323 try
1324 {
1326 }
1327 catch ( const beans::IllegalTypeException& )
1328 {
1329 // the container just has an unknown type, use current file format
1330 }
1331 catch ( const uno::Exception& )
1332 {
1333 SAL_WARN( "embeddedobj.common", "Can not retrieve own storage media type!" );
1334 }
1335
1336 PostEvent_Impl( "OnSaveAs" );
1337
1338 bool bTryOptimization = false;
1339 for ( beans::PropertyValue const & prop : lObjArgs )
1340 {
1341 // StoreVisualReplacement and VisualReplacement args have no sense here
1342 if ( prop.Name == "CanTryOptimization" )
1343 prop.Value >>= bTryOptimization;
1344 }
1345
1346 bool bSwitchBackToLoaded = false;
1347
1348 // Storing to different format can be done only in running state.
1349 if ( m_nObjectState == embed::EmbedStates::LOADED )
1350 {
1351 // TODO/LATER: copying is not legal for documents with relative links.
1352 if ( nTargetStorageFormat == nOriginalStorageFormat )
1353 {
1354 bool bOptimizationWorks = false;
1355 if ( bTryOptimization )
1356 {
1357 try
1358 {
1359 // try to use optimized copying
1360 uno::Reference< embed::XOptimizedStorage > xSource( m_xParentStorage, uno::UNO_QUERY_THROW );
1361 uno::Reference< embed::XOptimizedStorage > xTarget( xStorage, uno::UNO_QUERY_THROW );
1362 xSource->copyElementDirectlyTo( m_aEntryName, xTarget, sEntName );
1363 bOptimizationWorks = true;
1364 }
1365 catch( const uno::Exception& )
1366 {
1367 }
1368 }
1369
1370 if ( !bOptimizationWorks )
1371 m_xParentStorage->copyElementTo( m_aEntryName, xStorage, sEntName );
1372 }
1373 else
1374 {
1375 changeState( embed::EmbedStates::RUNNING );
1376 bSwitchBackToLoaded = true;
1377 }
1378 }
1379
1380 uno::Reference< embed::XStorage > xSubStorage =
1381 xStorage->openStorageElement( sEntName, embed::ElementModes::READWRITE );
1382
1383 if ( !xSubStorage.is() )
1384 throw uno::RuntimeException(); //TODO
1385
1386 if ( m_nObjectState != embed::EmbedStates::LOADED )
1387 {
1388 aGuard.clear();
1389 // TODO/LATER: support hierarchical name for embedded objects in embedded objects
1391 xSubStorage, lArguments, lObjArgs, nTargetStorageFormat, sEntName, false );
1392 aGuard.reset();
1393
1394 if ( bSwitchBackToLoaded )
1395 changeState( embed::EmbedStates::LOADED );
1396 }
1397
1398 m_bWaitSaveCompleted = true;
1399 m_xNewObjectStorage = xSubStorage;
1400 m_xNewParentStorage = xStorage;
1401 m_aNewEntryName = sEntName;
1402 m_aNewDocMediaDescriptor = GetValuableArgs_Impl( lArguments, true );
1403
1404 // TODO: register listeners for storages above, in case they are disposed
1405 // an exception will be thrown on saveCompleted( true )
1406
1407 // TODO: should the listener notification be done here or in saveCompleted?
1408}
1409
1410
1412{
1413 ::osl::MutexGuard aGuard( m_aMutex );
1414 if ( m_bDisposed )
1415 throw lang::DisposedException(); // TODO
1416
1417 if ( m_nObjectState == -1 )
1418 {
1419 // the object is still not loaded
1420 throw embed::WrongStateException( "Can't store object without persistence!",
1421 static_cast< ::cppu::OWeakObject* >(this) );
1422 }
1423
1424 // for now support of this interface is required to allow breaking of links and converting them to normal embedded
1425 // objects, so the persist name must be handled correctly ( althowgh no real persist entry is used )
1426 // OSL_ENSURE( !m_bIsLinkURL, "This method implementation must not be used for links!" );
1427 if ( m_bIsLinkURL )
1428 {
1429 if ( bUseNew )
1431 m_aNewEntryName.clear();
1432 return;
1433 }
1434
1435 // it is allowed to call saveCompleted( false ) for nonstored objects
1436 if ( !m_bWaitSaveCompleted && !bUseNew )
1437 return;
1438
1439 SAL_WARN_IF( !m_bWaitSaveCompleted, "embeddedobj.common", "Unexpected saveCompleted() call!" );
1440 if ( !m_bWaitSaveCompleted )
1441 throw io::IOException(); // TODO: illegal call
1442
1443 OSL_ENSURE( m_xNewObjectStorage.is() && m_xNewParentStorage.is() , "Internal object information is broken!" );
1444 if ( !m_xNewObjectStorage.is() || !m_xNewParentStorage.is() )
1445 throw uno::RuntimeException(); // TODO: broken internal information
1446
1447 if ( bUseNew )
1448 {
1451
1452 uno::Reference< util::XModifiable > xModif( m_xDocHolder->GetComponent(), uno::UNO_QUERY );
1453 if ( xModif.is() )
1454 xModif->setModified( false );
1455
1456 PostEvent_Impl( "OnSaveAsDone");
1457 }
1458 else
1459 {
1460 try {
1461 m_xNewObjectStorage->dispose();
1462 }
1463 catch ( const uno::Exception& )
1464 {
1465 }
1466 }
1467
1468 m_xNewObjectStorage.clear();
1469 m_xNewParentStorage.clear();
1470 m_aNewEntryName.clear();
1471 m_aNewDocMediaDescriptor.realloc( 0 );
1472 m_bWaitSaveCompleted = false;
1473
1474 if ( bUseNew )
1475 {
1476 // TODO: notify listeners
1477
1478 if ( m_nUpdateMode == embed::EmbedUpdateModes::ALWAYS_UPDATE )
1479 {
1480 // TODO: update visual representation
1481 }
1482 }
1483}
1484
1485
1487{
1488 ::osl::MutexGuard aGuard( m_aMutex );
1489 if ( m_bDisposed )
1490 throw lang::DisposedException(); // TODO
1491
1493 throw embed::WrongStateException(
1494 "The object waits for saveCompleted() call!",
1495 static_cast< ::cppu::OWeakObject* >(this) );
1496
1497 if ( m_xObjectStorage.is() )
1498 return true;
1499
1500 return false;
1501}
1502
1503
1505{
1506 ::osl::MutexGuard aGuard( m_aMutex );
1507 if ( m_bDisposed )
1508 throw lang::DisposedException(); // TODO
1509
1510 if ( m_nObjectState == -1 )
1511 {
1512 // the object is still not loaded
1513 throw embed::WrongStateException( "The object persistence is not initialized!",
1514 static_cast< ::cppu::OWeakObject* >(this) );
1515 }
1516
1518 throw embed::WrongStateException(
1519 "The object waits for saveCompleted() call!",
1520 static_cast< ::cppu::OWeakObject* >(this) );
1521
1522 return m_aEntryName;
1523}
1524
1525
1527{
1528 // during switching from Activated to Running and from Running to Loaded states the object will
1529 // ask container to store the object, the container has to make decision
1530 // to do so or not
1531
1532 ::osl::ResettableMutexGuard aGuard( m_aMutex );
1533 if ( m_bDisposed )
1534 throw lang::DisposedException(); // TODO
1535
1536 if ( m_nObjectState == -1 )
1537 {
1538 // the object is still not loaded
1539 throw embed::WrongStateException( "Can't store object without persistence!",
1540 static_cast< ::cppu::OWeakObject* >(this) );
1541 }
1542
1544 throw embed::WrongStateException(
1545 "The object waits for saveCompleted() call!",
1546 static_cast< ::cppu::OWeakObject* >(this) );
1547
1548 if ( m_bReadOnly )
1549 throw io::IOException(); // TODO: access denied
1550
1551 // nothing to do, if the object is in loaded state
1552 if ( m_nObjectState == embed::EmbedStates::LOADED )
1553 return;
1554
1555 PostEvent_Impl( "OnSave" );
1556
1557 SAL_WARN_IF( !m_xDocHolder->GetComponent().is(), "embeddedobj.common", "If an object is activated or in running state it must have a document!" );
1558 if ( !m_xDocHolder->GetComponent().is() )
1559 throw uno::RuntimeException();
1560
1561 if ( m_bIsLinkURL )
1562 {
1563 // TODO: just store the document to its location
1564 uno::Reference< frame::XStorable > xStorable( m_xDocHolder->GetComponent(), uno::UNO_QUERY_THROW );
1565
1566 // free the main mutex for the storing time
1567 aGuard.clear();
1568
1569 xStorable->store();
1570
1571 aGuard.reset();
1572 }
1573 else
1574 {
1575 OSL_ENSURE( m_xParentStorage.is() && m_xObjectStorage.is(), "The object has no valid persistence!" );
1576
1577 if ( !m_xObjectStorage.is() )
1578 throw io::IOException(); //TODO: access denied
1579
1580 sal_Int32 nStorageFormat = SOFFICE_FILEFORMAT_CURRENT;
1581 try {
1583 }
1584 catch ( const beans::IllegalTypeException& )
1585 {
1586 // the container just has an unknown type, use current file format
1587 }
1588 catch ( const uno::Exception& )
1589 {
1590 SAL_WARN( "embeddedobj.common", "Can not retrieve storage media type!" );
1591 }
1592 if (nStorageFormat == SOFFICE_FILEFORMAT_60)
1593 {
1594 SAL_INFO("embeddedobj.common", "fdo#78159: Storing OOoXML as ODF");
1595 nStorageFormat = SOFFICE_FILEFORMAT_CURRENT;
1596 // setting MediaType is done later anyway, no need to do it here
1597 }
1598
1599 aGuard.clear();
1600 uno::Sequence<beans::PropertyValue> aEmpty;
1601 uno::Sequence<beans::PropertyValue> aMediaArgs{ comphelper::makePropertyValue(
1602 "DocumentBaseURL", GetBaseURL_Impl()) };
1603 StoreDocToStorage_Impl( m_xObjectStorage, aMediaArgs, aEmpty, nStorageFormat, m_aEntryName, true );
1604 aGuard.reset();
1605 }
1606
1607 uno::Reference< util::XModifiable > xModif( m_xDocHolder->GetComponent(), uno::UNO_QUERY );
1608 if ( xModif.is() )
1609 xModif->setModified( false );
1610
1611 PostEvent_Impl( "OnSaveDone" );
1612}
1613
1614
1616{
1617 ::osl::MutexGuard aGuard( m_aMutex );
1618 if ( m_bDisposed )
1619 throw lang::DisposedException(); // TODO
1620
1621 if ( m_nObjectState == -1 )
1622 {
1623 // the object is still not loaded
1624 throw embed::WrongStateException( "The object persistence is not initialized!",
1625 static_cast< ::cppu::OWeakObject* >(this) );
1626 }
1627
1629 throw embed::WrongStateException(
1630 "The object waits for saveCompleted() call!",
1631 static_cast< ::cppu::OWeakObject* >(this) );
1632
1633 return m_bReadOnly;
1634}
1635
1636
1638 const uno::Sequence< beans::PropertyValue >& lArguments,
1639 const uno::Sequence< beans::PropertyValue >& lObjArgs )
1640{
1641 // TODO: use lObjArgs
1642 // for now this method is used only to switch readonly state
1643
1644 ::osl::MutexGuard aGuard( m_aMutex );
1645 if ( m_bDisposed )
1646 throw lang::DisposedException(); // TODO
1647
1648 if ( m_nObjectState == -1 )
1649 {
1650 // the object is still not loaded
1651 throw embed::WrongStateException( "The object persistence is not initialized!",
1652 static_cast< ::cppu::OWeakObject* >(this) );
1653 }
1654
1655 if ( m_nObjectState != embed::EmbedStates::LOADED )
1656 {
1657 // the object is still not loaded
1658 throw embed::WrongStateException(
1659 "The object must be in loaded state to be reloaded!",
1660 static_cast< ::cppu::OWeakObject* >(this) );
1661 }
1662
1664 throw embed::WrongStateException(
1665 "The object waits for saveCompleted() call!",
1666 static_cast< ::cppu::OWeakObject* >(this) );
1667
1668 if ( m_bIsLinkURL )
1669 {
1670 // reload of the link
1671 OUString aOldLinkFilter = m_aLinkFilterName;
1672
1673 OUString aNewLinkFilter;
1674 for ( beans::PropertyValue const & prop : lArguments )
1675 {
1676 if ( prop.Name == "URL" )
1677 {
1678 // the new URL
1679 prop.Value >>= m_aLinkURL;
1680 m_aLinkFilterName.clear();
1681 }
1682 else if ( prop.Name == "FilterName" )
1683 {
1684 prop.Value >>= aNewLinkFilter;
1685 m_aLinkFilterName.clear();
1686 }
1687 }
1688
1690 if ( m_aLinkFilterName.isEmpty() )
1691 {
1692 if ( !aNewLinkFilter.isEmpty() )
1693 m_aLinkFilterName = aNewLinkFilter;
1694 else
1695 {
1696 uno::Sequence< beans::PropertyValue > aArgs{ comphelper::makePropertyValue(
1697 "URL", m_aLinkURL) };
1698 m_aLinkFilterName = aHelper.UpdateMediaDescriptorWithFilterName( aArgs, false );
1699 }
1700 }
1701
1702 if ( aOldLinkFilter != m_aLinkFilterName )
1703 {
1704 uno::Sequence< beans::NamedValue > aObject = aHelper.GetObjectPropsByFilter( m_aLinkFilterName );
1705
1706 // TODO/LATER: probably the document holder could be cleaned explicitly as in the destructor
1707 m_xDocHolder.clear();
1708
1709 LinkInit_Impl( aObject, lArguments, lObjArgs );
1710 }
1711 }
1712
1713 m_aDocMediaDescriptor = GetValuableArgs_Impl( lArguments, true );
1714
1715 // TODO: use lObjArgs for StoreVisualReplacement
1716 for ( beans::PropertyValue const & prop : lObjArgs )
1717 if ( prop.Name == "OutplaceDispatchInterceptor" )
1718 {
1719 uno::Reference< frame::XDispatchProviderInterceptor > xDispatchInterceptor;
1720 if ( prop.Value >>= xDispatchInterceptor )
1721 m_xDocHolder->SetOutplaceDispatchInterceptor( xDispatchInterceptor );
1722
1723 break;
1724 }
1725
1726 // TODO:
1727 // when document allows reloading through API the object can be reloaded not only in loaded state
1728
1729 bool bOldReadOnlyValue = m_bReadOnly;
1730
1731 m_bReadOnly = false;
1732 for ( beans::PropertyValue const & prop : lArguments )
1733 if ( prop.Name == "ReadOnly" )
1734 prop.Value >>= m_bReadOnly;
1735
1736 if ( bOldReadOnlyValue == m_bReadOnly || m_bIsLinkURL )
1737 return;
1738
1739 // close own storage
1740 try {
1741 if ( m_xObjectStorage.is() )
1742 m_xObjectStorage->dispose();
1743 }
1744 catch ( const uno::Exception& )
1745 {
1746 }
1747
1748 sal_Int32 nStorageMode = m_bReadOnly ? embed::ElementModes::READ : embed::ElementModes::READWRITE;
1749 m_xObjectStorage = m_xParentStorage->openStorageElement( m_aEntryName, nStorageMode );
1750}
1751
1753{
1754 if (!m_xObjectStorage.is())
1755 return false;
1756
1757 return m_xObjectStorage->getElementNames().hasElements();
1758}
1759
1760
1761void SAL_CALL OCommonEmbeddedObject::breakLink( const uno::Reference< embed::XStorage >& xStorage,
1762 const OUString& sEntName )
1763{
1764 ::osl::ResettableMutexGuard aGuard( m_aMutex );
1765 if ( m_bDisposed )
1766 throw lang::DisposedException(); // TODO
1767
1768 if (!m_bIsLinkURL || m_nObjectState == -1)
1769 {
1770 // it must be a linked initialized object
1771 throw embed::WrongStateException(
1772 "The object is not a valid linked object!",
1773 static_cast< ::cppu::OWeakObject* >(this) );
1774 }
1775 // the current implementation of OOo links does not implement this method since it does not implement
1776 // all the set of interfaces required for OOo embedded object ( XEmbedPersist is not supported ).
1777
1778 if ( !xStorage.is() )
1779 throw lang::IllegalArgumentException( "No parent storage is provided!",
1780 static_cast< ::cppu::OWeakObject* >(this),
1781 1 );
1782
1783 if ( sEntName.isEmpty() )
1784 throw lang::IllegalArgumentException( "Empty element name is provided!",
1785 static_cast< ::cppu::OWeakObject* >(this),
1786 2 );
1787
1789 throw embed::WrongStateException(
1790 "The object waits for saveCompleted() call!",
1791 static_cast< ::cppu::OWeakObject* >(this) );
1792
1793 uno::Reference< container::XNameAccess > xNameAccess( xStorage, uno::UNO_QUERY_THROW );
1794
1795 m_bReadOnly = false;
1796
1797 if ( m_xParentStorage != xStorage || m_aEntryName != sEntName )
1798 SwitchOwnPersistence( xStorage, sEntName );
1799
1800 // for linked object it means that it becomes embedded object
1801 // the document must switch it's persistence also
1802
1803 // TODO/LATER: handle the case when temp doc can not be created
1804 // the document is a new embedded object so it must be marked as modified
1805 uno::Reference< util::XCloseable > xDocument = CreateTempDocFromLink_Impl();
1806 try
1807 {
1808 if(m_xDocHolder.is() && m_xDocHolder->GetComponent().is())
1809 {
1810 // tdf#141528 m_xDocHolder->GetComponent() may be not set, so add it
1811 // to the try path to not get thrown out of the local context to the next
1812 // higher try...catch on the stack. To make breakLink work it is
1813 // *necessary* to execute the code below that resets the linked state,
1814 // esp. the *.clear stuff and resetting m_bIsLink.
1815 uno::Reference< util::XModifiable > xModif( m_xDocHolder->GetComponent(), uno::UNO_QUERY_THROW );
1816
1817 // all other locations in this file check for xModif.is(), so do it here, too
1818 if ( xModif.is() )
1819 xModif->setModified( true );
1820 }
1821 }
1822 catch( const uno::Exception& )
1823 {}
1824
1825 m_xDocHolder->SetComponent( xDocument, m_bReadOnly );
1826 SAL_WARN_IF( !m_xDocHolder->GetComponent().is(), "embeddedobj.common", "If document can't be created, an exception must be thrown!" );
1827
1828 if ( m_nObjectState == embed::EmbedStates::LOADED )
1829 {
1830 // the state is changed and can not be switched to loaded state back without saving
1831 m_nObjectState = embed::EmbedStates::RUNNING;
1832 StateChangeNotification_Impl( false, embed::EmbedStates::LOADED, m_nObjectState, aGuard );
1833 }
1834 else if ( m_nObjectState == embed::EmbedStates::ACTIVE )
1835 m_xDocHolder->Show();
1836
1837 // tdf#141529 reset all stuff involved in linked state, including
1838 // the OLE content copied to the temp file
1839 m_bIsLinkURL = false;
1840 m_aLinkTempFile.clear();
1841 m_aLinkFilterName.clear();
1842 m_aLinkURL.clear();
1843}
1844
1845
1847{
1848 ::osl::MutexGuard aGuard( m_aMutex );
1849 if ( m_bDisposed )
1850 throw lang::DisposedException(); // TODO
1851
1852 return m_bIsLinkURL;
1853}
1854
1855
1857{
1858 ::osl::MutexGuard aGuard( m_aMutex );
1859 if ( m_bDisposed )
1860 throw lang::DisposedException(); // TODO
1861
1862 if ( !m_bIsLinkURL )
1863 throw embed::WrongStateException(
1864 "The object is not a link object!",
1865 static_cast< ::cppu::OWeakObject* >(this) );
1866
1867 return m_aLinkURL;
1868}
1869
1870/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
constexpr OUStringLiteral sDocumentBaseURL
constexpr OUStringLiteral sHierarchicalDocumentName
css::uno::Sequence< css::beans::PropertyValue > m_aDocMediaDescriptor
virtual sal_Bool SAL_CALL isReadonly() override
css::awt::Size m_aDefaultSizeForChart_In_100TH_MM
css::uno::Reference< css::uno::XComponentContext > m_xContext
css::uno::Sequence< css::beans::PropertyValue > m_aNewDocMediaDescriptor
const OUString & GetDocumentServiceName() const
css::uno::Reference< css::uno::XInterface > m_xParent
virtual void SAL_CALL reload(const css::uno::Sequence< css::beans::PropertyValue > &lArguments, const css::uno::Sequence< css::beans::PropertyValue > &lObjArgs) override
virtual sal_Bool SAL_CALL hasEntry() override
static OUString GetBaseURLFrom_Impl(const css::uno::Sequence< css::beans::PropertyValue > &lArguments, const css::uno::Sequence< css::beans::PropertyValue > &lObjArgs)
void PostEvent_Impl(const OUString &aEventName)
Definition: miscobj.cxx:313
void StateChangeNotification_Impl(bool bBeforeChange, sal_Int32 nOldState, sal_Int32 nNewState,::osl::ResettableMutexGuard &_rGuard)
Definition: embedobj.cxx:182
virtual sal_Bool SAL_CALL isLink() override
css::uno::Reference< css::embed::XStorage > m_xRecoveryStorage
css::uno::Reference< css::util::XCloseable > InitNewDocument_Impl()
virtual void SAL_CALL changeState(sal_Int32 nNewState) override
Definition: embedobj.cxx:476
OUString GetBaseURL_Impl() const
virtual void SAL_CALL setPersistentEntry(const css::uno::Reference< css::embed::XStorage > &xStorage, const OUString &sEntName, sal_Int32 nEntryConnectionMode, const css::uno::Sequence< css::beans::PropertyValue > &lArguments, const css::uno::Sequence< css::beans::PropertyValue > &lObjArgs) override
void StoreDocToStorage_Impl(const css::uno::Reference< css::embed::XStorage > &xStorage, const css::uno::Sequence< css::beans::PropertyValue > &rMediaArgs, const css::uno::Sequence< css::beans::PropertyValue > &rObjArgs, sal_Int32 nStorageVersion, const OUString &aHierarchName, bool bAttachToStorage)
virtual void SAL_CALL breakLink(const css::uno::Reference< css::embed::XStorage > &xStorage, const OUString &sEntName) override
css::uno::Reference< css::util::XCloseable > CreateTempDocFromLink_Impl()
virtual OUString SAL_CALL getEntryName() override
virtual void SAL_CALL saveCompleted(sal_Bool bUseNew) override
OUString m_aDefaultParentBaseURL
void LinkInit_Impl(const css::uno::Sequence< css::beans::NamedValue > &aObjectProps, const css::uno::Sequence< css::beans::PropertyValue > &aMediaDescr, const css::uno::Sequence< css::beans::PropertyValue > &aObjectDescr)
Definition: miscobj.cxx:173
css::uno::Reference< css::io::XTempFile > m_aLinkTempFile
virtual void SAL_CALL storeAsEntry(const css::uno::Reference< css::embed::XStorage > &xStorage, const OUString &sEntName, const css::uno::Sequence< css::beans::PropertyValue > &lArguments, const css::uno::Sequence< css::beans::PropertyValue > &lObjArgs) override
css::uno::Reference< css::util::XCloseable > LoadLink_Impl()
css::uno::Reference< css::embed::XStorage > m_xNewObjectStorage
virtual void SAL_CALL storeToEntry(const css::uno::Reference< css::embed::XStorage > &xStorage, const OUString &sEntName, const css::uno::Sequence< css::beans::PropertyValue > &lArguments, const css::uno::Sequence< css::beans::PropertyValue > &lObjArgs) override
void EmbedAndReparentDoc_Impl(const css::uno::Reference< css::util::XCloseable > &i_rxDocument) const
const OUString & GetPresetFilterName() const
css::awt::Size m_aClonedSize
rtl::Reference< DocumentHolder > m_xDocHolder
css::uno::Reference< css::util::XCloseable > CreateDocFromMediaDescr_Impl(const css::uno::Sequence< css::beans::PropertyValue > &aMedDescr)
void SwitchOwnPersistence(const css::uno::Reference< css::embed::XStorage > &xNewParentStorage, const css::uno::Reference< css::embed::XStorage > &xNewObjectStorage, const OUString &aNewName)
virtual sal_Bool SAL_CALL isStored() override
void handleLinkedOLE(CopyBackToOLELink eState)
Definition: miscobj.cxx:370
OUString GetFilterName(sal_Int32 nVersion) const
css::uno::Reference< css::embed::XStorage > m_xNewParentStorage
void SwitchDocToStorage_Impl(const css::uno::Reference< css::document::XStorageBasedDocument > &xDoc, const css::uno::Reference< css::embed::XStorage > &xStorage)
css::uno::Reference< css::embed::XEmbeddedClient > m_xClientSite
virtual void SAL_CALL storeOwn() override
css::uno::Reference< css::embed::XStorage > m_xParentStorage
css::uno::Reference< css::io::XInputStream > StoreDocumentToTempStream_Impl(sal_Int32 nStorageFormat, const OUString &aBaseURL, const OUString &aHierarchName)
css::uno::Reference< css::util::XCloseable > LoadDocumentFromStorage_Impl()
css::uno::Reference< css::embed::XStorage > m_xObjectStorage
void FillDefaultLoadArgs_Impl(const css::uno::Reference< css::embed::XStorage > &i_rxStorage, ::comphelper::NamedValueCollection &o_rLoadArgs) const
virtual OUString SAL_CALL getLinkURL() override
bool put(const OUString &_rValueName, const VALUE_TYPE &_rValue)
NamedValueCollection & merge(const NamedValueCollection &_rAdditionalValues, bool _bOverwriteExisting)
css::uno::Sequence< css::beans::PropertyValue > getPropertyValues() const
static sal_Int32 GetXStorageFormat(const css::uno::Reference< css::embed::XStorage > &xStorage)
static bool IsFuzzing()
static constexpr OUStringLiteral PROP_AUTOSAVEEVENT
#define ENSURE_OR_THROW(c, m)
#define DBG_UNHANDLED_EXCEPTION(...)
float u
Any aHelper
sal_Int16 nVersion
Reference< XInterface > xTarget
#define SOFFICE_FILEFORMAT_CURRENT
#define SOFFICE_FILEFORMAT_60
Sequence< PropertyValue > aArguments
Sequence< sal_Int8 > aSeq
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
aStr
css::beans::PropertyValue makePropertyValue(const OUString &rName, T &&rValue)
Any SAL_CALL getCaughtException()
static uno::Sequence< beans::PropertyValue > addAsTemplate(const uno::Sequence< beans::PropertyValue > &aOrig)
Definition: persistence.cxx:94
static uno::Reference< io::XInputStream > createTempInpStreamFromStor(const uno::Reference< embed::XStorage > &xStorage, const uno::Reference< uno::XComponentContext > &xContext)
uno::Sequence< beans::PropertyValue > GetValuableArgs_Impl(const uno::Sequence< beans::PropertyValue > &aMedDescr, bool bCanUseDocumentBaseURL)
Definition: persistence.cxx:67
static uno::Reference< util::XCloseable > CreateDocument(const uno::Reference< uno::XComponentContext > &_rxContext, const OUString &_rDocumentServiceName, bool _bEmbeddedScriptSupport, const bool i_bDocumentRecoverySupport)
static void TransferMediaType(const uno::Reference< embed::XStorage > &i_rSource, const uno::Reference< embed::XStorage > &i_rTarget)
static void SetDocToEmbedded(const uno::Reference< frame::XModel > &rDocument, const OUString &aModuleName)
Reference< XModel > xModel
OUString Name
unsigned char sal_Bool
sal_Int32 nLength