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 .
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>
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-";
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
},
65 SfxHTMLParser::SfxHTMLParser( SvStream
& rStream
, bool bIsNewDoc
,
67 : HTMLParser(rStream
, bIsNewDoc
)
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" );
88 bool SfxHTMLParser::ParseMapOptions(
89 ImageMap
* pImageMap
, const HTMLOptions
& rOptions
)
91 DBG_ASSERT( pImageMap
, "ParseMapOptions: No Image-Map" );
95 for (size_t i
= rOptions
.size(); i
; )
97 const HTMLOption
& aOption
= rOptions
[--i
];
98 switch( aOption
.GetToken() )
101 aName
= aOption
.GetString();
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() )
133 aName
= rOption
.GetString();
136 rOption
.GetEnum( nShape
, aAreaShapeOptEnums
);
139 rOption
.GetNumbers( aCoords
, true );
142 aHRef
= INetURLObject::GetAbsURL( rBaseURL
, rOption
.GetString() );
148 aAlt
= rOption
.GetString();
151 aTarget
= rOption
.GetString();
154 case HTML_O_ONMOUSEOVER
:
155 eScrpType
= JAVASCRIPT
;
157 case HTML_O_SDONMOUSEOVER
:
158 nEvent
= nEventMouseOver
;
159 goto IMAPOBJ_SETEVENT
;
161 case HTML_O_ONMOUSEOUT
:
162 eScrpType
= JAVASCRIPT
;
164 case HTML_O_SDONMOUSEOUT
:
165 nEvent
= nEventMouseOut
;
166 goto IMAPOBJ_SETEVENT
;
170 OUString
sTmp( rOption
.GetString() );
171 if( !sTmp
.isEmpty() )
173 sTmp
= convertLineEnd(sTmp
, GetSystemLineEnd());
174 aMacroTbl
.Insert( nEvent
, SvxMacro( sTmp
, sEmpty
, eScrpType
));
184 bool bNewArea
= true;
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
,
194 if( !aMacroTbl
.empty() )
195 aMapRObj
.SetMacroTable( aMacroTbl
);
196 pImageMap
->InsertIMapObject( aMapRObj
);
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
);
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
,
219 if( !aMacroTbl
.empty() )
220 aMapPObj
.SetMacroTable( aMacroTbl
);
221 pImageMap
->InsertIMapObject( aMapPObj
);
231 void SfxHTMLParser::StartFileDownload(const OUString
& rURL
)
233 DBG_ASSERT( !pDLMedium
, "StartFileDownload when active Download" );
237 pDLMedium
= new SfxMedium( rURL
, SFX_STREAM_READONLY
);
238 pDLMedium
->Download();
241 bool SfxHTMLParser::FinishFileDownload( OUString
& rStr
)
243 bool bOK
= pDLMedium
&& pDLMedium
->GetErrorCode()==0;
246 SvStream
* pStream
= pDLMedium
->GetInStream();
247 DBG_ASSERT( pStream
, "No In-Stream received from Medium" );
249 SvMemoryStream aStream
;
251 aStream
.WriteStream( *pStream
);
253 aStream
.Seek( STREAM_SEEK_TO_END
);
254 sal_Size nLen
= aStream
.Tell();
256 OString sBuffer
= read_uInt8s_ToOString(aStream
, nLen
);
257 rStr
= OStringToOUString( sBuffer
, RTL_TEXTENCODING_UTF8
);
266 void SfxHTMLParser::GetScriptType_Impl( SvKeyValueIterator
*pHTTPHeader
)
268 aScriptType
= SVX_MACRO_LANGUAGE_JAVASCRIPT
;
269 eScriptType
= JAVASCRIPT
;
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 );
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
;
311 ScriptType
SfxHTMLParser::GetScriptType( SvKeyValueIterator
*pHTTPHeader
) const
313 if( aScriptType
.isEmpty() )
314 const_cast<SfxHTMLParser
*>(this)->GetScriptType_Impl( pHTTPHeader
);
319 const OUString
& SfxHTMLParser::GetScriptTypeString(
320 SvKeyValueIterator
*pHTTPHeader
) const
322 if( aScriptType
.isEmpty() )
323 const_cast<SfxHTMLParser
*>(this)->GetScriptType_Impl( pHTTPHeader
);
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
);
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 ) );
344 if ( eNumLang
!= LANGUAGE_SYSTEM
)
345 rFormatter
.PutEntry( aFormat
, nCheckPos
, nType
, nNumForm
, eNumLang
);
347 rFormatter
.PutandConvertEntry( aFormat
, nCheckPos
, nType
, nNumForm
,
348 eParseLang
, eNumLang
);
352 eNumLang
= LANGUAGE_SYSTEM
;
353 nNumForm
= rFormatter
.GetFormatForLanguageIfBuiltIn( 0, eNumLang
);
358 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */