Update ooo320-m1
[ooovba.git] / sfx2 / source / bastyp / sfxhtml.cxx
blobeba014f8926031e2a8c6ac84a0569cd87485de8a
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: sfxhtml.cxx,v $
10 * $Revision: 1.23 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sfx2.hxx"
34 #include <tools/urlobj.hxx>
36 #include <sfx2/objsh.hxx>
37 #include <sfx2/docfile.hxx>
38 #include "openflag.hxx"
40 #include <svtools/htmlkywd.hxx>
41 #include <svtools/htmltokn.h>
42 #include <svtools/imap.hxx>
43 #include <svtools/imapcirc.hxx>
44 #include <svtools/imapobj.hxx>
45 #include <svtools/imappoly.hxx>
46 #include <svtools/imaprect.hxx>
47 #ifndef _SVSTDARR_ULONGS_DECL
48 #define _SVSTDARR_ULONGS
49 #include <svtools/svstdarr.hxx>
50 #endif
51 #include <svtools/zforlist.hxx>
52 #include <rtl/tencinfo.h>
53 #include <tools/tenccvt.hxx>
55 #include <sfx2/sfxhtml.hxx>
57 #include <com/sun/star/beans/XPropertyContainer.hpp>
60 using namespace ::com::sun::star;
63 sal_Char __FAR_DATA sHTML_MIME_text[] = "text/";
64 sal_Char __FAR_DATA sHTML_MIME_application[] = "application/";
65 sal_Char __FAR_DATA sHTML_MIME_experimental[] = "x-";
67 // <INPUT TYPE=xxx>
68 #ifdef __MINGW32__ // for runtime pseudo reloc
69 static HTMLOptionEnum aAreaShapeOptEnums[] =
70 #else
71 static HTMLOptionEnum __READONLY_DATA aAreaShapeOptEnums[] =
72 #endif
74 { OOO_STRING_SVTOOLS_HTML_SH_rect, IMAP_OBJ_RECTANGLE },
75 { OOO_STRING_SVTOOLS_HTML_SH_rectangle, IMAP_OBJ_RECTANGLE },
76 { OOO_STRING_SVTOOLS_HTML_SH_circ, IMAP_OBJ_CIRCLE },
77 { OOO_STRING_SVTOOLS_HTML_SH_circle, IMAP_OBJ_CIRCLE },
78 { OOO_STRING_SVTOOLS_HTML_SH_poly, IMAP_OBJ_POLYGON },
79 { OOO_STRING_SVTOOLS_HTML_SH_polygon, IMAP_OBJ_POLYGON },
80 { 0, 0 }
83 SfxHTMLParser::SfxHTMLParser( SvStream& rStream, BOOL bIsNewDoc,
84 SfxMedium *pMed ) :
85 HTMLParser( rStream, bIsNewDoc ),
86 pMedium( pMed ), pDLMedium( 0 ),
87 nMetaTags( 0 )
89 DBG_ASSERT( RTL_TEXTENCODING_DONTKNOW == GetSrcEncoding( ),
90 "SfxHTMLParser::SfxHTMLParser: Wo kommt der ZS her?" );
91 DBG_ASSERT( !IsSwitchToUCS2(),
92 "SfxHTMLParser::SfxHTMLParser: Switch to UCS2?" );
94 // Altough the real default encoding is ISO8859-1, we use MS-1252
95 // als default encoding.
96 SetSrcEncoding( GetExtendedCompatibilityTextEncoding( RTL_TEXTENCODING_ISO_8859_1 ) );
98 // If the file starts with a BOM, switch to UCS2.
99 SetSwitchToUCS2( TRUE );
102 __EXPORT SfxHTMLParser::~SfxHTMLParser()
104 DBG_ASSERT( !pDLMedium, "Da ist ein File-Download stehengeblieben" );
105 delete pDLMedium;
108 BOOL SfxHTMLParser::ParseMapOptions(ImageMap * pImageMap,
109 const HTMLOptions * pOptions)
111 DBG_ASSERT( pImageMap, "ParseMapOptions: keine Image-Map" );
112 DBG_ASSERT( pOptions, "ParseMapOptions: keine Optionen" );
114 String aName;
116 for( USHORT i=pOptions->Count(); i; )
118 const HTMLOption *pOption = (*pOptions)[--i];
119 switch( pOption->GetToken() )
121 case HTML_O_NAME:
122 aName = pOption->GetString();
123 break;
127 if( aName.Len() )
128 pImageMap->SetName( aName );
130 return aName.Len() > 0;
133 BOOL SfxHTMLParser::ParseAreaOptions(ImageMap * pImageMap, const String& rBaseURL,
134 const HTMLOptions * pOptions,
135 USHORT nEventMouseOver,
136 USHORT nEventMouseOut )
138 DBG_ASSERT( pImageMap, "ParseAreaOptions: keine Image-Map" );
139 DBG_ASSERT( pOptions, "ParseAreaOptions: keine Optionen" );
141 USHORT nShape = IMAP_OBJ_RECTANGLE;
142 SvULongs aCoords;
143 String aName, aHRef, aAlt, aTarget, sEmpty;
144 BOOL bNoHRef = FALSE;
145 SvxMacroTableDtor aMacroTbl;
147 for( USHORT i=pOptions->Count(); i; )
149 USHORT nEvent = 0;
150 ScriptType eScrpType = STARBASIC;
151 const HTMLOption *pOption = (*pOptions)[--i];
152 switch( pOption->GetToken() )
154 case HTML_O_NAME:
155 aName = pOption->GetString();
156 break;
157 case HTML_O_SHAPE:
158 pOption->GetEnum( nShape, aAreaShapeOptEnums );
159 break;
160 case HTML_O_COORDS:
161 pOption->GetNumbers( aCoords, TRUE );
162 break;
163 case HTML_O_HREF:
164 aHRef = INetURLObject::GetAbsURL( rBaseURL, pOption->GetString() );
165 break;
166 case HTML_O_NOHREF:
167 bNoHRef = TRUE;
168 break;
169 case HTML_O_ALT:
170 aAlt = pOption->GetString();
171 break;
172 case HTML_O_TARGET:
173 aTarget = pOption->GetString();
174 break;
176 case HTML_O_ONMOUSEOVER:
177 eScrpType = JAVASCRIPT;
178 case HTML_O_SDONMOUSEOVER:
179 nEvent = nEventMouseOver;
180 goto IMAPOBJ_SETEVENT;
182 case HTML_O_ONMOUSEOUT:
183 eScrpType = JAVASCRIPT;
184 case HTML_O_SDONMOUSEOUT:
185 nEvent = nEventMouseOut;
186 goto IMAPOBJ_SETEVENT;
187 IMAPOBJ_SETEVENT:
188 if( nEvent )
190 String sTmp( pOption->GetString() );
191 if( sTmp.Len() )
193 sTmp.ConvertLineEnd();
194 aMacroTbl.Insert( nEvent,
195 new SvxMacro( sTmp, sEmpty, eScrpType ));
198 break;
202 if( bNoHRef )
203 aHRef.Erase();
205 BOOL bNewArea = TRUE;
206 switch( nShape )
208 case IMAP_OBJ_RECTANGLE:
209 if( aCoords.Count() >=4 )
211 Rectangle aRec( aCoords[0], aCoords[1],
212 aCoords[2], aCoords[3] );
213 IMapRectangleObject aMapRObj( aRec, aHRef, aAlt, String(), aTarget, aName,
214 !bNoHRef );
215 if( aMacroTbl.Count() )
216 aMapRObj.SetMacroTable( aMacroTbl );
217 pImageMap->InsertIMapObject( aMapRObj );
219 break;
220 case IMAP_OBJ_CIRCLE:
221 if( aCoords.Count() >=3 )
223 Point aPoint( aCoords[0], aCoords[1] );
224 IMapCircleObject aMapCObj( aPoint, aCoords[2],aHRef, aAlt, String(),
225 aTarget, aName, !bNoHRef );
226 if( aMacroTbl.Count() )
227 aMapCObj.SetMacroTable( aMacroTbl );
228 pImageMap->InsertIMapObject( aMapCObj );
230 break;
231 case IMAP_OBJ_POLYGON:
232 if( aCoords.Count() >=6 )
234 USHORT nCount = aCoords.Count() / 2;
235 Polygon aPoly( nCount );
236 for( USHORT i=0; i<nCount; i++ )
237 aPoly[i] = Point( aCoords[2*i], aCoords[2*i+1] );
238 IMapPolygonObject aMapPObj( aPoly, aHRef, aAlt, String(), aTarget, aName,
239 !bNoHRef );
240 if( aMacroTbl.Count() )
241 aMapPObj.SetMacroTable( aMacroTbl );
242 pImageMap->InsertIMapObject( aMapPObj );
244 break;
245 default:
246 bNewArea = FALSE;
249 return bNewArea;
253 void SfxHTMLParser::StartFileDownload( const String& rURL, int nToken,
254 SfxObjectShell *pSh )
256 DBG_ASSERT( !pDLMedium, "StartFileDwonload bei aktivem Download" );
257 if( pDLMedium )
258 return;
260 pDLMedium = new SfxMedium( rURL, SFX_STREAM_READONLY, FALSE );
261 if( pSh )
263 // Medium registrieren, damit abgebrochen werden kann
264 pSh->RegisterTransfer( *pDLMedium );
266 // Target-Frame uebertragen, damit auch javascript:-URLs
267 // "geladen" werden koennen.
268 //const SfxMedium *pShMedium = pSh->GetMedium();
269 //if( pShMedium )
270 // pDLMedium->SetLoadTargetFrame( pShMedium->GetLoadTargetFrame() );
273 // Download anstossen (Achtung: Kann auch synchron sein).
274 if ( TRUE /*pMedium->GetDoneLink() == Link()*/ )
275 pDLMedium->DownLoad();
276 else
278 // Downloading-Flag auf TRUE setzen. Es werden dann auch
279 // Data-Available-Links, wenn wir in den Pending-Staus gelangen.
280 SetDownloadingFile( TRUE );
281 pDLMedium->DownLoad( STATIC_LINK( this, SfxHTMLParser, FileDownloadDone ) );
283 // Wenn das Dowsnloading-Flag noch gesetzt ist erfolgt der Download
284 // asynchron. Wir gehen dann in den Pedning-Staus und warten dort.
285 // Solange sind alle Aufrufe des Data-Avaialble-Link gesperrt.
286 if( IsDownloadingFile() )
288 // Den aktuellen Zustand einfrieren und in den Pending-Status gehen.
289 // Wenn der Download beendet oder abgebrochen wurde, wird ueber
290 // NewDataRead ein Continue mit dem uebergeben Token angesteossen.
291 SaveState( nToken );
292 eState = SVPAR_PENDING;
297 BOOL SfxHTMLParser::GetFileDownloadMIME( String& rMIME )
299 return pDLMedium && pDLMedium->GetErrorCode()==0 &&
300 pDLMedium->GetMIMEAndRedirect(rMIME)==0;
303 BOOL SfxHTMLParser::FinishFileDownload( String& rStr )
305 String aStr;
307 BOOL bOK = pDLMedium && pDLMedium->GetErrorCode()==0;
308 if( bOK )
310 SvStream* pStream = pDLMedium->GetInStream();
311 DBG_ASSERT( pStream, "Kein In-Stream vom Medium erhalten" );
313 SvMemoryStream aStream;
314 if( pStream ) // HACK wegen #65563#
315 aStream << *pStream;
317 aStream.Seek( STREAM_SEEK_TO_END );
318 DBG_ASSERT( aStream.Tell() < STRING_MAXLEN,
319 "File zu lang fuer einen String, Ende abgeschnitten" );
320 xub_StrLen nLen = aStream.Tell() < STRING_MAXLEN
321 ? (xub_StrLen)aStream.Tell()
322 : STRING_MAXLEN;
324 // TODO: untested!!!
325 rtl_TextEncoding eEnc =
326 GetExtendedCompatibilityTextEncoding( RTL_TEXTENCODING_ISO_8859_1 );
327 String sMime;
328 if( pDLMedium->GetMIMEAndRedirect( sMime ) == 0 )
330 rtl_TextEncoding eMimeEnc = GetEncodingByMIME( sMime );
331 if( RTL_TEXTENCODING_DONTKNOW != eMimeEnc )
332 eEnc = eMimeEnc;
335 ByteString sBuffer;
336 sal_Char* pBuffer = sBuffer.AllocBuffer(nLen);
337 aStream.Seek( 0 );
338 aStream.Read((void*)pBuffer, nLen);
339 rStr = String( S2U(pBuffer) );
342 delete pDLMedium;
343 pDLMedium = 0;
345 return bOK;
348 IMPL_STATIC_LINK( SfxHTMLParser, FileDownloadDone, void*, EMPTYARG )
350 // Der Download ist jetzt abgeschlossen. Ausserdem muss/darf der
351 // Data-Available-Link wieder durchgelassen werden.
352 pThis->SetDownloadingFile( FALSE );
354 // ... und einmal aufrufen, damit weitergelesen wird.
355 pThis->CallAsyncCallLink();
357 return 0;
360 rtl_TextEncoding SfxHTMLParser::GetEncodingByHttpHeader( SvKeyValueIterator *pHTTPHeader )
362 rtl_TextEncoding eRet = RTL_TEXTENCODING_DONTKNOW;
363 if( pHTTPHeader )
365 SvKeyValue aKV;
366 for( BOOL bCont = pHTTPHeader->GetFirst( aKV ); bCont;
367 bCont = pHTTPHeader->GetNext( aKV ) )
369 if( aKV.GetKey().EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_META_content_type ) )
371 if( aKV.GetValue().Len() )
373 eRet = SfxHTMLParser::GetEncodingByMIME( aKV.GetValue() );
378 return eRet;
381 BOOL SfxHTMLParser::SetEncodingByHTTPHeader(
382 SvKeyValueIterator *pHTTPHeader )
384 BOOL bRet = FALSE;
385 rtl_TextEncoding eEnc = SfxHTMLParser::GetEncodingByHttpHeader( pHTTPHeader );
386 if(RTL_TEXTENCODING_DONTKNOW != eEnc)
388 SetSrcEncoding( eEnc );
389 bRet = TRUE;
391 return bRet;
394 void SfxHTMLParser::GetScriptType_Impl( SvKeyValueIterator *pHTTPHeader )
396 aScriptType = DEFINE_CONST_UNICODE(SVX_MACRO_LANGUAGE_JAVASCRIPT);
397 eScriptType = JAVASCRIPT;
398 if( pHTTPHeader )
400 SvKeyValue aKV;
401 for( BOOL bCont = pHTTPHeader->GetFirst( aKV ); bCont;
402 bCont = pHTTPHeader->GetNext( aKV ) )
404 if( aKV.GetKey().EqualsIgnoreCaseAscii(
405 OOO_STRING_SVTOOLS_HTML_META_content_script_type ) )
407 if( aKV.GetValue().Len() )
409 String aTmp( aKV.GetValue() );
410 if( aTmp.EqualsIgnoreCaseAscii( sHTML_MIME_text, 0, 5 ) )
411 aTmp.Erase( 0, 5 );
412 else if( aTmp.EqualsIgnoreCaseAscii( sHTML_MIME_application,
413 0, 12 ) )
414 aTmp.Erase( 0, 12 );
415 else
416 break;
418 if( aTmp.EqualsIgnoreCaseAscii( sHTML_MIME_experimental, 0,
419 2 ) )
421 aTmp.Erase( 0, 2 );
424 if( aTmp.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_LG_starbasic ) )
426 eScriptType = STARBASIC;
427 aScriptType = DEFINE_CONST_UNICODE(SVX_MACRO_LANGUAGE_STARBASIC);
429 if( !aTmp.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_LG_javascript ) )
431 eScriptType = EXTENDED_STYPE;
432 aScriptType = aTmp;
435 break;
441 ScriptType SfxHTMLParser::GetScriptType( SvKeyValueIterator *pHTTPHeader ) const
443 if( !aScriptType.Len() )
444 ((SfxHTMLParser *)this)->GetScriptType_Impl( pHTTPHeader );
446 return eScriptType;
449 const String& SfxHTMLParser::GetScriptTypeString(
450 SvKeyValueIterator *pHTTPHeader ) const
452 if( !aScriptType.Len() )
453 ((SfxHTMLParser *)this)->GetScriptType_Impl( pHTTPHeader );
455 return aScriptType;
458 double SfxHTMLParser::GetTableDataOptionsValNum( sal_uInt32& nNumForm,
459 LanguageType& eNumLang, const String& aValStr, const String& aNumStr,
460 SvNumberFormatter& rFormatter )
462 LanguageType eParseLang = (LanguageType )aNumStr.ToInt32();
463 sal_uInt32 nParseForm =
464 rFormatter.GetFormatForLanguageIfBuiltIn( 0, eParseLang );
465 double fVal;
466 rFormatter.IsNumberFormat( aValStr, nParseForm, fVal );
467 if ( aNumStr.GetTokenCount( ';' ) > 2 )
469 eNumLang = (LanguageType)aNumStr.GetToken( 1, ';' ).ToInt32();
470 xub_StrLen nPos = aNumStr.Search( ';' );
471 nPos = aNumStr.Search( ';', nPos + 1 );
472 String aFormat( aNumStr.Copy( nPos + 1 ) );
473 xub_StrLen nCheckPos;
474 short nType;
475 if ( eNumLang != LANGUAGE_SYSTEM )
476 rFormatter.PutEntry( aFormat, nCheckPos, nType, nNumForm, eNumLang );
477 else
478 rFormatter.PutandConvertEntry( aFormat, nCheckPos, nType, nNumForm,
479 eParseLang, eNumLang );
481 else
483 eNumLang = LANGUAGE_SYSTEM;
484 nNumForm = rFormatter.GetFormatForLanguageIfBuiltIn( 0, eNumLang );
486 return fVal;