android: Update app-specific/MIME type icons
[LibreOffice.git] / sw / source / filter / xml / xmltexte.cxx
blob5565de4dfcd6ca0864ce7dfb40761bc5b7395cca
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
33 #include <ndole.hxx>
34 #include <fmtcntnt.hxx>
35 #include <unoframe.hxx>
36 #include "xmlexp.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;
55 namespace {
57 enum SvEmbeddedObjectTypes
59 SV_EMBEDDED_OWN,
60 SV_EMBEDDED_OUTPLACE,
61 SV_EMBEDDED_APPLET,
62 SV_EMBEDDED_PLUGIN,
63 SV_EMBEDDED_FRAME
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(
82 SwXMLExport& rExp,
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,
96 bool bToRel = true )
98 const OUString sRelURL = ( bToRel && !rURL.isEmpty() )
99 ? URIHelper::simpleNormalizedMakeRelative(rExport.GetOrigFileName(), rURL)
100 : 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();
117 if ( nAspect )
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()) )
130 return;
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 ) )
144 return;
146 uno::Reference < beans::XPropertySet > xSet( xObj->getComponent(), uno::UNO_QUERY );
147 if ( !xSet.is() )
148 return;
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");
170 aAny >>= nWidth;
171 aAny = xSet->getPropertyValue("FrameMarginHeight");
172 aAny >>= nHeight;
174 if( !bIsAutoScroll )
175 rStates.emplace_back( rMapper->FindEntryIndex( CTF_FRAME_DISPLAY_SCROLLBAR ), Any(bIsScrollingMode) );
176 if( !bIsAutoBorder )
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();
189 if( !rObjRef.is() )
190 return;
192 std::vector<XMLPropertyState> aStates;
193 aStates.reserve(8);
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();
220 if( !rObjRef.is() )
221 return;
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
247 OUString sStyle;
248 Any aAny;
249 if( rPropSetInfo->hasPropertyByName( gsFrameStyleName ) )
251 aAny = rPropSet->getPropertyValue( gsFrameStyleName );
252 aAny >>= sStyle;
255 std::vector<XMLPropertyState> aStates;
256 aStates.reserve(8);
257 switch( nType )
259 case SV_EMBEDDED_FRAME:
260 lcl_addFrameProperties( rObjRef.GetObject(), aStates,
261 GetAutoFramePropMapper()->getPropertySetMapper() );
262 break;
263 case SV_EMBEDDED_OUTPLACE:
264 lcl_addOutplaceProperties( rObjRef, aStates,
265 GetAutoFramePropMapper()->getPropertySetMapper() );
266 break;
267 default:
271 lcl_addAspect( rObjRef, aStates,
272 GetAutoFramePropMapper()->getPropertySetMapper() );
274 const OUString sAutoStyle = Find( XmlStyleFamily::TEXT_FRAME,
275 rPropSet, sStyle, aStates );
276 aStates.clear();
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 );
285 switch (nType)
287 case SV_EMBEDDED_OUTPLACE:
288 case SV_EMBEDDED_OWN:
289 if( !(rXMLExport.getExportFlags() & SvXMLExportFlags::EMBEDDED) )
291 OUString sURL;
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();
300 if ( bIsOwnLink )
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!" );
310 if ( !bIsOwnLink )
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];
325 switch( c )
327 case ' ':
328 case '.':
329 case '\'':
330 case '\\':
331 if( aBuffer.isEmpty() )
333 aBuffer.append( OUString::Concat("\'") + sRange.subView(0, i) );
335 if( '\'' == c || '\\' == c )
336 aBuffer.append( '\\' );
337 [[fallthrough]];
338 default:
339 if( !aBuffer.isEmpty() )
340 aBuffer.append( c );
343 if( !aBuffer.isEmpty() )
345 aBuffer.append( '\'' );
346 sRange = aBuffer.makeStringAndClear();
349 rXMLExport.AddAttribute( XML_NAMESPACE_DRAW, XML_NOTIFY_ON_UPDATE_OF_RANGES,
350 sRange );
352 eElementName = SV_EMBEDDED_OUTPLACE==nType ? XML_OBJECT_OLE
353 : XML_OBJECT;
354 break;
355 case SV_EMBEDDED_APPLET:
357 // It's an applet!
358 if( svt::EmbeddedObjectRef::TryRunningState( rObjRef.GetObject() ) )
360 uno::Reference < beans::XPropertySet > xSet( rObjRef->getComponent(), uno::UNO_QUERY );
361 OUString aStr;
362 Any aAny2 = xSet->getPropertyValue("AppletCodeBase");
363 aAny2 >>= aStr;
364 if (!aStr.isEmpty() )
365 lcl_addURL(rXMLExport, aStr);
367 aAny2 = xSet->getPropertyValue("AppletName");
368 aAny2 >>= aStr;
369 if (!aStr.isEmpty())
370 rXMLExport.AddAttribute( XML_NAMESPACE_DRAW, XML_APPLET_NAME, aStr );
372 aAny2 = xSet->getPropertyValue("AppletCode");
373 aAny2 >>= aStr;
374 rXMLExport.AddAttribute( XML_NAMESPACE_DRAW, XML_CODE, aStr );
376 bool bScript = false;
377 aAny2 = xSet->getPropertyValue("AppletIsScript");
378 aAny2 >>= bScript;
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");
383 aAny2 >>= aProps;
385 sal_Int32 i = aProps.getLength();
386 while ( i > 0 )
388 const beans::PropertyValue& aProp = aProps[--i];
389 const SwHtmlOptType nType2 = SwApplet_Impl::GetOptionType( aProp.Name, true );
390 if ( nType2 == SwHtmlOptType::TAG)
392 OUString aStr2;
393 aProp.Value >>= aStr2;
394 rXMLExport.AddAttribute( XML_NAMESPACE_DRAW, aProp.Name, aStr2);
398 eElementName = XML_APPLET;
401 break;
402 case SV_EMBEDDED_PLUGIN:
404 // It's a plugin!
405 if ( svt::EmbeddedObjectRef::TryRunningState( rObjRef.GetObject() ) )
407 uno::Reference < beans::XPropertySet > xSet( rObjRef->getComponent(), uno::UNO_QUERY );
408 OUString aStr;
409 Any aAny2 = xSet->getPropertyValue("PluginURL");
410 aAny2 >>= aStr;
411 lcl_addURL( rXMLExport, aStr );
413 aAny2 = xSet->getPropertyValue("PluginMimeType");
414 aAny2 >>= aStr;
415 if (!aStr.isEmpty())
416 rXMLExport.AddAttribute( XML_NAMESPACE_DRAW, XML_MIME_TYPE, aStr );
417 eElementName = XML_PLUGIN;
420 break;
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 );
427 OUString aStr;
428 Any aAny2 = xSet->getPropertyValue("FrameURL");
429 aAny2 >>= aStr;
431 lcl_addURL( rXMLExport, aStr );
433 aAny2 = xSet->getPropertyValue("FrameName");
434 aAny2 >>= aStr;
436 if (!aStr.isEmpty())
437 rXMLExport.AddAttribute( XML_NAMESPACE_DRAW, XML_FRAME_NAME, aStr );
438 eElementName = XML_FLOATING_FRAME;
441 break;
442 default:
443 OSL_ENSURE( false, "unknown object type! Base class should have been called!" );
447 SvXMLElementExport aElementExport( rXMLExport, XML_NAMESPACE_DRAW, eElementName,
448 false, true );
449 switch( nType )
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 );
459 break;
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 );
470 break;
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");
478 aAny >>= aProps;
480 sal_Int32 i = aProps.getLength();
481 while ( i > 0 )
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 )
487 OUString aStr;
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 );
496 break;
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");
504 aAny >>= aProps;
506 sal_Int32 i = aProps.getLength();
507 while ( i > 0 )
509 const beans::PropertyValue& aProp = aProps[--i];
510 const SwHtmlOptType nType2 = SwApplet_Impl::GetOptionType( aProp.Name, false );
511 if ( nType2 == SwHtmlOptType::TAG)
513 OUString aStr;
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 );
522 break;
523 default:
524 break;
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: */