847 lines
26 KiB
C++
847 lines
26 KiB
C++
/*************************************************************************
|
|
*
|
|
* $RCSfile: eehtml.cxx,v $
|
|
*
|
|
* $Revision: 1.4 $
|
|
*
|
|
* last change: $Author: mt $ $Date: 2001-07-17 13:25:24 $
|
|
*
|
|
* The Contents of this file are made available subject to the terms of
|
|
* either of the following licenses
|
|
*
|
|
* - GNU Lesser General Public License Version 2.1
|
|
* - Sun Industry Standards Source License Version 1.1
|
|
*
|
|
* Sun Microsystems Inc., October, 2000
|
|
*
|
|
* GNU Lesser General Public License Version 2.1
|
|
* =============================================
|
|
* Copyright 2000 by Sun Microsystems, Inc.
|
|
* 901 San Antonio Road, Palo Alto, CA 94303, USA
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License version 2.1, as published by the Free Software Foundation.
|
|
*
|
|
* This library 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 for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
|
* MA 02111-1307 USA
|
|
*
|
|
*
|
|
* Sun Industry Standards Source License Version 1.1
|
|
* =================================================
|
|
* The contents of this file are subject to the Sun Industry Standards
|
|
* Source License Version 1.1 (the "License"); You may not use this file
|
|
* except in compliance with the License. You may obtain a copy of the
|
|
* License at http://www.openoffice.org/license.html.
|
|
*
|
|
* Software provided under this License is provided on an "AS IS" basis,
|
|
* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
|
|
* WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
|
|
* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
|
|
* See the License for the specific provisions governing your rights and
|
|
* obligations concerning the Software.
|
|
*
|
|
* The Initial Developer of the Original Code is: Sun Microsystems, Inc.
|
|
*
|
|
* Copyright: 2000 by Sun Microsystems, Inc.
|
|
*
|
|
* All Rights Reserved.
|
|
*
|
|
* Contributor(s): _______________________________________
|
|
*
|
|
*
|
|
************************************************************************/
|
|
|
|
#include <eeng_pch.hxx>
|
|
|
|
#pragma hdrstop
|
|
|
|
#include <eehtml.hxx>
|
|
#include <impedit.hxx>
|
|
#include <eeitemid.hxx>
|
|
#include <adjitem.hxx>
|
|
#include <flditem.hxx>
|
|
#include <tools/urlobj.hxx>
|
|
#include "fhgtitem.hxx"
|
|
#include "fontitem.hxx"
|
|
#include "ulspitem.hxx"
|
|
#include "wghtitem.hxx"
|
|
#include <svtools/htmltokn.h>
|
|
#include <svtools/htmlkywd.hxx>
|
|
|
|
#include <vcl/system.hxx>
|
|
|
|
#define ACTION_INSERTTEXT 1
|
|
#define ACTION_INSERTPARABRK 2
|
|
|
|
#define STYLE_PRE 101
|
|
|
|
EditHTMLParser::EditHTMLParser( SvStream& rIn, SvKeyValueIterator* pHTTPHeaderAttrs, int bReadNewDoc )
|
|
: SfxHTMLParser( rIn, bReadNewDoc )
|
|
{
|
|
pImpEditEngine = 0;
|
|
pCurAnchor = 0;
|
|
bInPara = FALSE;
|
|
bWasInPara = FALSE;
|
|
nInTable = 0;
|
|
nInCell = 0;
|
|
nDefListLevel = 0;
|
|
nBulletLevel = 0;
|
|
nNumberingLevel = 0;
|
|
pNumbers = 0;
|
|
bFieldsInserted = FALSE;
|
|
DBG_ASSERT( pHTTPHeaderAttrs, "EditHTMLParser: no HTTPHeaderAttrs" );
|
|
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;
|
|
#endif
|
|
|
|
|
|
switch( nToken )
|
|
{
|
|
|
|
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 || 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_TITLE_ON:
|
|
case HTML_TITLE_OFF:
|
|
case HTML_THEAD_ON:
|
|
case HTML_THEAD_OFF:
|
|
case HTML_TBODY_ON:
|
|
case HTML_TBODY_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();
|
|
ContentNode* pEN = aEndPaM.GetNode();
|
|
USHORT nStartNode = pImpEditEngine->GetEditDoc().GetPos( pSN );
|
|
USHORT nEndNode = pImpEditEngine->GetEditDoc().GetPos( pEN );
|
|
|
|
// 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:
|
|
DBG_ASSERT( nStartNode == nEndNode, "ImpSetAttribs: Mehrere Absaetze?" );
|
|
/*
|
|
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( sHTML_AL_right ) == COMPARE_EQUAL )
|
|
eAdjust = SVX_ADJUST_RIGHT;
|
|
else if ( pOption->GetString().CompareIgnoreCaseToAscii( sHTML_AL_middle ) == COMPARE_EQUAL )
|
|
eAdjust = SVX_ADJUST_CENTER;
|
|
else if ( pOption->GetString().CompareIgnoreCaseToAscii( sHTML_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 bReal )
|
|
{
|
|
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() )
|
|
{
|
|
// BaseURL muss gesetzt sein!
|
|
String aURL = aRef;
|
|
if ( aURL.Len() && ( aURL.GetChar( 0 ) != '#' ) )
|
|
{
|
|
INetURLObject aTargetURL;
|
|
INetURLObject aRootURL( INetURLObject::GetBaseURL() );
|
|
aRootURL.GetNewAbsURL( aRef, &aTargetURL );
|
|
aURL = aTargetURL.GetMainURL();
|
|
}
|
|
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 = 1 + ( ( nToken - HTML_HEAD1_ON ) / 2 );
|
|
DBG_ASSERT( (nId >= 1) && (nId <= 9), "HeadingStart: ID kann nicht stimmen!" );
|
|
ImpSetStyleSheet( nId );
|
|
}
|
|
|
|
void EditHTMLParser::HeadingEnd( int nToken )
|
|
{
|
|
EndPara( FALSE );
|
|
ImpSetStyleSheet( 0 );
|
|
|
|
if ( bWasInPara )
|
|
{
|
|
bInPara = TRUE;
|
|
bWasInPara = FALSE;
|
|
}
|
|
}
|