1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <config_java.h>
21 
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 <tools/diagnose_ex.h>
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>
45 #include <frmfmt.hxx>
46 
47 #include <svl/ownlist.hxx>
48 #include <unotools/mediadescriptor.hxx>
49 #include <unotools/streamwrap.hxx>
50 #include <pam.hxx>
51 #include <doc.hxx>
52 #include <swerror.h>
53 #include <ndole.hxx>
54 #include <docsh.hxx>
55 #include "swhtml.hxx"
56 #include "wrthtml.hxx"
57 #include "htmlfly.hxx"
58 #include "swcss1.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>
69 
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>
83 
84 using namespace com::sun::star;
85 
86 #define HTML_DFLT_EMBED_WIDTH ((MM50*5)/2)
87 #define HTML_DFLT_EMBED_HEIGHT ((MM50*5)/2)
88 
89 #define HTML_DFLT_APPLET_WIDTH ((MM50*5)/2)
90 #define HTML_DFLT_APPLET_HEIGHT ((MM50*5)/2)
91 
92 
93 const HtmlFrmOpts HTML_FRMOPTS_EMBED_ALL      =
94     HtmlFrmOpts::Alt |
95     HtmlFrmOpts::Size |
96     HtmlFrmOpts::Name;
97 const HtmlFrmOpts HTML_FRMOPTS_EMBED_CNTNR    =
98     HTML_FRMOPTS_EMBED_ALL |
99     HtmlFrmOpts::AbsSize;
100 const HtmlFrmOpts HTML_FRMOPTS_EMBED          =
101     HTML_FRMOPTS_EMBED_ALL |
102     HtmlFrmOpts::Align |
103     HtmlFrmOpts::Space |
104     HtmlFrmOpts::BrClear |
105     HtmlFrmOpts::Name;
106 const HtmlFrmOpts HTML_FRMOPTS_HIDDEN_EMBED   =
107     HtmlFrmOpts::Alt |
108     HtmlFrmOpts::Name;
109 
110 const HtmlFrmOpts HTML_FRMOPTS_APPLET_ALL     =
111     HtmlFrmOpts::Alt |
112     HtmlFrmOpts::Size;
113 const HtmlFrmOpts HTML_FRMOPTS_APPLET_CNTNR   =
114     HTML_FRMOPTS_APPLET_ALL |
115     HtmlFrmOpts::AbsSize;
116 const HtmlFrmOpts HTML_FRMOPTS_APPLET         =
117     HTML_FRMOPTS_APPLET_ALL |
118     HtmlFrmOpts::Align |
119     HtmlFrmOpts::Space |
120     HtmlFrmOpts::BrClear;
121 
122 const HtmlFrmOpts HTML_FRMOPTS_IFRAME_ALL     =
123     HtmlFrmOpts::Alt |
124     HtmlFrmOpts::Size;
125 const HtmlFrmOpts HTML_FRMOPTS_IFRAME_CNTNR   =
126     HTML_FRMOPTS_IFRAME_ALL |
127     HtmlFrmOpts::AbsSize;
128 const HtmlFrmOpts HTML_FRMOPTS_IFRAME         =
129     HTML_FRMOPTS_IFRAME_ALL |
130     HtmlFrmOpts::Align |
131     HtmlFrmOpts::Space |
132     HtmlFrmOpts::Border |
133     HtmlFrmOpts::BrClear;
134 
135 const HtmlFrmOpts HTML_FRMOPTS_OLE_CSS1       =
136     HtmlFrmOpts::SAlign |
137     HtmlFrmOpts::SSpace;
138 
139 namespace
140 {
141 /**
142  * Calculates a filename for an image, provided the HTML file name, the image
143  * itself and a wanted extension.
144  */
lcl_CalculateFileName(const OUString * pOrigFileName,const Graphic & rGraphic,std::u16string_view rExtension)145 OUString lcl_CalculateFileName(const OUString* pOrigFileName, const Graphic& rGraphic,
146                                std::u16string_view rExtension)
147 {
148     OUString aFileName;
149 
150     if (pOrigFileName)
151         aFileName = *pOrigFileName;
152     INetURLObject aURL(aFileName);
153     OUString aName = aURL.getBase() + "_" +
154         aURL.getExtension() + "_" +
155         OUString::number(rGraphic.GetChecksum(), 16);
156     aURL.setBase(aName);
157     aURL.setExtension(rExtension);
158     aFileName = aURL.GetMainURL(INetURLObject::DecodeMechanism::NONE);
159 
160     return aFileName;
161 }
162 }
163 
SetFixSize(const Size & rPixSize,const Size & rTwipDfltSize,bool bPercentWidth,bool bPercentHeight,SvxCSS1PropertyInfo const & rCSS1PropInfo,SfxItemSet & rFlyItemSet)164 void SwHTMLParser::SetFixSize( const Size& rPixSize,
165                                const Size& rTwipDfltSize,
166                                bool bPercentWidth, bool bPercentHeight,
167                                SvxCSS1PropertyInfo const & rCSS1PropInfo,
168                                SfxItemSet& rFlyItemSet )
169 {
170     // convert absolute size values into Twip
171     sal_uInt8 nPercentWidth = 0, nPercentHeight = 0;
172     Size aTwipSz( bPercentWidth || USHRT_MAX==rPixSize.Width() ? 0 : rPixSize.Width(),
173                   bPercentHeight || USHRT_MAX==rPixSize.Height() ? 0 : rPixSize.Height() );
174     if( (aTwipSz.Width() || aTwipSz.Height()) && Application::GetDefaultDevice() )
175     {
176         aTwipSz =
177             Application::GetDefaultDevice()->PixelToLogic( aTwipSz,
178                                                 MapMode(MapUnit::MapTwip) );
179     }
180 
181     // process width
182     if( SVX_CSS1_LTYPE_PERCENTAGE == rCSS1PropInfo.m_eWidthType )
183     {
184         nPercentWidth = static_cast<sal_uInt8>(rCSS1PropInfo.m_nWidth);
185         aTwipSz.setWidth( rTwipDfltSize.Width() );
186     }
187     else if( SVX_CSS1_LTYPE_TWIP== rCSS1PropInfo.m_eWidthType )
188     {
189         aTwipSz.setWidth( rCSS1PropInfo.m_nWidth );
190     }
191     else if( bPercentWidth && rPixSize.Width() )
192     {
193         nPercentWidth = static_cast<sal_uInt8>(rPixSize.Width());
194         if( nPercentWidth > 100 )
195             nPercentWidth = 100;
196 
197         aTwipSz.setWidth( rTwipDfltSize.Width() );
198     }
199     else if( USHRT_MAX==rPixSize.Width() )
200     {
201         aTwipSz.setWidth( rTwipDfltSize.Width() );
202     }
203     if( aTwipSz.Width() < MINFLY )
204     {
205         aTwipSz.setWidth( MINFLY );
206     }
207 
208     // process height
209     if( SVX_CSS1_LTYPE_PERCENTAGE == rCSS1PropInfo.m_eHeightType )
210     {
211         nPercentHeight = static_cast<sal_uInt8>(rCSS1PropInfo.m_nHeight);
212         aTwipSz.setHeight( rTwipDfltSize.Height() );
213     }
214     else if( SVX_CSS1_LTYPE_TWIP== rCSS1PropInfo.m_eHeightType )
215     {
216         aTwipSz.setHeight( rCSS1PropInfo.m_nHeight );
217     }
218     else if( bPercentHeight && rPixSize.Height() )
219     {
220         nPercentHeight = static_cast<sal_uInt8>(rPixSize.Height());
221         if( nPercentHeight > 100 )
222             nPercentHeight = 100;
223 
224         aTwipSz.setHeight( rTwipDfltSize.Height() );
225     }
226     else if( USHRT_MAX==rPixSize.Height() )
227     {
228         aTwipSz.setHeight( rTwipDfltSize.Height() );
229     }
230     if( aTwipSz.Height() < MINFLY )
231     {
232         aTwipSz.setHeight( MINFLY );
233     }
234 
235     // set size
236     SwFormatFrameSize aFrameSize( SwFrameSize::Fixed, aTwipSz.Width(), aTwipSz.Height() );
237     aFrameSize.SetWidthPercent( nPercentWidth );
238     aFrameSize.SetHeightPercent( nPercentHeight );
239     rFlyItemSet.Put( aFrameSize );
240 }
241 
SetSpace(const Size & rPixSpace,SfxItemSet & rCSS1ItemSet,SvxCSS1PropertyInfo & rCSS1PropInfo,SfxItemSet & rFlyItemSet)242 void SwHTMLParser::SetSpace( const Size& rPixSpace,
243                              SfxItemSet& rCSS1ItemSet,
244                              SvxCSS1PropertyInfo& rCSS1PropInfo,
245                              SfxItemSet& rFlyItemSet )
246 {
247     sal_Int32 nLeftSpace = 0, nRightSpace = 0;
248     sal_uInt16 nUpperSpace = 0, nLowerSpace = 0;
249     if( (rPixSpace.Width() || rPixSpace.Height()) && Application::GetDefaultDevice() )
250     {
251         Size aTwipSpc( rPixSpace.Width(), rPixSpace.Height() );
252         aTwipSpc =
253             Application::GetDefaultDevice()->PixelToLogic( aTwipSpc,
254                                                 MapMode(MapUnit::MapTwip) );
255         nLeftSpace = nRightSpace = aTwipSpc.Width();
256         nUpperSpace = nLowerSpace = o3tl::narrowing<sal_uInt16>(aTwipSpc.Height());
257     }
258 
259     // set left/right margin
260     const SfxPoolItem *pItem;
261     if( SfxItemState::SET==rCSS1ItemSet.GetItemState( RES_LR_SPACE, true, &pItem ) )
262     {
263         // if applicable remove the first line indent
264         const SvxLRSpaceItem *pLRItem = static_cast<const SvxLRSpaceItem *>(pItem);
265         SvxLRSpaceItem aLRItem( *pLRItem );
266         aLRItem.SetTextFirstLineOffset( 0 );
267         if( rCSS1PropInfo.m_bLeftMargin )
268         {
269             nLeftSpace = aLRItem.GetLeft();
270             rCSS1PropInfo.m_bLeftMargin = false;
271         }
272         if( rCSS1PropInfo.m_bRightMargin )
273         {
274             nRightSpace = aLRItem.GetRight();
275             rCSS1PropInfo.m_bRightMargin = false;
276         }
277         rCSS1ItemSet.ClearItem( RES_LR_SPACE );
278     }
279     if( nLeftSpace > 0 || nRightSpace > 0 )
280     {
281         SvxLRSpaceItem aLRItem( RES_LR_SPACE );
282         aLRItem.SetLeft( std::max<sal_Int32>(nLeftSpace, 0) );
283         aLRItem.SetRight( std::max<sal_Int32>(nRightSpace, 0) );
284         rFlyItemSet.Put( aLRItem );
285         if( nLeftSpace )
286         {
287             const SwFormatHoriOrient& rHoriOri =
288                 rFlyItemSet.Get( RES_HORI_ORIENT );
289             if( text::HoriOrientation::NONE == rHoriOri.GetHoriOrient() )
290             {
291                 SwFormatHoriOrient aHoriOri( rHoriOri );
292                 aHoriOri.SetPos( aHoriOri.GetPos() + nLeftSpace );
293                 rFlyItemSet.Put( aHoriOri );
294             }
295         }
296     }
297 
298     // set top/bottom margin
299     if( SfxItemState::SET==rCSS1ItemSet.GetItemState( RES_UL_SPACE, true, &pItem ) )
300     {
301         // if applicable remove the first line indent
302         const SvxULSpaceItem *pULItem = static_cast<const SvxULSpaceItem *>(pItem);
303         if( rCSS1PropInfo.m_bTopMargin )
304         {
305             nUpperSpace = pULItem->GetUpper();
306             rCSS1PropInfo.m_bTopMargin = false;
307         }
308         if( rCSS1PropInfo.m_bBottomMargin )
309         {
310             nLowerSpace = pULItem->GetLower();
311             rCSS1PropInfo.m_bBottomMargin = false;
312         }
313         rCSS1ItemSet.ClearItem( RES_UL_SPACE );
314     }
315     if( !(nUpperSpace || nLowerSpace) )
316         return;
317 
318     SvxULSpaceItem aULItem( RES_UL_SPACE );
319     aULItem.SetUpper( nUpperSpace );
320     aULItem.SetLower( nLowerSpace );
321     rFlyItemSet.Put( aULItem );
322     if( nUpperSpace )
323     {
324         const SwFormatVertOrient& rVertOri =
325             rFlyItemSet.Get( RES_VERT_ORIENT );
326         if( text::VertOrientation::NONE == rVertOri.GetVertOrient() )
327         {
328             SwFormatVertOrient aVertOri( rVertOri );
329             aVertOri.SetPos( aVertOri.GetPos() + nUpperSpace );
330             rFlyItemSet.Put( aVertOri );
331         }
332     }
333 }
334 
StripQueryFromPath(const OUString & rBase,const OUString & rPath)335 OUString SwHTMLParser::StripQueryFromPath(const OUString& rBase, const OUString& rPath)
336 {
337     if (!comphelper::isFileUrl(rBase))
338         return rPath;
339 
340     sal_Int32 nIndex = rPath.indexOf('?');
341 
342     if (nIndex != -1)
343         return rPath.copy(0, nIndex);
344 
345     return rPath;
346 }
347 
InsertEmbed()348 bool SwHTMLParser::InsertEmbed()
349 {
350     OUString aURL, aType, aName, aAlt, aId, aStyle, aClass;
351     OUString aData;
352     Size aSize( USHRT_MAX, USHRT_MAX );
353     Size aSpace( USHRT_MAX, USHRT_MAX );
354     bool bPercentWidth = false, bPercentHeight = false, bHidden = false;
355     sal_Int16 eVertOri = text::VertOrientation::NONE;
356     sal_Int16 eHoriOri = text::HoriOrientation::NONE;
357     SvCommandList aCmdLst;
358     const HTMLOptions& rHTMLOptions = GetOptions();
359 
360     // The options are read forwards, because the plug-ins expect them in this
361     // order. Still only the first value of an option may be regarded.
362     for (const auto & rOption : rHTMLOptions)
363     {
364         switch( rOption.GetToken() )
365         {
366         case HtmlOptionId::ID:
367             aId = rOption.GetString();
368             break;
369         case HtmlOptionId::STYLE:
370             aStyle = rOption.GetString();
371             break;
372         case HtmlOptionId::CLASS:
373             aClass = rOption.GetString();
374             break;
375         case HtmlOptionId::NAME:
376             aName = rOption.GetString();
377             break;
378         case HtmlOptionId::SRC:
379             if( aURL.isEmpty() )
380                 aURL = rOption.GetString();
381             break;
382         case HtmlOptionId::ALT:
383             aAlt = rOption.GetString();
384             break;
385         case HtmlOptionId::TYPE:
386             if( aType.isEmpty() )
387                 aType = rOption.GetString();
388             break;
389         case HtmlOptionId::ALIGN:
390             if( eVertOri==text::VertOrientation::NONE && eHoriOri==text::HoriOrientation::NONE )
391             {
392                 eVertOri = rOption.GetEnum( aHTMLImgVAlignTable, eVertOri );
393                 eHoriOri = rOption.GetEnum( aHTMLImgHAlignTable, eHoriOri );
394             }
395             break;
396         case HtmlOptionId::WIDTH:
397             if( USHRT_MAX==aSize.Width() )
398             {
399                 bPercentWidth = (rOption.GetString().indexOf('%') != -1);
400                 aSize.setWidth( static_cast<tools::Long>(rOption.GetNumber()) );
401             }
402             break;
403         case HtmlOptionId::HEIGHT:
404             if( USHRT_MAX==aSize.Height() )
405             {
406                 bPercentHeight = (rOption.GetString().indexOf('%') != -1);
407                 aSize.setHeight( static_cast<tools::Long>(rOption.GetNumber()) );
408             }
409             break;
410         case HtmlOptionId::HSPACE:
411             if( USHRT_MAX==aSpace.Width() )
412                 aSpace.setWidth( static_cast<tools::Long>(rOption.GetNumber()) );
413             break;
414         case HtmlOptionId::VSPACE:
415             if( USHRT_MAX==aSpace.Height() )
416                 aSpace.setHeight( static_cast<tools::Long>(rOption.GetNumber()) );
417             break;
418         case HtmlOptionId::DATA:
419             if (m_bXHTML && aURL.isEmpty())
420                 aData = rOption.GetString();
421             break;
422         case HtmlOptionId::UNKNOWN:
423             if (rOption.GetTokenString().equalsIgnoreAsciiCase(
424                         OOO_STRING_SW_HTML_O_Hidden))
425             {
426                 bHidden = !rOption.GetString().equalsIgnoreAsciiCase(
427                                 "FALSE");
428             }
429             break;
430         default: break;
431         }
432 
433         // All parameters are passed to the plug-in.
434         aCmdLst.Append( rOption.GetTokenString(), rOption.GetString() );
435     }
436 
437     if (aType == "image/png" && m_aEmbeds.empty())
438         // Toplevel <object> for PNG -> that's an image, not an OLE object.
439         return false;
440 
441     SfxItemSet aItemSet( m_xDoc->GetAttrPool(), m_pCSS1Parser->GetWhichMap() );
442     SvxCSS1PropertyInfo aPropInfo;
443     if( HasStyleOptions( aStyle, aId, aClass ) )
444         ParseStyleOptions( aStyle, aId, aClass, aItemSet, aPropInfo );
445 
446     // Convert the default values (except height/width, which is done by SetFrameSize())
447     if( eVertOri==text::VertOrientation::NONE && eHoriOri==text::HoriOrientation::NONE )
448         eVertOri = text::VertOrientation::TOP;
449     if( USHRT_MAX==aSpace.Width() )
450         aSpace.setWidth( 0 );
451     if( USHRT_MAX==aSpace.Height() )
452         aSpace.setHeight( 0 );
453     if( bHidden )
454     {
455         // Size (0,0) will be changed to (MINFLY, MINFLY) in SetFrameSize()
456         aSize.setWidth( 0 ); aSize.setHeight( 0 );
457         aSpace.setWidth( 0 ); aSpace.setHeight( 0 );
458         bPercentWidth = bPercentHeight = false;
459     }
460 
461     // prepare the URL
462     INetURLObject aURLObj;
463     bool bHasURL = !aURL.isEmpty() &&
464                    aURLObj.SetURL(
465                        URIHelper::SmartRel2Abs(
466                            INetURLObject(m_sBaseURL), aURL,
467                            URIHelper::GetMaybeFileHdl()) );
468     bool bHasData = !aData.isEmpty();
469 
470     try
471     {
472         // Strip query and everything after that for file:// URLs, browsers do
473         // the same.
474         aURLObj.SetURL(rtl::Uri::convertRelToAbs(
475             m_sBaseURL, SwHTMLParser::StripQueryFromPath(m_sBaseURL, aData)));
476     }
477     catch (const rtl::MalformedUriException& /*rException*/)
478     {
479         bHasData = false;
480     }
481 
482     // do not insert plugin if it has neither URL nor type
483     bool bHasType = !aType.isEmpty();
484     if( !bHasURL && !bHasType && !bHasData )
485         return true;
486 
487     if (!m_aEmbeds.empty())
488     {
489         // Nested XHTML <object> element: points to replacement graphic.
490         SwOLENode* pOLENode = m_aEmbeds.top();
491         svt::EmbeddedObjectRef& rObj = pOLENode->GetOLEObj().GetObject();
492         Graphic aGraphic;
493         if (GraphicFilter::GetGraphicFilter().ImportGraphic(aGraphic, aURLObj) != ERRCODE_NONE)
494             return true;
495 
496         rObj.SetGraphic(aGraphic, aType);
497 
498         // Set the size of the OLE frame to the size of the graphic.
499         OutputDevice* pDevice = Application::GetDefaultDevice();
500         if (aSize.getHeight() == USHRT_MAX || aSize.getWidth() == USHRT_MAX)
501         {
502             Size aPixelSize = aGraphic.GetSizePixel(pDevice);
503             if (aSize.getWidth() == USHRT_MAX)
504                 aSize.setWidth(aPixelSize.getWidth());
505             if (aSize.getHeight() == USHRT_MAX)
506                 aSize.setHeight(aPixelSize.getHeight());
507         }
508 
509         SwFrameFormat* pFormat = pOLENode->GetFlyFormat();
510         if (!pFormat)
511             return true;
512 
513         SwAttrSet aAttrSet(pFormat->GetAttrSet());
514         aAttrSet.ClearItem(RES_CNTNT);
515         Size aTwipSize(pDevice->PixelToLogic(aSize, MapMode(MapUnit::MapTwip)));
516         SwFormatFrameSize aFrameSize(SwFrameSize::Fixed, aTwipSize.Width(), aTwipSize.Height());
517         aAttrSet.Put(aFrameSize);
518         pOLENode->GetDoc().SetFlyFrameAttr(*pFormat, aAttrSet);
519         return true;
520     }
521 
522     // create the plug-in
523     comphelper::EmbeddedObjectContainer aCnt;
524     OUString aObjName;
525     uno::Reference < embed::XEmbeddedObject > xObj;
526     if (!bHasData)
527     {
528         xObj = aCnt.CreateEmbeddedObject( SvGlobalName( SO3_PLUGIN_CLASSID ).GetByteSequence(), aObjName );
529         if ( svt::EmbeddedObjectRef::TryRunningState( xObj ) )
530         {
531             uno::Reference < beans::XPropertySet > xSet( xObj->getComponent(), uno::UNO_QUERY );
532             if ( xSet.is() )
533             {
534                 if( bHasURL )
535                     xSet->setPropertyValue("PluginURL", uno::makeAny( aURL ) );
536                 if( bHasType )
537                     xSet->setPropertyValue("PluginMimeType", uno::makeAny( aType ) );
538 
539                 uno::Sequence < beans::PropertyValue > aProps;
540                 aCmdLst.FillSequence( aProps );
541                 xSet->setPropertyValue("PluginCommands", uno::makeAny( aProps ) );
542 
543             }
544         }
545     }
546     else if (SwDocShell* pDocSh = m_xDoc->GetDocShell())
547     {
548         // Has non-empty data attribute in XHTML: map that to an OLE object.
549         uno::Reference<embed::XStorage> xStorage = pDocSh->GetStorage();
550         aCnt.SwitchPersistence(xStorage);
551         aObjName = aCnt.CreateUniqueObjectName();
552         {
553             SvFileStream aFileStream(aURLObj.GetMainURL(INetURLObject::DecodeMechanism::NONE),
554                                      StreamMode::READ);
555             uno::Reference<io::XInputStream> xInStream;
556             SvMemoryStream aMemoryStream;
557 
558             // Allow any MIME type that starts with magic, unless a set of allowed types are
559             // specified.
560             auto it = m_aAllowedRTFOLEMimeTypes.find(aType);
561             if (m_aAllowedRTFOLEMimeTypes.empty() || it != m_aAllowedRTFOLEMimeTypes.end())
562             {
563                 OString aMagic("{\\object");
564                 OString aHeader(read_uInt8s_ToOString(aFileStream, aMagic.getLength()));
565                 aFileStream.Seek(0);
566                 if (aHeader == aMagic)
567                 {
568                     // OLE2 wrapped in RTF: either own format or real OLE2 embedding.
569                     bool bOwnFormat = false;
570                     if (SwReqIfReader::ExtractOleFromRtf(aFileStream, aMemoryStream, bOwnFormat))
571                     {
572                         xInStream.set(new utl::OStreamWrapper(aMemoryStream));
573                     }
574 
575                     if (bOwnFormat)
576                     {
577                         uno::Sequence<beans::PropertyValue> aMedium = comphelper::InitPropertySequence(
578                             { { "InputStream", uno::makeAny(xInStream) },
579                               { "URL", uno::makeAny(OUString("private:stream")) },
580                               { "DocumentBaseURL", uno::makeAny(m_sBaseURL) } });
581                         xObj = aCnt.InsertEmbeddedObject(aMedium, aName, &m_sBaseURL);
582                     }
583                     else
584                     {
585                         // The type is now an OLE2 container, not the original XHTML type.
586                         aType = "application/vnd.sun.star.oleobject";
587                     }
588                 }
589             }
590 
591             if (!xInStream.is())
592                 // Non-RTF case.
593                 xInStream.set(new utl::OStreamWrapper(aFileStream));
594 
595             if (!xObj.is())
596             {
597                 uno::Reference<io::XStream> xOutStream
598                     = xStorage->openStreamElement(aObjName, embed::ElementModes::READWRITE);
599                 if (aFileStream.IsOpen())
600                     comphelper::OStorageHelper::CopyInputToOutput(xInStream,
601                                                                   xOutStream->getOutputStream());
602 
603                 if (!aType.isEmpty())
604                 {
605                     // Set media type of the native data.
606                     uno::Reference<beans::XPropertySet> xOutStreamProps(xOutStream, uno::UNO_QUERY);
607                     if (xOutStreamProps.is())
608                         xOutStreamProps->setPropertyValue("MediaType", uno::makeAny(aType));
609                 }
610             }
611             xObj = aCnt.GetEmbeddedObject(aObjName);
612         }
613     }
614 
615     SfxItemSet aFrameSet( m_xDoc->GetAttrPool(),
616                         svl::Items<RES_FRMATR_BEGIN, RES_FRMATR_END-1>{} );
617     if( !IsNewDoc() )
618         Reader::ResetFrameFormatAttrs( aFrameSet );
619 
620     // set the anchor
621     if( !bHidden )
622     {
623         SetAnchorAndAdjustment( eVertOri, eHoriOri, aPropInfo, aFrameSet );
624     }
625     else
626     {
627         SwFormatAnchor aAnchor( RndStdIds::FLY_AT_PARA );
628         aAnchor.SetAnchor( m_pPam->GetPoint() );
629         aFrameSet.Put( aAnchor );
630         aFrameSet.Put( SwFormatHoriOrient( 0, text::HoriOrientation::LEFT, text::RelOrientation::FRAME) );
631         aFrameSet.Put( SwFormatSurround( css::text::WrapTextMode_THROUGH ) );
632         aFrameSet.Put( SwFormatVertOrient( 0, text::VertOrientation::TOP, text::RelOrientation::PRINT_AREA ) );
633     }
634 
635     // and the size of the frame
636     Size aDfltSz( HTML_DFLT_EMBED_WIDTH, HTML_DFLT_EMBED_HEIGHT );
637     SetFixSize( aSize, aDfltSz, bPercentWidth, bPercentHeight, aPropInfo, aFrameSet );
638     SetSpace( aSpace, aItemSet, aPropInfo, aFrameSet );
639 
640     // and insert into the document
641     uno::Reference<lang::XInitialization> xObjInitialization(xObj, uno::UNO_QUERY);
642     if (xObjInitialization.is())
643     {
644         // Request that the native data of the embedded object is not modified
645         // during parsing.
646         uno::Sequence<beans::PropertyValue> aValues{ comphelper::makePropertyValue("StreamReadOnly",
647                                                                                    true) };
648         uno::Sequence<uno::Any> aArguments{ uno::makeAny(aValues) };
649         xObjInitialization->initialize(aArguments);
650     }
651     SwFrameFormat* pFlyFormat =
652         m_xDoc->getIDocumentContentOperations().InsertEmbObject(*m_pPam,
653                 ::svt::EmbeddedObjectRef(xObj, embed::Aspects::MSOLE_CONTENT),
654                 &aFrameSet);
655     if (xObjInitialization.is())
656     {
657         uno::Sequence<beans::PropertyValue> aValues{ comphelper::makePropertyValue("StreamReadOnly",
658                                                                                    false) };
659         uno::Sequence<uno::Any> aArguments{ uno::makeAny(aValues) };
660         xObjInitialization->initialize(aArguments);
661     }
662 
663     // set name at FrameFormat
664     if( !aName.isEmpty() )
665         pFlyFormat->SetName( aName );
666 
667     // set the alternative text
668     SwNoTextNode *pNoTextNd =
669         m_xDoc->GetNodes()[ pFlyFormat->GetContent().GetContentIdx()
670                           ->GetIndex()+1 ]->GetNoTextNode();
671     pNoTextNd->SetTitle( aAlt );
672 
673     // if applicable create frames and register auto-bound frames
674     if( !bHidden )
675     {
676         // HIDDEN plug-ins should stay paragraph-bound. Since RegisterFlyFrame()
677         // will change paragraph-bound frames with wrap-through into a
678         // character-bound frame, here we must create the frames by hand.
679         RegisterFlyFrame( pFlyFormat );
680     }
681 
682     if (!bHasData)
683         return true;
684 
685     SwOLENode* pOLENode = pNoTextNd->GetOLENode();
686     if (!pOLENode)
687         return true;
688 
689     m_aEmbeds.push(pOLENode);
690 
691     return true;
692 }
693 
694 #if HAVE_FEATURE_JAVA
NewObject()695 void SwHTMLParser::NewObject()
696 {
697     OUString aClassID;
698     OUString aStandBy, aId, aStyle, aClass;
699     Size aSize( USHRT_MAX, USHRT_MAX );
700     Size aSpace( 0, 0 );
701     sal_Int16 eVertOri = text::VertOrientation::TOP;
702     sal_Int16 eHoriOri = text::HoriOrientation::NONE;
703 
704     bool bPercentWidth = false, bPercentHeight = false,
705              bDeclare = false;
706     // create a new Command list
707     m_pAppletImpl.reset(new SwApplet_Impl( m_xDoc->GetAttrPool() ));
708 
709     const HTMLOptions& rHTMLOptions = GetOptions();
710     for (size_t i = rHTMLOptions.size(); i; )
711     {
712         const HTMLOption& rOption = rHTMLOptions[--i];
713         switch( rOption.GetToken() )
714         {
715         case HtmlOptionId::ID:
716             aId = rOption.GetString();
717             break;
718         case HtmlOptionId::STYLE:
719             aStyle = rOption.GetString();
720             break;
721         case HtmlOptionId::CLASS:
722             aClass = rOption.GetString();
723             break;
724         case HtmlOptionId::DECLARE:
725             bDeclare = true;
726             break;
727         case HtmlOptionId::CLASSID:
728             aClassID = rOption.GetString();
729             break;
730         case HtmlOptionId::CODEBASE:
731             break;
732         case HtmlOptionId::DATA:
733             break;
734         case HtmlOptionId::TYPE:
735             break;
736         case HtmlOptionId::CODETYPE:
737             break;
738         case HtmlOptionId::ARCHIVE:
739         case HtmlOptionId::UNKNOWN:
740             break;
741         case HtmlOptionId::STANDBY:
742             aStandBy = rOption.GetString();
743             break;
744         case HtmlOptionId::WIDTH:
745             bPercentWidth = (rOption.GetString().indexOf('%') != -1);
746             aSize.setWidth( static_cast<tools::Long>(rOption.GetNumber()) );
747             break;
748         case HtmlOptionId::HEIGHT:
749             bPercentHeight = (rOption.GetString().indexOf('%') != -1);
750             aSize.setHeight( static_cast<tools::Long>(rOption.GetNumber()) );
751             break;
752         case HtmlOptionId::ALIGN:
753             eVertOri = rOption.GetEnum( aHTMLImgVAlignTable, eVertOri );
754             eHoriOri = rOption.GetEnum( aHTMLImgHAlignTable, eHoriOri );
755             break;
756         case HtmlOptionId::USEMAP:
757             break;
758         case HtmlOptionId::NAME:
759             break;
760         case HtmlOptionId::HSPACE:
761             aSpace.setWidth( static_cast<tools::Long>(rOption.GetNumber()) );
762             break;
763         case HtmlOptionId::VSPACE:
764             aSpace.setHeight( static_cast<tools::Long>(rOption.GetNumber()) );
765             break;
766         case HtmlOptionId::BORDER:
767             break;
768 
769         case HtmlOptionId::SDONCLICK:
770         case HtmlOptionId::ONCLICK:
771         case HtmlOptionId::SDONMOUSEOVER:
772         case HtmlOptionId::ONMOUSEOVER:
773         case HtmlOptionId::SDONMOUSEOUT:
774         case HtmlOptionId::ONMOUSEOUT:
775             break;
776         default: break;
777         }
778         // All parameters are passed to the applet.
779         m_pAppletImpl->AppendParam( rOption.GetTokenString(),
780                                   rOption.GetString() );
781 
782     }
783 
784     // Objects that are declared only are not evaluated. Moreover, only
785     // Java applets are supported.
786     bool bIsApplet = false;
787 
788     if( !bDeclare && aClassID.getLength() == 42 &&
789         aClassID.startsWith("clsid:") )
790     {
791         aClassID = aClassID.copy(6);
792         SvGlobalName aCID;
793         if( aCID.MakeId( aClassID ) )
794         {
795             SvGlobalName aJavaCID( 0x8AD9C840UL, 0x044EU, 0x11D1U, 0xB3U, 0xE9U,
796                                    0x00U, 0x80U, 0x5FU, 0x49U, 0x9DU, 0x93U );
797 
798             bIsApplet = aJavaCID == aCID;
799         }
800     }
801 
802     if( !bIsApplet )
803     {
804         m_pAppletImpl.reset();
805         return;
806     }
807 
808     m_pAppletImpl->SetAltText( aStandBy );
809 
810     SfxItemSet aItemSet( m_xDoc->GetAttrPool(), m_pCSS1Parser->GetWhichMap() );
811     SvxCSS1PropertyInfo aPropInfo;
812     if( HasStyleOptions( aStyle, aId, aClass ) )
813         ParseStyleOptions( aStyle, aId, aClass, aItemSet, aPropInfo );
814 
815     SfxItemSet& rFrameSet = m_pAppletImpl->GetItemSet();
816     if( !IsNewDoc() )
817         Reader::ResetFrameFormatAttrs( rFrameSet );
818 
819     // set the anchor and the adjustment
820     SetAnchorAndAdjustment( eVertOri, eHoriOri, aPropInfo, rFrameSet );
821 
822     // and still the size of the frame
823     Size aDfltSz( HTML_DFLT_APPLET_WIDTH, HTML_DFLT_APPLET_HEIGHT );
824     SetFixSize( aSize, aDfltSz, bPercentWidth, bPercentHeight, aPropInfo, rFrameSet );
825     SetSpace( aSpace, aItemSet, aPropInfo, rFrameSet );
826 }
827 #endif
828 
EndObject()829 void SwHTMLParser::EndObject()
830 {
831 #if HAVE_FEATURE_JAVA
832     if( !m_pAppletImpl )
833         return;
834     if( !m_pAppletImpl->CreateApplet( m_sBaseURL ) )
835         return;
836 
837     m_pAppletImpl->FinishApplet();
838 
839     // and insert into the document
840     SwFrameFormat* pFlyFormat =
841         m_xDoc->getIDocumentContentOperations().InsertEmbObject(*m_pPam,
842                 ::svt::EmbeddedObjectRef( m_pAppletImpl->GetApplet(), embed::Aspects::MSOLE_CONTENT ),
843                 &m_pAppletImpl->GetItemSet() );
844 
845     // set the alternative name
846     SwNoTextNode *pNoTextNd =
847         m_xDoc->GetNodes()[ pFlyFormat->GetContent().GetContentIdx()
848                           ->GetIndex()+1 ]->GetNoTextNode();
849     pNoTextNd->SetTitle( m_pAppletImpl->GetAltText() );
850 
851     // if applicable create frames and register auto-bound frames
852     RegisterFlyFrame( pFlyFormat );
853 
854     m_pAppletImpl.reset();
855 #else
856     (void) this;                // Silence loplugin:staticmethods
857 #endif
858 }
859 
860 #if HAVE_FEATURE_JAVA
InsertApplet()861 void SwHTMLParser::InsertApplet()
862 {
863     OUString aCodeBase, aCode, aName, aAlt, aId, aStyle, aClass;
864     Size aSize( USHRT_MAX, USHRT_MAX );
865     Size aSpace( 0, 0 );
866     bool bPercentWidth = false, bPercentHeight = false, bMayScript = false;
867     sal_Int16 eVertOri = text::VertOrientation::TOP;
868     sal_Int16 eHoriOri = text::HoriOrientation::NONE;
869 
870     // create a new Command list
871     m_pAppletImpl.reset(new SwApplet_Impl( m_xDoc->GetAttrPool() ));
872 
873     const HTMLOptions& rHTMLOptions = GetOptions();
874     for (size_t i = rHTMLOptions.size(); i; )
875     {
876         const HTMLOption& rOption = rHTMLOptions[--i];
877         switch( rOption.GetToken() )
878         {
879         case HtmlOptionId::ID:
880             aId = rOption.GetString();
881             break;
882         case HtmlOptionId::STYLE:
883             aStyle = rOption.GetString();
884             break;
885         case HtmlOptionId::CLASS:
886             aClass = rOption.GetString();
887             break;
888         case HtmlOptionId::CODEBASE:
889             aCodeBase = rOption.GetString();
890             break;
891         case HtmlOptionId::CODE:
892             aCode = rOption.GetString();
893             break;
894         case HtmlOptionId::NAME:
895             aName = rOption.GetString();
896             break;
897         case HtmlOptionId::ALT:
898             aAlt = rOption.GetString();
899             break;
900         case HtmlOptionId::ALIGN:
901             eVertOri = rOption.GetEnum( aHTMLImgVAlignTable, eVertOri );
902             eHoriOri = rOption.GetEnum( aHTMLImgHAlignTable, eHoriOri );
903             break;
904         case HtmlOptionId::WIDTH:
905             bPercentWidth = (rOption.GetString().indexOf('%') != -1);
906             aSize.setWidth( static_cast<tools::Long>(rOption.GetNumber()) );
907             break;
908         case HtmlOptionId::HEIGHT:
909             bPercentHeight = (rOption.GetString().indexOf('%') != -1);
910             aSize.setHeight( static_cast<tools::Long>(rOption.GetNumber()) );
911             break;
912         case HtmlOptionId::HSPACE:
913             aSpace.setWidth( static_cast<tools::Long>(rOption.GetNumber()) );
914             break;
915         case HtmlOptionId::VSPACE:
916             aSpace.setHeight( static_cast<tools::Long>(rOption.GetNumber()) );
917             break;
918         case HtmlOptionId::MAYSCRIPT:
919             bMayScript = true;
920             break;
921         default: break;
922         }
923 
924         // All parameters are passed to the applet.
925         m_pAppletImpl->AppendParam( rOption.GetTokenString(),
926                                   rOption.GetString() );
927     }
928 
929     if( aCode.isEmpty() )
930     {
931         m_pAppletImpl.reset();
932         return;
933     }
934 
935     if ( !aCodeBase.isEmpty() )
936         aCodeBase = INetURLObject::GetAbsURL( m_sBaseURL, aCodeBase );
937     m_pAppletImpl->CreateApplet( aCode, aName, bMayScript, aCodeBase, m_sBaseURL );//, aAlt );
938     m_pAppletImpl->SetAltText( aAlt );
939 
940     SfxItemSet aItemSet( m_xDoc->GetAttrPool(), m_pCSS1Parser->GetWhichMap() );
941     SvxCSS1PropertyInfo aPropInfo;
942     if( HasStyleOptions( aStyle, aId, aClass ) )
943         ParseStyleOptions( aStyle, aId, aClass, aItemSet, aPropInfo );
944 
945     SfxItemSet& rFrameSet = m_pAppletImpl->GetItemSet();
946     if( !IsNewDoc() )
947         Reader::ResetFrameFormatAttrs( rFrameSet );
948 
949     // set the anchor and the adjustment
950     SetAnchorAndAdjustment( eVertOri, eHoriOri, aPropInfo, rFrameSet );
951 
952     // and still the size or the frame
953     Size aDfltSz( HTML_DFLT_APPLET_WIDTH, HTML_DFLT_APPLET_HEIGHT );
954     SetFixSize( aSize, aDfltSz, bPercentWidth, bPercentHeight, aPropInfo, rFrameSet );
955     SetSpace( aSpace, aItemSet, aPropInfo, rFrameSet );
956 }
957 #endif
958 
EndApplet()959 void SwHTMLParser::EndApplet()
960 {
961 #if HAVE_FEATURE_JAVA
962     if( !m_pAppletImpl )
963         return;
964 
965     m_pAppletImpl->FinishApplet();
966 
967     // and insert into the document
968     SwFrameFormat* pFlyFormat =
969         m_xDoc->getIDocumentContentOperations().InsertEmbObject(*m_pPam,
970                     ::svt::EmbeddedObjectRef( m_pAppletImpl->GetApplet(), embed::Aspects::MSOLE_CONTENT ),
971                     &m_pAppletImpl->GetItemSet());
972 
973     // set the alternative name
974     SwNoTextNode *pNoTextNd =
975         m_xDoc->GetNodes()[ pFlyFormat->GetContent().GetContentIdx()
976                           ->GetIndex()+1 ]->GetNoTextNode();
977     pNoTextNd->SetTitle( m_pAppletImpl->GetAltText() );
978 
979     // if applicable create frames and register auto-bound frames
980     RegisterFlyFrame( pFlyFormat );
981 
982     m_pAppletImpl.reset();
983 #else
984     (void) this;
985 #endif
986 }
987 
InsertParam()988 void SwHTMLParser::InsertParam()
989 {
990 #if HAVE_FEATURE_JAVA
991     if( !m_pAppletImpl )
992         return;
993 
994     OUString aName, aValue;
995 
996     const HTMLOptions& rHTMLOptions = GetOptions();
997     for (size_t i = rHTMLOptions.size(); i; )
998     {
999         const HTMLOption& rOption = rHTMLOptions[--i];
1000         switch( rOption.GetToken() )
1001         {
1002         case HtmlOptionId::NAME:
1003             aName = rOption.GetString();
1004             break;
1005         case HtmlOptionId::VALUE:
1006             aValue = rOption.GetString();
1007             break;
1008         default: break;
1009         }
1010     }
1011 
1012     if( aName.isEmpty() )
1013         return;
1014 
1015     m_pAppletImpl->AppendParam( aName, aValue );
1016 #else
1017     (void) this;
1018 #endif
1019 }
1020 
InsertFloatingFrame()1021 void SwHTMLParser::InsertFloatingFrame()
1022 {
1023     OUString aAlt, aId, aStyle, aClass;
1024     Size aSize( USHRT_MAX, USHRT_MAX );
1025     Size aSpace( 0, 0 );
1026     bool bPercentWidth = false, bPercentHeight = false;
1027     sal_Int16 eVertOri = text::VertOrientation::TOP;
1028     sal_Int16 eHoriOri = text::HoriOrientation::NONE;
1029 
1030     const HTMLOptions& rHTMLOptions = GetOptions();
1031 
1032     // First fetch the options of the Writer-Frame-Format
1033     for (const auto & rOption : rHTMLOptions)
1034     {
1035         switch( rOption.GetToken() )
1036         {
1037         case HtmlOptionId::ID:
1038             aId = rOption.GetString();
1039             break;
1040         case HtmlOptionId::STYLE:
1041             aStyle = rOption.GetString();
1042             break;
1043         case HtmlOptionId::CLASS:
1044             aClass = rOption.GetString();
1045             break;
1046         case HtmlOptionId::ALT:
1047             aAlt = rOption.GetString();
1048             break;
1049         case HtmlOptionId::ALIGN:
1050             eVertOri = rOption.GetEnum( aHTMLImgVAlignTable, eVertOri );
1051             eHoriOri = rOption.GetEnum( aHTMLImgHAlignTable, eHoriOri );
1052             break;
1053         case HtmlOptionId::WIDTH:
1054             bPercentWidth = (rOption.GetString().indexOf('%') != -1);
1055             aSize.setWidth( static_cast<tools::Long>(rOption.GetNumber()) );
1056             break;
1057         case HtmlOptionId::HEIGHT:
1058             bPercentHeight = (rOption.GetString().indexOf('%') != -1);
1059             aSize.setHeight( static_cast<tools::Long>(rOption.GetNumber()) );
1060             break;
1061         case HtmlOptionId::HSPACE:
1062             aSpace.setWidth( static_cast<tools::Long>(rOption.GetNumber()) );
1063             break;
1064         case HtmlOptionId::VSPACE:
1065             aSpace.setHeight( static_cast<tools::Long>(rOption.GetNumber()) );
1066             break;
1067         default: break;
1068         }
1069     }
1070 
1071     // and now the ones for the SfxFrame
1072     SfxFrameDescriptor aFrameDesc;
1073 
1074     SfxFrameHTMLParser::ParseFrameOptions( &aFrameDesc, rHTMLOptions, m_sBaseURL );
1075 
1076     // create a floating frame
1077     comphelper::EmbeddedObjectContainer aCnt;
1078     OUString aObjName;
1079     uno::Reference < embed::XEmbeddedObject > xObj = aCnt.CreateEmbeddedObject( SvGlobalName( SO3_IFRAME_CLASSID ).GetByteSequence(), aObjName );
1080 
1081     try
1082     {
1083         // TODO/MBA: testing
1084         if ( svt::EmbeddedObjectRef::TryRunningState( xObj ) )
1085         {
1086             uno::Reference < beans::XPropertySet > xSet( xObj->getComponent(), uno::UNO_QUERY );
1087             if ( xSet.is() )
1088             {
1089                 const OUString& aName = aFrameDesc.GetName();
1090                 ScrollingMode eScroll = aFrameDesc.GetScrollingMode();
1091                 bool bHasBorder = aFrameDesc.HasFrameBorder();
1092                 Size aMargin = aFrameDesc.GetMargin();
1093 
1094                 xSet->setPropertyValue("FrameURL", uno::makeAny( aFrameDesc.GetURL().GetMainURL( INetURLObject::DecodeMechanism::NONE ) ) );
1095                 xSet->setPropertyValue("FrameName", uno::makeAny( aName ) );
1096 
1097                 if ( eScroll == ScrollingMode::Auto )
1098                     xSet->setPropertyValue("FrameIsAutoScroll",
1099                         uno::makeAny( true ) );
1100                 else
1101                     xSet->setPropertyValue("FrameIsScrollingMode",
1102                         uno::makeAny( eScroll == ScrollingMode::Yes ) );
1103 
1104                 xSet->setPropertyValue("FrameIsBorder",
1105                         uno::makeAny( bHasBorder ) );
1106 
1107                 xSet->setPropertyValue("FrameMarginWidth",
1108                     uno::makeAny( sal_Int32( aMargin.Width() ) ) );
1109 
1110                 xSet->setPropertyValue("FrameMarginHeight",
1111                     uno::makeAny( sal_Int32( aMargin.Height() ) ) );
1112             }
1113         }
1114     }
1115     catch ( uno::Exception& )
1116     {
1117     }
1118 
1119     SfxItemSet aItemSet( m_xDoc->GetAttrPool(), m_pCSS1Parser->GetWhichMap() );
1120     SvxCSS1PropertyInfo aPropInfo;
1121     if( HasStyleOptions( aStyle, aId, aClass ) )
1122         ParseStyleOptions( aStyle, aId, aClass, aItemSet, aPropInfo );
1123 
1124     // fetch the ItemSet
1125     SfxItemSet aFrameSet( m_xDoc->GetAttrPool(),
1126                         svl::Items<RES_FRMATR_BEGIN, RES_FRMATR_END-1>{} );
1127     if( !IsNewDoc() )
1128         Reader::ResetFrameFormatAttrs( aFrameSet );
1129 
1130     // set the anchor and the adjustment
1131     SetAnchorAndAdjustment( eVertOri, eHoriOri, aPropInfo, aFrameSet );
1132 
1133     // and still the size of the frame
1134     Size aDfltSz( HTML_DFLT_APPLET_WIDTH, HTML_DFLT_APPLET_HEIGHT );
1135     SetFixSize( aSize, aDfltSz, bPercentWidth, bPercentHeight, aPropInfo, aFrameSet );
1136     SetSpace( aSpace, aItemSet, aPropInfo, aFrameSet );
1137 
1138     // and insert into the document
1139     SwFrameFormat* pFlyFormat =
1140         m_xDoc->getIDocumentContentOperations().InsertEmbObject(*m_pPam,
1141             ::svt::EmbeddedObjectRef(xObj, embed::Aspects::MSOLE_CONTENT),
1142             &aFrameSet);
1143 
1144     // set the alternative name
1145     SwNoTextNode *pNoTextNd =
1146         m_xDoc->GetNodes()[ pFlyFormat->GetContent().GetContentIdx()
1147                           ->GetIndex()+1 ]->GetNoTextNode();
1148     pNoTextNd->SetTitle( aAlt );
1149 
1150     // if applicable create frames and register auto-bound frames
1151     RegisterFlyFrame( pFlyFormat );
1152 
1153     m_bInFloatingFrame = true;
1154 }
1155 
GuessOLENodeFrameType(const SwNode & rNode)1156 sal_uInt16 SwHTMLWriter::GuessOLENodeFrameType( const SwNode& rNode )
1157 {
1158     SwOLEObj& rObj = const_cast<SwOLENode*>(rNode.GetOLENode())->GetOLEObj();
1159 
1160     SwHTMLFrameType eType = HTML_FRMTYPE_OLE;
1161 
1162     uno::Reference < embed::XClassifiedObject > xClass = rObj.GetOleRef();
1163     SvGlobalName aClass( xClass->getClassID() );
1164     if( aClass == SvGlobalName( SO3_PLUGIN_CLASSID ) )
1165     {
1166         eType = HTML_FRMTYPE_PLUGIN;
1167     }
1168     else if( aClass == SvGlobalName( SO3_IFRAME_CLASSID ) )
1169     {
1170         eType = HTML_FRMTYPE_IFRAME;
1171     }
1172 #if HAVE_FEATURE_JAVA
1173     else if( aClass == SvGlobalName( SO3_APPLET_CLASSID ) )
1174     {
1175         eType = HTML_FRMTYPE_APPLET;
1176     }
1177 #endif
1178 
1179     return static_cast< sal_uInt16 >(eType);
1180 }
1181 
OutHTML_FrameFormatOLENode(Writer & rWrt,const SwFrameFormat & rFrameFormat,bool bInCntnr)1182 Writer& OutHTML_FrameFormatOLENode( Writer& rWrt, const SwFrameFormat& rFrameFormat,
1183                                bool bInCntnr )
1184 {
1185     SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt);
1186 
1187     const SwFormatContent& rFlyContent = rFrameFormat.GetContent();
1188     sal_uLong nStt = rFlyContent.GetContentIdx()->GetIndex()+1;
1189     SwOLENode *pOLENd = rHTMLWrt.m_pDoc->GetNodes()[ nStt ]->GetOLENode();
1190 
1191     OSL_ENSURE( pOLENd, "OLE-Node expected" );
1192     if( !pOLENd )
1193         return rWrt;
1194 
1195     SwOLEObj &rObj = pOLENd->GetOLEObj();
1196 
1197     uno::Reference < embed::XEmbeddedObject > xObj( rObj.GetOleRef() );
1198     if ( !svt::EmbeddedObjectRef::TryRunningState( xObj ) )
1199         return rWrt;
1200 
1201     uno::Reference < beans::XPropertySet > xSet( xObj->getComponent(), uno::UNO_QUERY );
1202     bool bHiddenEmbed = false;
1203 
1204     if( !xSet.is() )
1205     {
1206         OSL_FAIL("Unknown Object" );
1207         return rWrt;
1208     }
1209 
1210     HtmlFrmOpts nFrameOpts;
1211 
1212     // if possible output a line break before the "object"
1213     if( rHTMLWrt.m_bLFPossible )
1214         rHTMLWrt.OutNewLine( true );
1215 
1216     if( !rFrameFormat.GetName().isEmpty() )
1217         rHTMLWrt.OutImplicitMark( rFrameFormat.GetName(),
1218                                   "ole" );
1219     uno::Any aAny;
1220     SvGlobalName aGlobName( xObj->getClassID() );
1221     OStringBuffer sOut;
1222     sOut.append('<');
1223     if( aGlobName == SvGlobalName( SO3_PLUGIN_CLASSID ) )
1224     {
1225         // first the plug-in specifics
1226         sOut.append(rHTMLWrt.GetNamespace() + OOO_STRING_SVTOOLS_HTML_embed);
1227 
1228         OUString aStr;
1229         OUString aURL;
1230         aAny = xSet->getPropertyValue("PluginURL");
1231         if( (aAny >>= aStr) && !aStr.isEmpty() )
1232         {
1233             aURL = URIHelper::simpleNormalizedMakeRelative( rWrt.GetBaseURL(),
1234                       aStr);
1235         }
1236 
1237         if( !aURL.isEmpty() )
1238         {
1239             sOut.append(" " OOO_STRING_SVTOOLS_HTML_O_src "=\"");
1240             rWrt.Strm().WriteOString( sOut.makeStringAndClear() );
1241             HTMLOutFuncs::Out_String( rWrt.Strm(), aURL, rHTMLWrt.m_eDestEnc, &rHTMLWrt.m_aNonConvertableCharacters );
1242             sOut.append('\"');
1243         }
1244 
1245         OUString aType;
1246         aAny = xSet->getPropertyValue("PluginMimeType");
1247         if( (aAny >>= aType) && !aType.isEmpty() )
1248         {
1249             sOut.append(" " OOO_STRING_SVTOOLS_HTML_O_type "=\"");
1250             rWrt.Strm().WriteOString( sOut.makeStringAndClear() );
1251             HTMLOutFuncs::Out_String( rWrt.Strm(), aType, rHTMLWrt.m_eDestEnc, &rHTMLWrt.m_aNonConvertableCharacters );
1252             sOut.append('\"');
1253         }
1254 
1255         if ((RndStdIds::FLY_AT_PARA == rFrameFormat.GetAnchor().GetAnchorId()) &&
1256             css::text::WrapTextMode_THROUGH == rFrameFormat.GetSurround().GetSurround() )
1257         {
1258             // A HIDDEN plug-in
1259             sOut.append(' ').append(OOO_STRING_SW_HTML_O_Hidden);
1260             nFrameOpts = HTML_FRMOPTS_HIDDEN_EMBED;
1261             bHiddenEmbed = true;
1262         }
1263         else
1264         {
1265             nFrameOpts = bInCntnr ? HTML_FRMOPTS_EMBED_CNTNR
1266                                 : HTML_FRMOPTS_EMBED;
1267         }
1268     }
1269     else if( aGlobName == SvGlobalName( SO3_APPLET_CLASSID ) )
1270     {
1271         // or the applet specifics
1272 
1273         sOut.append(rHTMLWrt.GetNamespace() + OOO_STRING_SVTOOLS_HTML_applet);
1274 
1275         // CODEBASE
1276         OUString aCd;
1277         aAny = xSet->getPropertyValue("AppletCodeBase");
1278         if( (aAny >>= aCd) && !aCd.isEmpty() )
1279         {
1280             OUString sCodeBase( URIHelper::simpleNormalizedMakeRelative(rWrt.GetBaseURL(), aCd) );
1281             if( !sCodeBase.isEmpty() )
1282             {
1283                 sOut.append(" " OOO_STRING_SVTOOLS_HTML_O_codebase "=\"");
1284                 rWrt.Strm().WriteOString( sOut.makeStringAndClear() );
1285                 HTMLOutFuncs::Out_String( rWrt.Strm(), sCodeBase, rHTMLWrt.m_eDestEnc, &rHTMLWrt.m_aNonConvertableCharacters );
1286                 sOut.append('\"');
1287             }
1288         }
1289 
1290         // CODE
1291         OUString aClass;
1292         aAny = xSet->getPropertyValue("AppletCode");
1293         aAny >>= aClass;
1294         sOut.append(" " OOO_STRING_SVTOOLS_HTML_O_code "=\"");
1295         rWrt.Strm().WriteOString( sOut.makeStringAndClear() );
1296         HTMLOutFuncs::Out_String( rWrt.Strm(), aClass, rHTMLWrt.m_eDestEnc, &rHTMLWrt.m_aNonConvertableCharacters );
1297         sOut.append('\"');
1298 
1299         // NAME
1300         OUString aAppletName;
1301         aAny = xSet->getPropertyValue("AppletName");
1302         aAny >>= aAppletName;
1303         if( !aAppletName.isEmpty() )
1304         {
1305             sOut.append(" " OOO_STRING_SVTOOLS_HTML_O_name "=\"");
1306             rWrt.Strm().WriteOString( sOut.makeStringAndClear() );
1307             HTMLOutFuncs::Out_String( rWrt.Strm(), aAppletName, rHTMLWrt.m_eDestEnc, &rHTMLWrt.m_aNonConvertableCharacters );
1308             sOut.append('\"');
1309         }
1310 
1311         bool bScript = false;
1312         aAny = xSet->getPropertyValue("AppletIsScript");
1313         aAny >>= bScript;
1314         if( bScript )
1315             sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_mayscript);
1316 
1317         nFrameOpts = bInCntnr ? HTML_FRMOPTS_APPLET_CNTNR
1318                             : HTML_FRMOPTS_APPLET;
1319     }
1320     else
1321     {
1322         // or the Floating-Frame specifics
1323 
1324         sOut.append(rHTMLWrt.GetNamespace() + OOO_STRING_SVTOOLS_HTML_iframe);
1325         rWrt.Strm().WriteOString( sOut.makeStringAndClear() );
1326 
1327         SfxFrameHTMLWriter::Out_FrameDescriptor( rWrt.Strm(), rWrt.GetBaseURL(),
1328                                         xSet,
1329                                         rHTMLWrt.m_eDestEnc,
1330                                         &rHTMLWrt.m_aNonConvertableCharacters );
1331 
1332         nFrameOpts = bInCntnr ? HTML_FRMOPTS_IFRAME_CNTNR
1333                             : HTML_FRMOPTS_IFRAME;
1334     }
1335 
1336     rWrt.Strm().WriteOString( sOut.makeStringAndClear() );
1337 
1338     // ALT, WIDTH, HEIGHT, HSPACE, VSPACE, ALIGN
1339     if( rHTMLWrt.IsHTMLMode( HTMLMODE_ABS_POS_FLY ) && !bHiddenEmbed )
1340         nFrameOpts |= HTML_FRMOPTS_OLE_CSS1;
1341     OString aEndTags = rHTMLWrt.OutFrameFormatOptions( rFrameFormat, pOLENd->GetTitle(), nFrameOpts );
1342     if( rHTMLWrt.IsHTMLMode( HTMLMODE_ABS_POS_FLY ) && !bHiddenEmbed )
1343         rHTMLWrt.OutCSS1_FrameFormatOptions( rFrameFormat, nFrameOpts );
1344 
1345     if( aGlobName == SvGlobalName( SO3_APPLET_CLASSID ) )
1346     {
1347         // output the parameters of applets as separate tags
1348         // and write a </APPLET>
1349 
1350         uno::Sequence < beans::PropertyValue > aProps;
1351         aAny = xSet->getPropertyValue("AppletCommands");
1352         aAny >>= aProps;
1353 
1354         SvCommandList aCommands;
1355         aCommands.FillFromSequence( aProps );
1356         std::vector<sal_uLong> aParams;
1357         size_t i = aCommands.size();
1358         while( i > 0 )
1359         {
1360             const SvCommand& rCommand = aCommands[ --i ];
1361             const OUString& rName = rCommand.GetCommand();
1362             SwHtmlOptType nType = SwApplet_Impl::GetOptionType( rName, true );
1363             if( SwHtmlOptType::TAG == nType )
1364             {
1365                 const OUString& rValue = rCommand.GetArgument();
1366                 rWrt.Strm().WriteChar( ' ' );
1367                 HTMLOutFuncs::Out_String( rWrt.Strm(), rName, rHTMLWrt.m_eDestEnc, &rHTMLWrt.m_aNonConvertableCharacters );
1368                 rWrt.Strm().WriteCharPtr( "=\"" );
1369                 HTMLOutFuncs::Out_String( rWrt.Strm(), rValue, rHTMLWrt.m_eDestEnc, &rHTMLWrt.m_aNonConvertableCharacters ).WriteChar( '\"' );
1370             }
1371             else if( SwHtmlOptType::PARAM == nType )
1372             {
1373                 aParams.push_back( i );
1374             }
1375         }
1376 
1377         rHTMLWrt.Strm().WriteChar( '>' );
1378 
1379         rHTMLWrt.IncIndentLevel(); // indent the applet content
1380 
1381         size_t ii = aParams.size();
1382         while( ii > 0  )
1383         {
1384             const SvCommand& rCommand = aCommands[ aParams[--ii] ];
1385             const OUString& rName = rCommand.GetCommand();
1386             const OUString& rValue = rCommand.GetArgument();
1387             rHTMLWrt.OutNewLine();
1388             OStringBuffer sBuf;
1389             sBuf.append("<" + rHTMLWrt.GetNamespace() + OOO_STRING_SVTOOLS_HTML_param
1390                     " " OOO_STRING_SVTOOLS_HTML_O_name
1391                     "=\"");
1392             rWrt.Strm().WriteOString( sBuf.makeStringAndClear() );
1393             HTMLOutFuncs::Out_String( rWrt.Strm(), rName, rHTMLWrt.m_eDestEnc, &rHTMLWrt.m_aNonConvertableCharacters );
1394             sBuf.append("\" " OOO_STRING_SVTOOLS_HTML_O_value "=\"");
1395             rWrt.Strm().WriteOString( sBuf.makeStringAndClear() );
1396             HTMLOutFuncs::Out_String( rWrt.Strm(), rValue, rHTMLWrt.m_eDestEnc, &rHTMLWrt.m_aNonConvertableCharacters ).WriteCharPtr( "\">" );
1397         }
1398 
1399         rHTMLWrt.DecIndentLevel(); // indent the applet content
1400         if( aCommands.size() )
1401             rHTMLWrt.OutNewLine();
1402         HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OString(rHTMLWrt.GetNamespace() + OOO_STRING_SVTOOLS_HTML_applet), false );
1403     }
1404     else if( aGlobName == SvGlobalName( SO3_PLUGIN_CLASSID ) )
1405     {
1406         // write plug-ins parameters as options
1407 
1408         uno::Sequence < beans::PropertyValue > aProps;
1409         aAny = xSet->getPropertyValue("PluginCommands");
1410         aAny >>= aProps;
1411 
1412         SvCommandList aCommands;
1413         aCommands.FillFromSequence( aProps );
1414         for( size_t i = 0; i < aCommands.size(); i++ )
1415         {
1416             const SvCommand& rCommand = aCommands[ i ];
1417             const OUString& rName = rCommand.GetCommand();
1418 
1419             if( SwApplet_Impl::GetOptionType( rName, false ) == SwHtmlOptType::TAG )
1420             {
1421                 const OUString& rValue = rCommand.GetArgument();
1422                 rWrt.Strm().WriteChar( ' ' );
1423                 HTMLOutFuncs::Out_String( rWrt.Strm(), rName, rHTMLWrt.m_eDestEnc, &rHTMLWrt.m_aNonConvertableCharacters );
1424                 rWrt.Strm().WriteCharPtr( "=\"" );
1425                 HTMLOutFuncs::Out_String( rWrt.Strm(), rValue, rHTMLWrt.m_eDestEnc, &rHTMLWrt.m_aNonConvertableCharacters ).WriteChar( '\"' );
1426             }
1427         }
1428         rHTMLWrt.Strm().WriteChar( '>' );
1429     }
1430     else
1431     {
1432         // and for Floating-Frames just output another </IFRAME>
1433 
1434         rHTMLWrt.Strm().WriteChar( '>' );
1435         HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OString(rHTMLWrt.GetNamespace() + OOO_STRING_SVTOOLS_HTML_iframe), false );
1436     }
1437 
1438     if( !aEndTags.isEmpty() )
1439         rWrt.Strm().WriteOString( aEndTags );
1440 
1441     return rWrt;
1442 }
1443 
OutHTML_FrameFormatOLENodeGrf(Writer & rWrt,const SwFrameFormat & rFrameFormat,bool bInCntnr)1444 Writer& OutHTML_FrameFormatOLENodeGrf( Writer& rWrt, const SwFrameFormat& rFrameFormat,
1445                                   bool bInCntnr )
1446 {
1447     SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt);
1448 
1449     const SwFormatContent& rFlyContent = rFrameFormat.GetContent();
1450     sal_uLong nStt = rFlyContent.GetContentIdx()->GetIndex()+1;
1451     SwOLENode *pOLENd = rHTMLWrt.m_pDoc->GetNodes()[ nStt ]->GetOLENode();
1452 
1453     OSL_ENSURE( pOLENd, "OLE-Node expected" );
1454     if( !pOLENd )
1455         return rWrt;
1456 
1457     if (rHTMLWrt.mbSkipImages)
1458     {
1459         // If we skip images, embedded objects would be completely lost.
1460         // Instead, try to use the HTML export of the embedded object.
1461         uno::Reference<text::XTextContent> xTextContent = SwXTextEmbeddedObject::CreateXTextEmbeddedObject(*rHTMLWrt.m_pDoc, const_cast<SwFrameFormat*>(&rFrameFormat));
1462         uno::Reference<document::XEmbeddedObjectSupplier2> xEmbeddedObjectSupplier(xTextContent, uno::UNO_QUERY);
1463         uno::Reference<frame::XStorable> xStorable(xEmbeddedObjectSupplier->getEmbeddedObject(), uno::UNO_QUERY);
1464         SAL_WARN_IF(!xStorable.is(), "sw.html", "OutHTML_FrameFormatOLENodeGrf: no embedded object");
1465 
1466         // Figure out what is the filter name of the embedded object.
1467         uno::Reference<lang::XServiceInfo> xServiceInfo(xStorable, uno::UNO_QUERY);
1468         OUString aFilter;
1469         if (xServiceInfo.is())
1470         {
1471             if (xServiceInfo->supportsService("com.sun.star.sheet.SpreadsheetDocument"))
1472                 aFilter = "HTML (StarCalc)";
1473             else if (xServiceInfo->supportsService("com.sun.star.text.TextDocument"))
1474                 aFilter = "HTML (StarWriter)";
1475         }
1476 
1477         if (xStorable.is() && !aFilter.isEmpty())
1478         {
1479             try
1480             {
1481                 // FIXME: exception for the simplest test document, too
1482                 SvMemoryStream aStream;
1483                 uno::Reference<io::XOutputStream> xOutputStream(new utl::OStreamWrapper(aStream));
1484                 utl::MediaDescriptor aMediaDescriptor;
1485                 aMediaDescriptor["FilterName"] <<= aFilter;
1486                 aMediaDescriptor["FilterOptions"] <<= OUString("SkipHeaderFooter");
1487                 aMediaDescriptor["OutputStream"] <<= xOutputStream;
1488                 xStorable->storeToURL("private:stream", aMediaDescriptor.getAsConstPropertyValueList());
1489                 SAL_WARN_IF(aStream.GetSize()>=o3tl::make_unsigned(SAL_MAX_INT32), "sw.html", "Stream can't fit in OString");
1490                 OString aData(static_cast<const char*>(aStream.GetData()), static_cast<sal_Int32>(aStream.GetSize()));
1491                 // Wrap output in a <span> tag to avoid 'HTML parser error: Unexpected end tag: p'
1492                 HTMLOutFuncs::Out_AsciiTag(rWrt.Strm(), OString(rHTMLWrt.GetNamespace() + OOO_STRING_SVTOOLS_HTML_span));
1493                 rWrt.Strm().WriteOString(aData);
1494                 HTMLOutFuncs::Out_AsciiTag(rWrt.Strm(), OString(rHTMLWrt.GetNamespace() + OOO_STRING_SVTOOLS_HTML_span), false);
1495             }
1496             catch ( uno::Exception& )
1497             {
1498             }
1499         }
1500 
1501         return rWrt;
1502     }
1503 
1504     if ( !pOLENd->GetGraphic() )
1505     {
1506         SAL_WARN("sw.html", "Unexpected missing OLE fallback graphic");
1507         return rWrt;
1508     }
1509 
1510     Graphic aGraphic( *pOLENd->GetGraphic() );
1511 
1512     SwDocShell* pDocSh = rHTMLWrt.m_pDoc->GetDocShell();
1513     bool bObjectOpened = false;
1514     OUString aRTFType = "text/rtf";
1515     if (!rHTMLWrt.m_aRTFOLEMimeType.isEmpty())
1516     {
1517         aRTFType = rHTMLWrt.m_aRTFOLEMimeType;
1518     }
1519 
1520     if (rHTMLWrt.mbXHTML && pDocSh)
1521     {
1522         // Map native data to an outer <object> element.
1523 
1524         // Calculate the file name, which is meant to be the same as the
1525         // replacement image, just with a .ole extension.
1526         OUString aFileName = lcl_CalculateFileName(rHTMLWrt.GetOrigFileName(), aGraphic, u"ole");
1527 
1528         // Write the data.
1529         SwOLEObj& rOLEObj = pOLENd->GetOLEObj();
1530         uno::Reference<embed::XEmbeddedObject> xEmbeddedObject = rOLEObj.GetOleRef();
1531         OUString aFileType;
1532         SvFileStream aOutStream(aFileName, StreamMode::WRITE);
1533         uno::Reference<io::XActiveDataStreamer> xStreamProvider;
1534         uno::Reference<embed::XEmbedPersist2> xOwnEmbedded;
1535         if (xEmbeddedObject.is())
1536         {
1537             xStreamProvider.set(xEmbeddedObject, uno::UNO_QUERY);
1538             xOwnEmbedded.set(xEmbeddedObject, uno::UNO_QUERY);
1539         }
1540         if (xStreamProvider.is())
1541         {
1542             // Real OLE2 case: OleEmbeddedObject.
1543             uno::Reference<io::XInputStream> xStream(xStreamProvider->getStream(), uno::UNO_QUERY);
1544             if (xStream.is())
1545             {
1546                 std::unique_ptr<SvStream> pStream(utl::UcbStreamHelper::CreateStream(xStream));
1547                 if (SwReqIfReader::WrapOleInRtf(*pStream, aOutStream, *pOLENd, rFrameFormat))
1548                 {
1549                     // Data always wrapped in RTF.
1550                     aFileType = aRTFType;
1551                 }
1552             }
1553         }
1554         else if (xOwnEmbedded.is())
1555         {
1556             // Our own embedded object: OCommonEmbeddedObject.
1557             SvxMSExportOLEObjects aOLEExp(0);
1558             // Trigger the load of the OLE object if needed, otherwise we can't
1559             // export it.
1560             pOLENd->GetTwipSize();
1561             SvMemoryStream aMemory;
1562             tools::SvRef<SotStorage> pStorage = new SotStorage(aMemory);
1563             aOLEExp.ExportOLEObject(rOLEObj.GetObject(), *pStorage);
1564             pStorage->Commit();
1565             aMemory.Seek(0);
1566             if (SwReqIfReader::WrapOleInRtf(aMemory, aOutStream, *pOLENd, rFrameFormat))
1567             {
1568                 // Data always wrapped in RTF.
1569                 aFileType = aRTFType;
1570             }
1571         }
1572         else
1573         {
1574             // Otherwise the native data is just a grab-bag: ODummyEmbeddedObject.
1575             const OUString& aStreamName = rOLEObj.GetCurrentPersistName();
1576             uno::Reference<embed::XStorage> xStorage = pDocSh->GetStorage();
1577             uno::Reference<io::XStream> xInStream;
1578             try
1579             {
1580                 // Even the native data may be missing.
1581                 xInStream = xStorage->openStreamElement(aStreamName, embed::ElementModes::READ);
1582             } catch (const uno::Exception&)
1583             {
1584                 TOOLS_WARN_EXCEPTION("sw.html", "OutHTML_FrameFormatOLENodeGrf: failed to open stream element");
1585             }
1586             if (xInStream.is())
1587             {
1588                 uno::Reference<io::XStream> xOutStream(new utl::OStreamWrapper(aOutStream));
1589                 comphelper::OStorageHelper::CopyInputToOutput(xInStream->getInputStream(),
1590                                                               xOutStream->getOutputStream());
1591             }
1592 
1593             uno::Reference<beans::XPropertySet> xOutStreamProps(xInStream, uno::UNO_QUERY);
1594             if (xOutStreamProps.is())
1595                 xOutStreamProps->getPropertyValue("MediaType") >>= aFileType;
1596             if (!aRTFType.isEmpty())
1597             {
1598                 aFileType = aRTFType;
1599             }
1600         }
1601         aFileName = URIHelper::simpleNormalizedMakeRelative(rWrt.GetBaseURL(), aFileName);
1602 
1603         // Refer to this data.
1604         if (rHTMLWrt.m_bLFPossible)
1605             rHTMLWrt.OutNewLine();
1606         rWrt.Strm().WriteOString(OString("<" + rHTMLWrt.GetNamespace() + OOO_STRING_SVTOOLS_HTML_object));
1607         rWrt.Strm().WriteOString(OString(" data=\"" + aFileName.toUtf8() + "\""));
1608         if (!aFileType.isEmpty())
1609             rWrt.Strm().WriteOString(OString(" type=\"" + aFileType.toUtf8() + "\""));
1610         rWrt.Strm().WriteOString(">");
1611         bObjectOpened = true;
1612         rHTMLWrt.m_bLFPossible = true;
1613     }
1614 
1615     OUString aGraphicURL;
1616     OUString aMimeType;
1617     if(!rHTMLWrt.mbEmbedImages)
1618     {
1619         const OUString* pTempFileName = rHTMLWrt.GetOrigFileName();
1620         if(pTempFileName)
1621             aGraphicURL = *pTempFileName;
1622 
1623         OUString aFilterName("JPG");
1624         XOutFlags nFlags = XOutFlags::UseGifIfPossible | XOutFlags::UseNativeIfPossible;
1625 
1626         if (bObjectOpened)
1627         {
1628             aFilterName = "PNG";
1629             nFlags = XOutFlags::NONE;
1630             aMimeType = "image/png";
1631 
1632             if (aGraphic.GetType() == GraphicType::NONE)
1633             {
1634                 // The OLE Object has no replacement image, write a stub.
1635                 aGraphicURL = lcl_CalculateFileName(rHTMLWrt.GetOrigFileName(), aGraphic, u"png");
1636                 osl::File aFile(aGraphicURL);
1637                 aFile.open(osl_File_OpenFlag_Create);
1638                 aFile.close();
1639             }
1640         }
1641 
1642         ErrCode nErr = XOutBitmap::WriteGraphic( aGraphic, aGraphicURL,
1643                                     aFilterName,
1644                                     nFlags );
1645         if( nErr )              // error, don't write anything
1646         {
1647             rHTMLWrt.m_nWarn = WARN_SWG_POOR_LOAD;
1648             return rWrt;
1649         }
1650         aGraphicURL = URIHelper::SmartRel2Abs(
1651             INetURLObject(rWrt.GetBaseURL()), aGraphicURL,
1652             URIHelper::GetMaybeFileHdl() );
1653 
1654     }
1655     HtmlFrmOpts nFlags = bInCntnr ? HtmlFrmOpts::GenImgAllMask
1656         : HtmlFrmOpts::GenImgMask;
1657     if (bObjectOpened)
1658         nFlags |= HtmlFrmOpts::Replacement;
1659     HtmlWriter aHtml(rWrt.Strm(), rHTMLWrt.maNamespace);
1660     OutHTML_ImageStart( aHtml, rWrt, rFrameFormat, aGraphicURL, aGraphic,
1661             pOLENd->GetTitle(), pOLENd->GetTwipSize(),
1662             nFlags, "ole", nullptr, aMimeType );
1663     OutHTML_ImageEnd(aHtml, rWrt);
1664 
1665     if (bObjectOpened)
1666         // Close native data.
1667         rWrt.Strm().WriteOString(OString("</" + rHTMLWrt.GetNamespace() + OOO_STRING_SVTOOLS_HTML_object
1668                                  ">"));
1669 
1670     return rWrt;
1671 }
1672 
1673 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1674