Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/LibreOffice/editeng/source/editeng/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 26 kB image not shown  

Quelle  eehtml.cxx   Sprache: C

 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 .
 */



#include "eehtml.hxx"
#include <editeng/adjustitem.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>
#include <tools/tenccvt.hxx>

#include <editeng/editeng.hxx>
#include <utility>

#define STYLE_PRE               101

EditHTMLParser::EditHTMLParser( SvStream& rIn, OUString _aBaseURL, SvKeyValueIterator* pHTTPHeaderAttrs )
    : HTMLParser( rIn, true ),
    aBaseURL(std::move( _aBaseURL )),
    mpEditEngine(nullptr),
    bInPara(false),
    bWasInPara(false),
    mbBreakForDivs(false),
    mbNewBlockNeeded(false),
    bFieldsInserted(false),
    bInTitle(false),
    nInTable(0),
    nInCell(0),
    nDefListLevel(0)
{
    DBG_ASSERT( !IsSwitchToUCS2(), "EditHTMLParser::::EditHTMLParser: Switch to UCS2?" );

    // Although the real default encoding is ISO8859-1, we use MS-1252
    // as default encoding.
    SetSrcEncoding( GetExtendedCompatibilityTextEncoding(  RTL_TEXTENCODING_ISO_8859_1 ) );

    // If the file starts with a BOM, switch to UCS2.
    SetSwitchToUCS2( true );

    if ( pHTTPHeaderAttrs )
    {
        SetEncodingByHTTPHeader( pHTTPHeaderAttrs );
        SetBreakForDivs(*pHTTPHeaderAttrs);
    }
}

void EditHTMLParser::SetBreakForDivs(SvKeyValueIterator& rHTTPOptions)
{
    SvKeyValue aKV;
    bool bCont = rHTTPOptions.GetFirst(aKV);
    while (bCont)
    {
        if (aKV.GetKey() == "newline-on-div")
        {
            mbBreakForDivs = aKV.GetValue() == "true";
            break;
        }
        bCont = rHTTPOptions.GetNext(aKV);
    }
}

EditHTMLParser::~EditHTMLParser()
{
}

SvParserState EditHTMLParser::CallParser(EditEngine* pEE, const EditPaM& rPaM)
{
    DBG_ASSERT(pEE, "CallParser: ImpEditEngine ?!");
    mpEditEngine = pEE;
    SvParserState _eState = SvParserState::NotStarted;
    if ( mpEditEngine )
    {
        // Build in wrap mimic in RTF import?
        aCurSel = EditSelection( rPaM, rPaM );

        if (mpEditEngine->IsHtmlImportHandlerSet())
        {
            HtmlImportInfo aImportInfo(HtmlImportState::Start, this, mpEditEngine->CreateESelection(aCurSel));
            mpEditEngine->CallHtmlImportHandler(aImportInfo);
        }

        ImpSetStyleSheet( 0 );
        _eState = HTMLParser::CallParser();

        if (mpEditEngine->IsHtmlImportHandlerSet())
        {
            HtmlImportInfo aImportInfo(HtmlImportState::End, this, mpEditEngine->CreateESelection(aCurSel));
            mpEditEngine->CallHtmlImportHandler(aImportInfo);
        }

        if ( bFieldsInserted )
            mpEditEngine->UpdateFieldsOnly();
    }
    return _eState;
}

void EditHTMLParser::Newline()
{
    bool bHasText = HasTextInCurrentPara();
    if ( bHasText )
        ImpInsertParaBreak();
    StartPara( false );
}

void EditHTMLParser::NextToken( HtmlTokenId nToken )
{
    switch( nToken )
    {
    case HtmlTokenId::META:
    {
        const HTMLOptions& aOptions = GetOptions();
        size_t nArrLen = aOptions.size();
        bool bEquiv = false;
        for ( size_t i = 0; i < nArrLen; i++ )
        {
            const HTMLOption& aOption = aOptions[i];
            switch( aOption.GetToken() )
            {
                case HtmlOptionId::HTTPEQUIV:
                {
                    bEquiv = true;
                }
                break;
                case HtmlOptionId::CONTENT:
                {
                    if ( bEquiv )
                    {
                        rtl_TextEncoding eEnc = GetEncodingByMIME( aOption.GetString() );
                        if ( eEnc != RTL_TEXTENCODING_DONTKNOW )
                            SetSrcEncoding( eEnc );
                    }
                }
                break;
                defaultbreak;
            }
        }

    }
    break;
    case HtmlTokenId::PLAINTEXT_ON:
    case HtmlTokenId::PLAINTEXT2_ON:
        bInPara = true;
    break;
    case HtmlTokenId::PLAINTEXT_OFF:
    case HtmlTokenId::PLAINTEXT2_OFF:
        bInPara = false;
    break;

    case HtmlTokenId::LINEBREAK:
    case HtmlTokenId::NEWPARA:
    {
        if ( ( bInPara || nInTable ) &&
            ( ( nToken == HtmlTokenId::LINEBREAK ) || HasTextInCurrentPara() ) )
        {
            ImpInsertParaBreak();
        }
    }
    break;
    case HtmlTokenId::HORZRULE:
    {
        if ( HasTextInCurrentPara() )
            ImpInsertParaBreak();
        ImpInsertParaBreak();
    }
    break;
    case HtmlTokenId::NONBREAKSPACE:
    {
        if ( bInPara )
        {
            ImpInsertText( u" "_ustr );
        }
    }
    break;
    case HtmlTokenId::RAWDATA:
        if (IsReadStyle() && !aToken.isEmpty())
        {
            // Each token represents a single line.
            maStyleSource.append(aToken);
            maStyleSource.append('\n');
        }
    break;
    case HtmlTokenId::TEXTTOKEN:
    {
        // #i110937# for <title> content, call aImportHdl (no SkipGroup), but don't insert the text into the EditEngine
        if (!bInTitle)
        {
            if ( !bInPara )
                StartPara( false );

            OUString aText = aToken.toString();
            if ( aText.startsWith(" ") && ThrowAwayBlank() && !IsReadPRE() )
                aText = aText.copy( 1 );

            if ( moCurAnchor )
            {
                moCurAnchor->aText += aText;
            }
            else
            {
                // Only written until HTML with 319?
                if ( IsReadPRE() )
                    aText = aText.replaceAll(u"\t", u" ");
                ImpInsertText( aText );
            }
        }
    }
    break;

    case HtmlTokenId::CENTER_ON:
    case HtmlTokenId::CENTER_OFF:
                            {
                                sal_Int32 nNode = mpEditEngine->GetEditDoc().GetPos( aCurSel.Max().GetNode() );
                                SfxItemSet aItems( aCurSel.Max().GetNode()->GetContentAttribs().GetItems() );
                                aItems.ClearItem( EE_PARA_JUST );
                                if ( nToken == HtmlTokenId::CENTER_ON )
                                    aItems.Put( SvxAdjustItem( SvxAdjust::Center, EE_PARA_JUST ) );
                                mpEditEngine->SetParaAttribsOnly(nNode, aItems);
                            }
                            break;

    case HtmlTokenId::ANCHOR_ON:    AnchorStart();
                            break;
    case HtmlTokenId::ANCHOR_OFF:   AnchorEnd();
                            break;

    case HtmlTokenId::PARABREAK_ON:
        if( bInPara && HasTextInCurrentPara() )
            EndPara();
        StartPara( true );
        break;

    case HtmlTokenId::PARABREAK_OFF:
        if( bInPara )
            EndPara();
        break;

    case HtmlTokenId::HEAD1_ON:
    case HtmlTokenId::HEAD2_ON:
    case HtmlTokenId::HEAD3_ON:
    case HtmlTokenId::HEAD4_ON:
    case HtmlTokenId::HEAD5_ON:
    case HtmlTokenId::HEAD6_ON:
    {
        HeadingStart( nToken );
    }
    break;

    case HtmlTokenId::HEAD1_OFF:
    case HtmlTokenId::HEAD2_OFF:
    case HtmlTokenId::HEAD3_OFF:
    case HtmlTokenId::HEAD4_OFF:
    case HtmlTokenId::HEAD5_OFF:
    case HtmlTokenId::HEAD6_OFF:
    {
        HeadingEnd();
    }
    break;

    case HtmlTokenId::PREFORMTXT_ON:
    case HtmlTokenId::XMP_ON:
    case HtmlTokenId::LISTING_ON:
    {
        StartPara( true );
        ImpSetStyleSheet( STYLE_PRE );
    }
    break;

    case HtmlTokenId::DEFLIST_ON:
    {
        nDefListLevel++;
    }
    break;

    case HtmlTokenId::DEFLIST_OFF:
    {
        if( nDefListLevel )
            nDefListLevel--;
    }
    break;

    case HtmlTokenId::TABLE_ON:     nInTable++;
                            break;
    case HtmlTokenId::TABLE_OFF:    DBG_ASSERT( nInTable, "Not in Table, but TABLE_OFF?" );
                            nInTable--;
                            break;

    case HtmlTokenId::TABLEHEADER_ON:
    case HtmlTokenId::TABLEDATA_ON:
        nInCell++;
        Newline();
    break;

    case HtmlTokenId::DIVISION_ON:
    case HtmlTokenId::DIVISION_OFF:
    {
        mbNewBlockNeeded = true;
        break;
    }

    case HtmlTokenId::BLOCKQUOTE_ON:
    case HtmlTokenId::BLOCKQUOTE_OFF:
    case HtmlTokenId::BLOCKQUOTE30_ON:
    case HtmlTokenId::BLOCKQUOTE30_OFF:
    case HtmlTokenId::LISTHEADER_ON:
    case HtmlTokenId::LI_ON:
    case HtmlTokenId::DD_ON:
    case HtmlTokenId::DT_ON:
    case HtmlTokenId::ORDERLIST_ON:
    case HtmlTokenId::UNORDERLIST_ON:
        Newline();
    break;

    case HtmlTokenId::TABLEHEADER_OFF:
    case HtmlTokenId::TABLEDATA_OFF:
        if ( nInCell )
            nInCell--;
        EndPara();
    break;
    case HtmlTokenId::LISTHEADER_OFF:
    case HtmlTokenId::LI_OFF:
    case HtmlTokenId::DD_OFF:
    case HtmlTokenId::DT_OFF:
    case HtmlTokenId::ORDERLIST_OFF:
    case HtmlTokenId::UNORDERLIST_OFF:
        EndPara();
    break;

    case HtmlTokenId::TABLEROW_ON:
    case HtmlTokenId::TABLEROW_OFF: // A RETURN only after a CELL, for Calc

    case HtmlTokenId::COL_ON:
    case HtmlTokenId::COLGROUP_ON:
    case HtmlTokenId::COLGROUP_OFF: break;

    case HtmlTokenId::FONT_ON:
                            break;
    case HtmlTokenId::FONT_OFF:
                            break;

    case HtmlTokenId::TITLE_ON:
        bInTitle = true;
        break;
    case HtmlTokenId::TITLE_OFF:
        bInTitle = false;
        break;

    // globals
    case HtmlTokenId::HTML_ON:
    case HtmlTokenId::HTML_OFF:
    case HtmlTokenId::STYLE_ON:
    case HtmlTokenId::STYLE_OFF:
    case HtmlTokenId::BODY_ON:
    case HtmlTokenId::BODY_OFF:
    case HtmlTokenId::HEAD_ON:
    case HtmlTokenId::HEAD_OFF:
    case HtmlTokenId::FORM_ON:
    case HtmlTokenId::FORM_OFF:
    case HtmlTokenId::THEAD_ON:
    case HtmlTokenId::THEAD_OFF:
    case HtmlTokenId::TBODY_ON:
    case HtmlTokenId::TBODY_OFF:
    // inline elements, structural markup
    // HTML 3.0
    case HtmlTokenId::BANNER_ON:
    case HtmlTokenId::BANNER_OFF:
//  case HtmlTokenId::LISTHEADER_ON:        //! special handling
//  case HtmlTokenId::LISTHEADER_OFF:
    case HtmlTokenId::NOTE_ON:
    case HtmlTokenId::NOTE_OFF:
    // inline elements, logical markup
    // HTML 2.0
    case HtmlTokenId::ADDRESS_ON:
    case HtmlTokenId::ADDRESS_OFF:
//  case HtmlTokenId::BLOCKQUOTE_ON:        //! special handling
//  case HtmlTokenId::BLOCKQUOTE_OFF:
    case HtmlTokenId::CITATION_ON:
    case HtmlTokenId::CITATION_OFF:
    case HtmlTokenId::CODE_ON:
    case HtmlTokenId::CODE_OFF:
    case HtmlTokenId::DEFINSTANCE_ON:
    case HtmlTokenId::DEFINSTANCE_OFF:
    case HtmlTokenId::EMPHASIS_ON:
    case HtmlTokenId::EMPHASIS_OFF:
    case HtmlTokenId::KEYBOARD_ON:
    case HtmlTokenId::KEYBOARD_OFF:
    case HtmlTokenId::SAMPLE_ON:
    case HtmlTokenId::SAMPLE_OFF:
    case HtmlTokenId::STRIKE_ON:
    case HtmlTokenId::STRIKE_OFF:
    case HtmlTokenId::STRONG_ON:
    case HtmlTokenId::STRONG_OFF:
    case HtmlTokenId::VARIABLE_ON:
    case HtmlTokenId::VARIABLE_OFF:
    // HTML 3.0
    case HtmlTokenId::ABBREVIATION_ON:
    case HtmlTokenId::ABBREVIATION_OFF:
    case HtmlTokenId::ACRONYM_ON:
    case HtmlTokenId::ACRONYM_OFF:
    case HtmlTokenId::AUTHOR_ON:
    case HtmlTokenId::AUTHOR_OFF:
//  case HtmlTokenId::BLOCKQUOTE30_ON:      //! special handling
//  case HtmlTokenId::BLOCKQUOTE30_OFF:
    case HtmlTokenId::DELETEDTEXT_ON:
    case HtmlTokenId::DELETEDTEXT_OFF:
    case HtmlTokenId::INSERTEDTEXT_ON:
    case HtmlTokenId::INSERTEDTEXT_OFF:
    case HtmlTokenId::LANGUAGE_ON:
    case HtmlTokenId::LANGUAGE_OFF:
    case HtmlTokenId::PERSON_ON:
    case HtmlTokenId::PERSON_OFF:
    case HtmlTokenId::SHORTQUOTE_ON:
    case HtmlTokenId::SHORTQUOTE_OFF:
    case HtmlTokenId::SUBSCRIPT_ON:
    case HtmlTokenId::SUBSCRIPT_OFF:
    case HtmlTokenId::SUPERSCRIPT_ON:
    case HtmlTokenId::SUPERSCRIPT_OFF:
    // inline elements, visual markup
    // HTML 2.0
    case HtmlTokenId::BOLD_ON:
    case HtmlTokenId::BOLD_OFF:
    case HtmlTokenId::ITALIC_ON:
    case HtmlTokenId::ITALIC_OFF:
    case HtmlTokenId::TELETYPE_ON:
    case HtmlTokenId::TELETYPE_OFF:
    case HtmlTokenId::UNDERLINE_ON:
    case HtmlTokenId::UNDERLINE_OFF:
    // HTML 3.0
    case HtmlTokenId::BIGPRINT_ON:
    case HtmlTokenId::BIGPRINT_OFF:
    case HtmlTokenId::STRIKETHROUGH_ON:
    case HtmlTokenId::STRIKETHROUGH_OFF:
    case HtmlTokenId::SMALLPRINT_ON:
    case HtmlTokenId::SMALLPRINT_OFF:
    // figures
    case HtmlTokenId::FIGURE_ON:
    case HtmlTokenId::FIGURE_OFF:
    case HtmlTokenId::CAPTION_ON:
    case HtmlTokenId::CAPTION_OFF:
    case HtmlTokenId::CREDIT_ON:
    case HtmlTokenId::CREDIT_OFF:
    // misc
    case HtmlTokenId::DIRLIST_ON:
    case HtmlTokenId::DIRLIST_OFF:
    case HtmlTokenId::FOOTNOTE_ON:          //! they land so in the text
    case HtmlTokenId::FOOTNOTE_OFF:
    case HtmlTokenId::MENULIST_ON:
    case HtmlTokenId::MENULIST_OFF:
//  case HtmlTokenId::PLAINTEXT_ON:         //! special handling
//  case HtmlTokenId::PLAINTEXT_OFF:
//  case HtmlTokenId::PREFORMTXT_ON:        //! special handling
//  case HtmlTokenId::PREFORMTXT_OFF:
    case HtmlTokenId::SPAN_ON:
    case HtmlTokenId::SPAN_OFF:
    // obsolete
//  case HtmlTokenId::XMP_ON:               //! special handling
//  case HtmlTokenId::XMP_OFF:
//  case HtmlTokenId::LISTING_ON:           //! special handling
//  case HtmlTokenId::LISTING_OFF:
    // Netscape
    case HtmlTokenId::BLINK_ON:
    case HtmlTokenId::BLINK_OFF:
    case HtmlTokenId::NOBR_ON:
    case HtmlTokenId::NOBR_OFF:
    case HtmlTokenId::NOEMBED_ON:
    case HtmlTokenId::NOEMBED_OFF:
    case HtmlTokenId::NOFRAMES_ON:
    case HtmlTokenId::NOFRAMES_OFF:
    // Internet Explorer
    case HtmlTokenId::MARQUEE_ON:
    case HtmlTokenId::MARQUEE_OFF:
//  case HtmlTokenId::PLAINTEXT2_ON:        //! special handling
//  case HtmlTokenId::PLAINTEXT2_OFF:
    break;

    default:
    {
        if ( nToken >= HtmlTokenId::ONOFF_START )
        {
            if ( ( nToken == HtmlTokenId::UNKNOWNCONTROL_ON ) || ( nToken == HtmlTokenId::UNKNOWNCONTROL_OFF ) )
            {
                ;
            }
            else if ( !isOffToken(nToken) )
            {
                DBG_ASSERT( !isOffToken( nToken ), "No Start-Token ?!" );
                SkipGroup( static_cast<HtmlTokenId>(static_cast<int>(nToken) + 1) );
            }
        }
    }
    }   // SWITCH

    if (mpEditEngine->IsHtmlImportHandlerSet())
    {
        HtmlImportInfo aImportInfo(HtmlImportState::NextToken, this, mpEditEngine->CreateESelection(aCurSel));
        aImportInfo.nToken = nToken;
        if ( nToken == HtmlTokenId::TEXTTOKEN )
            aImportInfo.aText = aToken;
        else if (nToken == HtmlTokenId::STYLE_OFF)
            aImportInfo.aText = maStyleSource.makeStringAndClear();
        mpEditEngine->CallHtmlImportHandler(aImportInfo);
    }

}

void EditHTMLParser::ImpInsertParaBreak()
{
    if (mpEditEngine->IsHtmlImportHandlerSet())
    {
        HtmlImportInfo aImportInfo(HtmlImportState::InsertPara, this, mpEditEngine->CreateESelection(aCurSel));
        mpEditEngine->CallHtmlImportHandler(aImportInfo);
    }
    aCurSel = mpEditEngine->InsertParaBreak(aCurSel);
    mbNewBlockNeeded = false;
}

void EditHTMLParser::ImpSetAttribs( const SfxItemSet& rItems )
{
    // pSel, when character attributes, otherwise paragraph attributes for
    // the current paragraph.
    DBG_ASSERT( aCurSel.Min().GetNode() == aCurSel.Max().GetNode(), "ImpInsertAttribs: Selection?" );

    EditPaM aStartPaM( aCurSel.Min() );
    EditPaM aEndPaM( aCurSel.Max() );

    aStartPaM.SetIndex( 0 );
    aEndPaM.SetIndex( aEndPaM.GetNode()->Len() );

    if (mpEditEngine->IsHtmlImportHandlerSet())
    {
        EditSelection aSel( aStartPaM, aEndPaM );
        HtmlImportInfo aImportInfo(HtmlImportState::SetAttr, this, mpEditEngine->CreateESelection(aSel));
        mpEditEngine->CallHtmlImportHandler(aImportInfo);
    }

    ContentNode* pSN = aStartPaM.GetNode();
    sal_Int32 nStartNode = mpEditEngine->GetEditDoc().GetPos( pSN );

    // If an attribute goes from 0 to current Paragraph length,
    // then it should be a paragraph attribute!

    // Note: Selection can reach over several Paragraphs.
    // All complete paragraphs are paragraph attributes ...

    // not really HTML:
#ifdef DBG_UTIL
    ContentNode* pEN = aEndPaM.GetNode();
    sal_Int32 nEndNode = mpEditEngine->GetEditDoc().GetPos( pEN );
    DBG_ASSERT( nStartNode == nEndNode, "ImpSetAttribs: Several paragraphs?" );
#endif

    if ( ( aStartPaM.GetIndex() == 0 ) && ( aEndPaM.GetIndex() == aEndPaM.GetNode()->Len() ) )
    {
        // Has to be merged:
        SfxItemSet aItems = mpEditEngine->GetBaseParaAttribs(nStartNode);
        aItems.Put( rItems );
        mpEditEngine->SetParaAttribsOnly(nStartNode, aItems);
    }
    else
        mpEditEngine->SetAttribs( EditSelection( aStartPaM, aEndPaM ), rItems );
}

void EditHTMLParser::ImpSetStyleSheet( sal_uInt16 nHLevel )
{
    /*
        nHLevel:    0:          Turn off
                    1-6:        Heading
                    STYLE_PRE:  Preformatted
    */

    // Create hard attributes ...
    // Enough for Calc, would have to be clarified with StyleSheets
    // that they should also be in the app so that when they are feed
    // in a different engine still are here ...
    sal_Int32 nNode = mpEditEngine->GetEditDoc().GetPos( aCurSel.Max().GetNode() );

    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 );

    aItems.ClearItem( EE_CHAR_FONTHEIGHT_CJK );
    aItems.ClearItem( EE_CHAR_FONTINFO_CJK );
    aItems.ClearItem( EE_CHAR_WEIGHT_CJK );

    aItems.ClearItem( EE_CHAR_FONTHEIGHT_CTL );
    aItems.ClearItem( EE_CHAR_FONTINFO_CTL );
    aItems.ClearItem( EE_CHAR_WEIGHT_CTL );

    // Bold in the first 3 Headings
    if ( ( nHLevel >= 1 ) && ( nHLevel <= 3 ) )
    {
        SvxWeightItem aWeightItem( WEIGHT_BOLD, EE_CHAR_WEIGHT );
        aItems.Put( aWeightItem );

        SvxWeightItem aWeightItemCJK( WEIGHT_BOLD, EE_CHAR_WEIGHT_CJK );
        aItems.Put( aWeightItemCJK );

        SvxWeightItem aWeightItemCTL( WEIGHT_BOLD, EE_CHAR_WEIGHT_CTL );
        aItems.Put( aWeightItemCTL );
    }

    // Font height and margins, when LogicToLogic is possible:
    MapUnit eUnit = mpEditEngine->GetRefMapMode().GetMapUnit();
    if ( ( eUnit != MapUnit::MapPixel ) && ( eUnit != MapUnit::MapSysFont ) &&
         ( eUnit != MapUnit::MapAppFont ) && ( eUnit != MapUnit::MapRelative ) )
    {
        tools::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, MapUnit::MapPoint, eUnit );

        SvxFontHeightItem aHeightItem( nPoints, 100, EE_CHAR_FONTHEIGHT );
        aItems.Put( aHeightItem );

        SvxFontHeightItem aHeightItemCJK( nPoints, 100, EE_CHAR_FONTHEIGHT_CJK );
        aItems.Put( aHeightItemCJK );

        SvxFontHeightItem aHeightItemCTL( nPoints, 100, EE_CHAR_FONTHEIGHT_CTL );
        aItems.Put( aHeightItemCTL );

        // Paragraph margins, when Heading:
        if (nHLevel <= 6)
        {
            SvxULSpaceItem aULSpaceItem( EE_PARA_ULSPACE );
            aULSpaceItem.SetUpper( static_cast<sal_uInt16>(OutputDevice::LogicToLogic( 42, MapUnit::Map10thMM, eUnit )) );
            aULSpaceItem.SetLower( static_cast<sal_uInt16>(OutputDevice::LogicToLogic( 35, MapUnit::Map10thMM, eUnit )) );
            aItems.Put( aULSpaceItem );
        }
    }

    // Choose a proportional Font for Pre
    if ( nHLevel == STYLE_PRE )
    {
        vcl::Font aFont = OutputDevice::GetDefaultFont( DefaultFontType::FIXED, LANGUAGE_SYSTEM, GetDefaultFontFlags::NONE );
        SvxFontItem aFontItem( aFont.GetFamilyTypeMaybeAskConfig(), aFont.GetFamilyName(), OUString(), aFont.GetPitchMaybeAskConfig(), aFont.GetCharSet(), EE_CHAR_FONTINFO );
        aItems.Put( aFontItem );

        SvxFontItem aFontItemCJK( aFont.GetFamilyTypeMaybeAskConfig(), aFont.GetFamilyName(), OUString(), aFont.GetPitchMaybeAskConfig(), aFont.GetCharSet(), EE_CHAR_FONTINFO_CJK );
        aItems.Put( aFontItemCJK );

        SvxFontItem aFontItemCTL( aFont.GetFamilyTypeMaybeAskConfig(), aFont.GetFamilyName(), OUString(), aFont.GetPitchMaybeAskConfig(), aFont.GetCharSet(), EE_CHAR_FONTINFO_CTL );
        aItems.Put( aFontItemCTL );
    }

    mpEditEngine->SetParaAttribsOnly(nNode, aItems);
}

void EditHTMLParser::ImpInsertText( const OUString& rText )
{
    if (mbNewBlockNeeded)
    {
        if (mbBreakForDivs)
            Newline();
        mbNewBlockNeeded = false;
    }

    if (mpEditEngine->IsHtmlImportHandlerSet())
    {
        HtmlImportInfo aImportInfo(HtmlImportState::InsertText, this, mpEditEngine->CreateESelection(aCurSel));
        aImportInfo.aText = rText;
        mpEditEngine->CallHtmlImportHandler(aImportInfo);
    }

    aCurSel = mpEditEngine->InsertText(aCurSel, rText);
}

void EditHTMLParser::SkipGroup( HtmlTokenId nEndToken )
{
    // 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>
    sal_uInt8 nCellLevel = nInCell;
    HtmlTokenId nToken;
    while( nCellLevel <= nInCell )
    {
        nToken = GetNextToken();
        if (nToken == nEndToken || nToken == HtmlTokenId::NONE)
            break;
        switch ( nToken )
        {
            case HtmlTokenId::TABLEHEADER_ON:
            case HtmlTokenId::TABLEDATA_ON:
                nInCell++;
            break;
            case HtmlTokenId::TABLEHEADER_OFF:
            case HtmlTokenId::TABLEDATA_OFF:
                if ( nInCell )
                    nInCell--;
            break;
            defaultbreak;
        }
    }
}

void EditHTMLParser::StartPara( bool bReal )
{
    if ( bReal )
    {
        const HTMLOptions& aOptions = GetOptions();
        SvxAdjust eAdjust = SvxAdjust::Left;
        for (const auto & aOption : aOptions)
        {
            if( aOption.GetToken() == HtmlOptionId::ALIGN )
            {
                OUString const& rTmp(aOption.GetString());
                if (rTmp.equalsIgnoreAsciiCase(OOO_STRING_SVTOOLS_HTML_AL_right))
                    eAdjust = SvxAdjust::Right;
                else if (rTmp.equalsIgnoreAsciiCase(OOO_STRING_SVTOOLS_HTML_AL_middle))
                    eAdjust = SvxAdjust::Center;
                else if (rTmp.equalsIgnoreAsciiCase(OOO_STRING_SVTOOLS_HTML_AL_center))
                    eAdjust = SvxAdjust::Center;
                else
                    eAdjust = SvxAdjust::Left;
            }
        }
        SfxItemSet aItemSet = mpEditEngine->GetEmptyItemSet();
        aItemSet.Put( SvxAdjustItem( eAdjust, EE_PARA_JUST ) );
        ImpSetAttribs( aItemSet );
    }
    bInPara = true;
}

void EditHTMLParser::EndPara()
{
    if ( bInPara )
    {
        bool bHasText = HasTextInCurrentPara();
        if ( bHasText )
            ImpInsertParaBreak();
    }
    bInPara = false;
}

bool EditHTMLParser::ThrowAwayBlank()
{
    // A blank must be thrown away if the new text begins with a Blank and
    // if the current paragraph is empty or ends with a Blank...
    ContentNode* pNode = aCurSel.Max().GetNode();
    return !(pNode->Len() && ( pNode->GetChar( pNode->Len()-1 ) != ' ' ));
}

bool EditHTMLParser::HasTextInCurrentPara()
{
    return aCurSel.Max().GetNode()->Len() != 0;
}

void EditHTMLParser::AnchorStart()
{
    // ignore anchor in anchor
    if ( moCurAnchor )
        return;

    const HTMLOptions& aOptions = GetOptions();
    OUString aRef;

    for (const auto & aOption : aOptions)
    {
        if( aOption.GetToken() == HtmlOptionId::HREF)
            aRef = aOption.GetString();
    }

    if ( aRef.isEmpty() )
        return;

    OUString aURL = aRef;
    if ( !aURL.isEmpty() && ( aURL[ 0 ] != '#' ) )
    {
        INetURLObject aTargetURL;
        INetURLObject aRootURL( aBaseURL );
        aRootURL.GetNewAbsURL( aRef, &aTargetURL );
        aURL = aTargetURL.GetMainURL( INetURLObject::DecodeMechanism::ToIUri );
    }
    moCurAnchor.emplace();
    moCurAnchor->aHRef = aURL;
}

void EditHTMLParser::AnchorEnd()
{
    if ( !moCurAnchor )
        return;

    // Insert as URL-Field...
    SvxFieldItem aFld( SvxURLField( moCurAnchor->aHRef, moCurAnchor->aText, SvxURLFormat::Repr ), EE_FEATURE_FIELD  );
    aCurSel = mpEditEngine->InsertField(aCurSel, aFld);
    bFieldsInserted = true;
    moCurAnchor.reset();

    if (mpEditEngine->IsHtmlImportHandlerSet())
    {
        HtmlImportInfo aImportInfo(HtmlImportState::InsertField, this, mpEditEngine->CreateESelection(aCurSel));
        mpEditEngine->CallHtmlImportHandler(aImportInfo);
    }
}

void EditHTMLParser::HeadingStart( HtmlTokenId nToken )
{
    bWasInPara = bInPara;
    StartPara( false );

    if ( bWasInPara && HasTextInCurrentPara() )
        ImpInsertParaBreak();

    sal_uInt16 nId = sal::static_int_cast< sal_uInt16 >(
        1 + ( ( static_cast<int>(nToken) - int(HtmlTokenId::HEAD1_ON) ) / 2 ) );
    DBG_ASSERT( (nId >= 1) && (nId <= 9), "HeadingStart: ID can not be correct!" );
    ImpSetStyleSheet( nId );
}

void EditHTMLParser::HeadingEnd()
{
    EndPara();
    ImpSetStyleSheet( 0 );

    if ( bWasInPara )
    {
        bInPara = true;
        bWasInPara = false;
    }
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Messung V0.5
C=92 H=91 G=91

¤ Dauer der Verarbeitung: 0.3 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.