1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <sal/config.h>
22 #include <comphelper/classids.hxx>
23 #include <com/sun/star/embed/XEmbeddedObject.hpp>
24 #include <com/sun/star/embed/XLinkageSupport.hpp>
25 #include <com/sun/star/document/XEmbeddedObjectSupplier.hpp>
26 #include <xmloff/families.hxx>
27 #include <xmloff/xmlnamespace.hxx>
28 #include <xmloff/xmltoken.hxx>
29 #include <xmloff/txtprmap.hxx>
30 #include <xmloff/maptype.hxx>
31 #include <xmloff/xmlexppr.hxx>
34 #include <fmtcntnt.hxx>
35 #include <unoframe.hxx>
37 #include "xmltexte.hxx"
38 #include <SwAppletImpl.hxx>
39 #include <ndindex.hxx>
41 #include <osl/diagnose.h>
42 #include <sot/exchange.hxx>
43 #include <svl/urihelper.hxx>
44 #include <sfx2/frmdescr.hxx>
46 using namespace ::com::sun::star
;
47 using namespace ::com::sun::star::uno
;
48 using namespace ::com::sun::star::style
;
49 using namespace ::com::sun::star::beans
;
50 using namespace ::com::sun::star::lang
;
51 using namespace ::com::sun::star::document
;
52 using namespace ::com::sun::star::io
;
53 using namespace ::xmloff::token
;
57 enum SvEmbeddedObjectTypes
68 SwNoTextNode
*SwXMLTextParagraphExport::GetNoTextNode(
69 const Reference
< XPropertySet
>& rPropSet
)
71 SwXFrame
* pFrame
= dynamic_cast<SwXFrame
*>(rPropSet
.get());
72 assert(pFrame
&& "SwXFrame missing");
73 SwFrameFormat
*pFrameFormat
= pFrame
->GetFrameFormat();
74 const SwFormatContent
& rContent
= pFrameFormat
->GetContent();
75 const SwNodeIndex
*pNdIdx
= rContent
.GetContentIdx();
76 return pNdIdx
->GetNodes()[pNdIdx
->GetIndex() + 1]->GetNoTextNode();
79 constexpr OUStringLiteral
gsEmbeddedObjectProtocol( u
"vnd.sun.star.EmbeddedObject:" );
81 SwXMLTextParagraphExport::SwXMLTextParagraphExport(
83 SvXMLAutoStylePoolP
& _rAutoStylePool
) :
84 XMLTextParagraphExport( rExp
, _rAutoStylePool
),
85 m_aAppletClassId( SO3_APPLET_CLASSID
),
86 m_aPluginClassId( SO3_PLUGIN_CLASSID
),
87 m_aIFrameClassId( SO3_IFRAME_CLASSID
)
91 SwXMLTextParagraphExport::~SwXMLTextParagraphExport()
95 static void lcl_addURL ( SvXMLExport
&rExport
, const OUString
&rURL
,
98 const OUString sRelURL
= ( bToRel
&& !rURL
.isEmpty() )
99 ? URIHelper::simpleNormalizedMakeRelative(rExport
.GetOrigFileName(), rURL
)
102 if (!sRelURL
.isEmpty())
104 rExport
.AddAttribute ( XML_NAMESPACE_XLINK
, XML_HREF
, sRelURL
);
105 rExport
.AddAttribute ( XML_NAMESPACE_XLINK
, XML_TYPE
, XML_SIMPLE
);
106 rExport
.AddAttribute ( XML_NAMESPACE_XLINK
, XML_SHOW
, XML_EMBED
);
107 rExport
.AddAttribute ( XML_NAMESPACE_XLINK
, XML_ACTUATE
, XML_ONLOAD
);
111 static void lcl_addAspect(
112 const svt::EmbeddedObjectRef
& rObj
,
113 std::vector
<XMLPropertyState
>& rStates
,
114 const rtl::Reference
< XMLPropertySetMapper
>& rMapper
)
116 sal_Int64 nAspect
= rObj
.GetViewAspect();
118 rStates
.emplace_back( rMapper
->FindEntryIndex( CTF_OLE_DRAW_ASPECT
), uno::Any( nAspect
) );
121 static void lcl_addOutplaceProperties(
122 const svt::EmbeddedObjectRef
& rObj
,
123 std::vector
<XMLPropertyState
>& rStates
,
124 const rtl::Reference
< XMLPropertySetMapper
>& rMapper
)
126 MapMode
aMode( MapUnit::Map100thMM
); // the API expects this map mode for the embedded objects
127 Size aSize
= rObj
.GetSize( &aMode
); // get the size in the requested map mode
129 if( !(aSize
.Width() && aSize
.Height()) )
132 rStates
.emplace_back( rMapper
->FindEntryIndex( CTF_OLE_VIS_AREA_LEFT
), Any(sal_Int32(0)) );
133 rStates
.emplace_back( rMapper
->FindEntryIndex( CTF_OLE_VIS_AREA_TOP
), Any(sal_Int32(0)) );
134 rStates
.emplace_back( rMapper
->FindEntryIndex( CTF_OLE_VIS_AREA_WIDTH
), Any(static_cast<sal_Int32
>(aSize
.Width())) );
135 rStates
.emplace_back( rMapper
->FindEntryIndex( CTF_OLE_VIS_AREA_HEIGHT
), Any(static_cast<sal_Int32
>(aSize
.Height())) );
138 static void lcl_addFrameProperties(
139 const uno::Reference
< embed::XEmbeddedObject
>& xObj
,
140 std::vector
<XMLPropertyState
>& rStates
,
141 const rtl::Reference
< XMLPropertySetMapper
>& rMapper
)
143 if ( !::svt::EmbeddedObjectRef::TryRunningState( xObj
) )
146 uno::Reference
< beans::XPropertySet
> xSet( xObj
->getComponent(), uno::UNO_QUERY
);
150 bool bIsAutoScroll
= false, bIsScrollingMode
= false;
151 Any aAny
= xSet
->getPropertyValue("FrameIsAutoScroll");
152 aAny
>>= bIsAutoScroll
;
153 if ( !bIsAutoScroll
)
155 aAny
= xSet
->getPropertyValue("FrameIsScrollingMode");
156 aAny
>>= bIsScrollingMode
;
159 bool bIsBorderSet
= false, bIsAutoBorder
= false;
160 aAny
= xSet
->getPropertyValue("FrameIsAutoBorder");
161 aAny
>>= bIsAutoBorder
;
162 if ( !bIsAutoBorder
)
164 aAny
= xSet
->getPropertyValue("FrameIsBorder");
165 aAny
>>= bIsBorderSet
;
168 sal_Int32 nWidth
, nHeight
;
169 aAny
= xSet
->getPropertyValue("FrameMarginWidth");
171 aAny
= xSet
->getPropertyValue("FrameMarginHeight");
175 rStates
.emplace_back( rMapper
->FindEntryIndex( CTF_FRAME_DISPLAY_SCROLLBAR
), Any(bIsScrollingMode
) );
177 rStates
.emplace_back( rMapper
->FindEntryIndex( CTF_FRAME_DISPLAY_BORDER
), Any(bIsBorderSet
) );
178 if( SIZE_NOT_SET
!= nWidth
)
179 rStates
.emplace_back( rMapper
->FindEntryIndex( CTF_FRAME_MARGIN_HORI
), Any(nWidth
) );
180 if( SIZE_NOT_SET
!= nHeight
)
181 rStates
.emplace_back( rMapper
->FindEntryIndex( CTF_FRAME_MARGIN_VERT
), Any(nHeight
) );
184 void SwXMLTextParagraphExport::_collectTextEmbeddedAutoStyles(
185 const Reference
< XPropertySet
> & rPropSet
)
187 SwOLENode
*pOLENd
= GetNoTextNode( rPropSet
)->GetOLENode();
188 svt::EmbeddedObjectRef
& rObjRef
= pOLENd
->GetOLEObj().GetObject();
192 std::vector
<XMLPropertyState
> aStates
;
194 SvGlobalName
aClassId( rObjRef
->getClassID() );
196 if( m_aIFrameClassId
== aClassId
)
198 lcl_addFrameProperties( rObjRef
.GetObject(), aStates
,
199 GetAutoFramePropMapper()->getPropertySetMapper() );
201 else if ( !SotExchange::IsInternal( aClassId
) )
203 lcl_addOutplaceProperties( rObjRef
, aStates
,
204 GetAutoFramePropMapper()->getPropertySetMapper() );
207 lcl_addAspect( rObjRef
, aStates
,
208 GetAutoFramePropMapper()->getPropertySetMapper() );
210 Add( XmlStyleFamily::TEXT_FRAME
, rPropSet
, aStates
);
213 void SwXMLTextParagraphExport::_exportTextEmbedded(
214 const Reference
< XPropertySet
> & rPropSet
,
215 const Reference
< XPropertySetInfo
> & rPropSetInfo
)
217 SwOLENode
*pOLENd
= GetNoTextNode( rPropSet
)->GetOLENode();
218 SwOLEObj
& rOLEObj
= pOLENd
->GetOLEObj();
219 svt::EmbeddedObjectRef
& rObjRef
= rOLEObj
.GetObject();
223 SvGlobalName
aClassId( rObjRef
->getClassID() );
225 SvEmbeddedObjectTypes nType
= SV_EMBEDDED_OWN
;
226 if( m_aPluginClassId
== aClassId
)
228 nType
= SV_EMBEDDED_PLUGIN
;
230 else if( m_aAppletClassId
== aClassId
)
232 nType
= SV_EMBEDDED_APPLET
;
234 else if( m_aIFrameClassId
== aClassId
)
236 nType
= SV_EMBEDDED_FRAME
;
238 else if ( !SotExchange::IsInternal( aClassId
) )
240 nType
= SV_EMBEDDED_OUTPLACE
;
243 enum XMLTokenEnum eElementName
= XML__UNKNOWN_
;
244 SvXMLExport
&rXMLExport
= GetExport();
246 // First the stuff common to each of Applet/Plugin/Floating Frame
249 if( rPropSetInfo
->hasPropertyByName( gsFrameStyleName
) )
251 aAny
= rPropSet
->getPropertyValue( gsFrameStyleName
);
255 std::vector
<XMLPropertyState
> aStates
;
259 case SV_EMBEDDED_FRAME
:
260 lcl_addFrameProperties( rObjRef
.GetObject(), aStates
,
261 GetAutoFramePropMapper()->getPropertySetMapper() );
263 case SV_EMBEDDED_OUTPLACE
:
264 lcl_addOutplaceProperties( rObjRef
, aStates
,
265 GetAutoFramePropMapper()->getPropertySetMapper() );
271 lcl_addAspect( rObjRef
, aStates
,
272 GetAutoFramePropMapper()->getPropertySetMapper() );
274 const OUString sAutoStyle
= Find( XmlStyleFamily::TEXT_FRAME
,
275 rPropSet
, sStyle
, aStates
);
278 if( !sAutoStyle
.isEmpty() )
279 rXMLExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_STYLE_NAME
, sAutoStyle
);
280 addTextFrameAttributes( rPropSet
, false );
282 SvXMLElementExport
aElem( GetExport(), XML_NAMESPACE_DRAW
,
283 XML_FRAME
, false, true );
287 case SV_EMBEDDED_OUTPLACE
:
288 case SV_EMBEDDED_OWN
:
289 if( !(rXMLExport
.getExportFlags() & SvXMLExportFlags::EMBEDDED
) )
293 bool bIsOwnLink
= false;
294 if( SV_EMBEDDED_OWN
== nType
)
298 uno::Reference
< embed::XLinkageSupport
> xLinkage( rObjRef
.GetObject(), uno::UNO_QUERY
);
299 bIsOwnLink
= xLinkage
.is() && xLinkage
->isLink();
301 sURL
= xLinkage
->getLinkURL();
303 catch(const uno::Exception
&)
305 // TODO/LATER: error handling
306 OSL_FAIL( "Link detection or retrieving of the URL of OOo link is failed!" );
312 sURL
= gsEmbeddedObjectProtocol
+ rOLEObj
.GetCurrentPersistName();
315 sURL
= GetExport().AddEmbeddedObject( sURL
);
316 lcl_addURL( rXMLExport
, sURL
, false );
318 if( SV_EMBEDDED_OWN
== nType
&& !pOLENd
->GetChartTableName().isEmpty() )
320 OUString
sRange( pOLENd
->GetChartTableName() );
321 OUStringBuffer
aBuffer( sRange
.getLength() + 2 );
322 for( sal_Int32 i
=0; i
< sRange
.getLength(); i
++ )
324 sal_Unicode c
= sRange
[i
];
331 if( aBuffer
.isEmpty() )
333 aBuffer
.append( OUString::Concat("\'") + sRange
.subView(0, i
) );
335 if( '\'' == c
|| '\\' == c
)
336 aBuffer
.append( '\\' );
339 if( !aBuffer
.isEmpty() )
343 if( !aBuffer
.isEmpty() )
345 aBuffer
.append( '\'' );
346 sRange
= aBuffer
.makeStringAndClear();
349 rXMLExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_NOTIFY_ON_UPDATE_OF_RANGES
,
352 eElementName
= SV_EMBEDDED_OUTPLACE
==nType
? XML_OBJECT_OLE
355 case SV_EMBEDDED_APPLET
:
358 if( svt::EmbeddedObjectRef::TryRunningState( rObjRef
.GetObject() ) )
360 uno::Reference
< beans::XPropertySet
> xSet( rObjRef
->getComponent(), uno::UNO_QUERY
);
362 Any aAny2
= xSet
->getPropertyValue("AppletCodeBase");
364 if (!aStr
.isEmpty() )
365 lcl_addURL(rXMLExport
, aStr
);
367 aAny2
= xSet
->getPropertyValue("AppletName");
370 rXMLExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_APPLET_NAME
, aStr
);
372 aAny2
= xSet
->getPropertyValue("AppletCode");
374 rXMLExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_CODE
, aStr
);
376 bool bScript
= false;
377 aAny2
= xSet
->getPropertyValue("AppletIsScript");
379 rXMLExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_MAY_SCRIPT
, bScript
? XML_TRUE
: XML_FALSE
);
381 uno::Sequence
< beans::PropertyValue
> aProps
;
382 aAny2
= xSet
->getPropertyValue("AppletCommands");
385 sal_Int32 i
= aProps
.getLength();
388 const beans::PropertyValue
& aProp
= aProps
[--i
];
389 const SwHtmlOptType nType2
= SwApplet_Impl::GetOptionType( aProp
.Name
, true );
390 if ( nType2
== SwHtmlOptType::TAG
)
393 aProp
.Value
>>= aStr2
;
394 rXMLExport
.AddAttribute( XML_NAMESPACE_DRAW
, aProp
.Name
, aStr2
);
398 eElementName
= XML_APPLET
;
402 case SV_EMBEDDED_PLUGIN
:
405 if ( svt::EmbeddedObjectRef::TryRunningState( rObjRef
.GetObject() ) )
407 uno::Reference
< beans::XPropertySet
> xSet( rObjRef
->getComponent(), uno::UNO_QUERY
);
409 Any aAny2
= xSet
->getPropertyValue("PluginURL");
411 lcl_addURL( rXMLExport
, aStr
);
413 aAny2
= xSet
->getPropertyValue("PluginMimeType");
416 rXMLExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_MIME_TYPE
, aStr
);
417 eElementName
= XML_PLUGIN
;
421 case SV_EMBEDDED_FRAME
:
423 // It's a floating frame!
424 if ( svt::EmbeddedObjectRef::TryRunningState( rObjRef
.GetObject() ) )
426 uno::Reference
< beans::XPropertySet
> xSet( rObjRef
->getComponent(), uno::UNO_QUERY
);
428 Any aAny2
= xSet
->getPropertyValue("FrameURL");
431 lcl_addURL( rXMLExport
, aStr
);
433 aAny2
= xSet
->getPropertyValue("FrameName");
437 rXMLExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_FRAME_NAME
, aStr
);
438 eElementName
= XML_FLOATING_FRAME
;
443 OSL_ENSURE( false, "unknown object type! Base class should have been called!" );
447 SvXMLElementExport
aElementExport( rXMLExport
, XML_NAMESPACE_DRAW
, eElementName
,
451 case SV_EMBEDDED_OWN
:
452 if( rXMLExport
.getExportFlags() & SvXMLExportFlags::EMBEDDED
)
454 Reference
< XEmbeddedObjectSupplier
> xEOS( rPropSet
, UNO_QUERY
);
455 OSL_ENSURE( xEOS
.is(), "no embedded object supplier for own object" );
456 Reference
< XComponent
> xComp
= xEOS
->getEmbeddedObject();
457 rXMLExport
.ExportEmbeddedOwnObject( xComp
);
460 case SV_EMBEDDED_OUTPLACE
:
461 if( rXMLExport
.getExportFlags() & SvXMLExportFlags::EMBEDDED
)
463 OUString
sURL( gsEmbeddedObjectProtocol
+ rOLEObj
.GetCurrentPersistName() );
465 if ( !( rXMLExport
.getExportFlags() & SvXMLExportFlags::OASIS
) )
466 sURL
+= "?oasis=false";
468 rXMLExport
.AddEmbeddedObjectAsBase64( sURL
);
471 case SV_EMBEDDED_APPLET
:
473 if ( svt::EmbeddedObjectRef::TryRunningState( rObjRef
.GetObject() ) )
475 uno::Reference
< beans::XPropertySet
> xSet( rObjRef
->getComponent(), uno::UNO_QUERY
);
476 uno::Sequence
< beans::PropertyValue
> aProps
;
477 aAny
= xSet
->getPropertyValue("AppletCommands");
480 sal_Int32 i
= aProps
.getLength();
483 const beans::PropertyValue
& aProp
= aProps
[--i
];
484 const SwHtmlOptType nType2
= SwApplet_Impl::GetOptionType( aProp
.Name
, true );
485 if (SwHtmlOptType::PARAM
== nType2
|| SwHtmlOptType::SIZE
== nType2
)
488 aProp
.Value
>>= aStr
;
489 rXMLExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_NAME
, aProp
.Name
);
490 rXMLExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_VALUE
, aStr
);
491 SvXMLElementExport
aElementExport2( rXMLExport
, XML_NAMESPACE_DRAW
, XML_PARAM
, false, true );
497 case SV_EMBEDDED_PLUGIN
:
499 if ( svt::EmbeddedObjectRef::TryRunningState( rObjRef
.GetObject() ) )
501 uno::Reference
< beans::XPropertySet
> xSet( rObjRef
->getComponent(), uno::UNO_QUERY
);
502 uno::Sequence
< beans::PropertyValue
> aProps
;
503 aAny
= xSet
->getPropertyValue("PluginCommands");
506 sal_Int32 i
= aProps
.getLength();
509 const beans::PropertyValue
& aProp
= aProps
[--i
];
510 const SwHtmlOptType nType2
= SwApplet_Impl::GetOptionType( aProp
.Name
, false );
511 if ( nType2
== SwHtmlOptType::TAG
)
514 aProp
.Value
>>= aStr
;
515 rXMLExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_NAME
, aProp
.Name
);
516 rXMLExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_VALUE
, aStr
);
517 SvXMLElementExport
aElementExport2( rXMLExport
, XML_NAMESPACE_DRAW
, XML_PARAM
, false, true );
527 if( SV_EMBEDDED_OUTPLACE
==nType
|| SV_EMBEDDED_OWN
==nType
)
529 OUString sURL
= XML_EMBEDDEDOBJECTGRAPHIC_URL_BASE
+ rOLEObj
.GetCurrentPersistName();
530 if( !(rXMLExport
.getExportFlags() & SvXMLExportFlags::EMBEDDED
) )
532 sURL
= GetExport().AddEmbeddedObject( sURL
);
533 lcl_addURL( rXMLExport
, sURL
, false );
536 SvXMLElementExport
aElementExport( GetExport(), XML_NAMESPACE_DRAW
,
537 XML_IMAGE
, false, true );
539 if( rXMLExport
.getExportFlags() & SvXMLExportFlags::EMBEDDED
)
540 GetExport().AddEmbeddedObjectAsBase64( sURL
);
543 // Lastly the stuff common to each of Applet/Plugin/Floating Frame
544 exportEvents( rPropSet
);
545 exportTitleAndDescription( rPropSet
, rPropSetInfo
); // #i73249#
546 exportContour( rPropSet
, rPropSetInfo
);
549 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */