blob: 1b639e46cc76454f2f8996fbf7841044149bc055 [file] [log] [blame]
/**************************************************************
*
* 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
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the 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 <eertfpar.hxx>
#include <impedit.hxx>
#include <svl/intitem.hxx>
#include <editeng/escpitem.hxx>
#include <editeng/fhgtitem.hxx>
#include <editeng/fontitem.hxx>
#include <editeng/flditem.hxx>
#include <svtools/rtftoken.h>
// alle Werte auf default; wird nach einlesen der Bitmap aufgerufen !
void SvxRTFPictureType::ResetValues()
{ // setze alle Werte RTF-Defaults
eStyle = RTF_BITMAP;
nMode = HEX_MODE;
nType = nGoalWidth = nGoalHeight = 0;
nWidth = nHeight = nWidthBytes = 0;
uPicLen = 0;
nBitsPerPixel = nPlanes = 1;
nScalX = nScalY = 100; // Skalierung in Prozent
nCropT = nCropB = nCropL = nCropR = 0;
aPropertyPairs.clear();
}
ImportInfo::ImportInfo( ImportState eSt, SvParser* pPrsrs, const ESelection& rSel )
: aSelection( rSel )
{
pParser = pPrsrs,
eState = eSt;
nToken = 0;
nTokenValue = 0;
pAttrs = NULL;
}
ImportInfo::~ImportInfo()
{
}
EditRTFParser::EditRTFParser( SvStream& rIn, EditSelection aSel, SfxItemPool& rAttrPool, ImpEditEngine* pImpEE )
: SvxRTFParser( rAttrPool, rIn, 0 ), aRTFMapMode( MAP_TWIP )
{
pImpEditEngine = pImpEE;
aCurSel = aSel;
eDestCharSet = RTL_TEXTENCODING_DONTKNOW;
nDefFont = 0;
nDefTab = 0;
nLastAction = 0;
nDefFontHeight = 0;
SetInsPos( EditPosition( pImpEditEngine, &aCurSel ) );
// Umwandeln der Twips-Werte...
SetCalcValue( sal_True );
SetChkStyleAttr( pImpEE->GetStatus().DoImportRTFStyleSheets() );
SetNewDoc( sal_False ); // damit die Pool-Defaults nicht
// ueberschrieben werden...
aEditMapMode = MapMode( pImpEE->GetRefDevice()->GetMapMode().GetMapUnit() );
}
EditRTFParser::~EditRTFParser()
{
}
SvParserState __EXPORT EditRTFParser::CallParser()
{
DBG_ASSERT( !aCurSel.HasRange(), "Selection bei CallParser!" );
// Den Teil, in den importiert wird, vom Rest abtrennen.
// Diese Mimik sollte fuer alle Imports verwendet werden.
// aStart1PaM: Letzte Position vor dem importierten Inhalt
// aEnd1PaM: Erste Position nach dem importierten Inhalt
// aStart2PaM: Erste Position des importierten Inhaltes
// aEnd2PaM: Letzte Position des importierten Inhaltes
EditPaM aStart1PaM( aCurSel.Min().GetNode(), aCurSel.Min().GetIndex() );
aCurSel = pImpEditEngine->ImpInsertParaBreak( aCurSel );
EditPaM aStart2PaM = aCurSel.Min();
// Sinnvoll oder nicht?:
aStart2PaM.GetNode()->GetContentAttribs().GetItems().ClearItem();
AddRTFDefaultValues( aStart2PaM, aStart2PaM );
EditPaM aEnd1PaM( pImpEditEngine->ImpInsertParaBreak( aCurSel.Max() ) );
// aCurCel zeigt jetzt auf den Zwischenraum
if ( pImpEditEngine->aImportHdl.IsSet() )
{
ImportInfo aImportInfo( RTFIMP_START, this, pImpEditEngine->CreateESel( aCurSel ) );
pImpEditEngine->aImportHdl.Call( &aImportInfo );
}
SvParserState _eState = SvxRTFParser::CallParser();
if ( pImpEditEngine->aImportHdl.IsSet() )
{
ImportInfo aImportInfo( RTFIMP_END, this, pImpEditEngine->CreateESel( aCurSel ) );
pImpEditEngine->aImportHdl.Call( &aImportInfo );
}
if ( nLastAction == ACTION_INSERTPARABRK )
{
ContentNode* pCurNode = aCurSel.Max().GetNode();
sal_uInt16 nPara = pImpEditEngine->GetEditDoc().GetPos( pCurNode );
ContentNode* pPrevNode = pImpEditEngine->GetEditDoc().SaveGetObject( nPara-1 );
DBG_ASSERT( pPrevNode, "Ungueltiges RTF-Dokument ?!" );
EditSelection aSel;
aSel.Min() = EditPaM( pPrevNode, pPrevNode->Len() );
aSel.Max() = EditPaM( pCurNode, 0 );
aCurSel.Max() = pImpEditEngine->ImpDeleteSelection( aSel );
}
EditPaM aEnd2PaM( aCurSel.Max() );
//AddRTFDefaultValues( aStart2PaM, aEnd2PaM );
sal_Bool bOnlyOnePara = ( aEnd2PaM.GetNode() == aStart2PaM.GetNode() );
// Den Brocken wieder einfuegen...
// Problem: Absatzattribute duerfen ggf. nicht uebernommen werden
// => Zeichenattribute machen.
sal_Bool bSpecialBackward = aStart1PaM.GetNode()->Len() ? sal_False : sal_True;
if ( bOnlyOnePara || aStart1PaM.GetNode()->Len() )
pImpEditEngine->ParaAttribsToCharAttribs( aStart2PaM.GetNode() );
aCurSel.Min() = pImpEditEngine->ImpConnectParagraphs(
aStart1PaM.GetNode(), aStart2PaM.GetNode(), bSpecialBackward );
bSpecialBackward = aEnd1PaM.GetNode()->Len() ? sal_True : sal_False;
// wenn bOnlyOnePara, dann ist der Node beim Connect verschwunden.
if ( !bOnlyOnePara && aEnd1PaM.GetNode()->Len() )
pImpEditEngine->ParaAttribsToCharAttribs( aEnd2PaM.GetNode() );
aCurSel.Max() = pImpEditEngine->ImpConnectParagraphs(
( bOnlyOnePara ? aStart1PaM.GetNode() : aEnd2PaM.GetNode() ),
aEnd1PaM.GetNode(), bSpecialBackward );
return _eState;
}
void EditRTFParser::AddRTFDefaultValues( const EditPaM& rStart, const EditPaM& rEnd )
{
// Problem: DefFont und DefFontHeight
Size aSz( 12, 0 );
MapMode aPntMode( MAP_POINT );
MapMode _aEditMapMode( pImpEditEngine->GetRefDevice()->GetMapMode().GetMapUnit() );
aSz = pImpEditEngine->GetRefDevice()->LogicToLogic( aSz, &aPntMode, &_aEditMapMode );
SvxFontHeightItem aFontHeightItem( aSz.Width(), 100, EE_CHAR_FONTHEIGHT );
Font aDefFont( GetDefFont() );
SvxFontItem aFontItem( aDefFont.GetFamily(), aDefFont.GetName(),
aDefFont.GetStyleName(), aDefFont.GetPitch(), aDefFont.GetCharSet(), EE_CHAR_FONTINFO );
sal_uInt16 nStartPara = pImpEditEngine->GetEditDoc().GetPos( rStart.GetNode() );
sal_uInt16 nEndPara = pImpEditEngine->GetEditDoc().GetPos( rEnd.GetNode() );
for ( sal_uInt16 nPara = nStartPara; nPara <= nEndPara; nPara++ )
{
ContentNode* pNode = pImpEditEngine->GetEditDoc().SaveGetObject( nPara );
DBG_ASSERT( pNode, "AddRTFDefaultValues - Kein Absatz ?!" );
if ( !pNode->GetContentAttribs().HasItem( EE_CHAR_FONTINFO ) )
pNode->GetContentAttribs().GetItems().Put( aFontItem );
if ( !pNode->GetContentAttribs().HasItem( EE_CHAR_FONTHEIGHT ) )
pNode->GetContentAttribs().GetItems().Put( aFontHeightItem );
}
}
void __EXPORT EditRTFParser::NextToken( int nToken )
{
switch( nToken )
{
case RTF_DEFF:
{
nDefFont = sal_uInt16(nTokenValue);
}
break;
case RTF_DEFTAB:
{
nDefTab = sal_uInt16(nTokenValue);
}
break;
case RTF_CELL:
{
aCurSel = pImpEditEngine->ImpInsertParaBreak( aCurSel );
}
break;
case RTF_LINE:
{
aCurSel = pImpEditEngine->InsertLineBreak( aCurSel );
}
break;
case RTF_FIELD:
{
ReadField();
}
break;
case RTF_PGDSCTBL: // #i29453# ignore \*\pgdsctbl destination
case RTF_LISTTEXT:
{
SkipGroup();
}
break;
default:
{
SvxRTFParser::NextToken( nToken );
if ( nToken == RTF_STYLESHEET )
CreateStyleSheets();
}
break;
}
if ( pImpEditEngine->aImportHdl.IsSet() )
{
ImportInfo aImportInfo( RTFIMP_NEXTTOKEN, this, pImpEditEngine->CreateESel( aCurSel ) );
aImportInfo.nToken = nToken;
aImportInfo.nTokenValue = short(nTokenValue);
pImpEditEngine->aImportHdl.Call( &aImportInfo );
}
}
void __EXPORT EditRTFParser::UnknownAttrToken( int nToken, SfxItemSet* )
{
// fuer Tokens, die im ReadAttr nicht ausgewertet werden
// Eigentlich nur fuer Calc (RTFTokenHdl), damit RTF_INTBL
if ( pImpEditEngine->aImportHdl.IsSet() )
{
ImportInfo aImportInfo( RTFIMP_UNKNOWNATTR, this, pImpEditEngine->CreateESel( aCurSel ) );
aImportInfo.nToken = nToken;
aImportInfo.nTokenValue = short(nTokenValue);
pImpEditEngine->aImportHdl.Call( &aImportInfo );
}
}
void __EXPORT EditRTFParser::InsertText()
{
String aText( aToken );
if ( pImpEditEngine->aImportHdl.IsSet() )
{
ImportInfo aImportInfo( RTFIMP_INSERTTEXT, this, pImpEditEngine->CreateESel( aCurSel ) );
aImportInfo.aText = aText;
pImpEditEngine->aImportHdl.Call( &aImportInfo );
}
aCurSel = pImpEditEngine->ImpInsertText( aCurSel, aText );
nLastAction = ACTION_INSERTTEXT;
}
void __EXPORT EditRTFParser::InsertPara()
{
if ( pImpEditEngine->aImportHdl.IsSet() )
{
ImportInfo aImportInfo( RTFIMP_INSERTPARA, this, pImpEditEngine->CreateESel( aCurSel ) );
pImpEditEngine->aImportHdl.Call( &aImportInfo );
}
aCurSel = pImpEditEngine->ImpInsertParaBreak( aCurSel );
nLastAction = ACTION_INSERTPARABRK;
}
void __EXPORT EditRTFParser::MovePos( int bForward )
{
if( bForward )
aCurSel = pImpEditEngine->CursorRight( aCurSel.Max(), ::com::sun::star::i18n::CharacterIteratorMode::SKIPCHARACTER );
else
aCurSel = pImpEditEngine->CursorLeft( aCurSel.Max(), ::com::sun::star::i18n::CharacterIteratorMode::SKIPCHARACTER );
}
void __EXPORT EditRTFParser::SetEndPrevPara( SvxNodeIdx*& rpNodePos,
sal_uInt16& rCntPos )
{
// Gewollt ist: von der aktuellen Einfuegeposition den vorherigen
// Absatz bestimmen und von dem das Ende setzen.
// Dadurch wird "\pard" immer auf den richtigen Absatz
// angewendet.
ContentNode* pN = aCurSel.Max().GetNode();
sal_uInt16 nCurPara = pImpEditEngine->GetEditDoc().GetPos( pN );
DBG_ASSERT( nCurPara != 0, "Absatz gleich 0: SetEnfPrevPara" );
if ( nCurPara )
nCurPara--;
ContentNode* pPrevNode = pImpEditEngine->GetEditDoc().SaveGetObject( nCurPara );
DBG_ASSERT( pPrevNode, "pPrevNode = 0!" );
rpNodePos = new EditNodeIdx( pImpEditEngine, pPrevNode );
rCntPos = pPrevNode->Len();
}
int __EXPORT EditRTFParser::IsEndPara( SvxNodeIdx* pNd, sal_uInt16 nCnt ) const
{
return ( nCnt == ( ((EditNodeIdx*)pNd)->GetNode()->Len()) );
}
void __EXPORT EditRTFParser::SetAttrInDoc( SvxRTFItemStackType &rSet )
{
ContentNode* pSttNode = ((EditNodeIdx&)rSet.GetSttNode()).GetNode();
ContentNode* pEndNode = ((EditNodeIdx&)rSet.GetEndNode()).GetNode();
EditPaM aStartPaM( pSttNode, rSet.GetSttCnt() );
EditPaM aEndPaM( pEndNode, rSet.GetEndCnt() );
// ggf. noch das Escapemant-Item umbiegen:
const SfxPoolItem* pItem;
// #i66167# adapt font heights to destination MapUnit if necessary
const MapUnit eDestUnit = ( MapUnit )( pImpEditEngine->GetEditDoc().GetItemPool().GetMetric(0) );
const MapUnit eSrcUnit = aRTFMapMode.GetMapUnit();
if (eDestUnit != eSrcUnit)
{
sal_uInt16 aFntHeightIems[3] = { EE_CHAR_FONTHEIGHT, EE_CHAR_FONTHEIGHT_CJK, EE_CHAR_FONTHEIGHT_CTL };
for (int i = 0; i < 2; ++i)
{
if (SFX_ITEM_SET == rSet.GetAttrSet().GetItemState( aFntHeightIems[i], sal_False, &pItem ))
{
sal_uInt32 nHeight = ((SvxFontHeightItem*)pItem)->GetHeight();
long nNewHeight;
nNewHeight = pImpEditEngine->GetRefDevice()->LogicToLogic( (long)nHeight, eSrcUnit, eDestUnit );
SvxFontHeightItem aFntHeightItem( nNewHeight, ((SvxFontHeightItem*)pItem)->GetProp(), aFntHeightIems[i] );
rSet.GetAttrSet().Put( aFntHeightItem );
}
}
}
if( SFX_ITEM_SET == rSet.GetAttrSet().GetItemState( EE_CHAR_ESCAPEMENT, sal_False, &pItem ))
{
// die richtige
long nEsc = ((SvxEscapementItem*)pItem)->GetEsc();
if( ( DFLT_ESC_AUTO_SUPER != nEsc ) && ( DFLT_ESC_AUTO_SUB != nEsc ) )
{
nEsc *= 10; //HalPoints => Twips wurde in RTFITEM.CXX unterschlagen!
SvxFont aFont;
pImpEditEngine->SeekCursor( aStartPaM.GetNode(), aStartPaM.GetIndex()+1, aFont );
nEsc = nEsc * 100 / aFont.GetSize().Height();
SvxEscapementItem aEscItem( (short) nEsc, ((SvxEscapementItem*)pItem)->GetProp(), EE_CHAR_ESCAPEMENT );
rSet.GetAttrSet().Put( aEscItem );
}
}
if ( pImpEditEngine->aImportHdl.IsSet() )
{
EditSelection aSel( aStartPaM, aEndPaM );
ImportInfo aImportInfo( RTFIMP_SETATTR, this, pImpEditEngine->CreateESel( aSel ) );
aImportInfo.pAttrs = &rSet;
pImpEditEngine->aImportHdl.Call( &aImportInfo );
}
ContentNode* pSN = aStartPaM.GetNode();
ContentNode* pEN = aEndPaM.GetNode();
sal_uInt16 nStartNode = pImpEditEngine->GetEditDoc().GetPos( pSN );
sal_uInt16 nEndNode = pImpEditEngine->GetEditDoc().GetPos( pEN );
sal_Int16 nOutlLevel = 0xff;
if ( rSet.StyleNo() && pImpEditEngine->GetStyleSheetPool() && pImpEditEngine->GetStatus().DoImportRTFStyleSheets() )
{
SvxRTFStyleType* pS = GetStyleTbl().Get( rSet.StyleNo() );
DBG_ASSERT( pS, "Vorlage in RTF nicht definiert!" );
if ( pS )
{
pImpEditEngine->SetStyleSheet( EditSelection( aStartPaM, aEndPaM ), (SfxStyleSheet*)pImpEditEngine->GetStyleSheetPool()->Find( pS->sName, SFX_STYLE_FAMILY_ALL ) );
nOutlLevel = pS->nOutlineNo;
}
}
// 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...
for ( sal_uInt16 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() ) )
{
// #96298# When settings char attribs as para attribs, we must merge with existing attribs, not overwrite the ItemSet!
SfxItemSet aAttrs = pImpEditEngine->GetParaAttribs( nStartNode );
aAttrs.Put( rSet.GetAttrSet() );
pImpEditEngine->SetParaAttribs( nStartNode, aAttrs );
}
else
{
pImpEditEngine->SetAttribs( EditSelection( aStartPaM, aEndPaM ), rSet.GetAttrSet() );
}
}
// OutlLevel...
if ( nOutlLevel != 0xff )
{
for ( sal_uInt16 n = nStartNode; n <= nEndNode; n++ )
{
ContentNode* pNode = pImpEditEngine->GetEditDoc().SaveGetObject( n );
pNode->GetContentAttribs().GetItems().Put( SfxInt16Item( EE_PARA_OUTLLEVEL, nOutlLevel ) );
}
}
}
SvxRTFStyleType* EditRTFParser::FindStyleSheet( const XubString& rName )
{
SvxRTFStyleType* pS = GetStyleTbl().First();
while ( pS && ( pS->sName != rName ) )
pS = GetStyleTbl().Next();
return pS;
}
SfxStyleSheet* EditRTFParser::CreateStyleSheet( SvxRTFStyleType* pRTFStyle )
{
// Prueffen, ob so eine Vorlage existiert....
// dann wird sie auch nicht geaendert!
SfxStyleSheet* pStyle = (SfxStyleSheet*)pImpEditEngine->GetStyleSheetPool()->Find( pRTFStyle->sName, SFX_STYLE_FAMILY_ALL );
if ( pStyle )
return pStyle;
String aName( pRTFStyle->sName );
String aParent;
if ( pRTFStyle->nBasedOn )
{
SvxRTFStyleType* pS = GetStyleTbl().Get( pRTFStyle->nBasedOn );
if ( pS && ( pS !=pRTFStyle ) )
aParent = pS->sName;
}
pStyle = (SfxStyleSheet*) &pImpEditEngine->GetStyleSheetPool()->Make( aName, SFX_STYLE_FAMILY_PARA );
// 1) Items konvertieren und uebernehmen...
ConvertAndPutItems( pStyle->GetItemSet(), pRTFStyle->aAttrSet );
// 2) Solange Parent nicht im Pool, auch diesen kreieren...
if ( aParent.Len() && ( aParent != aName ) )
{
SfxStyleSheet* pS = (SfxStyleSheet*)pImpEditEngine->GetStyleSheetPool()->Find( aParent, SFX_STYLE_FAMILY_ALL );
if ( !pS )
{
// Wenn nirgendwo gefunden, aus RTF erzeugen...
SvxRTFStyleType* _pRTFStyle = FindStyleSheet( aParent );
if ( _pRTFStyle )
pS = CreateStyleSheet( _pRTFStyle );
}
// 2b) ItemSet mit Parent verknuepfen...
if ( pS )
pStyle->GetItemSet().SetParent( &pS->GetItemSet() );
}
return pStyle;
}
void EditRTFParser::CreateStyleSheets()
{
// der SvxRTFParser hat jetzt die Vorlagen erzeugt...
if ( pImpEditEngine->GetStyleSheetPool() && pImpEditEngine->GetStatus().DoImportRTFStyleSheets() )
{
SvxRTFStyleType* pRTFStyle = GetStyleTbl().First();
while ( pRTFStyle )
{
CreateStyleSheet( pRTFStyle );
pRTFStyle = GetStyleTbl().Next();
}
}
}
void __EXPORT EditRTFParser::CalcValue()
{
const MapUnit eDestUnit = static_cast< MapUnit >( aEditMapMode.GetMapUnit() );
const MapUnit eSrcUnit = aRTFMapMode.GetMapUnit();
if (eDestUnit != eSrcUnit)
nTokenValue = OutputDevice::LogicToLogic( (long)nTokenValue, eSrcUnit, eDestUnit );
}
void EditRTFParser::ReadField()
{
// Aus SwRTFParser::ReadField()
int _nOpenBrakets = 1; // die erste wurde schon vorher erkannt
sal_Bool bFldInst = sal_False;
sal_Bool bFldRslt = sal_False;
String aFldInst;
String aFldRslt;
while( _nOpenBrakets && IsParserWorking() )
{
switch( GetNextToken() )
{
case '}':
{
_nOpenBrakets--;
if ( _nOpenBrakets == 1 )
{
bFldInst = sal_False;
bFldRslt = sal_False;
}
}
break;
case '{': _nOpenBrakets++;
break;
case RTF_FIELD: SkipGroup();
break;
case RTF_FLDINST: bFldInst = sal_True;
break;
case RTF_FLDRSLT: bFldRslt = sal_True;
break;
case RTF_TEXTTOKEN:
{
if ( bFldInst )
aFldInst += aToken;
else if ( bFldRslt )
aFldRslt += aToken;
}
break;
}
}
if ( aFldInst.Len() )
{
String aHyperLinkMarker( RTL_CONSTASCII_USTRINGPARAM( "HYPERLINK " ) );
if ( aFldInst.CompareIgnoreCaseToAscii( aHyperLinkMarker, aHyperLinkMarker.Len() ) == COMPARE_EQUAL )
{
aFldInst.Erase( 0, aHyperLinkMarker.Len() );
aFldInst.EraseLeadingChars();
aFldInst.EraseTrailingChars();
aFldInst.Erase( 0, 1 ); // "
aFldInst.Erase( aFldInst.Len()-1, 1 ); // "
if ( !aFldRslt.Len() )
aFldRslt = aFldInst;
SvxFieldItem aField( SvxURLField( aFldInst, aFldRslt, SVXURLFORMAT_REPR ), EE_FEATURE_FIELD );
aCurSel = pImpEditEngine->InsertField( aCurSel, aField );
pImpEditEngine->UpdateFields();
nLastAction = ACTION_INSERTTEXT;
}
}
SkipToken( -1 ); // die schliesende Klammer wird "oben" ausgewertet
}
void EditRTFParser::SkipGroup()
{
int _nOpenBrakets = 1; // die erste wurde schon vorher erkannt
while( _nOpenBrakets && IsParserWorking() )
{
switch( GetNextToken() )
{
case '}':
{
_nOpenBrakets--;
}
break;
case '{':
{
_nOpenBrakets++;
}
break;
}
}
SkipToken( -1 ); // die schliesende Klammer wird "oben" ausgewertet
}
sal_uLong __EXPORT EditNodeIdx::GetIdx() const
{
return pImpEditEngine->GetEditDoc().GetPos( pNode );
}
SvxNodeIdx* __EXPORT EditNodeIdx::Clone() const
{
return new EditNodeIdx( pImpEditEngine, pNode );
}
SvxPosition* __EXPORT EditPosition::Clone() const
{
return new EditPosition( pImpEditEngine, pCurSel );
}
SvxNodeIdx* __EXPORT EditPosition::MakeNodeIdx() const
{
return new EditNodeIdx( pImpEditEngine, pCurSel->Max().GetNode() );
}
sal_uLong __EXPORT EditPosition::GetNodeIdx() const
{
ContentNode* pN = pCurSel->Max().GetNode();
return pImpEditEngine->GetEditDoc().GetPos( pN );
}
sal_uInt16 __EXPORT EditPosition::GetCntIdx() const
{
return pCurSel->Max().GetIndex();
}