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::beans
;
49 using namespace ::com::sun::star::lang
;
50 using namespace ::com::sun::star::document
;
51 using namespace ::xmloff::token
;
55 enum SvEmbeddedObjectTypes
66 SwNoTextNode
*SwXMLTextParagraphExport::GetNoTextNode(
67 const Reference
< XPropertySet
>& rPropSet
)
69 SwXFrame
* pFrame
= dynamic_cast<SwXFrame
*>(rPropSet
.get());
70 assert(pFrame
&& "SwXFrame missing");
71 SwFrameFormat
*pFrameFormat
= pFrame
->GetFrameFormat();
72 const SwFormatContent
& rContent
= pFrameFormat
->GetContent();
73 const SwNodeIndex
*pNdIdx
= rContent
.GetContentIdx();
74 return pNdIdx
->GetNodes()[pNdIdx
->GetIndex() + 1]->GetNoTextNode();
77 constexpr OUString
gsEmbeddedObjectProtocol( u
"vnd.sun.star.EmbeddedObject:"_ustr
);
79 SwXMLTextParagraphExport::SwXMLTextParagraphExport(
81 SvXMLAutoStylePoolP
& _rAutoStylePool
) :
82 XMLTextParagraphExport( rExp
, _rAutoStylePool
),
83 m_aAppletClassId( SO3_APPLET_CLASSID
),
84 m_aPluginClassId( SO3_PLUGIN_CLASSID
),
85 m_aIFrameClassId( SO3_IFRAME_CLASSID
)
89 SwXMLTextParagraphExport::~SwXMLTextParagraphExport()
93 static void lcl_addURL ( SvXMLExport
&rExport
, const OUString
&rURL
,
96 const OUString sRelURL
= ( bToRel
&& !rURL
.isEmpty() )
97 ? URIHelper::simpleNormalizedMakeRelative(rExport
.GetOrigFileName(), rURL
)
100 if (!sRelURL
.isEmpty())
102 rExport
.AddAttribute ( XML_NAMESPACE_XLINK
, XML_HREF
, sRelURL
);
103 rExport
.AddAttribute ( XML_NAMESPACE_XLINK
, XML_TYPE
, XML_SIMPLE
);
104 rExport
.AddAttribute ( XML_NAMESPACE_XLINK
, XML_SHOW
, XML_EMBED
);
105 rExport
.AddAttribute ( XML_NAMESPACE_XLINK
, XML_ACTUATE
, XML_ONLOAD
);
109 static void lcl_addAspect(
110 const svt::EmbeddedObjectRef
& rObj
,
111 std::vector
<XMLPropertyState
>& rStates
,
112 const rtl::Reference
< XMLPropertySetMapper
>& rMapper
)
114 sal_Int64 nAspect
= rObj
.GetViewAspect();
116 rStates
.emplace_back( rMapper
->FindEntryIndex( CTF_OLE_DRAW_ASPECT
), uno::Any( nAspect
) );
119 static void lcl_addOutplaceProperties(
120 const svt::EmbeddedObjectRef
& rObj
,
121 std::vector
<XMLPropertyState
>& rStates
,
122 const rtl::Reference
< XMLPropertySetMapper
>& rMapper
)
124 MapMode
aMode( MapUnit::Map100thMM
); // the API expects this map mode for the embedded objects
125 Size aSize
= rObj
.GetSize( &aMode
); // get the size in the requested map mode
127 if( !(aSize
.Width() && aSize
.Height()) )
130 rStates
.emplace_back( rMapper
->FindEntryIndex( CTF_OLE_VIS_AREA_LEFT
), Any(sal_Int32(0)) );
131 rStates
.emplace_back( rMapper
->FindEntryIndex( CTF_OLE_VIS_AREA_TOP
), Any(sal_Int32(0)) );
132 rStates
.emplace_back( rMapper
->FindEntryIndex( CTF_OLE_VIS_AREA_WIDTH
), Any(static_cast<sal_Int32
>(aSize
.Width())) );
133 rStates
.emplace_back( rMapper
->FindEntryIndex( CTF_OLE_VIS_AREA_HEIGHT
), Any(static_cast<sal_Int32
>(aSize
.Height())) );
136 static void lcl_addFrameProperties(
137 const uno::Reference
< embed::XEmbeddedObject
>& xObj
,
138 std::vector
<XMLPropertyState
>& rStates
,
139 const rtl::Reference
< XMLPropertySetMapper
>& rMapper
)
141 if ( !::svt::EmbeddedObjectRef::TryRunningState( xObj
) )
144 uno::Reference
< beans::XPropertySet
> xSet( xObj
->getComponent(), uno::UNO_QUERY
);
148 bool bIsAutoScroll
= false, bIsScrollingMode
= false;
149 Any aAny
= xSet
->getPropertyValue(u
"FrameIsAutoScroll"_ustr
);
150 aAny
>>= bIsAutoScroll
;
151 if ( !bIsAutoScroll
)
153 aAny
= xSet
->getPropertyValue(u
"FrameIsScrollingMode"_ustr
);
154 aAny
>>= bIsScrollingMode
;
157 bool bIsBorderSet
= false, bIsAutoBorder
= false;
158 aAny
= xSet
->getPropertyValue(u
"FrameIsAutoBorder"_ustr
);
159 aAny
>>= bIsAutoBorder
;
160 if ( !bIsAutoBorder
)
162 aAny
= xSet
->getPropertyValue(u
"FrameIsBorder"_ustr
);
163 aAny
>>= bIsBorderSet
;
166 sal_Int32 nWidth
, nHeight
;
167 aAny
= xSet
->getPropertyValue(u
"FrameMarginWidth"_ustr
);
169 aAny
= xSet
->getPropertyValue(u
"FrameMarginHeight"_ustr
);
173 rStates
.emplace_back( rMapper
->FindEntryIndex( CTF_FRAME_DISPLAY_SCROLLBAR
), Any(bIsScrollingMode
) );
175 rStates
.emplace_back( rMapper
->FindEntryIndex( CTF_FRAME_DISPLAY_BORDER
), Any(bIsBorderSet
) );
176 if( SIZE_NOT_SET
!= nWidth
)
177 rStates
.emplace_back( rMapper
->FindEntryIndex( CTF_FRAME_MARGIN_HORI
), Any(nWidth
) );
178 if( SIZE_NOT_SET
!= nHeight
)
179 rStates
.emplace_back( rMapper
->FindEntryIndex( CTF_FRAME_MARGIN_VERT
), Any(nHeight
) );
182 void SwXMLTextParagraphExport::_collectTextEmbeddedAutoStyles(
183 const Reference
< XPropertySet
> & rPropSet
)
185 SwOLENode
*pOLENd
= GetNoTextNode( rPropSet
)->GetOLENode();
186 svt::EmbeddedObjectRef
& rObjRef
= pOLENd
->GetOLEObj().GetObject();
190 std::vector
<XMLPropertyState
> aStates
;
192 SvGlobalName
aClassId( rObjRef
->getClassID() );
194 if( m_aIFrameClassId
== aClassId
)
196 lcl_addFrameProperties( rObjRef
.GetObject(), aStates
,
197 GetAutoFramePropMapper()->getPropertySetMapper() );
199 else if ( !SotExchange::IsInternal( aClassId
) )
201 lcl_addOutplaceProperties( rObjRef
, aStates
,
202 GetAutoFramePropMapper()->getPropertySetMapper() );
205 lcl_addAspect( rObjRef
, aStates
,
206 GetAutoFramePropMapper()->getPropertySetMapper() );
208 Add( XmlStyleFamily::TEXT_FRAME
, rPropSet
, aStates
);
211 void SwXMLTextParagraphExport::_exportTextEmbedded(
212 const Reference
< XPropertySet
> & rPropSet
,
213 const Reference
< XPropertySetInfo
> & rPropSetInfo
)
215 SwOLENode
*pOLENd
= GetNoTextNode( rPropSet
)->GetOLENode();
216 SwOLEObj
& rOLEObj
= pOLENd
->GetOLEObj();
217 svt::EmbeddedObjectRef
& rObjRef
= rOLEObj
.GetObject();
221 SvGlobalName
aClassId( rObjRef
->getClassID() );
223 SvEmbeddedObjectTypes nType
= SV_EMBEDDED_OWN
;
224 if( m_aPluginClassId
== aClassId
)
226 nType
= SV_EMBEDDED_PLUGIN
;
228 else if( m_aAppletClassId
== aClassId
)
230 nType
= SV_EMBEDDED_APPLET
;
232 else if( m_aIFrameClassId
== aClassId
)
234 nType
= SV_EMBEDDED_FRAME
;
236 else if ( !SotExchange::IsInternal( aClassId
) )
238 nType
= SV_EMBEDDED_OUTPLACE
;
241 enum XMLTokenEnum eElementName
= XML__UNKNOWN_
;
242 SvXMLExport
&rXMLExport
= GetExport();
244 // First the stuff common to each of Applet/Plugin/Floating Frame
247 if( rPropSetInfo
->hasPropertyByName( gsFrameStyleName
) )
249 aAny
= rPropSet
->getPropertyValue( gsFrameStyleName
);
253 std::vector
<XMLPropertyState
> aStates
;
257 case SV_EMBEDDED_FRAME
:
258 lcl_addFrameProperties( rObjRef
.GetObject(), aStates
,
259 GetAutoFramePropMapper()->getPropertySetMapper() );
261 case SV_EMBEDDED_OUTPLACE
:
262 lcl_addOutplaceProperties( rObjRef
, aStates
,
263 GetAutoFramePropMapper()->getPropertySetMapper() );
269 lcl_addAspect( rObjRef
, aStates
,
270 GetAutoFramePropMapper()->getPropertySetMapper() );
272 const OUString sAutoStyle
= Find( XmlStyleFamily::TEXT_FRAME
,
273 rPropSet
, sStyle
, aStates
);
276 if( !sAutoStyle
.isEmpty() )
277 rXMLExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_STYLE_NAME
, sAutoStyle
);
278 addTextFrameAttributes( rPropSet
, false );
280 SvXMLElementExport
aElem( GetExport(), XML_NAMESPACE_DRAW
,
281 XML_FRAME
, false, true );
285 case SV_EMBEDDED_OUTPLACE
:
286 case SV_EMBEDDED_OWN
:
287 if( !(rXMLExport
.getExportFlags() & SvXMLExportFlags::EMBEDDED
) )
291 bool bIsOwnLink
= false;
292 if( SV_EMBEDDED_OWN
== nType
)
296 uno::Reference
< embed::XLinkageSupport
> xLinkage( rObjRef
.GetObject(), uno::UNO_QUERY
);
297 bIsOwnLink
= xLinkage
.is() && xLinkage
->isLink();
299 sURL
= xLinkage
->getLinkURL();
301 catch(const uno::Exception
&)
303 // TODO/LATER: error handling
304 OSL_FAIL( "Link detection or retrieving of the URL of OOo link is failed!" );
310 sURL
= gsEmbeddedObjectProtocol
+ rOLEObj
.GetCurrentPersistName();
313 sURL
= GetExport().AddEmbeddedObject( sURL
);
314 lcl_addURL( rXMLExport
, sURL
, false );
316 if( SV_EMBEDDED_OWN
== nType
&& !pOLENd
->GetChartTableName().isEmpty() )
318 OUString
sRange( pOLENd
->GetChartTableName() );
319 OUStringBuffer
aBuffer( sRange
.getLength() + 2 );
320 for( sal_Int32 i
=0; i
< sRange
.getLength(); i
++ )
322 sal_Unicode c
= sRange
[i
];
329 if( aBuffer
.isEmpty() )
331 aBuffer
.append( OUString::Concat("\'") + sRange
.subView(0, i
) );
333 if( '\'' == c
|| '\\' == c
)
334 aBuffer
.append( '\\' );
337 if( !aBuffer
.isEmpty() )
341 if( !aBuffer
.isEmpty() )
343 aBuffer
.append( '\'' );
344 sRange
= aBuffer
.makeStringAndClear();
347 rXMLExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_NOTIFY_ON_UPDATE_OF_RANGES
,
350 eElementName
= SV_EMBEDDED_OUTPLACE
==nType
? XML_OBJECT_OLE
353 case SV_EMBEDDED_APPLET
:
356 if( svt::EmbeddedObjectRef::TryRunningState( rObjRef
.GetObject() ) )
358 uno::Reference
< beans::XPropertySet
> xSet( rObjRef
->getComponent(), uno::UNO_QUERY
);
360 Any aAny2
= xSet
->getPropertyValue(u
"AppletCodeBase"_ustr
);
362 if (!aStr
.isEmpty() )
363 lcl_addURL(rXMLExport
, aStr
);
365 aAny2
= xSet
->getPropertyValue(u
"AppletName"_ustr
);
368 rXMLExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_APPLET_NAME
, aStr
);
370 aAny2
= xSet
->getPropertyValue(u
"AppletCode"_ustr
);
372 rXMLExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_CODE
, aStr
);
374 bool bScript
= false;
375 aAny2
= xSet
->getPropertyValue(u
"AppletIsScript"_ustr
);
377 rXMLExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_MAY_SCRIPT
, bScript
? XML_TRUE
: XML_FALSE
);
379 uno::Sequence
< beans::PropertyValue
> aProps
;
380 aAny2
= xSet
->getPropertyValue(u
"AppletCommands"_ustr
);
383 sal_Int32 i
= aProps
.getLength();
386 const beans::PropertyValue
& aProp
= aProps
[--i
];
387 const SwHtmlOptType nType2
= SwApplet_Impl::GetOptionType( aProp
.Name
, true );
388 if ( nType2
== SwHtmlOptType::TAG
)
391 aProp
.Value
>>= aStr2
;
392 rXMLExport
.AddAttribute( XML_NAMESPACE_DRAW
, aProp
.Name
, aStr2
);
396 eElementName
= XML_APPLET
;
400 case SV_EMBEDDED_PLUGIN
:
403 if ( svt::EmbeddedObjectRef::TryRunningState( rObjRef
.GetObject() ) )
405 uno::Reference
< beans::XPropertySet
> xSet( rObjRef
->getComponent(), uno::UNO_QUERY
);
407 Any aAny2
= xSet
->getPropertyValue(u
"PluginURL"_ustr
);
409 lcl_addURL( rXMLExport
, aStr
);
411 aAny2
= xSet
->getPropertyValue(u
"PluginMimeType"_ustr
);
414 rXMLExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_MIME_TYPE
, aStr
);
415 eElementName
= XML_PLUGIN
;
419 case SV_EMBEDDED_FRAME
:
421 // It's a floating frame!
422 if ( svt::EmbeddedObjectRef::TryRunningState( rObjRef
.GetObject() ) )
424 uno::Reference
< beans::XPropertySet
> xSet( rObjRef
->getComponent(), uno::UNO_QUERY
);
426 Any aAny2
= xSet
->getPropertyValue(u
"FrameURL"_ustr
);
429 lcl_addURL( rXMLExport
, aStr
);
431 aAny2
= xSet
->getPropertyValue(u
"FrameName"_ustr
);
435 rXMLExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_FRAME_NAME
, aStr
);
436 eElementName
= XML_FLOATING_FRAME
;
441 OSL_ENSURE( false, "unknown object type! Base class should have been called!" );
445 SvXMLElementExport
aElementExport( rXMLExport
, XML_NAMESPACE_DRAW
, eElementName
,
449 case SV_EMBEDDED_OWN
:
450 if( rXMLExport
.getExportFlags() & SvXMLExportFlags::EMBEDDED
)
452 Reference
< XEmbeddedObjectSupplier
> xEOS( rPropSet
, UNO_QUERY
);
453 OSL_ENSURE( xEOS
.is(), "no embedded object supplier for own object" );
454 Reference
< XComponent
> xComp
= xEOS
->getEmbeddedObject();
455 rXMLExport
.ExportEmbeddedOwnObject( xComp
);
458 case SV_EMBEDDED_OUTPLACE
:
459 if( rXMLExport
.getExportFlags() & SvXMLExportFlags::EMBEDDED
)
461 OUString
sURL( gsEmbeddedObjectProtocol
+ rOLEObj
.GetCurrentPersistName() );
463 if ( !( rXMLExport
.getExportFlags() & SvXMLExportFlags::OASIS
) )
464 sURL
+= "?oasis=false";
466 rXMLExport
.AddEmbeddedObjectAsBase64( sURL
);
469 case SV_EMBEDDED_APPLET
:
471 if ( svt::EmbeddedObjectRef::TryRunningState( rObjRef
.GetObject() ) )
473 uno::Reference
< beans::XPropertySet
> xSet( rObjRef
->getComponent(), uno::UNO_QUERY
);
474 uno::Sequence
< beans::PropertyValue
> aProps
;
475 aAny
= xSet
->getPropertyValue(u
"AppletCommands"_ustr
);
478 sal_Int32 i
= aProps
.getLength();
481 const beans::PropertyValue
& aProp
= aProps
[--i
];
482 const SwHtmlOptType nType2
= SwApplet_Impl::GetOptionType( aProp
.Name
, true );
483 if (SwHtmlOptType::PARAM
== nType2
|| SwHtmlOptType::SIZE
== nType2
)
486 aProp
.Value
>>= aStr
;
487 rXMLExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_NAME
, aProp
.Name
);
488 rXMLExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_VALUE
, aStr
);
489 SvXMLElementExport
aElementExport2( rXMLExport
, XML_NAMESPACE_DRAW
, XML_PARAM
, false, true );
495 case SV_EMBEDDED_PLUGIN
:
497 if ( svt::EmbeddedObjectRef::TryRunningState( rObjRef
.GetObject() ) )
499 uno::Reference
< beans::XPropertySet
> xSet( rObjRef
->getComponent(), uno::UNO_QUERY
);
500 uno::Sequence
< beans::PropertyValue
> aProps
;
501 aAny
= xSet
->getPropertyValue(u
"PluginCommands"_ustr
);
504 sal_Int32 i
= aProps
.getLength();
507 const beans::PropertyValue
& aProp
= aProps
[--i
];
508 const SwHtmlOptType nType2
= SwApplet_Impl::GetOptionType( aProp
.Name
, false );
509 if ( nType2
== SwHtmlOptType::TAG
)
512 aProp
.Value
>>= aStr
;
513 rXMLExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_NAME
, aProp
.Name
);
514 rXMLExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_VALUE
, aStr
);
515 SvXMLElementExport
aElementExport2( rXMLExport
, XML_NAMESPACE_DRAW
, XML_PARAM
, false, true );
525 if( SV_EMBEDDED_OUTPLACE
==nType
|| SV_EMBEDDED_OWN
==nType
)
527 OUString sURL
= XML_EMBEDDEDOBJECTGRAPHIC_URL_BASE
+ rOLEObj
.GetCurrentPersistName();
528 if( !(rXMLExport
.getExportFlags() & SvXMLExportFlags::EMBEDDED
) )
530 sURL
= GetExport().AddEmbeddedObject( sURL
);
531 lcl_addURL( rXMLExport
, sURL
, false );
534 SvXMLElementExport
aElementExport( GetExport(), XML_NAMESPACE_DRAW
,
535 XML_IMAGE
, false, true );
537 if( rXMLExport
.getExportFlags() & SvXMLExportFlags::EMBEDDED
)
538 GetExport().AddEmbeddedObjectAsBase64( sURL
);
541 // Lastly the stuff common to each of Applet/Plugin/Floating Frame
542 exportEvents( rPropSet
);
543 exportTitleAndDescription( rPropSet
, rPropSetInfo
); // #i73249#
544 exportContour( rPropSet
, rPropSetInfo
);
547 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */