summaryrefslogtreecommitdiff
path: root/editeng/source/editeng/eehtml.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'editeng/source/editeng/eehtml.cxx')
-rw-r--r--editeng/source/editeng/eehtml.cxx850
1 files changed, 850 insertions, 0 deletions
diff --git a/editeng/source/editeng/eehtml.cxx b/editeng/source/editeng/eehtml.cxx
new file mode 100644
index 000000000000..ddb82a06661d
--- /dev/null
+++ b/editeng/source/editeng/eehtml.cxx
@@ -0,0 +1,850 @@
+/*************************************************************************
+ *
+ * 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_editeng.hxx"
+
+#include <vcl/wrkwin.hxx>
+#include <vcl/dialog.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/svapp.hxx>
+#include <eehtml.hxx>
+#include <impedit.hxx>
+#include <editeng/adjitem.hxx>
+#include <editeng/flditem.hxx>
+#include <tools/urlobj.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <svtools/htmltokn.h>
+#include <svtools/htmlkywd.hxx>
+
+
+#define ACTION_INSERTTEXT 1
+#define ACTION_INSERTPARABRK 2
+
+#define STYLE_PRE 101
+
+EditHTMLParser::EditHTMLParser( SvStream& rIn, const String& rBaseURL, SvKeyValueIterator* pHTTPHeaderAttrs )
+ : HTMLParser( rIn, true )
+ , aBaseURL( rBaseURL )
+{
+ pImpEditEngine = 0;
+ pCurAnchor = 0;
+ bInPara = FALSE;
+ bWasInPara = FALSE;
+ nInTable = 0;
+ nInCell = 0;
+ nDefListLevel = 0;
+ nBulletLevel = 0;
+ nNumberingLevel = 0;
+ bFieldsInserted = FALSE;
+
+ if ( pHTTPHeaderAttrs )
+ SetEncodingByHTTPHeader( pHTTPHeaderAttrs );
+}
+
+EditHTMLParser::~EditHTMLParser()
+{
+ delete pCurAnchor;
+}
+
+SvParserState EditHTMLParser::CallParser( ImpEditEngine* pImpEE, const EditPaM& rPaM )
+{
+ DBG_ASSERT( pImpEE, "CallParser: ImpEditEngine ?!" );
+ pImpEditEngine = pImpEE;
+ SvParserState _eState = SVPAR_NOTSTARTED;
+ if ( pImpEditEngine )
+ {
+ // Umbrechmimik vom RTF-Import einbauen?
+ aCurSel = EditSelection( rPaM, rPaM );
+
+ if ( pImpEditEngine->aImportHdl.IsSet() )
+ {
+ ImportInfo aImportInfo( HTMLIMP_START, this, pImpEditEngine->CreateESel( aCurSel ) );
+ pImpEditEngine->aImportHdl.Call( &aImportInfo );
+ }
+
+ ImpSetStyleSheet( 0 );
+ _eState = HTMLParser::CallParser();
+
+ if ( pImpEditEngine->aImportHdl.IsSet() )
+ {
+ ImportInfo aImportInfo( HTMLIMP_END, this, pImpEditEngine->CreateESel( aCurSel ) );
+ pImpEditEngine->aImportHdl.Call( &aImportInfo );
+ }
+
+ if ( bFieldsInserted )
+ pImpEditEngine->UpdateFields();
+ }
+ return _eState;
+}
+
+void EditHTMLParser::NextToken( int nToken )
+{
+ #ifdef DBG_UTIL
+ HTML_TOKEN_IDS xID = (HTML_TOKEN_IDS)nToken;
+ (void)xID;
+ #endif
+
+ switch( nToken )
+ {
+ case HTML_META:
+ {
+ const HTMLOptions *_pOptions = GetOptions();
+ USHORT nArrLen = _pOptions->Count();
+ BOOL bEquiv = FALSE;
+ for ( USHORT i = 0; i < nArrLen; i++ )
+ {
+ const HTMLOption *pOption = (*_pOptions)[i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_HTTPEQUIV:
+ {
+ bEquiv = TRUE;
+ }
+ break;
+ case HTML_O_CONTENT:
+ {
+ if ( bEquiv )
+ {
+ rtl_TextEncoding eEnc = GetEncodingByMIME( pOption->GetString() );
+ if ( eEnc != RTL_TEXTENCODING_DONTKNOW )
+ SetSrcEncoding( eEnc );
+ }
+ }
+ break;
+ }
+ }
+
+ }
+ break;
+ case HTML_PLAINTEXT_ON:
+ case HTML_PLAINTEXT2_ON:
+ bInPara = TRUE;
+ break;
+ case HTML_PLAINTEXT_OFF:
+ case HTML_PLAINTEXT2_OFF:
+ bInPara = FALSE;
+ break;
+
+ case HTML_LINEBREAK:
+ case HTML_NEWPARA:
+ {
+ if ( ( bInPara || nInTable ) &&
+ ( ( nToken == HTML_LINEBREAK ) || HasTextInCurrentPara() ) )
+ {
+ ImpInsertParaBreak();
+ }
+ }
+ break;
+ case HTML_HORZRULE:
+ {
+ if ( HasTextInCurrentPara() )
+ ImpInsertParaBreak();
+ ImpInsertParaBreak();
+ }
+ case HTML_NONBREAKSPACE:
+ {
+ if ( bInPara )
+ {
+ ImpInsertText( String( RTL_CONSTASCII_USTRINGPARAM( " " ) ) );
+ }
+ }
+ break;
+ case HTML_TEXTTOKEN:
+ {
+ if ( !bInPara )
+ StartPara( FALSE );
+
+// if ( bInPara || pCurAnchor )
+ {
+ String aText = aToken;
+ if ( aText.Len() && ( aText.GetChar( 0 ) == ' ' )
+ && ThrowAwayBlank() && !IsReadPRE() )
+ aText.Erase( 0, 1 );
+
+ if ( pCurAnchor )
+ {
+ pCurAnchor->aText += aText;
+ }
+ else
+ {
+ // Nur bis HTML mit 319 geschrieben ?!
+ if ( IsReadPRE() )
+ {
+ USHORT nTabPos = aText.Search( '\t', 0 );
+ while ( nTabPos != STRING_NOTFOUND )
+ {
+ aText.Erase( nTabPos, 1 );
+ aText.Insert( String( RTL_CONSTASCII_USTRINGPARAM( " " ) ), nTabPos );
+ nTabPos = aText.Search( '\t', nTabPos+8 );
+ }
+ }
+ ImpInsertText( aText );
+ }
+ }
+ }
+ break;
+
+ case HTML_CENTER_ON:
+ case HTML_CENTER_OFF: // if ( bInPara )
+ {
+ USHORT nNode = pImpEditEngine->GetEditDoc().GetPos( aCurSel.Max().GetNode() );
+ SfxItemSet aItems( aCurSel.Max().GetNode()->GetContentAttribs().GetItems() );
+ aItems.ClearItem( EE_PARA_JUST );
+ if ( nToken == HTML_CENTER_ON )
+ aItems.Put( SvxAdjustItem( SVX_ADJUST_CENTER, EE_PARA_JUST ) );
+ pImpEditEngine->SetParaAttribs( nNode, aItems );
+ }
+ break;
+
+ case HTML_ANCHOR_ON: AnchorStart();
+ break;
+ case HTML_ANCHOR_OFF: AnchorEnd();
+ break;
+
+ case HTML_PARABREAK_ON:
+ if( bInPara && HasTextInCurrentPara() )
+ EndPara( TRUE );
+ StartPara( TRUE );
+ break;
+
+ case HTML_PARABREAK_OFF:
+ if( bInPara )
+ EndPara( TRUE );
+ break;
+
+ case HTML_HEAD1_ON:
+ case HTML_HEAD2_ON:
+ case HTML_HEAD3_ON:
+ case HTML_HEAD4_ON:
+ case HTML_HEAD5_ON:
+ case HTML_HEAD6_ON:
+ {
+ HeadingStart( nToken );
+ }
+ break;
+
+ case HTML_HEAD1_OFF:
+ case HTML_HEAD2_OFF:
+ case HTML_HEAD3_OFF:
+ case HTML_HEAD4_OFF:
+ case HTML_HEAD5_OFF:
+ case HTML_HEAD6_OFF:
+ {
+ HeadingEnd( nToken );
+ }
+ break;
+
+ case HTML_PREFORMTXT_ON:
+ case HTML_XMP_ON:
+ case HTML_LISTING_ON:
+ {
+ StartPara( TRUE );
+ ImpSetStyleSheet( STYLE_PRE );
+ }
+ break;
+
+ case HTML_DEFLIST_ON:
+ {
+ nDefListLevel++;
+ }
+ break;
+
+ case HTML_DEFLIST_OFF:
+ {
+ if( nDefListLevel )
+ nDefListLevel--;
+ }
+ break;
+
+ case HTML_TABLE_ON: nInTable++;
+ break;
+ case HTML_TABLE_OFF: DBG_ASSERT( nInTable, "Nicht in Table, aber TABLE_OFF?" );
+ nInTable--;
+ break;
+
+ case HTML_TABLEHEADER_ON:
+ case HTML_TABLEDATA_ON:
+ nInCell++;
+ // fallthru
+ case HTML_BLOCKQUOTE_ON:
+ case HTML_BLOCKQUOTE_OFF:
+ case HTML_BLOCKQUOTE30_ON:
+ case HTML_BLOCKQUOTE30_OFF:
+ case HTML_LISTHEADER_ON:
+ case HTML_LI_ON:
+ case HTML_DD_ON:
+ case HTML_DT_ON:
+ case HTML_ORDERLIST_ON:
+ case HTML_UNORDERLIST_ON:
+ {
+ BOOL bHasText = HasTextInCurrentPara();
+ if ( bHasText )
+ ImpInsertParaBreak();
+ StartPara( FALSE );
+ }
+ break;
+
+ case HTML_TABLEHEADER_OFF:
+ case HTML_TABLEDATA_OFF:
+ {
+ if ( nInCell )
+ nInCell--;
+ }
+ // fallthru
+ case HTML_LISTHEADER_OFF:
+ case HTML_LI_OFF:
+ case HTML_DD_OFF:
+ case HTML_DT_OFF:
+ case HTML_ORDERLIST_OFF:
+ case HTML_UNORDERLIST_OFF: EndPara( FALSE );
+ break;
+
+ case HTML_TABLEROW_ON:
+ case HTML_TABLEROW_OFF: // Nur nach einem CELL ein RETURN, fuer Calc
+
+ case HTML_COL_ON:
+ case HTML_COLGROUP_ON:
+ case HTML_COLGROUP_OFF: break;
+
+ case HTML_FONT_ON: // ...
+ break;
+ case HTML_FONT_OFF: // ...
+ break;
+
+
+ // #58335# kein SkipGroup on/off auf inline markup etc.
+
+ // globals
+ case HTML_HTML_ON:
+ case HTML_HTML_OFF:
+ case HTML_BODY_ON:
+ case HTML_BODY_OFF:
+ case HTML_HEAD_ON:
+ case HTML_HEAD_OFF:
+ case HTML_FORM_ON:
+ case HTML_FORM_OFF:
+ case HTML_THEAD_ON:
+ case HTML_THEAD_OFF:
+ case HTML_TBODY_ON:
+ case HTML_TBODY_OFF:
+ case HTML_TITLE_ON:
+ case HTML_TITLE_OFF:
+ // inline elements, structural markup
+ // HTML 3.0
+ case HTML_BANNER_ON:
+ case HTML_BANNER_OFF:
+ case HTML_DIVISION_ON:
+ case HTML_DIVISION_OFF:
+// case HTML_LISTHEADER_ON: //! special handling
+// case HTML_LISTHEADER_OFF:
+ case HTML_NOTE_ON:
+ case HTML_NOTE_OFF:
+ // inline elements, logical markup
+ // HTML 2.0
+ case HTML_ADDRESS_ON:
+ case HTML_ADDRESS_OFF:
+// case HTML_BLOCKQUOTE_ON: //! extra Behandlung
+// case HTML_BLOCKQUOTE_OFF:
+ case HTML_CITIATION_ON:
+ case HTML_CITIATION_OFF:
+ case HTML_CODE_ON:
+ case HTML_CODE_OFF:
+ case HTML_DEFINSTANCE_ON:
+ case HTML_DEFINSTANCE_OFF:
+ case HTML_EMPHASIS_ON:
+ case HTML_EMPHASIS_OFF:
+ case HTML_KEYBOARD_ON:
+ case HTML_KEYBOARD_OFF:
+ case HTML_SAMPLE_ON:
+ case HTML_SAMPLE_OFF:
+ case HTML_STRIKE_ON:
+ case HTML_STRIKE_OFF:
+ case HTML_STRONG_ON:
+ case HTML_STRONG_OFF:
+ case HTML_VARIABLE_ON:
+ case HTML_VARIABLE_OFF:
+ // HTML 3.0
+ case HTML_ABBREVIATION_ON:
+ case HTML_ABBREVIATION_OFF:
+ case HTML_ACRONYM_ON:
+ case HTML_ACRONYM_OFF:
+ case HTML_AUTHOR_ON:
+ case HTML_AUTHOR_OFF:
+// case HTML_BLOCKQUOTE30_ON: //! extra Behandlung
+// case HTML_BLOCKQUOTE30_OFF:
+ case HTML_DELETEDTEXT_ON:
+ case HTML_DELETEDTEXT_OFF:
+ case HTML_INSERTEDTEXT_ON:
+ case HTML_INSERTEDTEXT_OFF:
+ case HTML_LANGUAGE_ON:
+ case HTML_LANGUAGE_OFF:
+ case HTML_PERSON_ON:
+ case HTML_PERSON_OFF:
+ case HTML_SHORTQUOTE_ON:
+ case HTML_SHORTQUOTE_OFF:
+ case HTML_SUBSCRIPT_ON:
+ case HTML_SUBSCRIPT_OFF:
+ case HTML_SUPERSCRIPT_ON:
+ case HTML_SUPERSCRIPT_OFF:
+ // inline elements, visual markup
+ // HTML 2.0
+ case HTML_BOLD_ON:
+ case HTML_BOLD_OFF:
+ case HTML_ITALIC_ON:
+ case HTML_ITALIC_OFF:
+ case HTML_TELETYPE_ON:
+ case HTML_TELETYPE_OFF:
+ case HTML_UNDERLINE_ON:
+ case HTML_UNDERLINE_OFF:
+ // HTML 3.0
+ case HTML_BIGPRINT_ON:
+ case HTML_BIGPRINT_OFF:
+ case HTML_STRIKETHROUGH_ON:
+ case HTML_STRIKETHROUGH_OFF:
+ case HTML_SMALLPRINT_ON:
+ case HTML_SMALLPRINT_OFF:
+ // figures
+ case HTML_FIGURE_ON:
+ case HTML_FIGURE_OFF:
+ case HTML_CAPTION_ON:
+ case HTML_CAPTION_OFF:
+ case HTML_CREDIT_ON:
+ case HTML_CREDIT_OFF:
+ // misc
+ case HTML_DIRLIST_ON:
+ case HTML_DIRLIST_OFF:
+ case HTML_FOOTNOTE_ON: //! landen so im Text
+ case HTML_FOOTNOTE_OFF:
+ case HTML_MENULIST_ON:
+ case HTML_MENULIST_OFF:
+// case HTML_PLAINTEXT_ON: //! extra Behandlung
+// case HTML_PLAINTEXT_OFF:
+// case HTML_PREFORMTXT_ON: //! extra Behandlung
+// case HTML_PREFORMTXT_OFF:
+ case HTML_SPAN_ON:
+ case HTML_SPAN_OFF:
+ // obsolete
+// case HTML_XMP_ON: //! extra Behandlung
+// case HTML_XMP_OFF:
+// case HTML_LISTING_ON: //! extra Behandlung
+// case HTML_LISTING_OFF:
+ // Netscape
+ case HTML_BLINK_ON:
+ case HTML_BLINK_OFF:
+ case HTML_NOBR_ON:
+ case HTML_NOBR_OFF:
+ case HTML_NOEMBED_ON:
+ case HTML_NOEMBED_OFF:
+ case HTML_NOFRAMES_ON:
+ case HTML_NOFRAMES_OFF:
+ // Internet Explorer
+ case HTML_MARQUEE_ON:
+ case HTML_MARQUEE_OFF:
+// case HTML_PLAINTEXT2_ON: //! extra Behandlung
+// case HTML_PLAINTEXT2_OFF:
+ break;
+
+ default:
+ {
+ if ( nToken & HTML_TOKEN_ONOFF )
+ {
+ if ( ( nToken == HTML_UNKNOWNCONTROL_ON ) || ( nToken == HTML_UNKNOWNCONTROL_OFF ) )
+ {
+ ;
+ }
+ else if ( !(nToken & 1) )
+ {
+ DBG_ASSERT( !( nToken & 1 ), "Kein Start-Token ?!" );
+ SkipGroup( nToken + 1 );
+ }
+ }
+ }
+ } // SWITCH
+
+ if ( pImpEditEngine->aImportHdl.IsSet() )
+ {
+ ImportInfo aImportInfo( HTMLIMP_NEXTTOKEN, this, pImpEditEngine->CreateESel( aCurSel ) );
+ aImportInfo.nToken = nToken;
+ aImportInfo.nTokenValue = (short)nTokenValue;
+ if ( nToken == HTML_TEXTTOKEN )
+ aImportInfo.aText = aToken;
+ pImpEditEngine->aImportHdl.Call( &aImportInfo );
+ }
+
+}
+
+void EditHTMLParser::ImpInsertParaBreak()
+{
+ if ( pImpEditEngine->aImportHdl.IsSet() )
+ {
+ ImportInfo aImportInfo( HTMLIMP_INSERTPARA, this, pImpEditEngine->CreateESel( aCurSel ) );
+ pImpEditEngine->aImportHdl.Call( &aImportInfo );
+ }
+ aCurSel = pImpEditEngine->ImpInsertParaBreak( aCurSel );
+ nLastAction = ACTION_INSERTPARABRK;
+}
+
+void EditHTMLParser::ImpSetAttribs( const SfxItemSet& rItems, EditSelection* pSel )
+{
+ // pSel, wenn Zeichenattribute, sonst Absatzattribute fuer den
+ // aktuellen Absatz.
+ DBG_ASSERT( pSel || ( aCurSel.Min().GetNode() == aCurSel.Max().GetNode() ), "ImpInsertAttribs: Selektion?" );
+
+ EditPaM aStartPaM( pSel ? pSel->Min() : aCurSel.Min() );
+ EditPaM aEndPaM( pSel ? pSel->Max() : aCurSel.Max() );
+
+ if ( !pSel )
+ {
+ aStartPaM.SetIndex( 0 );
+ aEndPaM.SetIndex( aEndPaM.GetNode()->Len() );
+ }
+
+ if ( pImpEditEngine->aImportHdl.IsSet() )
+ {
+ EditSelection aSel( aStartPaM, aEndPaM );
+ ImportInfo aImportInfo( HTMLIMP_SETATTR, this, pImpEditEngine->CreateESel( aSel ) );
+ aImportInfo.pAttrs = (void*)&rItems;
+ pImpEditEngine->aImportHdl.Call( &aImportInfo );
+ }
+
+ ContentNode* pSN = aStartPaM.GetNode();
+ USHORT nStartNode = pImpEditEngine->GetEditDoc().GetPos( pSN );
+
+ // Wenn ein Attribut von 0 bis aktuelle Absatzlaenge geht,
+ // soll es ein Absatz-Attribut sein!
+
+ // Achtung: Selektion kann ueber mehrere Absaetze gehen.
+ // Alle vollstaendigen Absaetze sind Absatzattribute...
+
+ // HTML eigentlich nicht:
+#ifdef DBG_UTIL
+ ContentNode* pEN = aEndPaM.GetNode();
+ USHORT nEndNode = pImpEditEngine->GetEditDoc().GetPos( pEN );
+ DBG_ASSERT( nStartNode == nEndNode, "ImpSetAttribs: Mehrere Absaetze?" );
+#endif
+
+/*
+ for ( USHORT z = nStartNode+1; z < nEndNode; z++ )
+ {
+ DBG_ASSERT( pImpEditEngine->GetEditDoc().SaveGetObject( z ), "Node existiert noch nicht(RTF)" );
+ pImpEditEngine->SetParaAttribs( z, rSet.GetAttrSet() );
+ }
+
+ if ( aStartPaM.GetNode() != aEndPaM.GetNode() )
+ {
+ // Den Rest des StartNodes...
+ if ( aStartPaM.GetIndex() == 0 )
+ pImpEditEngine->SetParaAttribs( nStartNode, rSet.GetAttrSet() );
+ else
+ pImpEditEngine->SetAttribs( EditSelection( aStartPaM, EditPaM( aStartPaM.GetNode(), aStartPaM.GetNode()->Len() ) ), rSet.GetAttrSet() );
+
+ // Den Anfang des EndNodes....
+ if ( aEndPaM.GetIndex() == aEndPaM.GetNode()->Len() )
+ pImpEditEngine->SetParaAttribs( nEndNode, rSet.GetAttrSet() );
+ else
+ pImpEditEngine->SetAttribs( EditSelection( EditPaM( aEndPaM.GetNode(), 0 ), aEndPaM ), rSet.GetAttrSet() );
+ }
+ else
+*/
+ {
+ if ( ( aStartPaM.GetIndex() == 0 ) && ( aEndPaM.GetIndex() == aEndPaM.GetNode()->Len() ) )
+ {
+ // Muesse gemergt werden:
+ SfxItemSet aItems( pImpEditEngine->GetParaAttribs( nStartNode ) );
+ aItems.Put( rItems );
+ pImpEditEngine->SetParaAttribs( nStartNode, aItems );
+ }
+ else
+ pImpEditEngine->SetAttribs( EditSelection( aStartPaM, aEndPaM ), rItems );
+ }
+}
+
+void EditHTMLParser::ImpSetStyleSheet( USHORT nHLevel )
+{
+ /*
+ nHLevel: 0: Ausschalten
+ 1-6: Heading
+ STYLE_PRE: Preformatted
+ */
+
+// if ( pImpEditEngine->GetStatus().DoImportRTFStyleSheets() )
+// {
+// SvxRTFStyleType* pS = GetStyleTbl().Get( rSet.StyleNo() );
+// DBG_ASSERT( pS, "Vorlage in RTF nicht definiert!" );
+// if ( pS )
+// pImpEditEngine->SetStyleSheet( EditSelection( aStartPaM, aEndPaM ), pS->sName, SFX_STYLE_FAMILY_ALL );
+// }
+// else
+ {
+ // Harte Attribute erzeugen...
+ // Reicht fuer Calc, bei StyleSheets muesste noch geklaert werden,
+ // dass diese auch in der App liegen sollten, damit sie beim
+ // fuettern in eine andere Engine auch noch da sind...
+
+ USHORT nNode = pImpEditEngine->GetEditDoc().GetPos( aCurSel.Max().GetNode() );
+// SfxItemSet aItems( pImpEditEngine->GetEmptyItemSet() );
+ SfxItemSet aItems( aCurSel.Max().GetNode()->GetContentAttribs().GetItems() );
+
+ aItems.ClearItem( EE_PARA_ULSPACE );
+ aItems.ClearItem( EE_CHAR_FONTHEIGHT );
+ aItems.ClearItem( EE_CHAR_FONTINFO );
+ aItems.ClearItem( EE_CHAR_WEIGHT );
+
+ // Fett in den ersten 3 Headings
+ if ( ( nHLevel >= 1 ) && ( nHLevel <= 3 ) )
+ {
+ SvxWeightItem aWeightItem( WEIGHT_BOLD, EE_CHAR_WEIGHT );
+ aItems.Put( aWeightItem );
+ }
+
+ // Fonthoehe und Abstaende, wenn LogicToLogic moeglich:
+ MapUnit eUnit = pImpEditEngine->GetRefMapMode().GetMapUnit();
+ if ( ( eUnit != MAP_PIXEL ) && ( eUnit != MAP_SYSFONT ) &&
+ ( eUnit != MAP_APPFONT ) && ( eUnit != MAP_RELATIVE ) )
+ {
+ long nPoints = 10;
+ if ( nHLevel == 1 )
+ nPoints = 22;
+ else if ( nHLevel == 2 )
+ nPoints = 16;
+ else if ( nHLevel == 3 )
+ nPoints = 12;
+ else if ( nHLevel == 4 )
+ nPoints = 11;
+
+ nPoints = OutputDevice::LogicToLogic( nPoints, MAP_POINT, eUnit );
+ SvxFontHeightItem aHeightItem( nPoints, 100, EE_CHAR_FONTHEIGHT );
+ aItems.Put( aHeightItem );
+
+ // Absatzabstaende, wenn Heading:
+ if ( !nHLevel || ((nHLevel >= 1) && (nHLevel <= 6)) )
+ {
+ SvxULSpaceItem aULSpaceItem( EE_PARA_ULSPACE );
+ aULSpaceItem.SetUpper( (USHORT)OutputDevice::LogicToLogic( 42, MAP_10TH_MM, eUnit ) );
+ aULSpaceItem.SetLower( (USHORT)OutputDevice::LogicToLogic( 35, MAP_10TH_MM, eUnit ) );
+ aItems.Put( aULSpaceItem );
+ }
+ }
+
+ // Bei Pre einen proportionalen Font waehlen
+ if ( nHLevel == STYLE_PRE )
+ {
+ Font aFont = OutputDevice::GetDefaultFont( DEFAULTFONT_FIXED, LANGUAGE_SYSTEM, 0 );
+ SvxFontItem aFontItem( aFont.GetFamily(), aFont.GetName(), XubString(), aFont.GetPitch(), aFont.GetCharSet(), EE_CHAR_FONTINFO );
+ aItems.Put( aFontItem );
+ }
+
+ pImpEditEngine->SetParaAttribs( nNode, aItems );
+ }
+}
+
+void EditHTMLParser::ImpInsertText( const String& rText )
+{
+ String aText( rText );
+ if ( pImpEditEngine->aImportHdl.IsSet() )
+ {
+ ImportInfo aImportInfo( HTMLIMP_INSERTTEXT, this, pImpEditEngine->CreateESel( aCurSel ) );
+ aImportInfo.aText = aText;
+ pImpEditEngine->aImportHdl.Call( &aImportInfo );
+ }
+
+ aCurSel = pImpEditEngine->ImpInsertText( aCurSel, aText );
+ nLastAction = ACTION_INSERTTEXT;
+}
+
+void EditHTMLParser::SkipGroup( int nEndToken )
+{
+ // #69109# groups in cells are closed upon leaving the cell, because those
+ // ******* web authors don't know their job
+ // for example: <td><form></td> lacks a closing </form>
+ BYTE nCellLevel = nInCell;
+ int nToken;
+ while( nCellLevel <= nInCell && ( (nToken = GetNextToken() ) != nEndToken ) && nToken )
+ {
+ switch ( nToken )
+ {
+ case HTML_TABLEHEADER_ON:
+ case HTML_TABLEDATA_ON:
+ nInCell++;
+ break;
+ case HTML_TABLEHEADER_OFF:
+ case HTML_TABLEDATA_OFF:
+ if ( nInCell )
+ nInCell--;
+ break;
+ }
+ }
+}
+
+void EditHTMLParser::StartPara( BOOL bReal )
+{
+ if ( bReal )
+ {
+ const HTMLOptions *_pOptions = GetOptions();
+ USHORT nArrLen = _pOptions->Count();
+ SvxAdjust eAdjust = SVX_ADJUST_LEFT;
+ for ( USHORT i = 0; i < nArrLen; i++ )
+ {
+ const HTMLOption *pOption = (*_pOptions)[i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_ALIGN:
+ {
+ if ( pOption->GetString().CompareIgnoreCaseToAscii( OOO_STRING_SVTOOLS_HTML_AL_right ) == COMPARE_EQUAL )
+ eAdjust = SVX_ADJUST_RIGHT;
+ else if ( pOption->GetString().CompareIgnoreCaseToAscii( OOO_STRING_SVTOOLS_HTML_AL_middle ) == COMPARE_EQUAL )
+ eAdjust = SVX_ADJUST_CENTER;
+ else if ( pOption->GetString().CompareIgnoreCaseToAscii( OOO_STRING_SVTOOLS_HTML_AL_center ) == COMPARE_EQUAL )
+ eAdjust = SVX_ADJUST_CENTER;
+ else
+ eAdjust = SVX_ADJUST_LEFT;
+ }
+ break;
+ }
+ }
+ SfxItemSet aItemSet( pImpEditEngine->GetEmptyItemSet() );
+ aItemSet.Put( SvxAdjustItem( eAdjust, EE_PARA_JUST ) );
+ ImpSetAttribs( aItemSet );
+ }
+ bInPara = TRUE;
+}
+
+void EditHTMLParser::EndPara( BOOL )
+{
+ if ( bInPara )
+ {
+ BOOL bHasText = HasTextInCurrentPara();
+ if ( bHasText )
+ ImpInsertParaBreak();
+ // Nur, wenn ohne Absatzabstaende gearbeitet wird...
+// if ( !nInTable && bReal && (nNumberingLevel<=1) && (nBulletLevel<=1) )
+// ImpInsertParaBreak();
+ }
+ bInPara = FALSE;
+}
+
+BOOL EditHTMLParser::ThrowAwayBlank()
+{
+ // Ein Blank muss weggeschmissen werden, wenn der neue Text mit einem
+ // Blank beginnt und der aktuelle Absatz leer ist oder mit einem
+ // Blank endet...
+ ContentNode* pNode = aCurSel.Max().GetNode();
+ if ( pNode->Len() && ( pNode->GetChar( pNode->Len()-1 ) != ' ' ) )
+ return FALSE;
+ return TRUE;
+}
+
+BOOL EditHTMLParser::HasTextInCurrentPara()
+{
+ return aCurSel.Max().GetNode()->Len() ? TRUE : FALSE;
+}
+
+void EditHTMLParser::AnchorStart()
+{
+ // Anker im Anker ignoriern
+ if ( !pCurAnchor )
+ {
+ const HTMLOptions* _pOptions = GetOptions();
+ USHORT nArrLen = _pOptions->Count();
+
+ String aRef;
+
+ for ( USHORT i = 0; i < nArrLen; i++ )
+ {
+ const HTMLOption* pOption = (*_pOptions)[i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_HREF:
+ aRef = pOption->GetString();
+ break;
+ }
+ }
+
+ if ( aRef.Len() )
+ {
+ String aURL = aRef;
+ if ( aURL.Len() && ( aURL.GetChar( 0 ) != '#' ) )
+ {
+ INetURLObject aTargetURL;
+ INetURLObject aRootURL( aBaseURL );
+ aRootURL.GetNewAbsURL( aRef, &aTargetURL );
+ aURL = aTargetURL.GetMainURL( INetURLObject::DECODE_TO_IURI );
+ }
+ pCurAnchor = new AnchorInfo;
+ pCurAnchor->aHRef = aURL;
+ }
+ }
+}
+
+void EditHTMLParser::AnchorEnd()
+{
+ if ( pCurAnchor )
+ {
+ // Als URL-Feld einfuegen...
+ SvxFieldItem aFld( SvxURLField( pCurAnchor->aHRef, pCurAnchor->aText, SVXURLFORMAT_REPR ), EE_FEATURE_FIELD );
+ aCurSel = pImpEditEngine->InsertField( aCurSel, aFld );
+ bFieldsInserted = TRUE;
+ delete pCurAnchor;
+ pCurAnchor = 0;
+
+ if ( pImpEditEngine->aImportHdl.IsSet() )
+ {
+ ImportInfo aImportInfo( HTMLIMP_INSERTFIELD, this, pImpEditEngine->CreateESel( aCurSel ) );
+ pImpEditEngine->aImportHdl.Call( &aImportInfo );
+ }
+ }
+}
+
+void EditHTMLParser::HeadingStart( int nToken )
+{
+ bWasInPara = bInPara;
+ StartPara( FALSE );
+
+ if ( bWasInPara && HasTextInCurrentPara() )
+ ImpInsertParaBreak();
+
+ USHORT nId = sal::static_int_cast< USHORT >(
+ 1 + ( ( nToken - HTML_HEAD1_ON ) / 2 ) );
+ DBG_ASSERT( (nId >= 1) && (nId <= 9), "HeadingStart: ID kann nicht stimmen!" );
+ ImpSetStyleSheet( nId );
+}
+
+void EditHTMLParser::HeadingEnd( int )
+{
+ EndPara( FALSE );
+ ImpSetStyleSheet( 0 );
+
+ if ( bWasInPara )
+ {
+ bInPara = TRUE;
+ bWasInPara = FALSE;
+ }
+}