Branch libreoffice-5-0-4
[LibreOffice.git] / sfx2 / source / bastyp / sfxhtml.cxx
blob5335eca582f75e470b3b84cca04b438e955a23ff
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <tools/urlobj.hxx>
23 #include <sfx2/objsh.hxx>
24 #include <sfx2/docfile.hxx>
25 #include "openflag.hxx"
27 #include <svtools/htmlkywd.hxx>
28 #include <svtools/htmltokn.h>
29 #include <svtools/imap.hxx>
30 #include <svtools/imapcirc.hxx>
31 #include <svtools/imapobj.hxx>
32 #include <svtools/imappoly.hxx>
33 #include <svtools/imaprect.hxx>
34 #include <svl/zforlist.hxx>
35 #include <rtl/tencinfo.h>
36 #include <tools/tenccvt.hxx>
38 #include <sfx2/sfxhtml.hxx>
40 #include <com/sun/star/beans/XPropertyContainer.hpp>
41 #include <comphelper/string.hxx>
43 #include <vector>
46 using namespace ::com::sun::star;
49 const sal_Char sHTML_MIME_text[] = "text/";
50 const sal_Char sHTML_MIME_application[] = "application/";
51 const sal_Char sHTML_MIME_experimental[] = "x-";
53 // <INPUT TYPE=xxx>
54 static HTMLOptionEnum const aAreaShapeOptEnums[] =
56 { OOO_STRING_SVTOOLS_HTML_SH_rect, IMAP_OBJ_RECTANGLE },
57 { OOO_STRING_SVTOOLS_HTML_SH_rectangle, IMAP_OBJ_RECTANGLE },
58 { OOO_STRING_SVTOOLS_HTML_SH_circ, IMAP_OBJ_CIRCLE },
59 { OOO_STRING_SVTOOLS_HTML_SH_circle, IMAP_OBJ_CIRCLE },
60 { OOO_STRING_SVTOOLS_HTML_SH_poly, IMAP_OBJ_POLYGON },
61 { OOO_STRING_SVTOOLS_HTML_SH_polygon, IMAP_OBJ_POLYGON },
62 { 0, 0 }
65 SfxHTMLParser::SfxHTMLParser( SvStream& rStream, bool bIsNewDoc,
66 SfxMedium *pMed )
67 : HTMLParser(rStream, bIsNewDoc)
68 , pMedium(pMed)
69 , pDLMedium(0)
70 , eScriptType(STARBASIC)
72 DBG_ASSERT( RTL_TEXTENCODING_UTF8 == GetSrcEncoding( ),
73 "SfxHTMLParser::SfxHTMLParser: From where comes ZS?" );
75 DBG_ASSERT( !IsSwitchToUCS2(),
76 "SfxHTMLParser::SfxHTMLParser: Switch to UCS2?" );
78 // If the file starts with a BOM, switch to UCS2.
79 SetSwitchToUCS2( true );
82 SfxHTMLParser::~SfxHTMLParser()
84 DBG_ASSERT( !pDLMedium, "Here is a File Download that has got stuck" );
85 delete pDLMedium;
88 bool SfxHTMLParser::ParseMapOptions(
89 ImageMap* pImageMap, const HTMLOptions& rOptions)
91 DBG_ASSERT( pImageMap, "ParseMapOptions: No Image-Map" );
93 OUString aName;
95 for (size_t i = rOptions.size(); i; )
97 const HTMLOption& aOption = rOptions[--i];
98 switch( aOption.GetToken() )
100 case HTML_O_NAME:
101 aName = aOption.GetString();
102 break;
106 if( !aName.isEmpty() )
107 pImageMap->SetName( aName );
109 return !aName.isEmpty();
112 bool SfxHTMLParser::ParseAreaOptions(ImageMap * pImageMap, const OUString& rBaseURL,
113 const HTMLOptions& rOptions,
114 sal_uInt16 nEventMouseOver,
115 sal_uInt16 nEventMouseOut )
117 DBG_ASSERT( pImageMap, "ParseAreaOptions: no Image-Map" );
119 sal_uInt16 nShape = IMAP_OBJ_RECTANGLE;
120 std::vector<sal_uInt32> aCoords;
121 OUString aName, aHRef, aAlt, aTarget, sEmpty;
122 bool bNoHRef = false;
123 SvxMacroTableDtor aMacroTbl;
125 for (size_t i = rOptions.size(); i; )
127 sal_uInt16 nEvent = 0;
128 ScriptType eScrpType = STARBASIC;
129 const HTMLOption& rOption = rOptions[--i];
130 switch( rOption.GetToken() )
132 case HTML_O_NAME:
133 aName = rOption.GetString();
134 break;
135 case HTML_O_SHAPE:
136 rOption.GetEnum( nShape, aAreaShapeOptEnums );
137 break;
138 case HTML_O_COORDS:
139 rOption.GetNumbers( aCoords, true );
140 break;
141 case HTML_O_HREF:
142 aHRef = INetURLObject::GetAbsURL( rBaseURL, rOption.GetString() );
143 break;
144 case HTML_O_NOHREF:
145 bNoHRef = true;
146 break;
147 case HTML_O_ALT:
148 aAlt = rOption.GetString();
149 break;
150 case HTML_O_TARGET:
151 aTarget = rOption.GetString();
152 break;
154 case HTML_O_ONMOUSEOVER:
155 eScrpType = JAVASCRIPT;
156 //fallthrough
157 case HTML_O_SDONMOUSEOVER:
158 nEvent = nEventMouseOver;
159 goto IMAPOBJ_SETEVENT;
161 case HTML_O_ONMOUSEOUT:
162 eScrpType = JAVASCRIPT;
163 //fallthrough
164 case HTML_O_SDONMOUSEOUT:
165 nEvent = nEventMouseOut;
166 goto IMAPOBJ_SETEVENT;
167 IMAPOBJ_SETEVENT:
168 if( nEvent )
170 OUString sTmp( rOption.GetString() );
171 if( !sTmp.isEmpty() )
173 sTmp = convertLineEnd(sTmp, GetSystemLineEnd());
174 aMacroTbl.Insert( nEvent, SvxMacro( sTmp, sEmpty, eScrpType ));
177 break;
181 if( bNoHRef )
182 aHRef.clear();
184 bool bNewArea = true;
185 switch( nShape )
187 case IMAP_OBJ_RECTANGLE:
188 if( aCoords.size() >=4 )
190 Rectangle aRect( aCoords[0], aCoords[1],
191 aCoords[2], aCoords[3] );
192 IMapRectangleObject aMapRObj( aRect, aHRef, aAlt, OUString(), aTarget, aName,
193 !bNoHRef );
194 if( !aMacroTbl.empty() )
195 aMapRObj.SetMacroTable( aMacroTbl );
196 pImageMap->InsertIMapObject( aMapRObj );
198 break;
199 case IMAP_OBJ_CIRCLE:
200 if( aCoords.size() >=3 )
202 Point aPoint( aCoords[0], aCoords[1] );
203 IMapCircleObject aMapCObj( aPoint, aCoords[2],aHRef, aAlt, OUString(),
204 aTarget, aName, !bNoHRef );
205 if( !aMacroTbl.empty() )
206 aMapCObj.SetMacroTable( aMacroTbl );
207 pImageMap->InsertIMapObject( aMapCObj );
209 break;
210 case IMAP_OBJ_POLYGON:
211 if( aCoords.size() >=6 )
213 sal_uInt16 nCount = aCoords.size() / 2;
214 Polygon aPoly( nCount );
215 for( sal_uInt16 i=0; i<nCount; i++ )
216 aPoly[i] = Point( aCoords[2*i], aCoords[2*i+1] );
217 IMapPolygonObject aMapPObj( aPoly, aHRef, aAlt, OUString(), aTarget, aName,
218 !bNoHRef );
219 if( !aMacroTbl.empty() )
220 aMapPObj.SetMacroTable( aMacroTbl );
221 pImageMap->InsertIMapObject( aMapPObj );
223 break;
224 default:
225 bNewArea = false;
228 return bNewArea;
231 void SfxHTMLParser::StartFileDownload(const OUString& rURL)
233 DBG_ASSERT( !pDLMedium, "StartFileDownload when active Download" );
234 if( pDLMedium )
235 return;
237 pDLMedium = new SfxMedium( rURL, SFX_STREAM_READONLY );
238 pDLMedium->Download();
241 bool SfxHTMLParser::FinishFileDownload( OUString& rStr )
243 bool bOK = pDLMedium && pDLMedium->GetErrorCode()==0;
244 if( bOK )
246 SvStream* pStream = pDLMedium->GetInStream();
247 DBG_ASSERT( pStream, "No In-Stream received from Medium" );
249 SvMemoryStream aStream;
250 if( pStream )
251 aStream.WriteStream( *pStream );
253 aStream.Seek( STREAM_SEEK_TO_END );
254 sal_Size nLen = aStream.Tell();
255 aStream.Seek( 0 );
256 OString sBuffer = read_uInt8s_ToOString(aStream, nLen);
257 rStr = OStringToOUString( sBuffer, RTL_TEXTENCODING_UTF8 );
260 delete pDLMedium;
261 pDLMedium = 0;
263 return bOK;
266 void SfxHTMLParser::GetScriptType_Impl( SvKeyValueIterator *pHTTPHeader )
268 aScriptType = SVX_MACRO_LANGUAGE_JAVASCRIPT;
269 eScriptType = JAVASCRIPT;
270 if( pHTTPHeader )
272 SvKeyValue aKV;
273 for( bool bCont = pHTTPHeader->GetFirst( aKV ); bCont;
274 bCont = pHTTPHeader->GetNext( aKV ) )
276 if( aKV.GetKey().equalsIgnoreAsciiCase(
277 OOO_STRING_SVTOOLS_HTML_META_content_script_type ) )
279 if( !aKV.GetValue().isEmpty() )
281 OUString aTmp( aKV.GetValue() );
282 if( aTmp.startsWithIgnoreAsciiCase( sHTML_MIME_text ) )
283 aTmp = aTmp.copy( 5 );
284 else if( aTmp.startsWithIgnoreAsciiCase( sHTML_MIME_application ) )
285 aTmp = aTmp.copy( 12 );
286 else
287 break;
289 if( aTmp.startsWithIgnoreAsciiCase( sHTML_MIME_experimental ) )
291 aTmp = aTmp.copy( 2 );
294 if( aTmp.equalsIgnoreAsciiCase( OOO_STRING_SVTOOLS_HTML_LG_starbasic ) )
296 eScriptType = STARBASIC;
297 aScriptType = SVX_MACRO_LANGUAGE_STARBASIC;
299 if( !aTmp.equalsIgnoreAsciiCase( OOO_STRING_SVTOOLS_HTML_LG_javascript ) )
301 eScriptType = EXTENDED_STYPE;
302 aScriptType = aTmp;
305 break;
311 ScriptType SfxHTMLParser::GetScriptType( SvKeyValueIterator *pHTTPHeader ) const
313 if( aScriptType.isEmpty() )
314 const_cast<SfxHTMLParser *>(this)->GetScriptType_Impl( pHTTPHeader );
316 return eScriptType;
319 const OUString& SfxHTMLParser::GetScriptTypeString(
320 SvKeyValueIterator *pHTTPHeader ) const
322 if( aScriptType.isEmpty() )
323 const_cast<SfxHTMLParser *>(this)->GetScriptType_Impl( pHTTPHeader );
325 return aScriptType;
328 double SfxHTMLParser::GetTableDataOptionsValNum( sal_uInt32& nNumForm,
329 LanguageType& eNumLang, const OUString& aValStr, const OUString& aNumStr,
330 SvNumberFormatter& rFormatter )
332 LanguageType eParseLang = (LanguageType )aNumStr.toInt32();
333 sal_uInt32 nParseForm = rFormatter.GetFormatForLanguageIfBuiltIn( 0, eParseLang );
334 double fVal;
335 (void)rFormatter.IsNumberFormat(aValStr, nParseForm, fVal);
336 if ( comphelper::string::getTokenCount(aNumStr, ';') > 2 )
338 eNumLang = (LanguageType)aNumStr.getToken( 1, ';' ).toInt32();
339 sal_Int32 nPos = aNumStr.indexOf( ';' );
340 nPos = aNumStr.indexOf( ';', nPos + 1 );
341 OUString aFormat( aNumStr.copy( nPos + 1 ) );
342 sal_Int32 nCheckPos;
343 short nType;
344 if ( eNumLang != LANGUAGE_SYSTEM )
345 rFormatter.PutEntry( aFormat, nCheckPos, nType, nNumForm, eNumLang );
346 else
347 rFormatter.PutandConvertEntry( aFormat, nCheckPos, nType, nNumForm,
348 eParseLang, eNumLang );
350 else
352 eNumLang = LANGUAGE_SYSTEM;
353 nNumForm = rFormatter.GetFormatForLanguageIfBuiltIn( 0, eNumLang );
355 return fVal;
358 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */