1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 #include <tools/urlobj.hxx>
32 #include <sfx2/objsh.hxx>
33 #include <sfx2/docfile.hxx>
34 #include "openflag.hxx"
36 #include <svtools/htmlkywd.hxx>
37 #include <svtools/htmltokn.h>
38 #include <svtools/imap.hxx>
39 #include <svtools/imapcirc.hxx>
40 #include <svtools/imapobj.hxx>
41 #include <svtools/imappoly.hxx>
42 #include <svtools/imaprect.hxx>
43 #include <svl/zforlist.hxx>
44 #include <rtl/tencinfo.h>
45 #include <tools/tenccvt.hxx>
47 #include <sfx2/sfxhtml.hxx>
49 #include <com/sun/star/beans/XPropertyContainer.hpp>
50 #include <comphelper/string.hxx>
55 using namespace ::com::sun::star
;
58 sal_Char sHTML_MIME_text
[] = "text/";
59 sal_Char sHTML_MIME_application
[] = "application/";
60 sal_Char sHTML_MIME_experimental
[] = "x-";
63 static HTMLOptionEnum
const aAreaShapeOptEnums
[] =
65 { OOO_STRING_SVTOOLS_HTML_SH_rect
, IMAP_OBJ_RECTANGLE
},
66 { OOO_STRING_SVTOOLS_HTML_SH_rectangle
, IMAP_OBJ_RECTANGLE
},
67 { OOO_STRING_SVTOOLS_HTML_SH_circ
, IMAP_OBJ_CIRCLE
},
68 { OOO_STRING_SVTOOLS_HTML_SH_circle
, IMAP_OBJ_CIRCLE
},
69 { OOO_STRING_SVTOOLS_HTML_SH_poly
, IMAP_OBJ_POLYGON
},
70 { OOO_STRING_SVTOOLS_HTML_SH_polygon
, IMAP_OBJ_POLYGON
},
74 SfxHTMLParser::SfxHTMLParser( SvStream
& rStream
, sal_Bool bIsNewDoc
,
76 HTMLParser( rStream
, bIsNewDoc
),
77 pMedium( pMed
), pDLMedium( 0 ),
80 DBG_ASSERT( RTL_TEXTENCODING_UTF8
== GetSrcEncoding( ),
81 "SfxHTMLParser::SfxHTMLParser: From where comes ZS?" );
83 DBG_ASSERT( !IsSwitchToUCS2(),
84 "SfxHTMLParser::SfxHTMLParser: Switch to UCS2?" );
86 // If the file starts with a BOM, switch to UCS2.
87 SetSwitchToUCS2( sal_True
);
90 SfxHTMLParser::~SfxHTMLParser()
92 DBG_ASSERT( !pDLMedium
, "Here is a File Download that has got stuck" );
96 bool SfxHTMLParser::ParseMapOptions(
97 ImageMap
* pImageMap
, const HTMLOptions
& rOptions
)
99 DBG_ASSERT( pImageMap
, "ParseMapOptions: No Image-Map" );
103 for (size_t i
= rOptions
.size(); i
; )
105 const HTMLOption
& aOption
= rOptions
[--i
];
106 switch( aOption
.GetToken() )
109 aName
= aOption
.GetString();
115 pImageMap
->SetName( aName
);
117 return aName
.Len() > 0;
120 bool SfxHTMLParser::ParseAreaOptions(ImageMap
* pImageMap
, const String
& rBaseURL
,
121 const HTMLOptions
& rOptions
,
122 sal_uInt16 nEventMouseOver
,
123 sal_uInt16 nEventMouseOut
)
125 DBG_ASSERT( pImageMap
, "ParseAreaOptions: no Image-Map" );
127 sal_uInt16 nShape
= IMAP_OBJ_RECTANGLE
;
128 std::vector
<sal_uInt32
> aCoords
;
129 String aName
, aHRef
, aAlt
, aTarget
, sEmpty
;
130 sal_Bool bNoHRef
= sal_False
;
131 SvxMacroTableDtor aMacroTbl
;
133 for (size_t i
= rOptions
.size(); i
; )
135 sal_uInt16 nEvent
= 0;
136 ScriptType eScrpType
= STARBASIC
;
137 const HTMLOption
& rOption
= rOptions
[--i
];
138 switch( rOption
.GetToken() )
141 aName
= rOption
.GetString();
144 rOption
.GetEnum( nShape
, aAreaShapeOptEnums
);
147 rOption
.GetNumbers( aCoords
, true );
150 aHRef
= INetURLObject::GetAbsURL( rBaseURL
, rOption
.GetString() );
156 aAlt
= rOption
.GetString();
159 aTarget
= rOption
.GetString();
162 case HTML_O_ONMOUSEOVER
:
163 eScrpType
= JAVASCRIPT
;
164 case HTML_O_SDONMOUSEOVER
:
165 nEvent
= nEventMouseOver
;
166 goto IMAPOBJ_SETEVENT
;
168 case HTML_O_ONMOUSEOUT
:
169 eScrpType
= JAVASCRIPT
;
170 case HTML_O_SDONMOUSEOUT
:
171 nEvent
= nEventMouseOut
;
172 goto IMAPOBJ_SETEVENT
;
176 String
sTmp( rOption
.GetString() );
179 sTmp
= convertLineEnd(sTmp
, GetSystemLineEnd());
180 aMacroTbl
.Insert( nEvent
, SvxMacro( sTmp
, sEmpty
, eScrpType
));
190 sal_Bool bNewArea
= sal_True
;
193 case IMAP_OBJ_RECTANGLE
:
194 if( aCoords
.size() >=4 )
196 Rectangle
aRec( aCoords
[0], aCoords
[1],
197 aCoords
[2], aCoords
[3] );
198 IMapRectangleObject
aMapRObj( aRec
, aHRef
, aAlt
, String(), aTarget
, aName
,
200 if( !aMacroTbl
.empty() )
201 aMapRObj
.SetMacroTable( aMacroTbl
);
202 pImageMap
->InsertIMapObject( aMapRObj
);
205 case IMAP_OBJ_CIRCLE
:
206 if( aCoords
.size() >=3 )
208 Point
aPoint( aCoords
[0], aCoords
[1] );
209 IMapCircleObject
aMapCObj( aPoint
, aCoords
[2],aHRef
, aAlt
, String(),
210 aTarget
, aName
, !bNoHRef
);
211 if( !aMacroTbl
.empty() )
212 aMapCObj
.SetMacroTable( aMacroTbl
);
213 pImageMap
->InsertIMapObject( aMapCObj
);
216 case IMAP_OBJ_POLYGON
:
217 if( aCoords
.size() >=6 )
219 sal_uInt16 nCount
= aCoords
.size() / 2;
220 Polygon
aPoly( nCount
);
221 for( sal_uInt16 i
=0; i
<nCount
; i
++ )
222 aPoly
[i
] = Point( aCoords
[2*i
], aCoords
[2*i
+1] );
223 IMapPolygonObject
aMapPObj( aPoly
, aHRef
, aAlt
, String(), aTarget
, aName
,
225 if( !aMacroTbl
.empty() )
226 aMapPObj
.SetMacroTable( aMacroTbl
);
227 pImageMap
->InsertIMapObject( aMapPObj
);
231 bNewArea
= sal_False
;
238 void SfxHTMLParser::StartFileDownload( const String
& rURL
,
239 SfxObjectShell
*pSh
)
241 DBG_ASSERT( !pDLMedium
, "StartFileDownload when active Download" );
245 pDLMedium
= new SfxMedium( rURL
, SFX_STREAM_READONLY
);
248 // Register the medium, so that it can be stopped.
249 pSh
->RegisterTransfer( *pDLMedium
);
252 pDLMedium
->DownLoad();
255 sal_Bool
SfxHTMLParser::FinishFileDownload( String
& rStr
)
259 sal_Bool bOK
= pDLMedium
&& pDLMedium
->GetErrorCode()==0;
262 SvStream
* pStream
= pDLMedium
->GetInStream();
263 DBG_ASSERT( pStream
, "No In-Stream received from Medium" );
265 SvMemoryStream aStream
;
269 aStream
.Seek( STREAM_SEEK_TO_END
);
270 DBG_ASSERT( aStream
.Tell() < STRING_MAXLEN
,
271 "File too long for a string, cut off the end" );
272 xub_StrLen nLen
= aStream
.Tell() < STRING_MAXLEN
273 ? (xub_StrLen
)aStream
.Tell()
277 rtl::OString sBuffer
= read_uInt8s_ToOString(aStream
, nLen
);
287 void SfxHTMLParser::GetScriptType_Impl( SvKeyValueIterator
*pHTTPHeader
)
289 aScriptType
= DEFINE_CONST_UNICODE(SVX_MACRO_LANGUAGE_JAVASCRIPT
);
290 eScriptType
= JAVASCRIPT
;
294 for( sal_Bool bCont
= pHTTPHeader
->GetFirst( aKV
); bCont
;
295 bCont
= pHTTPHeader
->GetNext( aKV
) )
297 if( aKV
.GetKey().EqualsIgnoreCaseAscii(
298 OOO_STRING_SVTOOLS_HTML_META_content_script_type
) )
300 if( aKV
.GetValue().Len() )
302 String
aTmp( aKV
.GetValue() );
303 if( aTmp
.EqualsIgnoreCaseAscii( sHTML_MIME_text
, 0, 5 ) )
305 else if( aTmp
.EqualsIgnoreCaseAscii( sHTML_MIME_application
,
311 if( aTmp
.EqualsIgnoreCaseAscii( sHTML_MIME_experimental
, 0,
317 if( aTmp
.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_LG_starbasic
) )
319 eScriptType
= STARBASIC
;
320 aScriptType
= DEFINE_CONST_UNICODE(SVX_MACRO_LANGUAGE_STARBASIC
);
322 if( !aTmp
.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_LG_javascript
) )
324 eScriptType
= EXTENDED_STYPE
;
334 ScriptType
SfxHTMLParser::GetScriptType( SvKeyValueIterator
*pHTTPHeader
) const
336 if( !aScriptType
.Len() )
337 ((SfxHTMLParser
*)this)->GetScriptType_Impl( pHTTPHeader
);
342 const String
& SfxHTMLParser::GetScriptTypeString(
343 SvKeyValueIterator
*pHTTPHeader
) const
345 if( !aScriptType
.Len() )
346 ((SfxHTMLParser
*)this)->GetScriptType_Impl( pHTTPHeader
);
351 double SfxHTMLParser::GetTableDataOptionsValNum( sal_uInt32
& nNumForm
,
352 LanguageType
& eNumLang
, const String
& aValStr
, const String
& aNumStr
,
353 SvNumberFormatter
& rFormatter
)
355 LanguageType eParseLang
= (LanguageType
)aNumStr
.ToInt32();
356 sal_uInt32 nParseForm
=
357 rFormatter
.GetFormatForLanguageIfBuiltIn( 0, eParseLang
);
359 rFormatter
.IsNumberFormat( aValStr
, nParseForm
, fVal
);
360 if ( comphelper::string::getTokenCount(aNumStr
, ';') > 2 )
362 eNumLang
= (LanguageType
)aNumStr
.GetToken( 1, ';' ).ToInt32();
363 xub_StrLen nPos
= aNumStr
.Search( ';' );
364 nPos
= aNumStr
.Search( ';', nPos
+ 1 );
365 String
aFormat( aNumStr
.Copy( nPos
+ 1 ) );
366 xub_StrLen nCheckPos
;
368 if ( eNumLang
!= LANGUAGE_SYSTEM
)
369 rFormatter
.PutEntry( aFormat
, nCheckPos
, nType
, nNumForm
, eNumLang
);
371 rFormatter
.PutandConvertEntry( aFormat
, nCheckPos
, nType
, nNumForm
,
372 eParseLang
, eNumLang
);
376 eNumLang
= LANGUAGE_SYSTEM
;
377 nNumForm
= rFormatter
.GetFormatForLanguageIfBuiltIn( 0, eNumLang
);
382 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */