Line data Source code
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 :
21 : #include <tools/urlobj.hxx>
22 :
23 : #include <sfx2/objsh.hxx>
24 : #include <sfx2/docfile.hxx>
25 : #include "openflag.hxx"
26 :
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>
37 :
38 : #include <sfx2/sfxhtml.hxx>
39 :
40 : #include <com/sun/star/beans/XPropertyContainer.hpp>
41 : #include <comphelper/string.hxx>
42 :
43 : #include <vector>
44 :
45 :
46 : using namespace ::com::sun::star;
47 :
48 :
49 : const sal_Char sHTML_MIME_text[] = "text/";
50 : const sal_Char sHTML_MIME_application[] = "application/";
51 : const sal_Char sHTML_MIME_experimental[] = "x-";
52 :
53 : // <INPUT TYPE=xxx>
54 : static HTMLOptionEnum const aAreaShapeOptEnums[] =
55 : {
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 }
63 : };
64 :
65 22 : SfxHTMLParser::SfxHTMLParser( SvStream& rStream, bool bIsNewDoc,
66 : SfxMedium *pMed )
67 : : HTMLParser(rStream, bIsNewDoc)
68 : , pMedium(pMed)
69 : , pDLMedium(0)
70 22 : , eScriptType(STARBASIC)
71 : {
72 : DBG_ASSERT( RTL_TEXTENCODING_UTF8 == GetSrcEncoding( ),
73 : "SfxHTMLParser::SfxHTMLParser: From where comes ZS?" );
74 :
75 : DBG_ASSERT( !IsSwitchToUCS2(),
76 : "SfxHTMLParser::SfxHTMLParser: Switch to UCS2?" );
77 :
78 : // If the file starts with a BOM, switch to UCS2.
79 22 : SetSwitchToUCS2( true );
80 22 : }
81 :
82 44 : SfxHTMLParser::~SfxHTMLParser()
83 : {
84 : DBG_ASSERT( !pDLMedium, "Here is a File Download that has got stuck" );
85 22 : delete pDLMedium;
86 22 : }
87 :
88 0 : bool SfxHTMLParser::ParseMapOptions(
89 : ImageMap* pImageMap, const HTMLOptions& rOptions)
90 : {
91 : DBG_ASSERT( pImageMap, "ParseMapOptions: No Image-Map" );
92 :
93 0 : OUString aName;
94 :
95 0 : for (size_t i = rOptions.size(); i; )
96 : {
97 0 : const HTMLOption& aOption = rOptions[--i];
98 0 : switch( aOption.GetToken() )
99 : {
100 : case HTML_O_NAME:
101 0 : aName = aOption.GetString();
102 0 : break;
103 : }
104 : }
105 :
106 0 : if( !aName.isEmpty() )
107 0 : pImageMap->SetName( aName );
108 :
109 0 : return !aName.isEmpty();
110 : }
111 :
112 0 : bool SfxHTMLParser::ParseAreaOptions(ImageMap * pImageMap, const OUString& rBaseURL,
113 : const HTMLOptions& rOptions,
114 : sal_uInt16 nEventMouseOver,
115 : sal_uInt16 nEventMouseOut )
116 : {
117 : DBG_ASSERT( pImageMap, "ParseAreaOptions: no Image-Map" );
118 :
119 0 : sal_uInt16 nShape = IMAP_OBJ_RECTANGLE;
120 0 : std::vector<sal_uInt32> aCoords;
121 0 : OUString aName, aHRef, aAlt, aTarget, sEmpty;
122 0 : bool bNoHRef = false;
123 0 : SvxMacroTableDtor aMacroTbl;
124 :
125 0 : for (size_t i = rOptions.size(); i; )
126 : {
127 0 : sal_uInt16 nEvent = 0;
128 0 : ScriptType eScrpType = STARBASIC;
129 0 : const HTMLOption& rOption = rOptions[--i];
130 0 : switch( rOption.GetToken() )
131 : {
132 : case HTML_O_NAME:
133 0 : aName = rOption.GetString();
134 0 : break;
135 : case HTML_O_SHAPE:
136 0 : rOption.GetEnum( nShape, aAreaShapeOptEnums );
137 0 : break;
138 : case HTML_O_COORDS:
139 0 : rOption.GetNumbers( aCoords, true );
140 0 : break;
141 : case HTML_O_HREF:
142 0 : aHRef = INetURLObject::GetAbsURL( rBaseURL, rOption.GetString() );
143 0 : break;
144 : case HTML_O_NOHREF:
145 0 : bNoHRef = true;
146 0 : break;
147 : case HTML_O_ALT:
148 0 : aAlt = rOption.GetString();
149 0 : break;
150 : case HTML_O_TARGET:
151 0 : aTarget = rOption.GetString();
152 0 : break;
153 :
154 : case HTML_O_ONMOUSEOVER:
155 0 : eScrpType = JAVASCRIPT;
156 : //fallthrough
157 : case HTML_O_SDONMOUSEOVER:
158 0 : nEvent = nEventMouseOver;
159 0 : goto IMAPOBJ_SETEVENT;
160 :
161 : case HTML_O_ONMOUSEOUT:
162 0 : eScrpType = JAVASCRIPT;
163 : //fallthrough
164 : case HTML_O_SDONMOUSEOUT:
165 0 : nEvent = nEventMouseOut;
166 0 : goto IMAPOBJ_SETEVENT;
167 : IMAPOBJ_SETEVENT:
168 0 : if( nEvent )
169 : {
170 0 : OUString sTmp( rOption.GetString() );
171 0 : if( !sTmp.isEmpty() )
172 : {
173 0 : sTmp = convertLineEnd(sTmp, GetSystemLineEnd());
174 0 : aMacroTbl.Insert( nEvent, SvxMacro( sTmp, sEmpty, eScrpType ));
175 0 : }
176 : }
177 0 : break;
178 : }
179 : }
180 :
181 0 : if( bNoHRef )
182 0 : aHRef = "";
183 :
184 0 : bool bNewArea = true;
185 0 : switch( nShape )
186 : {
187 : case IMAP_OBJ_RECTANGLE:
188 0 : if( aCoords.size() >=4 )
189 : {
190 0 : Rectangle aRect( aCoords[0], aCoords[1],
191 0 : aCoords[2], aCoords[3] );
192 : IMapRectangleObject aMapRObj( aRect, aHRef, aAlt, OUString(), aTarget, aName,
193 0 : !bNoHRef );
194 0 : if( !aMacroTbl.empty() )
195 0 : aMapRObj.SetMacroTable( aMacroTbl );
196 0 : pImageMap->InsertIMapObject( aMapRObj );
197 : }
198 0 : break;
199 : case IMAP_OBJ_CIRCLE:
200 0 : if( aCoords.size() >=3 )
201 : {
202 0 : Point aPoint( aCoords[0], aCoords[1] );
203 0 : IMapCircleObject aMapCObj( aPoint, aCoords[2],aHRef, aAlt, OUString(),
204 0 : aTarget, aName, !bNoHRef );
205 0 : if( !aMacroTbl.empty() )
206 0 : aMapCObj.SetMacroTable( aMacroTbl );
207 0 : pImageMap->InsertIMapObject( aMapCObj );
208 : }
209 0 : break;
210 : case IMAP_OBJ_POLYGON:
211 0 : if( aCoords.size() >=6 )
212 : {
213 0 : sal_uInt16 nCount = aCoords.size() / 2;
214 0 : Polygon aPoly( nCount );
215 0 : for( sal_uInt16 i=0; i<nCount; i++ )
216 0 : aPoly[i] = Point( aCoords[2*i], aCoords[2*i+1] );
217 : IMapPolygonObject aMapPObj( aPoly, aHRef, aAlt, OUString(), aTarget, aName,
218 0 : !bNoHRef );
219 0 : if( !aMacroTbl.empty() )
220 0 : aMapPObj.SetMacroTable( aMacroTbl );
221 0 : pImageMap->InsertIMapObject( aMapPObj );
222 : }
223 0 : break;
224 : default:
225 0 : bNewArea = false;
226 : }
227 :
228 0 : return bNewArea;
229 : }
230 :
231 0 : void SfxHTMLParser::StartFileDownload(const OUString& rURL)
232 : {
233 : DBG_ASSERT( !pDLMedium, "StartFileDownload when active Download" );
234 0 : if( pDLMedium )
235 0 : return;
236 :
237 0 : pDLMedium = new SfxMedium( rURL, SFX_STREAM_READONLY );
238 0 : pDLMedium->Download();
239 : }
240 :
241 0 : bool SfxHTMLParser::FinishFileDownload( OUString& rStr )
242 : {
243 0 : bool bOK = pDLMedium && pDLMedium->GetErrorCode()==0;
244 0 : if( bOK )
245 : {
246 0 : SvStream* pStream = pDLMedium->GetInStream();
247 : DBG_ASSERT( pStream, "No In-Stream received from Medium" );
248 :
249 0 : SvMemoryStream aStream;
250 0 : if( pStream )
251 0 : aStream.WriteStream( *pStream );
252 :
253 0 : aStream.Seek( STREAM_SEEK_TO_END );
254 0 : sal_Size nLen = aStream.Tell();
255 0 : aStream.Seek( 0 );
256 0 : OString sBuffer = read_uInt8s_ToOString(aStream, nLen);
257 0 : rStr = OStringToOUString( sBuffer, RTL_TEXTENCODING_UTF8 );
258 : }
259 :
260 0 : delete pDLMedium;
261 0 : pDLMedium = 0;
262 :
263 0 : return bOK;
264 : }
265 :
266 20 : void SfxHTMLParser::GetScriptType_Impl( SvKeyValueIterator *pHTTPHeader )
267 : {
268 20 : aScriptType = SVX_MACRO_LANGUAGE_JAVASCRIPT;
269 20 : eScriptType = JAVASCRIPT;
270 20 : if( pHTTPHeader )
271 : {
272 20 : SvKeyValue aKV;
273 54 : for( bool bCont = pHTTPHeader->GetFirst( aKV ); bCont;
274 34 : bCont = pHTTPHeader->GetNext( aKV ) )
275 : {
276 34 : if( aKV.GetKey().equalsIgnoreAsciiCase(
277 : OOO_STRING_SVTOOLS_HTML_META_content_script_type ) )
278 : {
279 0 : if( !aKV.GetValue().isEmpty() )
280 : {
281 0 : OUString aTmp( aKV.GetValue() );
282 0 : if( aTmp.startsWithIgnoreAsciiCase( sHTML_MIME_text ) )
283 0 : aTmp = aTmp.copy( 5 );
284 0 : else if( aTmp.startsWithIgnoreAsciiCase( sHTML_MIME_application ) )
285 0 : aTmp = aTmp.copy( 12 );
286 : else
287 0 : break;
288 :
289 0 : if( aTmp.startsWithIgnoreAsciiCase( sHTML_MIME_experimental ) )
290 : {
291 0 : aTmp = aTmp.copy( 2 );
292 : }
293 :
294 0 : if( aTmp.equalsIgnoreAsciiCase( OOO_STRING_SVTOOLS_HTML_LG_starbasic ) )
295 : {
296 0 : eScriptType = STARBASIC;
297 0 : aScriptType = SVX_MACRO_LANGUAGE_STARBASIC;
298 : }
299 0 : if( !aTmp.equalsIgnoreAsciiCase( OOO_STRING_SVTOOLS_HTML_LG_javascript ) )
300 : {
301 0 : eScriptType = EXTENDED_STYPE;
302 0 : aScriptType = aTmp;
303 0 : }
304 : }
305 0 : break;
306 : }
307 20 : }
308 : }
309 20 : }
310 :
311 50 : ScriptType SfxHTMLParser::GetScriptType( SvKeyValueIterator *pHTTPHeader ) const
312 : {
313 50 : if( aScriptType.isEmpty() )
314 20 : ((SfxHTMLParser *)this)->GetScriptType_Impl( pHTTPHeader );
315 :
316 50 : return eScriptType;
317 : }
318 :
319 50 : const OUString& SfxHTMLParser::GetScriptTypeString(
320 : SvKeyValueIterator *pHTTPHeader ) const
321 : {
322 50 : if( aScriptType.isEmpty() )
323 0 : ((SfxHTMLParser *)this)->GetScriptType_Impl( pHTTPHeader );
324 :
325 50 : return aScriptType;
326 : }
327 :
328 0 : double SfxHTMLParser::GetTableDataOptionsValNum( sal_uInt32& nNumForm,
329 : LanguageType& eNumLang, const OUString& aValStr, const OUString& aNumStr,
330 : SvNumberFormatter& rFormatter )
331 : {
332 0 : LanguageType eParseLang = (LanguageType )aNumStr.toInt32();
333 0 : sal_uInt32 nParseForm = rFormatter.GetFormatForLanguageIfBuiltIn( 0, eParseLang );
334 : double fVal;
335 0 : (void)rFormatter.IsNumberFormat(aValStr, nParseForm, fVal);
336 0 : if ( comphelper::string::getTokenCount(aNumStr, ';') > 2 )
337 : {
338 0 : eNumLang = (LanguageType)aNumStr.getToken( 1, ';' ).toInt32();
339 0 : sal_Int32 nPos = aNumStr.indexOf( ';' );
340 0 : nPos = aNumStr.indexOf( ';', nPos + 1 );
341 0 : OUString aFormat( aNumStr.copy( nPos + 1 ) );
342 : sal_Int32 nCheckPos;
343 : short nType;
344 0 : if ( eNumLang != LANGUAGE_SYSTEM )
345 0 : rFormatter.PutEntry( aFormat, nCheckPos, nType, nNumForm, eNumLang );
346 : else
347 : rFormatter.PutandConvertEntry( aFormat, nCheckPos, nType, nNumForm,
348 0 : eParseLang, eNumLang );
349 : }
350 : else
351 : {
352 0 : eNumLang = LANGUAGE_SYSTEM;
353 0 : nNumForm = rFormatter.GetFormatForLanguageIfBuiltIn( 0, eNumLang );
354 : }
355 0 : return fVal;
356 951 : }
357 :
358 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|