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 <config_java.h>
22 #include <hintids.hxx>
23 #include <rtl/strbuf.hxx>
24 #include <sal/log.hxx>
25 #include <svl/urihelper.hxx>
26 #include <vcl/svapp.hxx>
27 #include <sfx2/frmhtml.hxx>
28 #include <sfx2/frmhtmlw.hxx>
29 #include <sfx2/frmdescr.hxx>
30 #include <sot/storage.hxx>
31 #include <svx/xoutbmp.hxx>
32 #include <editeng/ulspitem.hxx>
33 #include <editeng/lrspitem.hxx>
34 #include <svtools/htmlout.hxx>
35 #include <svtools/htmlkywd.hxx>
36 #include <svtools/htmltokn.h>
37 #include <comphelper/diagnose_ex.hxx>
38 #include <IDocumentContentOperations.hxx>
39 #include <SwAppletImpl.hxx>
40 #include <fmtornt.hxx>
41 #include <fmtfsize.hxx>
42 #include <fmtsrnd.hxx>
43 #include <fmtanchr.hxx>
44 #include <fmtcntnt.hxx>
47 #include <svl/ownlist.hxx>
48 #include <unotools/mediadescriptor.hxx>
49 #include <unotools/streamwrap.hxx>
56 #include "wrthtml.hxx"
57 #include "htmlfly.hxx"
59 #include "htmlreqifreader.hxx"
60 #include <unoframe.hxx>
61 #include <com/sun/star/embed/XClassifiedObject.hpp>
62 #include <com/sun/star/embed/Aspects.hpp>
63 #include <com/sun/star/beans/XPropertySet.hpp>
64 #include <com/sun/star/frame/XStorable.hpp>
65 #include <com/sun/star/embed/ElementModes.hpp>
66 #include <com/sun/star/io/XActiveDataStreamer.hpp>
67 #include <com/sun/star/embed/XEmbedPersist2.hpp>
68 #include <com/sun/star/lang/XInitialization.hpp>
70 #include <comphelper/embeddedobjectcontainer.hxx>
71 #include <comphelper/classids.hxx>
72 #include <rtl/uri.hxx>
73 #include <comphelper/storagehelper.hxx>
74 #include <vcl/graphicfilter.hxx>
75 #include <unotools/ucbstreamhelper.hxx>
76 #include <comphelper/propertysequence.hxx>
77 #include <filter/msfilter/msoleexp.hxx>
78 #include <comphelper/fileurl.hxx>
79 #include <o3tl/safeint.hxx>
80 #include <osl/file.hxx>
81 #include <comphelper/propertyvalue.hxx>
82 #include <svtools/HtmlWriter.hxx>
84 using namespace com::sun::star
;
87 #define HTML_DFLT_EMBED_WIDTH (o3tl::toTwips(125, o3tl::Length::mm10))
88 #define HTML_DFLT_EMBED_HEIGHT (o3tl::toTwips(125, o3tl::Length::mm10))
90 #define HTML_DFLT_APPLET_WIDTH (o3tl::toTwips(125, o3tl::Length::mm10))
91 #define HTML_DFLT_APPLET_HEIGHT (o3tl::toTwips(125, o3tl::Length::mm10))
94 const HtmlFrmOpts HTML_FRMOPTS_EMBED_ALL
=
98 const HtmlFrmOpts HTML_FRMOPTS_EMBED_CNTNR
=
99 HTML_FRMOPTS_EMBED_ALL
|
100 HtmlFrmOpts::AbsSize
;
101 const HtmlFrmOpts HTML_FRMOPTS_EMBED
=
102 HTML_FRMOPTS_EMBED_ALL
|
105 HtmlFrmOpts::BrClear
|
107 const HtmlFrmOpts HTML_FRMOPTS_HIDDEN_EMBED
=
111 const HtmlFrmOpts HTML_FRMOPTS_APPLET_ALL
=
114 const HtmlFrmOpts HTML_FRMOPTS_APPLET_CNTNR
=
115 HTML_FRMOPTS_APPLET_ALL
|
116 HtmlFrmOpts::AbsSize
;
117 const HtmlFrmOpts HTML_FRMOPTS_APPLET
=
118 HTML_FRMOPTS_APPLET_ALL
|
121 HtmlFrmOpts::BrClear
;
123 const HtmlFrmOpts HTML_FRMOPTS_IFRAME_ALL
=
126 const HtmlFrmOpts HTML_FRMOPTS_IFRAME_CNTNR
=
127 HTML_FRMOPTS_IFRAME_ALL
|
128 HtmlFrmOpts::AbsSize
;
129 const HtmlFrmOpts HTML_FRMOPTS_IFRAME
=
130 HTML_FRMOPTS_IFRAME_ALL
|
133 HtmlFrmOpts::Border
|
134 HtmlFrmOpts::BrClear
;
136 const HtmlFrmOpts HTML_FRMOPTS_OLE_CSS1
=
137 HtmlFrmOpts::SAlign
|
143 * Calculates a filename for an image, provided the HTML file name, the image
144 * itself and a wanted extension.
146 OUString
lcl_CalculateFileName(const OUString
* pOrigFileName
, const Graphic
& rGraphic
,
147 std::u16string_view rExtension
)
152 aFileName
= *pOrigFileName
;
153 INetURLObject
aURL(aFileName
);
154 OUString aName
= aURL
.getBase() + "_" +
155 aURL
.getExtension() + "_" +
156 OUString::number(rGraphic
.GetChecksum(), 16);
158 aURL
.setExtension(rExtension
);
159 aFileName
= aURL
.GetMainURL(INetURLObject::DecodeMechanism::NONE
);
165 void SwHTMLParser::SetFixSize( const Size
& rPixSize
,
166 const Size
& rTwipDfltSize
,
167 bool bPercentWidth
, bool bPercentHeight
,
168 SvxCSS1PropertyInfo
const & rCSS1PropInfo
,
169 SfxItemSet
& rFlyItemSet
)
171 // convert absolute size values into Twip
172 sal_uInt8 nPercentWidth
= 0, nPercentHeight
= 0;
173 Size
aTwipSz( bPercentWidth
|| USHRT_MAX
==rPixSize
.Width() ? 0 : rPixSize
.Width(),
174 bPercentHeight
|| USHRT_MAX
==rPixSize
.Height() ? 0 : rPixSize
.Height() );
175 if( aTwipSz
.Width() || aTwipSz
.Height() )
177 aTwipSz
= o3tl::convert(aTwipSz
, o3tl::Length::px
, o3tl::Length::twip
);
181 if( SVX_CSS1_LTYPE_PERCENTAGE
== rCSS1PropInfo
.m_eWidthType
)
183 nPercentWidth
= static_cast<sal_uInt8
>(rCSS1PropInfo
.m_nWidth
);
184 aTwipSz
.setWidth( rTwipDfltSize
.Width() );
186 else if( SVX_CSS1_LTYPE_TWIP
== rCSS1PropInfo
.m_eWidthType
)
188 aTwipSz
.setWidth( rCSS1PropInfo
.m_nWidth
);
190 else if( bPercentWidth
&& rPixSize
.Width() )
192 nPercentWidth
= static_cast<sal_uInt8
>(rPixSize
.Width());
193 if (nPercentWidth
> 100 && nPercentWidth
!= SwFormatFrameSize::SYNCED
)
196 aTwipSz
.setWidth( rTwipDfltSize
.Width() );
198 else if( USHRT_MAX
==rPixSize
.Width() )
200 aTwipSz
.setWidth( rTwipDfltSize
.Width() );
202 if( aTwipSz
.Width() < MINFLY
)
204 aTwipSz
.setWidth( MINFLY
);
208 if( SVX_CSS1_LTYPE_PERCENTAGE
== rCSS1PropInfo
.m_eHeightType
)
210 nPercentHeight
= static_cast<sal_uInt8
>(rCSS1PropInfo
.m_nHeight
);
211 aTwipSz
.setHeight( rTwipDfltSize
.Height() );
213 else if( SVX_CSS1_LTYPE_TWIP
== rCSS1PropInfo
.m_eHeightType
)
215 aTwipSz
.setHeight( rCSS1PropInfo
.m_nHeight
);
217 else if( bPercentHeight
&& rPixSize
.Height() )
219 nPercentHeight
= static_cast<sal_uInt8
>(rPixSize
.Height());
220 if (nPercentHeight
> 100 && nPercentHeight
!= SwFormatFrameSize::SYNCED
)
221 nPercentHeight
= 100;
223 aTwipSz
.setHeight( rTwipDfltSize
.Height() );
225 else if( USHRT_MAX
==rPixSize
.Height() )
227 aTwipSz
.setHeight( rTwipDfltSize
.Height() );
229 if( aTwipSz
.Height() < MINFLY
)
231 aTwipSz
.setHeight( MINFLY
);
235 SwFormatFrameSize
aFrameSize( SwFrameSize::Fixed
, aTwipSz
.Width(), aTwipSz
.Height() );
236 aFrameSize
.SetWidthPercent( nPercentWidth
);
237 aFrameSize
.SetHeightPercent( nPercentHeight
);
238 rFlyItemSet
.Put( aFrameSize
);
241 void SwHTMLParser::SetSpace( const Size
& rPixSpace
,
242 SfxItemSet
& rCSS1ItemSet
,
243 SvxCSS1PropertyInfo
& rCSS1PropInfo
,
244 SfxItemSet
& rFlyItemSet
)
246 sal_Int32 nLeftSpace
= 0, nRightSpace
= 0;
247 sal_uInt16 nUpperSpace
= 0, nLowerSpace
= 0;
248 if( rPixSpace
.Width() || rPixSpace
.Height() )
250 nLeftSpace
= nRightSpace
= o3tl::convert(rPixSpace
.Width(), o3tl::Length::px
, o3tl::Length::twip
);
251 nUpperSpace
= nLowerSpace
= o3tl::convert(rPixSpace
.Height(), o3tl::Length::px
, o3tl::Length::twip
);
254 // set left/right margin
255 // note: parser never creates SvxLeftMarginItem! must be converted
256 if (const SvxTextLeftMarginItem
*const pLeft
= rCSS1ItemSet
.GetItemIfSet(RES_MARGIN_TEXTLEFT
))
258 if( rCSS1PropInfo
.m_bLeftMargin
)
260 // should be SvxLeftMarginItem... "cast" it
261 nLeftSpace
= pLeft
->GetTextLeft();
262 rCSS1PropInfo
.m_bLeftMargin
= false;
264 rCSS1ItemSet
.ClearItem(RES_MARGIN_TEXTLEFT
);
266 if (const SvxRightMarginItem
*const pRight
= rCSS1ItemSet
.GetItemIfSet(RES_MARGIN_RIGHT
))
268 if( rCSS1PropInfo
.m_bRightMargin
)
270 nRightSpace
= pRight
->GetRight();
271 rCSS1PropInfo
.m_bRightMargin
= false;
273 rCSS1ItemSet
.ClearItem(RES_MARGIN_RIGHT
);
275 if( nLeftSpace
> 0 || nRightSpace
> 0 )
277 SvxLRSpaceItem
aLRItem( RES_LR_SPACE
);
278 aLRItem
.SetLeft( std::max
<sal_Int32
>(nLeftSpace
, 0) );
279 aLRItem
.SetRight( std::max
<sal_Int32
>(nRightSpace
, 0) );
280 rFlyItemSet
.Put( aLRItem
);
283 const SwFormatHoriOrient
& rHoriOri
=
284 rFlyItemSet
.Get( RES_HORI_ORIENT
);
285 if( text::HoriOrientation::NONE
== rHoriOri
.GetHoriOrient() )
287 SwFormatHoriOrient
aHoriOri( rHoriOri
);
288 aHoriOri
.SetPos( aHoriOri
.GetPos() + nLeftSpace
);
289 rFlyItemSet
.Put( aHoriOri
);
294 // set top/bottom margin
295 if( const SvxULSpaceItem
*pULItem
= rCSS1ItemSet
.GetItemIfSet( RES_UL_SPACE
) )
297 // if applicable remove the first line indent
298 if( rCSS1PropInfo
.m_bTopMargin
)
300 nUpperSpace
= pULItem
->GetUpper();
301 rCSS1PropInfo
.m_bTopMargin
= false;
303 if( rCSS1PropInfo
.m_bBottomMargin
)
305 nLowerSpace
= pULItem
->GetLower();
306 rCSS1PropInfo
.m_bBottomMargin
= false;
308 rCSS1ItemSet
.ClearItem( RES_UL_SPACE
);
310 if( !(nUpperSpace
|| nLowerSpace
) )
313 SvxULSpaceItem
aULItem( RES_UL_SPACE
);
314 aULItem
.SetUpper( nUpperSpace
);
315 aULItem
.SetLower( nLowerSpace
);
316 rFlyItemSet
.Put( aULItem
);
319 const SwFormatVertOrient
& rVertOri
=
320 rFlyItemSet
.Get( RES_VERT_ORIENT
);
321 if( text::VertOrientation::NONE
== rVertOri
.GetVertOrient() )
323 SwFormatVertOrient
aVertOri( rVertOri
);
324 aVertOri
.SetPos( aVertOri
.GetPos() + nUpperSpace
);
325 rFlyItemSet
.Put( aVertOri
);
330 OUString
SwHTMLParser::StripQueryFromPath(std::u16string_view rBase
, const OUString
& rPath
)
332 if (!comphelper::isFileUrl(rBase
))
335 sal_Int32 nIndex
= rPath
.indexOf('?');
338 return rPath
.copy(0, nIndex
);
343 bool SwHTMLParser::InsertEmbed()
345 OUString aURL
, aType
, aName
, aAlt
, aId
, aStyle
, aClass
;
347 Size
aSize( USHRT_MAX
, USHRT_MAX
);
348 Size
aSpace( USHRT_MAX
, USHRT_MAX
);
349 bool bPercentWidth
= false, bPercentHeight
= false, bHidden
= false;
350 sal_Int16 eVertOri
= text::VertOrientation::NONE
;
351 sal_Int16 eHoriOri
= text::HoriOrientation::NONE
;
352 SvCommandList aCmdLst
;
353 const HTMLOptions
& rHTMLOptions
= GetOptions();
355 // The options are read forwards, because the plug-ins expect them in this
356 // order. Still only the first value of an option may be regarded.
357 for (const auto & rOption
: rHTMLOptions
)
359 switch( rOption
.GetToken() )
361 case HtmlOptionId::ID
:
362 aId
= rOption
.GetString();
364 case HtmlOptionId::STYLE
:
365 aStyle
= rOption
.GetString();
367 case HtmlOptionId::CLASS
:
368 aClass
= rOption
.GetString();
370 case HtmlOptionId::NAME
:
371 aName
= rOption
.GetString();
373 case HtmlOptionId::SRC
:
375 aURL
= rOption
.GetString();
377 case HtmlOptionId::ALT
:
378 aAlt
= rOption
.GetString();
380 case HtmlOptionId::TYPE
:
381 if( aType
.isEmpty() )
382 aType
= rOption
.GetString();
384 case HtmlOptionId::ALIGN
:
385 if( eVertOri
==text::VertOrientation::NONE
&& eHoriOri
==text::HoriOrientation::NONE
)
387 eVertOri
= rOption
.GetEnum( aHTMLImgVAlignTable
, eVertOri
);
388 eHoriOri
= rOption
.GetEnum( aHTMLImgHAlignTable
, eHoriOri
);
391 case HtmlOptionId::WIDTH
:
392 if( USHRT_MAX
==aSize
.Width() )
394 bPercentWidth
= (rOption
.GetString().indexOf('%') != -1);
395 aSize
.setWidth( static_cast<tools::Long
>(rOption
.GetNumber()) );
398 case HtmlOptionId::HEIGHT
:
399 if( USHRT_MAX
==aSize
.Height() )
401 bPercentHeight
= (rOption
.GetString().indexOf('%') != -1);
402 aSize
.setHeight( static_cast<tools::Long
>(rOption
.GetNumber()) );
405 case HtmlOptionId::HSPACE
:
406 if( USHRT_MAX
==aSpace
.Width() )
407 aSpace
.setWidth( static_cast<tools::Long
>(rOption
.GetNumber()) );
409 case HtmlOptionId::VSPACE
:
410 if( USHRT_MAX
==aSpace
.Height() )
411 aSpace
.setHeight( static_cast<tools::Long
>(rOption
.GetNumber()) );
413 case HtmlOptionId::DATA
:
414 if (m_bXHTML
&& aURL
.isEmpty())
415 aData
= rOption
.GetString();
417 case HtmlOptionId::UNKNOWN
:
418 if (rOption
.GetTokenString().equalsIgnoreAsciiCase(
419 OOO_STRING_SW_HTML_O_Hidden
))
421 bHidden
= !rOption
.GetString().equalsIgnoreAsciiCase(
428 // All parameters are passed to the plug-in.
429 aCmdLst
.Append( rOption
.GetTokenString(), rOption
.GetString() );
432 static const std::set
<std::u16string_view
> vAllowlist
= {
446 if (vAllowlist
.find(aType
) != vAllowlist
.end() && m_aEmbeds
.empty())
448 // Toplevel <object> for an image format -> that's an image, not an OLE object.
449 m_aEmbeds
.push(nullptr);
453 SfxItemSet
aItemSet( m_xDoc
->GetAttrPool(), m_pCSS1Parser
->GetWhichMap() );
454 SvxCSS1PropertyInfo aPropInfo
;
455 if( HasStyleOptions( aStyle
, aId
, aClass
) )
456 ParseStyleOptions( aStyle
, aId
, aClass
, aItemSet
, aPropInfo
);
458 // Convert the default values (except height/width, which is done by SetFrameSize())
459 if( eVertOri
==text::VertOrientation::NONE
&& eHoriOri
==text::HoriOrientation::NONE
)
460 eVertOri
= text::VertOrientation::TOP
;
461 if( USHRT_MAX
==aSpace
.Width() )
462 aSpace
.setWidth( 0 );
463 if( USHRT_MAX
==aSpace
.Height() )
464 aSpace
.setHeight( 0 );
467 // Size (0,0) will be changed to (MINFLY, MINFLY) in SetFrameSize()
468 aSize
.setWidth( 0 ); aSize
.setHeight( 0 );
469 aSpace
.setWidth( 0 ); aSpace
.setHeight( 0 );
470 bPercentWidth
= bPercentHeight
= false;
474 INetURLObject aURLObj
;
475 bool bHasURL
= !aURL
.isEmpty() &&
477 URIHelper::SmartRel2Abs(
478 INetURLObject(m_sBaseURL
), aURL
,
479 URIHelper::GetMaybeFileHdl()) );
480 bool bHasData
= !aData
.isEmpty();
484 // Strip query and everything after that for file:// URLs, browsers do
486 aURLObj
.SetURL(rtl::Uri::convertRelToAbs(
487 m_sBaseURL
, SwHTMLParser::StripQueryFromPath(m_sBaseURL
, aData
)));
489 catch (const rtl::MalformedUriException
& /*rException*/)
494 // do not insert plugin if it has neither URL nor type
495 bool bHasType
= !aType
.isEmpty();
496 if( !bHasURL
&& !bHasType
&& !bHasData
)
499 if (!m_aEmbeds
.empty())
501 // Nested XHTML <object> element: points to replacement graphic.
502 SwOLENode
* pOLENode
= m_aEmbeds
.top();
505 // <object> is mapped to an image -> ignore replacement graphic.
509 svt::EmbeddedObjectRef
& rObj
= pOLENode
->GetOLEObj().GetObject();
511 if (GraphicFilter::GetGraphicFilter().ImportGraphic(aGraphic
, aURLObj
) != ERRCODE_NONE
)
514 rObj
.SetGraphic(aGraphic
, aType
);
516 // Set the size of the OLE frame to the size of the graphic.
517 SwFrameFormat
* pFormat
= pOLENode
->GetFlyFormat();
520 SwAttrSet
aAttrSet(pFormat
->GetAttrSet());
521 aAttrSet
.ClearItem(RES_CNTNT
);
522 Size
aDefaultTwipSize(o3tl::convert(aGraphic
.GetSizePixel(), o3tl::Length::px
, o3tl::Length::twip
));
524 if (aSize
.Width() == USHRT_MAX
&& bPercentHeight
)
526 // Height is relative, width is not set: keep aspect ratio.
527 aSize
.setWidth(SwFormatFrameSize::SYNCED
);
528 bPercentWidth
= true;
530 if (aSize
.Height() == USHRT_MAX
&& bPercentWidth
)
532 // Width is relative, height is not set: keep aspect ratio.
533 aSize
.setHeight(SwFormatFrameSize::SYNCED
);
534 bPercentHeight
= true;
537 SetFixSize(aSize
, aDefaultTwipSize
, bPercentWidth
, bPercentHeight
, aPropInfo
, aAttrSet
);
538 pOLENode
->GetDoc().SetFlyFrameAttr(*pFormat
, aAttrSet
);
542 // create the plug-in
543 comphelper::EmbeddedObjectContainer aCnt
;
545 uno::Reference
< embed::XEmbeddedObject
> xObj
;
548 xObj
= aCnt
.CreateEmbeddedObject( SvGlobalName( SO3_PLUGIN_CLASSID
).GetByteSequence(), aObjName
);
549 if ( svt::EmbeddedObjectRef::TryRunningState( xObj
) )
551 uno::Reference
< beans::XPropertySet
> xSet( xObj
->getComponent(), uno::UNO_QUERY
);
555 xSet
->setPropertyValue("PluginURL", uno::Any( aURL
) );
557 xSet
->setPropertyValue("PluginMimeType", uno::Any( aType
) );
559 uno::Sequence
< beans::PropertyValue
> aProps
;
560 aCmdLst
.FillSequence( aProps
);
561 xSet
->setPropertyValue("PluginCommands", uno::Any( aProps
) );
566 else if (SwDocShell
* pDocSh
= m_xDoc
->GetDocShell())
568 // Has non-empty data attribute in XHTML: map that to an OLE object.
569 uno::Reference
<embed::XStorage
> xStorage
= pDocSh
->GetStorage();
570 aCnt
.SwitchPersistence(xStorage
);
571 aObjName
= aCnt
.CreateUniqueObjectName();
573 OUString aEmbedURL
= aURLObj
.GetMainURL(INetURLObject::DecodeMechanism::NONE
);
574 SvFileStream
aFileStream(aEmbedURL
, StreamMode::READ
);
575 uno::Reference
<io::XInputStream
> xInStream
;
576 SvMemoryStream aMemoryStream
;
578 // Allow any MIME type that starts with magic, unless a set of allowed types are
580 auto it
= m_aAllowedRTFOLEMimeTypes
.find(aType
);
581 if (m_aAllowedRTFOLEMimeTypes
.empty() || it
!= m_aAllowedRTFOLEMimeTypes
.end())
583 OString
aMagic("{\\object");
584 OString
aHeader(read_uInt8s_ToOString(aFileStream
, aMagic
.getLength()));
586 if (aHeader
== aMagic
)
588 // OLE2 wrapped in RTF: either own format or real OLE2 embedding.
589 bool bOwnFormat
= false;
590 if (SwReqIfReader::ExtractOleFromRtf(aFileStream
, aMemoryStream
, bOwnFormat
))
592 xInStream
.set(new utl::OStreamWrapper(aMemoryStream
));
597 uno::Sequence
<beans::PropertyValue
> aMedium
= comphelper::InitPropertySequence(
598 { { "InputStream", uno::Any(xInStream
) },
599 { "URL", uno::Any(OUString("private:stream")) },
600 { "DocumentBaseURL", uno::Any(m_sBaseURL
) } });
601 xObj
= aCnt
.InsertEmbeddedObject(aMedium
, aName
, &m_sBaseURL
);
605 // The type is now an OLE2 container, not the original XHTML type.
606 aType
= "application/vnd.sun.star.oleobject";
613 // Object data is neither OLE2 in RTF, nor an image. Then map this to an URL that
614 // will be set on the inner image.
615 m_aEmbedURL
= aEmbedURL
;
616 // Signal success, so the outer object won't fall back to the image handler.
622 uno::Reference
<io::XStream
> xOutStream
623 = xStorage
->openStreamElement(aObjName
, embed::ElementModes::READWRITE
);
624 if (aFileStream
.IsOpen())
625 comphelper::OStorageHelper::CopyInputToOutput(xInStream
,
626 xOutStream
->getOutputStream());
628 if (!aType
.isEmpty())
630 // Set media type of the native data.
631 uno::Reference
<beans::XPropertySet
> xOutStreamProps(xOutStream
, uno::UNO_QUERY
);
632 if (xOutStreamProps
.is())
633 xOutStreamProps
->setPropertyValue("MediaType", uno::Any(aType
));
636 xObj
= aCnt
.GetEmbeddedObject(aObjName
);
640 SfxItemSetFixed
<RES_FRMATR_BEGIN
, RES_FRMATR_END
-1> aFrameSet( m_xDoc
->GetAttrPool() );
642 Reader::ResetFrameFormatAttrs( aFrameSet
);
647 SetAnchorAndAdjustment( eVertOri
, eHoriOri
, aPropInfo
, aFrameSet
);
651 SwFormatAnchor
aAnchor( RndStdIds::FLY_AT_PARA
);
652 aAnchor
.SetAnchor( m_pPam
->GetPoint() );
653 aFrameSet
.Put( aAnchor
);
654 aFrameSet
.Put( SwFormatHoriOrient( 0, text::HoriOrientation::LEFT
, text::RelOrientation::FRAME
) );
655 aFrameSet
.Put( SwFormatSurround( css::text::WrapTextMode_THROUGH
) );
656 aFrameSet
.Put( SwFormatVertOrient( 0, text::VertOrientation::TOP
, text::RelOrientation::PRINT_AREA
) );
659 // and the size of the frame
660 Size
aDfltSz( HTML_DFLT_EMBED_WIDTH
, HTML_DFLT_EMBED_HEIGHT
);
661 SetFixSize( aSize
, aDfltSz
, bPercentWidth
, bPercentHeight
, aPropInfo
, aFrameSet
);
662 SetSpace( aSpace
, aItemSet
, aPropInfo
, aFrameSet
);
664 // and insert into the document
665 uno::Reference
<lang::XInitialization
> xObjInitialization(xObj
, uno::UNO_QUERY
);
666 if (xObjInitialization
.is())
668 // Request that the native data of the embedded object is not modified
670 uno::Sequence
<beans::PropertyValue
> aValues
{ comphelper::makePropertyValue("StreamReadOnly",
672 uno::Sequence
<uno::Any
> aArguments
{ uno::Any(aValues
) };
673 xObjInitialization
->initialize(aArguments
);
675 SwFrameFormat
* pFlyFormat
=
676 m_xDoc
->getIDocumentContentOperations().InsertEmbObject(*m_pPam
,
677 ::svt::EmbeddedObjectRef(xObj
, embed::Aspects::MSOLE_CONTENT
),
679 if (xObjInitialization
.is())
681 uno::Sequence
<beans::PropertyValue
> aValues
{ comphelper::makePropertyValue("StreamReadOnly",
683 uno::Sequence
<uno::Any
> aArguments
{ uno::Any(aValues
) };
684 xObjInitialization
->initialize(aArguments
);
687 // set name at FrameFormat
688 if( !aName
.isEmpty() )
689 pFlyFormat
->SetFormatName( aName
);
691 // set the alternative text
692 SwNoTextNode
*pNoTextNd
=
693 m_xDoc
->GetNodes()[ pFlyFormat
->GetContent().GetContentIdx()
694 ->GetIndex()+1 ]->GetNoTextNode();
695 pNoTextNd
->SetTitle( aAlt
);
697 // if applicable create frames and register auto-bound frames
700 // HIDDEN plug-ins should stay paragraph-bound. Since RegisterFlyFrame()
701 // will change paragraph-bound frames with wrap-through into a
702 // character-bound frame, here we must create the frames by hand.
703 RegisterFlyFrame( pFlyFormat
);
709 SwOLENode
* pOLENode
= pNoTextNd
->GetOLENode();
713 m_aEmbeds
.push(pOLENode
);
718 #if HAVE_FEATURE_JAVA
719 void SwHTMLParser::NewObject()
722 OUString aStandBy
, aId
, aStyle
, aClass
;
723 Size
aSize( USHRT_MAX
, USHRT_MAX
);
725 sal_Int16 eVertOri
= text::VertOrientation::TOP
;
726 sal_Int16 eHoriOri
= text::HoriOrientation::NONE
;
728 bool bPercentWidth
= false, bPercentHeight
= false,
730 // create a new Command list
731 m_pAppletImpl
.reset(new SwApplet_Impl( m_xDoc
->GetAttrPool() ));
733 const HTMLOptions
& rHTMLOptions
= GetOptions();
734 for (size_t i
= rHTMLOptions
.size(); i
; )
736 const HTMLOption
& rOption
= rHTMLOptions
[--i
];
737 switch( rOption
.GetToken() )
739 case HtmlOptionId::ID
:
740 aId
= rOption
.GetString();
742 case HtmlOptionId::STYLE
:
743 aStyle
= rOption
.GetString();
745 case HtmlOptionId::CLASS
:
746 aClass
= rOption
.GetString();
748 case HtmlOptionId::DECLARE
:
751 case HtmlOptionId::CLASSID
:
752 aClassID
= rOption
.GetString();
754 case HtmlOptionId::CODEBASE
:
756 case HtmlOptionId::DATA
:
758 case HtmlOptionId::TYPE
:
760 case HtmlOptionId::CODETYPE
:
762 case HtmlOptionId::ARCHIVE
:
763 case HtmlOptionId::UNKNOWN
:
765 case HtmlOptionId::STANDBY
:
766 aStandBy
= rOption
.GetString();
768 case HtmlOptionId::WIDTH
:
769 bPercentWidth
= (rOption
.GetString().indexOf('%') != -1);
770 aSize
.setWidth( static_cast<tools::Long
>(rOption
.GetNumber()) );
772 case HtmlOptionId::HEIGHT
:
773 bPercentHeight
= (rOption
.GetString().indexOf('%') != -1);
774 aSize
.setHeight( static_cast<tools::Long
>(rOption
.GetNumber()) );
776 case HtmlOptionId::ALIGN
:
777 eVertOri
= rOption
.GetEnum( aHTMLImgVAlignTable
, eVertOri
);
778 eHoriOri
= rOption
.GetEnum( aHTMLImgHAlignTable
, eHoriOri
);
780 case HtmlOptionId::USEMAP
:
782 case HtmlOptionId::NAME
:
784 case HtmlOptionId::HSPACE
:
785 aSpace
.setWidth( static_cast<tools::Long
>(rOption
.GetNumber()) );
787 case HtmlOptionId::VSPACE
:
788 aSpace
.setHeight( static_cast<tools::Long
>(rOption
.GetNumber()) );
790 case HtmlOptionId::BORDER
:
793 case HtmlOptionId::SDONCLICK
:
794 case HtmlOptionId::ONCLICK
:
795 case HtmlOptionId::SDONMOUSEOVER
:
796 case HtmlOptionId::ONMOUSEOVER
:
797 case HtmlOptionId::SDONMOUSEOUT
:
798 case HtmlOptionId::ONMOUSEOUT
:
802 // All parameters are passed to the applet.
803 m_pAppletImpl
->AppendParam( rOption
.GetTokenString(),
804 rOption
.GetString() );
808 // Objects that are declared only are not evaluated. Moreover, only
809 // Java applets are supported.
810 bool bIsApplet
= false;
812 if( !bDeclare
&& aClassID
.getLength() == 42 &&
813 aClassID
.startsWith("clsid:") )
815 aClassID
= aClassID
.copy(6);
817 if( aCID
.MakeId( aClassID
) )
819 SvGlobalName
aJavaCID( 0x8AD9C840UL
, 0x044EU
, 0x11D1U
, 0xB3U
, 0xE9U
,
820 0x00U
, 0x80U
, 0x5FU
, 0x49U
, 0x9DU
, 0x93U
);
822 bIsApplet
= aJavaCID
== aCID
;
828 m_pAppletImpl
.reset();
832 m_pAppletImpl
->SetAltText( aStandBy
);
834 SfxItemSet
aItemSet( m_xDoc
->GetAttrPool(), m_pCSS1Parser
->GetWhichMap() );
835 SvxCSS1PropertyInfo aPropInfo
;
836 if( HasStyleOptions( aStyle
, aId
, aClass
) )
837 ParseStyleOptions( aStyle
, aId
, aClass
, aItemSet
, aPropInfo
);
839 SfxItemSet
& rFrameSet
= m_pAppletImpl
->GetItemSet();
841 Reader::ResetFrameFormatAttrs( rFrameSet
);
843 // set the anchor and the adjustment
844 SetAnchorAndAdjustment( eVertOri
, eHoriOri
, aPropInfo
, rFrameSet
);
846 // and still the size of the frame
847 Size
aDfltSz( HTML_DFLT_APPLET_WIDTH
, HTML_DFLT_APPLET_HEIGHT
);
848 SetFixSize( aSize
, aDfltSz
, bPercentWidth
, bPercentHeight
, aPropInfo
, rFrameSet
);
849 SetSpace( aSpace
, aItemSet
, aPropInfo
, rFrameSet
);
853 void SwHTMLParser::EndObject()
855 #if HAVE_FEATURE_JAVA
858 if( !m_pAppletImpl
->CreateApplet( m_sBaseURL
) )
861 m_pAppletImpl
->FinishApplet();
863 // and insert into the document
864 SwFrameFormat
* pFlyFormat
=
865 m_xDoc
->getIDocumentContentOperations().InsertEmbObject(*m_pPam
,
866 ::svt::EmbeddedObjectRef( m_pAppletImpl
->GetApplet(), embed::Aspects::MSOLE_CONTENT
),
867 &m_pAppletImpl
->GetItemSet() );
869 // set the alternative name
870 SwNoTextNode
*pNoTextNd
=
871 m_xDoc
->GetNodes()[ pFlyFormat
->GetContent().GetContentIdx()
872 ->GetIndex()+1 ]->GetNoTextNode();
873 pNoTextNd
->SetTitle( m_pAppletImpl
->GetAltText() );
875 // if applicable create frames and register auto-bound frames
876 RegisterFlyFrame( pFlyFormat
);
878 m_pAppletImpl
.reset();
880 (void) this; // Silence loplugin:staticmethods
884 #if HAVE_FEATURE_JAVA
885 void SwHTMLParser::InsertApplet()
887 OUString aCodeBase
, aCode
, aName
, aAlt
, aId
, aStyle
, aClass
;
888 Size
aSize( USHRT_MAX
, USHRT_MAX
);
890 bool bPercentWidth
= false, bPercentHeight
= false, bMayScript
= false;
891 sal_Int16 eVertOri
= text::VertOrientation::TOP
;
892 sal_Int16 eHoriOri
= text::HoriOrientation::NONE
;
894 // create a new Command list
895 m_pAppletImpl
.reset(new SwApplet_Impl( m_xDoc
->GetAttrPool() ));
897 const HTMLOptions
& rHTMLOptions
= GetOptions();
898 for (size_t i
= rHTMLOptions
.size(); i
; )
900 const HTMLOption
& rOption
= rHTMLOptions
[--i
];
901 switch( rOption
.GetToken() )
903 case HtmlOptionId::ID
:
904 aId
= rOption
.GetString();
906 case HtmlOptionId::STYLE
:
907 aStyle
= rOption
.GetString();
909 case HtmlOptionId::CLASS
:
910 aClass
= rOption
.GetString();
912 case HtmlOptionId::CODEBASE
:
913 aCodeBase
= rOption
.GetString();
915 case HtmlOptionId::CODE
:
916 aCode
= rOption
.GetString();
918 case HtmlOptionId::NAME
:
919 aName
= rOption
.GetString();
921 case HtmlOptionId::ALT
:
922 aAlt
= rOption
.GetString();
924 case HtmlOptionId::ALIGN
:
925 eVertOri
= rOption
.GetEnum( aHTMLImgVAlignTable
, eVertOri
);
926 eHoriOri
= rOption
.GetEnum( aHTMLImgHAlignTable
, eHoriOri
);
928 case HtmlOptionId::WIDTH
:
929 bPercentWidth
= (rOption
.GetString().indexOf('%') != -1);
930 aSize
.setWidth( static_cast<tools::Long
>(rOption
.GetNumber()) );
932 case HtmlOptionId::HEIGHT
:
933 bPercentHeight
= (rOption
.GetString().indexOf('%') != -1);
934 aSize
.setHeight( static_cast<tools::Long
>(rOption
.GetNumber()) );
936 case HtmlOptionId::HSPACE
:
937 aSpace
.setWidth( static_cast<tools::Long
>(rOption
.GetNumber()) );
939 case HtmlOptionId::VSPACE
:
940 aSpace
.setHeight( static_cast<tools::Long
>(rOption
.GetNumber()) );
942 case HtmlOptionId::MAYSCRIPT
:
948 // All parameters are passed to the applet.
949 m_pAppletImpl
->AppendParam( rOption
.GetTokenString(),
950 rOption
.GetString() );
953 if( aCode
.isEmpty() )
955 m_pAppletImpl
.reset();
959 if ( !aCodeBase
.isEmpty() )
960 aCodeBase
= INetURLObject::GetAbsURL( m_sBaseURL
, aCodeBase
);
961 m_pAppletImpl
->CreateApplet( aCode
, aName
, bMayScript
, aCodeBase
, m_sBaseURL
);//, aAlt );
962 m_pAppletImpl
->SetAltText( aAlt
);
964 SfxItemSet
aItemSet( m_xDoc
->GetAttrPool(), m_pCSS1Parser
->GetWhichMap() );
965 SvxCSS1PropertyInfo aPropInfo
;
966 if( HasStyleOptions( aStyle
, aId
, aClass
) )
967 ParseStyleOptions( aStyle
, aId
, aClass
, aItemSet
, aPropInfo
);
969 SfxItemSet
& rFrameSet
= m_pAppletImpl
->GetItemSet();
971 Reader::ResetFrameFormatAttrs( rFrameSet
);
973 // set the anchor and the adjustment
974 SetAnchorAndAdjustment( eVertOri
, eHoriOri
, aPropInfo
, rFrameSet
);
976 // and still the size or the frame
977 Size
aDfltSz( HTML_DFLT_APPLET_WIDTH
, HTML_DFLT_APPLET_HEIGHT
);
978 SetFixSize( aSize
, aDfltSz
, bPercentWidth
, bPercentHeight
, aPropInfo
, rFrameSet
);
979 SetSpace( aSpace
, aItemSet
, aPropInfo
, rFrameSet
);
983 void SwHTMLParser::EndApplet()
985 #if HAVE_FEATURE_JAVA
989 m_pAppletImpl
->FinishApplet();
991 // and insert into the document
992 SwFrameFormat
* pFlyFormat
=
993 m_xDoc
->getIDocumentContentOperations().InsertEmbObject(*m_pPam
,
994 ::svt::EmbeddedObjectRef( m_pAppletImpl
->GetApplet(), embed::Aspects::MSOLE_CONTENT
),
995 &m_pAppletImpl
->GetItemSet());
997 // set the alternative name
998 SwNoTextNode
*pNoTextNd
=
999 m_xDoc
->GetNodes()[ pFlyFormat
->GetContent().GetContentIdx()
1000 ->GetIndex()+1 ]->GetNoTextNode();
1001 pNoTextNd
->SetTitle( m_pAppletImpl
->GetAltText() );
1003 // if applicable create frames and register auto-bound frames
1004 RegisterFlyFrame( pFlyFormat
);
1006 m_pAppletImpl
.reset();
1012 void SwHTMLParser::InsertParam()
1014 #if HAVE_FEATURE_JAVA
1015 if( !m_pAppletImpl
)
1018 OUString aName
, aValue
;
1020 const HTMLOptions
& rHTMLOptions
= GetOptions();
1021 for (size_t i
= rHTMLOptions
.size(); i
; )
1023 const HTMLOption
& rOption
= rHTMLOptions
[--i
];
1024 switch( rOption
.GetToken() )
1026 case HtmlOptionId::NAME
:
1027 aName
= rOption
.GetString();
1029 case HtmlOptionId::VALUE
:
1030 aValue
= rOption
.GetString();
1036 if( aName
.isEmpty() )
1039 m_pAppletImpl
->AppendParam( aName
, aValue
);
1045 void SwHTMLParser::InsertFloatingFrame()
1047 OUString aAlt
, aId
, aStyle
, aClass
;
1048 Size
aSize( USHRT_MAX
, USHRT_MAX
);
1049 Size
aSpace( 0, 0 );
1050 bool bPercentWidth
= false, bPercentHeight
= false;
1051 sal_Int16 eVertOri
= text::VertOrientation::TOP
;
1052 sal_Int16 eHoriOri
= text::HoriOrientation::NONE
;
1054 const HTMLOptions
& rHTMLOptions
= GetOptions();
1056 // First fetch the options of the Writer-Frame-Format
1057 for (const auto & rOption
: rHTMLOptions
)
1059 switch( rOption
.GetToken() )
1061 case HtmlOptionId::ID
:
1062 aId
= rOption
.GetString();
1064 case HtmlOptionId::STYLE
:
1065 aStyle
= rOption
.GetString();
1067 case HtmlOptionId::CLASS
:
1068 aClass
= rOption
.GetString();
1070 case HtmlOptionId::ALT
:
1071 aAlt
= rOption
.GetString();
1073 case HtmlOptionId::ALIGN
:
1074 eVertOri
= rOption
.GetEnum( aHTMLImgVAlignTable
, eVertOri
);
1075 eHoriOri
= rOption
.GetEnum( aHTMLImgHAlignTable
, eHoriOri
);
1077 case HtmlOptionId::WIDTH
:
1078 bPercentWidth
= (rOption
.GetString().indexOf('%') != -1);
1079 aSize
.setWidth( static_cast<tools::Long
>(rOption
.GetNumber()) );
1081 case HtmlOptionId::HEIGHT
:
1082 bPercentHeight
= (rOption
.GetString().indexOf('%') != -1);
1083 aSize
.setHeight( static_cast<tools::Long
>(rOption
.GetNumber()) );
1085 case HtmlOptionId::HSPACE
:
1086 aSpace
.setWidth( static_cast<tools::Long
>(rOption
.GetNumber()) );
1088 case HtmlOptionId::VSPACE
:
1089 aSpace
.setHeight( static_cast<tools::Long
>(rOption
.GetNumber()) );
1095 // and now the ones for the SfxFrame
1096 SfxFrameDescriptor aFrameDesc
;
1098 SfxFrameHTMLParser::ParseFrameOptions( &aFrameDesc
, rHTMLOptions
, m_sBaseURL
);
1100 // create a floating frame
1101 comphelper::EmbeddedObjectContainer aCnt
;
1103 uno::Reference
< embed::XEmbeddedObject
> xObj
= aCnt
.CreateEmbeddedObject( SvGlobalName( SO3_IFRAME_CLASSID
).GetByteSequence(), aObjName
);
1107 // TODO/MBA: testing
1108 if ( svt::EmbeddedObjectRef::TryRunningState( xObj
) )
1110 uno::Reference
< beans::XPropertySet
> xSet( xObj
->getComponent(), uno::UNO_QUERY
);
1113 const OUString
& aName
= aFrameDesc
.GetName();
1114 ScrollingMode eScroll
= aFrameDesc
.GetScrollingMode();
1115 bool bHasBorder
= aFrameDesc
.HasFrameBorder();
1116 Size aMargin
= aFrameDesc
.GetMargin();
1118 OUString sHRef
= aFrameDesc
.GetURL().GetMainURL( INetURLObject::DecodeMechanism::NONE
);
1120 if (INetURLObject(sHRef
).GetProtocol() == INetProtocol::Macro
)
1121 NotifyMacroEventRead();
1123 xSet
->setPropertyValue("FrameURL", uno::Any( sHRef
) );
1124 xSet
->setPropertyValue("FrameName", uno::Any( aName
) );
1126 if ( eScroll
== ScrollingMode::Auto
)
1127 xSet
->setPropertyValue("FrameIsAutoScroll",
1130 xSet
->setPropertyValue("FrameIsScrollingMode",
1131 uno::Any( eScroll
== ScrollingMode::Yes
) );
1133 xSet
->setPropertyValue("FrameIsBorder",
1134 uno::Any( bHasBorder
) );
1136 xSet
->setPropertyValue("FrameMarginWidth",
1137 uno::Any( sal_Int32( aMargin
.Width() ) ) );
1139 xSet
->setPropertyValue("FrameMarginHeight",
1140 uno::Any( sal_Int32( aMargin
.Height() ) ) );
1144 catch ( uno::Exception
& )
1148 SfxItemSet
aItemSet( m_xDoc
->GetAttrPool(), m_pCSS1Parser
->GetWhichMap() );
1149 SvxCSS1PropertyInfo aPropInfo
;
1150 if( HasStyleOptions( aStyle
, aId
, aClass
) )
1151 ParseStyleOptions( aStyle
, aId
, aClass
, aItemSet
, aPropInfo
);
1153 // fetch the ItemSet
1154 SfxItemSetFixed
<RES_FRMATR_BEGIN
, RES_FRMATR_END
-1> aFrameSet( m_xDoc
->GetAttrPool() );
1156 Reader::ResetFrameFormatAttrs( aFrameSet
);
1158 // set the anchor and the adjustment
1159 SetAnchorAndAdjustment( eVertOri
, eHoriOri
, aPropInfo
, aFrameSet
);
1161 // and still the size of the frame
1162 Size
aDfltSz( HTML_DFLT_APPLET_WIDTH
, HTML_DFLT_APPLET_HEIGHT
);
1163 SetFixSize( aSize
, aDfltSz
, bPercentWidth
, bPercentHeight
, aPropInfo
, aFrameSet
);
1164 SetSpace( aSpace
, aItemSet
, aPropInfo
, aFrameSet
);
1166 // and insert into the document
1167 SwFrameFormat
* pFlyFormat
=
1168 m_xDoc
->getIDocumentContentOperations().InsertEmbObject(*m_pPam
,
1169 ::svt::EmbeddedObjectRef(xObj
, embed::Aspects::MSOLE_CONTENT
),
1172 // set the alternative name
1173 SwNoTextNode
*pNoTextNd
=
1174 m_xDoc
->GetNodes()[ pFlyFormat
->GetContent().GetContentIdx()
1175 ->GetIndex()+1 ]->GetNoTextNode();
1176 pNoTextNd
->SetTitle( aAlt
);
1178 // if applicable create frames and register auto-bound frames
1179 RegisterFlyFrame( pFlyFormat
);
1181 m_bInFloatingFrame
= true;
1183 ++m_nFloatingFrames
;
1186 SwHTMLFrameType
SwHTMLWriter::GuessOLENodeFrameType( const SwNode
& rNode
)
1188 SwHTMLFrameType eType
= HTML_FRMTYPE_OLE
;
1190 SwOLENode
* pOLENode
= const_cast<SwOLENode
*>(rNode
.GetOLENode());
1191 assert(pOLENode
&& "must exist");
1192 SwOLEObj
& rObj
= pOLENode
->GetOLEObj();
1194 uno::Reference
< embed::XClassifiedObject
> xClass
= rObj
.GetOleRef();
1195 SvGlobalName
aClass( xClass
->getClassID() );
1196 if( aClass
== SvGlobalName( SO3_PLUGIN_CLASSID
) )
1198 eType
= HTML_FRMTYPE_PLUGIN
;
1200 else if( aClass
== SvGlobalName( SO3_IFRAME_CLASSID
) )
1202 eType
= HTML_FRMTYPE_IFRAME
;
1204 #if HAVE_FEATURE_JAVA
1205 else if( aClass
== SvGlobalName( SO3_APPLET_CLASSID
) )
1207 eType
= HTML_FRMTYPE_APPLET
;
1214 SwHTMLWriter
& OutHTML_FrameFormatOLENode( SwHTMLWriter
& rWrt
, const SwFrameFormat
& rFrameFormat
,
1217 const SwFormatContent
& rFlyContent
= rFrameFormat
.GetContent();
1218 SwNodeOffset nStt
= rFlyContent
.GetContentIdx()->GetIndex()+1;
1219 SwOLENode
*pOLENd
= rWrt
.m_pDoc
->GetNodes()[ nStt
]->GetOLENode();
1221 OSL_ENSURE( pOLENd
, "OLE-Node expected" );
1225 SwOLEObj
&rObj
= pOLENd
->GetOLEObj();
1227 uno::Reference
< embed::XEmbeddedObject
> xObj( rObj
.GetOleRef() );
1228 if ( !svt::EmbeddedObjectRef::TryRunningState( xObj
) )
1231 uno::Reference
< beans::XPropertySet
> xSet( xObj
->getComponent(), uno::UNO_QUERY
);
1232 bool bHiddenEmbed
= false;
1236 OSL_FAIL("Unknown Object" );
1240 HtmlFrmOpts nFrameOpts
;
1242 // if possible output a line break before the "object"
1243 if( rWrt
.m_bLFPossible
)
1244 rWrt
.OutNewLine( true );
1246 if( !rFrameFormat
.GetName().isEmpty() )
1247 rWrt
.OutImplicitMark( rFrameFormat
.GetName(),
1250 SvGlobalName
aGlobName( xObj
->getClassID() );
1251 OStringBuffer
sOut("<");
1252 if( aGlobName
== SvGlobalName( SO3_PLUGIN_CLASSID
) )
1254 // first the plug-in specifics
1255 sOut
.append(rWrt
.GetNamespace() + OOO_STRING_SVTOOLS_HTML_embed
);
1259 aAny
= xSet
->getPropertyValue("PluginURL");
1260 if( (aAny
>>= aStr
) && !aStr
.isEmpty() )
1262 aURL
= URIHelper::simpleNormalizedMakeRelative( rWrt
.GetBaseURL(),
1266 if( !aURL
.isEmpty() )
1268 sOut
.append(" " OOO_STRING_SVTOOLS_HTML_O_src
"=\"");
1269 rWrt
.Strm().WriteOString( sOut
);
1271 HTMLOutFuncs::Out_String( rWrt
.Strm(), aURL
);
1276 aAny
= xSet
->getPropertyValue("PluginMimeType");
1277 if( (aAny
>>= aType
) && !aType
.isEmpty() )
1279 sOut
.append(" " OOO_STRING_SVTOOLS_HTML_O_type
"=\"");
1280 rWrt
.Strm().WriteOString( sOut
);
1282 HTMLOutFuncs::Out_String( rWrt
.Strm(), aType
);
1286 if ((RndStdIds::FLY_AT_PARA
== rFrameFormat
.GetAnchor().GetAnchorId()) &&
1287 css::text::WrapTextMode_THROUGH
== rFrameFormat
.GetSurround().GetSurround() )
1290 sOut
.append(" " OOO_STRING_SW_HTML_O_Hidden
);
1291 nFrameOpts
= HTML_FRMOPTS_HIDDEN_EMBED
;
1292 bHiddenEmbed
= true;
1296 nFrameOpts
= bInCntnr
? HTML_FRMOPTS_EMBED_CNTNR
1297 : HTML_FRMOPTS_EMBED
;
1300 else if( aGlobName
== SvGlobalName( SO3_APPLET_CLASSID
) )
1302 // or the applet specifics
1304 sOut
.append(rWrt
.GetNamespace() + OOO_STRING_SVTOOLS_HTML_applet
);
1308 aAny
= xSet
->getPropertyValue("AppletCodeBase");
1309 if( (aAny
>>= aCd
) && !aCd
.isEmpty() )
1311 OUString
sCodeBase( URIHelper::simpleNormalizedMakeRelative(rWrt
.GetBaseURL(), aCd
) );
1312 if( !sCodeBase
.isEmpty() )
1314 sOut
.append(" " OOO_STRING_SVTOOLS_HTML_O_codebase
"=\"");
1315 rWrt
.Strm().WriteOString( sOut
);
1317 HTMLOutFuncs::Out_String( rWrt
.Strm(), sCodeBase
);
1324 aAny
= xSet
->getPropertyValue("AppletCode");
1326 sOut
.append(" " OOO_STRING_SVTOOLS_HTML_O_code
"=\"");
1327 rWrt
.Strm().WriteOString( sOut
);
1329 HTMLOutFuncs::Out_String( rWrt
.Strm(), aClass
);
1333 OUString aAppletName
;
1334 aAny
= xSet
->getPropertyValue("AppletName");
1335 aAny
>>= aAppletName
;
1336 if( !aAppletName
.isEmpty() )
1338 sOut
.append(" " OOO_STRING_SVTOOLS_HTML_O_name
"=\"");
1339 rWrt
.Strm().WriteOString( sOut
);
1341 HTMLOutFuncs::Out_String( rWrt
.Strm(), aAppletName
);
1345 bool bScript
= false;
1346 aAny
= xSet
->getPropertyValue("AppletIsScript");
1349 sOut
.append(" " OOO_STRING_SVTOOLS_HTML_O_mayscript
);
1351 nFrameOpts
= bInCntnr
? HTML_FRMOPTS_APPLET_CNTNR
1352 : HTML_FRMOPTS_APPLET
;
1356 // or the Floating-Frame specifics
1358 sOut
.append(rWrt
.GetNamespace() + OOO_STRING_SVTOOLS_HTML_iframe
);
1359 rWrt
.Strm().WriteOString( sOut
);
1362 SfxFrameHTMLWriter::Out_FrameDescriptor( rWrt
.Strm(), rWrt
.GetBaseURL(),
1365 nFrameOpts
= bInCntnr
? HTML_FRMOPTS_IFRAME_CNTNR
1366 : HTML_FRMOPTS_IFRAME
;
1369 rWrt
.Strm().WriteOString( sOut
);
1372 // ALT, WIDTH, HEIGHT, HSPACE, VSPACE, ALIGN
1373 if( rWrt
.IsHTMLMode( HTMLMODE_ABS_POS_FLY
) && !bHiddenEmbed
)
1374 nFrameOpts
|= HTML_FRMOPTS_OLE_CSS1
;
1375 OString aEndTags
= rWrt
.OutFrameFormatOptions( rFrameFormat
, pOLENd
->GetTitle(), nFrameOpts
);
1376 if( rWrt
.IsHTMLMode( HTMLMODE_ABS_POS_FLY
) && !bHiddenEmbed
)
1377 rWrt
.OutCSS1_FrameFormatOptions( rFrameFormat
, nFrameOpts
);
1379 if( aGlobName
== SvGlobalName( SO3_APPLET_CLASSID
) )
1381 // output the parameters of applets as separate tags
1382 // and write a </APPLET>
1384 uno::Sequence
< beans::PropertyValue
> aProps
;
1385 aAny
= xSet
->getPropertyValue("AppletCommands");
1388 SvCommandList aCommands
;
1389 aCommands
.FillFromSequence( aProps
);
1390 std::vector
<sal_uLong
> aParams
;
1391 size_t i
= aCommands
.size();
1394 const SvCommand
& rCommand
= aCommands
[ --i
];
1395 const OUString
& rName
= rCommand
.GetCommand();
1396 SwHtmlOptType nType
= SwApplet_Impl::GetOptionType( rName
, true );
1397 if( SwHtmlOptType::TAG
== nType
)
1399 const OUString
& rValue
= rCommand
.GetArgument();
1400 rWrt
.Strm().WriteChar( ' ' );
1401 HTMLOutFuncs::Out_String( rWrt
.Strm(), rName
);
1402 rWrt
.Strm().WriteOString( "=\"" );
1403 HTMLOutFuncs::Out_String( rWrt
.Strm(), rValue
).WriteChar( '\"' );
1405 else if( SwHtmlOptType::PARAM
== nType
)
1407 aParams
.push_back( i
);
1411 rWrt
.Strm().WriteChar( '>' );
1413 rWrt
.IncIndentLevel(); // indent the applet content
1415 size_t ii
= aParams
.size();
1418 const SvCommand
& rCommand
= aCommands
[ aParams
[--ii
] ];
1419 const OUString
& rName
= rCommand
.GetCommand();
1420 const OUString
& rValue
= rCommand
.GetArgument();
1423 "<" + rWrt
.GetNamespace() + OOO_STRING_SVTOOLS_HTML_param
1424 " " OOO_STRING_SVTOOLS_HTML_O_name
1426 rWrt
.Strm().WriteOString( sOut
);
1428 HTMLOutFuncs::Out_String( rWrt
.Strm(), rName
);
1429 sOut
.append("\" " OOO_STRING_SVTOOLS_HTML_O_value
"=\"");
1430 rWrt
.Strm().WriteOString( sOut
);
1432 HTMLOutFuncs::Out_String( rWrt
.Strm(), rValue
).WriteOString( "\">" );
1435 rWrt
.DecIndentLevel(); // indent the applet content
1436 if( aCommands
.size() )
1438 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), Concat2View(rWrt
.GetNamespace() + OOO_STRING_SVTOOLS_HTML_applet
), false );
1440 else if( aGlobName
== SvGlobalName( SO3_PLUGIN_CLASSID
) )
1442 // write plug-ins parameters as options
1444 uno::Sequence
< beans::PropertyValue
> aProps
;
1445 aAny
= xSet
->getPropertyValue("PluginCommands");
1448 SvCommandList aCommands
;
1449 aCommands
.FillFromSequence( aProps
);
1450 for( size_t i
= 0; i
< aCommands
.size(); i
++ )
1452 const SvCommand
& rCommand
= aCommands
[ i
];
1453 const OUString
& rName
= rCommand
.GetCommand();
1455 if( SwApplet_Impl::GetOptionType( rName
, false ) == SwHtmlOptType::TAG
)
1457 const OUString
& rValue
= rCommand
.GetArgument();
1458 rWrt
.Strm().WriteChar( ' ' );
1459 HTMLOutFuncs::Out_String( rWrt
.Strm(), rName
);
1460 rWrt
.Strm().WriteOString( "=\"" );
1461 HTMLOutFuncs::Out_String( rWrt
.Strm(), rValue
).WriteChar( '\"' );
1464 rWrt
.Strm().WriteChar( '>' );
1468 // and for Floating-Frames just output another </IFRAME>
1470 rWrt
.Strm().WriteChar( '>' );
1471 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), Concat2View(rWrt
.GetNamespace() + OOO_STRING_SVTOOLS_HTML_iframe
), false );
1474 if( !aEndTags
.isEmpty() )
1475 rWrt
.Strm().WriteOString( aEndTags
);
1480 SwHTMLWriter
& OutHTML_FrameFormatOLENodeGrf( SwHTMLWriter
& rWrt
, const SwFrameFormat
& rFrameFormat
,
1481 bool bInCntnr
, bool bWriteReplacementGraphic
)
1483 const SwFormatContent
& rFlyContent
= rFrameFormat
.GetContent();
1484 SwNodeOffset nStt
= rFlyContent
.GetContentIdx()->GetIndex()+1;
1485 SwOLENode
*pOLENd
= rWrt
.m_pDoc
->GetNodes()[ nStt
]->GetOLENode();
1487 OSL_ENSURE( pOLENd
, "OLE-Node expected" );
1491 if (rWrt
.mbSkipImages
)
1493 // If we skip images, embedded objects would be completely lost.
1494 // Instead, try to use the HTML export of the embedded object.
1495 uno::Reference
<text::XTextContent
> xTextContent
= SwXTextEmbeddedObject::CreateXTextEmbeddedObject(*rWrt
.m_pDoc
, const_cast<SwFrameFormat
*>(&rFrameFormat
));
1496 uno::Reference
<document::XEmbeddedObjectSupplier2
> xEmbeddedObjectSupplier(xTextContent
, uno::UNO_QUERY
);
1497 uno::Reference
<frame::XStorable
> xStorable(xEmbeddedObjectSupplier
->getEmbeddedObject(), uno::UNO_QUERY
);
1498 SAL_WARN_IF(!xStorable
.is(), "sw.html", "OutHTML_FrameFormatOLENodeGrf: no embedded object");
1500 // Figure out what is the filter name of the embedded object.
1501 uno::Reference
<lang::XServiceInfo
> xServiceInfo(xStorable
, uno::UNO_QUERY
);
1503 if (xServiceInfo
.is())
1505 if (xServiceInfo
->supportsService("com.sun.star.sheet.SpreadsheetDocument"))
1506 aFilter
= "HTML (StarCalc)";
1507 else if (xServiceInfo
->supportsService("com.sun.star.text.TextDocument"))
1508 aFilter
= "HTML (StarWriter)";
1511 if (xStorable
.is() && !aFilter
.isEmpty())
1515 // FIXME: exception for the simplest test document, too
1516 SvMemoryStream aStream
;
1517 uno::Reference
<io::XOutputStream
> xOutputStream(new utl::OStreamWrapper(aStream
));
1518 utl::MediaDescriptor aMediaDescriptor
;
1519 aMediaDescriptor
["FilterName"] <<= aFilter
;
1520 aMediaDescriptor
["FilterOptions"] <<= OUString("SkipHeaderFooter");
1521 aMediaDescriptor
["OutputStream"] <<= xOutputStream
;
1522 xStorable
->storeToURL("private:stream", aMediaDescriptor
.getAsConstPropertyValueList());
1523 SAL_WARN_IF(aStream
.GetSize()>=o3tl::make_unsigned(SAL_MAX_INT32
), "sw.html", "Stream can't fit in OString");
1524 OString
aData(static_cast<const char*>(aStream
.GetData()), static_cast<sal_Int32
>(aStream
.GetSize()));
1525 // Wrap output in a <span> tag to avoid 'HTML parser error: Unexpected end tag: p'
1526 HTMLOutFuncs::Out_AsciiTag(rWrt
.Strm(), Concat2View(rWrt
.GetNamespace() + OOO_STRING_SVTOOLS_HTML_span
));
1527 rWrt
.Strm().WriteOString(aData
);
1528 HTMLOutFuncs::Out_AsciiTag(rWrt
.Strm(), Concat2View(rWrt
.GetNamespace() + OOO_STRING_SVTOOLS_HTML_span
), false);
1530 catch ( uno::Exception
& )
1538 if ( !pOLENd
->GetGraphic() )
1540 SAL_WARN("sw.html", "Unexpected missing OLE fallback graphic");
1544 Graphic
aGraphic( *pOLENd
->GetGraphic() );
1546 SwDocShell
* pDocSh
= rWrt
.m_pDoc
->GetDocShell();
1547 bool bObjectOpened
= false;
1548 OUString aRTFType
= "text/rtf";
1549 if (!rWrt
.m_aRTFOLEMimeType
.isEmpty())
1551 aRTFType
= rWrt
.m_aRTFOLEMimeType
;
1554 if (rWrt
.mbXHTML
&& pDocSh
)
1556 // Map native data to an outer <object> element.
1558 // Calculate the file name, which is meant to be the same as the
1559 // replacement image, just with a .ole extension.
1560 OUString aFileName
= lcl_CalculateFileName(rWrt
.GetOrigFileName(), aGraphic
, u
"ole");
1563 SwOLEObj
& rOLEObj
= pOLENd
->GetOLEObj();
1564 uno::Reference
<embed::XEmbeddedObject
> xEmbeddedObject
= rOLEObj
.GetOleRef();
1566 SvFileStream
aOutStream(aFileName
, StreamMode::WRITE
);
1567 uno::Reference
<io::XActiveDataStreamer
> xStreamProvider
;
1568 uno::Reference
<embed::XEmbedPersist2
> xOwnEmbedded
;
1569 if (xEmbeddedObject
.is())
1571 xStreamProvider
.set(xEmbeddedObject
, uno::UNO_QUERY
);
1572 xOwnEmbedded
.set(xEmbeddedObject
, uno::UNO_QUERY
);
1574 if (xStreamProvider
.is())
1576 // Real OLE2 case: OleEmbeddedObject.
1577 uno::Reference
<io::XInputStream
> xStream(xStreamProvider
->getStream(), uno::UNO_QUERY
);
1580 std::unique_ptr
<SvStream
> pStream(utl::UcbStreamHelper::CreateStream(xStream
));
1581 if (SwReqIfReader::WrapOleInRtf(*pStream
, aOutStream
, *pOLENd
, rFrameFormat
))
1583 // Data always wrapped in RTF.
1584 aFileType
= aRTFType
;
1588 else if (xOwnEmbedded
.is())
1590 // Our own embedded object: OCommonEmbeddedObject.
1591 SvxMSExportOLEObjects
aOLEExp(0);
1592 // Trigger the load of the OLE object if needed, otherwise we can't
1594 pOLENd
->GetTwipSize();
1595 SvMemoryStream aMemory
;
1596 tools::SvRef
<SotStorage
> pStorage
= new SotStorage(aMemory
);
1597 aOLEExp
.ExportOLEObject(rOLEObj
.GetObject(), *pStorage
);
1600 if (SwReqIfReader::WrapOleInRtf(aMemory
, aOutStream
, *pOLENd
, rFrameFormat
))
1602 // Data always wrapped in RTF.
1603 aFileType
= aRTFType
;
1608 // Otherwise the native data is just a grab-bag: ODummyEmbeddedObject.
1609 const OUString
& aStreamName
= rOLEObj
.GetCurrentPersistName();
1610 uno::Reference
<embed::XStorage
> xStorage
= pDocSh
->GetStorage();
1611 uno::Reference
<io::XStream
> xInStream
;
1614 // Even the native data may be missing.
1615 xInStream
= xStorage
->openStreamElement(aStreamName
, embed::ElementModes::READ
);
1616 } catch (const uno::Exception
&)
1618 TOOLS_WARN_EXCEPTION("sw.html", "OutHTML_FrameFormatOLENodeGrf: failed to open stream element");
1622 uno::Reference
<io::XStream
> xOutStream(new utl::OStreamWrapper(aOutStream
));
1623 comphelper::OStorageHelper::CopyInputToOutput(xInStream
->getInputStream(),
1624 xOutStream
->getOutputStream());
1627 uno::Reference
<beans::XPropertySet
> xOutStreamProps(xInStream
, uno::UNO_QUERY
);
1628 if (xOutStreamProps
.is())
1629 xOutStreamProps
->getPropertyValue("MediaType") >>= aFileType
;
1630 if (!aRTFType
.isEmpty())
1632 aFileType
= aRTFType
;
1635 aFileName
= URIHelper::simpleNormalizedMakeRelative(rWrt
.GetBaseURL(), aFileName
);
1637 // Refer to this data.
1638 if (rWrt
.m_bLFPossible
)
1640 rWrt
.Strm().WriteOString(Concat2View("<" + rWrt
.GetNamespace() + OOO_STRING_SVTOOLS_HTML_object
));
1641 rWrt
.Strm().WriteOString(Concat2View(" data=\"" + aFileName
.toUtf8() + "\""));
1642 if (!aFileType
.isEmpty())
1643 rWrt
.Strm().WriteOString(Concat2View(" type=\"" + aFileType
.toUtf8() + "\""));
1644 rWrt
.Strm().WriteOString(">");
1645 bObjectOpened
= true;
1646 rWrt
.m_bLFPossible
= true;
1649 if (!bObjectOpened
|| bWriteReplacementGraphic
)
1651 OUString aGraphicURL
;
1653 if(!rWrt
.mbEmbedImages
)
1655 const OUString
* pTempFileName
= rWrt
.GetOrigFileName();
1657 aGraphicURL
= *pTempFileName
;
1659 OUString
aFilterName("JPG");
1660 XOutFlags nFlags
= XOutFlags::UseGifIfPossible
| XOutFlags::UseNativeIfPossible
;
1664 aFilterName
= "PNG";
1665 nFlags
= XOutFlags::NONE
;
1666 aMimeType
= "image/png";
1668 if (aGraphic
.GetType() == GraphicType::NONE
)
1670 // The OLE Object has no replacement image, write a stub.
1671 aGraphicURL
= lcl_CalculateFileName(rWrt
.GetOrigFileName(), aGraphic
, u
"png");
1672 osl::File
aFile(aGraphicURL
);
1673 aFile
.open(osl_File_OpenFlag_Create
);
1678 ErrCode nErr
= XOutBitmap::WriteGraphic( aGraphic
, aGraphicURL
,
1681 if( nErr
) // error, don't write anything
1683 rWrt
.m_nWarn
= WARN_SWG_POOR_LOAD
;
1684 if (bObjectOpened
) // Still at least close the tag.
1685 rWrt
.Strm().WriteOString(Concat2View("</" + rWrt
.GetNamespace()
1686 + OOO_STRING_SVTOOLS_HTML_object
">"));
1689 aGraphicURL
= URIHelper::SmartRel2Abs(
1690 INetURLObject(rWrt
.GetBaseURL()), aGraphicURL
,
1691 URIHelper::GetMaybeFileHdl() );
1694 HtmlFrmOpts nFlags
= bInCntnr
? HtmlFrmOpts::GenImgAllMask
1695 : HtmlFrmOpts::GenImgMask
;
1697 nFlags
|= HtmlFrmOpts::Replacement
;
1698 HtmlWriter
aHtml(rWrt
.Strm(), rWrt
.maNamespace
);
1699 OutHTML_ImageStart( aHtml
, rWrt
, rFrameFormat
, aGraphicURL
, aGraphic
,
1700 pOLENd
->GetTitle(), pOLENd
->GetTwipSize(),
1701 nFlags
, "ole", nullptr, aMimeType
);
1702 OutHTML_ImageEnd(aHtml
, rWrt
);
1706 // Close native data.
1707 rWrt
.Strm().WriteOString(Concat2View("</" + rWrt
.GetNamespace() + OOO_STRING_SVTOOLS_HTML_object
1713 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */