summaryrefslogtreecommitdiff
path: root/sfx2/source/bastyp/sfxhtml.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sfx2/source/bastyp/sfxhtml.cxx')
-rw-r--r--sfx2/source/bastyp/sfxhtml.cxx447
1 files changed, 447 insertions, 0 deletions
diff --git a/sfx2/source/bastyp/sfxhtml.cxx b/sfx2/source/bastyp/sfxhtml.cxx
new file mode 100644
index 000000000000..8a4b434f460b
--- /dev/null
+++ b/sfx2/source/bastyp/sfxhtml.cxx
@@ -0,0 +1,447 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sfx2.hxx"
+
+#include <tools/urlobj.hxx>
+
+#include <sfx2/objsh.hxx>
+#include <sfx2/docfile.hxx>
+#include "openflag.hxx"
+
+#include <svtools/htmlkywd.hxx>
+#include <svtools/htmltokn.h>
+#include <svtools/imap.hxx>
+#include <svtools/imapcirc.hxx>
+#include <svtools/imapobj.hxx>
+#include <svtools/imappoly.hxx>
+#include <svtools/imaprect.hxx>
+#ifndef _SVSTDARR_ULONGS_DECL
+#define _SVSTDARR_ULONGS
+#include <svl/svstdarr.hxx>
+#endif
+#include <svl/zforlist.hxx>
+#include <rtl/tencinfo.h>
+#include <tools/tenccvt.hxx>
+
+#include <sfx2/sfxhtml.hxx>
+
+#include <com/sun/star/beans/XPropertyContainer.hpp>
+
+
+using namespace ::com::sun::star;
+
+
+sal_Char __FAR_DATA sHTML_MIME_text[] = "text/";
+sal_Char __FAR_DATA sHTML_MIME_application[] = "application/";
+sal_Char __FAR_DATA sHTML_MIME_experimental[] = "x-";
+
+// <INPUT TYPE=xxx>
+static HTMLOptionEnum __READONLY_DATA aAreaShapeOptEnums[] =
+{
+ { OOO_STRING_SVTOOLS_HTML_SH_rect, IMAP_OBJ_RECTANGLE },
+ { OOO_STRING_SVTOOLS_HTML_SH_rectangle, IMAP_OBJ_RECTANGLE },
+ { OOO_STRING_SVTOOLS_HTML_SH_circ, IMAP_OBJ_CIRCLE },
+ { OOO_STRING_SVTOOLS_HTML_SH_circle, IMAP_OBJ_CIRCLE },
+ { OOO_STRING_SVTOOLS_HTML_SH_poly, IMAP_OBJ_POLYGON },
+ { OOO_STRING_SVTOOLS_HTML_SH_polygon, IMAP_OBJ_POLYGON },
+ { 0, 0 }
+};
+
+SfxHTMLParser::SfxHTMLParser( SvStream& rStream, BOOL bIsNewDoc,
+ SfxMedium *pMed ) :
+ HTMLParser( rStream, bIsNewDoc ),
+ pMedium( pMed ), pDLMedium( 0 ),
+ nMetaTags( 0 )
+{
+ DBG_ASSERT( RTL_TEXTENCODING_DONTKNOW == GetSrcEncoding( ),
+ "SfxHTMLParser::SfxHTMLParser: Wo kommt der ZS her?" );
+ DBG_ASSERT( !IsSwitchToUCS2(),
+ "SfxHTMLParser::SfxHTMLParser: Switch to UCS2?" );
+
+ // Altough the real default encoding is ISO8859-1, we use MS-1252
+ // als default encoding.
+ SetSrcEncoding( GetExtendedCompatibilityTextEncoding( RTL_TEXTENCODING_ISO_8859_1 ) );
+
+ // If the file starts with a BOM, switch to UCS2.
+ SetSwitchToUCS2( TRUE );
+}
+
+__EXPORT SfxHTMLParser::~SfxHTMLParser()
+{
+ DBG_ASSERT( !pDLMedium, "Da ist ein File-Download stehengeblieben" );
+ delete pDLMedium;
+}
+
+BOOL SfxHTMLParser::ParseMapOptions(ImageMap * pImageMap,
+ const HTMLOptions * pOptions)
+{
+ DBG_ASSERT( pImageMap, "ParseMapOptions: keine Image-Map" );
+ DBG_ASSERT( pOptions, "ParseMapOptions: keine Optionen" );
+
+ String aName;
+
+ for( USHORT i=pOptions->Count(); i; )
+ {
+ const HTMLOption *pOption = (*pOptions)[--i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_NAME:
+ aName = pOption->GetString();
+ break;
+ }
+ }
+
+ if( aName.Len() )
+ pImageMap->SetName( aName );
+
+ return aName.Len() > 0;
+}
+
+BOOL SfxHTMLParser::ParseAreaOptions(ImageMap * pImageMap, const String& rBaseURL,
+ const HTMLOptions * pOptions,
+ USHORT nEventMouseOver,
+ USHORT nEventMouseOut )
+{
+ DBG_ASSERT( pImageMap, "ParseAreaOptions: keine Image-Map" );
+ DBG_ASSERT( pOptions, "ParseAreaOptions: keine Optionen" );
+
+ USHORT nShape = IMAP_OBJ_RECTANGLE;
+ SvULongs aCoords;
+ String aName, aHRef, aAlt, aTarget, sEmpty;
+ BOOL bNoHRef = FALSE;
+ SvxMacroTableDtor aMacroTbl;
+
+ for( USHORT i=pOptions->Count(); i; )
+ {
+ USHORT nEvent = 0;
+ ScriptType eScrpType = STARBASIC;
+ const HTMLOption *pOption = (*pOptions)[--i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_NAME:
+ aName = pOption->GetString();
+ break;
+ case HTML_O_SHAPE:
+ pOption->GetEnum( nShape, aAreaShapeOptEnums );
+ break;
+ case HTML_O_COORDS:
+ pOption->GetNumbers( aCoords, TRUE );
+ break;
+ case HTML_O_HREF:
+ aHRef = INetURLObject::GetAbsURL( rBaseURL, pOption->GetString() );
+ break;
+ case HTML_O_NOHREF:
+ bNoHRef = TRUE;
+ break;
+ case HTML_O_ALT:
+ aAlt = pOption->GetString();
+ break;
+ case HTML_O_TARGET:
+ aTarget = pOption->GetString();
+ break;
+
+ case HTML_O_ONMOUSEOVER:
+ eScrpType = JAVASCRIPT;
+ case HTML_O_SDONMOUSEOVER:
+ nEvent = nEventMouseOver;
+ goto IMAPOBJ_SETEVENT;
+
+ case HTML_O_ONMOUSEOUT:
+ eScrpType = JAVASCRIPT;
+ case HTML_O_SDONMOUSEOUT:
+ nEvent = nEventMouseOut;
+ goto IMAPOBJ_SETEVENT;
+IMAPOBJ_SETEVENT:
+ if( nEvent )
+ {
+ String sTmp( pOption->GetString() );
+ if( sTmp.Len() )
+ {
+ sTmp.ConvertLineEnd();
+ aMacroTbl.Insert( nEvent,
+ new SvxMacro( sTmp, sEmpty, eScrpType ));
+ }
+ }
+ break;
+ }
+ }
+
+ if( bNoHRef )
+ aHRef.Erase();
+
+ BOOL bNewArea = TRUE;
+ switch( nShape )
+ {
+ case IMAP_OBJ_RECTANGLE:
+ if( aCoords.Count() >=4 )
+ {
+ Rectangle aRec( aCoords[0], aCoords[1],
+ aCoords[2], aCoords[3] );
+ IMapRectangleObject aMapRObj( aRec, aHRef, aAlt, String(), aTarget, aName,
+ !bNoHRef );
+ if( aMacroTbl.Count() )
+ aMapRObj.SetMacroTable( aMacroTbl );
+ pImageMap->InsertIMapObject( aMapRObj );
+ }
+ break;
+ case IMAP_OBJ_CIRCLE:
+ if( aCoords.Count() >=3 )
+ {
+ Point aPoint( aCoords[0], aCoords[1] );
+ IMapCircleObject aMapCObj( aPoint, aCoords[2],aHRef, aAlt, String(),
+ aTarget, aName, !bNoHRef );
+ if( aMacroTbl.Count() )
+ aMapCObj.SetMacroTable( aMacroTbl );
+ pImageMap->InsertIMapObject( aMapCObj );
+ }
+ break;
+ case IMAP_OBJ_POLYGON:
+ if( aCoords.Count() >=6 )
+ {
+ USHORT nCount = aCoords.Count() / 2;
+ Polygon aPoly( nCount );
+ for( USHORT i=0; i<nCount; i++ )
+ aPoly[i] = Point( aCoords[2*i], aCoords[2*i+1] );
+ IMapPolygonObject aMapPObj( aPoly, aHRef, aAlt, String(), aTarget, aName,
+ !bNoHRef );
+ if( aMacroTbl.Count() )
+ aMapPObj.SetMacroTable( aMacroTbl );
+ pImageMap->InsertIMapObject( aMapPObj );
+ }
+ break;
+ default:
+ bNewArea = FALSE;
+ }
+
+ return bNewArea;
+}
+
+
+void SfxHTMLParser::StartFileDownload( const String& rURL, int nToken,
+ SfxObjectShell *pSh )
+{
+ DBG_ASSERT( !pDLMedium, "StartFileDwonload bei aktivem Download" );
+ if( pDLMedium )
+ return;
+
+ pDLMedium = new SfxMedium( rURL, SFX_STREAM_READONLY, FALSE );
+ if( pSh )
+ {
+ // Medium registrieren, damit abgebrochen werden kann
+ pSh->RegisterTransfer( *pDLMedium );
+
+ // Target-Frame uebertragen, damit auch javascript:-URLs
+ // "geladen" werden koennen.
+ //const SfxMedium *pShMedium = pSh->GetMedium();
+ //if( pShMedium )
+ // pDLMedium->SetLoadTargetFrame( pShMedium->GetLoadTargetFrame() );
+ }
+
+ // Download anstossen (Achtung: Kann auch synchron sein).
+ if ( TRUE /*pMedium->GetDoneLink() == Link()*/ )
+ pDLMedium->DownLoad();
+ else
+ {
+ // Downloading-Flag auf TRUE setzen. Es werden dann auch
+ // Data-Available-Links, wenn wir in den Pending-Staus gelangen.
+ SetDownloadingFile( TRUE );
+ pDLMedium->DownLoad( STATIC_LINK( this, SfxHTMLParser, FileDownloadDone ) );
+
+ // Wenn das Dowsnloading-Flag noch gesetzt ist erfolgt der Download
+ // asynchron. Wir gehen dann in den Pedning-Staus und warten dort.
+ // Solange sind alle Aufrufe des Data-Avaialble-Link gesperrt.
+ if( IsDownloadingFile() )
+ {
+ // Den aktuellen Zustand einfrieren und in den Pending-Status gehen.
+ // Wenn der Download beendet oder abgebrochen wurde, wird ueber
+ // NewDataRead ein Continue mit dem uebergeben Token angesteossen.
+ SaveState( nToken );
+ eState = SVPAR_PENDING;
+ }
+ }
+}
+
+BOOL SfxHTMLParser::GetFileDownloadMIME( String& rMIME )
+{
+ return pDLMedium && pDLMedium->GetErrorCode()==0 &&
+ pDLMedium->GetMIMEAndRedirect(rMIME)==0;
+}
+
+BOOL SfxHTMLParser::FinishFileDownload( String& rStr )
+{
+ String aStr;
+
+ BOOL bOK = pDLMedium && pDLMedium->GetErrorCode()==0;
+ if( bOK )
+ {
+ SvStream* pStream = pDLMedium->GetInStream();
+ DBG_ASSERT( pStream, "Kein In-Stream vom Medium erhalten" );
+
+ SvMemoryStream aStream;
+ if( pStream ) // HACK wegen #65563#
+ aStream << *pStream;
+
+ aStream.Seek( STREAM_SEEK_TO_END );
+ DBG_ASSERT( aStream.Tell() < STRING_MAXLEN,
+ "File zu lang fuer einen String, Ende abgeschnitten" );
+ xub_StrLen nLen = aStream.Tell() < STRING_MAXLEN
+ ? (xub_StrLen)aStream.Tell()
+ : STRING_MAXLEN;
+
+ // TODO: untested!!!
+ rtl_TextEncoding eEnc =
+ GetExtendedCompatibilityTextEncoding( RTL_TEXTENCODING_ISO_8859_1 );
+ String sMime;
+ if( pDLMedium->GetMIMEAndRedirect( sMime ) == 0 )
+ {
+ rtl_TextEncoding eMimeEnc = GetEncodingByMIME( sMime );
+ if( RTL_TEXTENCODING_DONTKNOW != eMimeEnc )
+ eEnc = eMimeEnc;
+ }
+
+ ByteString sBuffer;
+ sal_Char* pBuffer = sBuffer.AllocBuffer(nLen);
+ aStream.Seek( 0 );
+ aStream.Read((void*)pBuffer, nLen);
+ rStr = String( S2U(pBuffer) );
+ }
+
+ delete pDLMedium;
+ pDLMedium = 0;
+
+ return bOK;
+}
+
+IMPL_STATIC_LINK( SfxHTMLParser, FileDownloadDone, void*, EMPTYARG )
+{
+ // Der Download ist jetzt abgeschlossen. Ausserdem muss/darf der
+ // Data-Available-Link wieder durchgelassen werden.
+ pThis->SetDownloadingFile( FALSE );
+
+ // ... und einmal aufrufen, damit weitergelesen wird.
+ pThis->CallAsyncCallLink();
+
+ return 0;
+}
+
+void SfxHTMLParser::GetScriptType_Impl( SvKeyValueIterator *pHTTPHeader )
+{
+ aScriptType = DEFINE_CONST_UNICODE(SVX_MACRO_LANGUAGE_JAVASCRIPT);
+ eScriptType = JAVASCRIPT;
+ if( pHTTPHeader )
+ {
+ SvKeyValue aKV;
+ for( BOOL bCont = pHTTPHeader->GetFirst( aKV ); bCont;
+ bCont = pHTTPHeader->GetNext( aKV ) )
+ {
+ if( aKV.GetKey().EqualsIgnoreCaseAscii(
+ OOO_STRING_SVTOOLS_HTML_META_content_script_type ) )
+ {
+ if( aKV.GetValue().Len() )
+ {
+ String aTmp( aKV.GetValue() );
+ if( aTmp.EqualsIgnoreCaseAscii( sHTML_MIME_text, 0, 5 ) )
+ aTmp.Erase( 0, 5 );
+ else if( aTmp.EqualsIgnoreCaseAscii( sHTML_MIME_application,
+ 0, 12 ) )
+ aTmp.Erase( 0, 12 );
+ else
+ break;
+
+ if( aTmp.EqualsIgnoreCaseAscii( sHTML_MIME_experimental, 0,
+ 2 ) )
+ {
+ aTmp.Erase( 0, 2 );
+ }
+
+ if( aTmp.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_LG_starbasic ) )
+ {
+ eScriptType = STARBASIC;
+ aScriptType = DEFINE_CONST_UNICODE(SVX_MACRO_LANGUAGE_STARBASIC);
+ }
+ if( !aTmp.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_LG_javascript ) )
+ {
+ eScriptType = EXTENDED_STYPE;
+ aScriptType = aTmp;
+ }
+ }
+ break;
+ }
+ }
+ }
+}
+
+ScriptType SfxHTMLParser::GetScriptType( SvKeyValueIterator *pHTTPHeader ) const
+{
+ if( !aScriptType.Len() )
+ ((SfxHTMLParser *)this)->GetScriptType_Impl( pHTTPHeader );
+
+ return eScriptType;
+}
+
+const String& SfxHTMLParser::GetScriptTypeString(
+ SvKeyValueIterator *pHTTPHeader ) const
+{
+ if( !aScriptType.Len() )
+ ((SfxHTMLParser *)this)->GetScriptType_Impl( pHTTPHeader );
+
+ return aScriptType;
+}
+
+double SfxHTMLParser::GetTableDataOptionsValNum( sal_uInt32& nNumForm,
+ LanguageType& eNumLang, const String& aValStr, const String& aNumStr,
+ SvNumberFormatter& rFormatter )
+{
+ LanguageType eParseLang = (LanguageType )aNumStr.ToInt32();
+ sal_uInt32 nParseForm =
+ rFormatter.GetFormatForLanguageIfBuiltIn( 0, eParseLang );
+ double fVal;
+ rFormatter.IsNumberFormat( aValStr, nParseForm, fVal );
+ if ( aNumStr.GetTokenCount( ';' ) > 2 )
+ {
+ eNumLang = (LanguageType)aNumStr.GetToken( 1, ';' ).ToInt32();
+ xub_StrLen nPos = aNumStr.Search( ';' );
+ nPos = aNumStr.Search( ';', nPos + 1 );
+ String aFormat( aNumStr.Copy( nPos + 1 ) );
+ xub_StrLen nCheckPos;
+ short nType;
+ if ( eNumLang != LANGUAGE_SYSTEM )
+ rFormatter.PutEntry( aFormat, nCheckPos, nType, nNumForm, eNumLang );
+ else
+ rFormatter.PutandConvertEntry( aFormat, nCheckPos, nType, nNumForm,
+ eParseLang, eNumLang );
+ }
+ else
+ {
+ eNumLang = LANGUAGE_SYSTEM;
+ nNumForm = rFormatter.GetFormatForLanguageIfBuiltIn( 0, eNumLang );
+ }
+ return fVal;
+}
+