xref: /trunk/main/editeng/source/editeng/eertfpar.cxx (revision 3974c066)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_editeng.hxx"
26 
27 #include <vcl/wrkwin.hxx>
28 #include <vcl/dialog.hxx>
29 #include <vcl/msgbox.hxx>
30 #include <vcl/svapp.hxx>
31 
32 #include <eertfpar.hxx>
33 #include <impedit.hxx>
34 #include <svl/intitem.hxx>
35 #include <editeng/escpitem.hxx>
36 #include <editeng/fhgtitem.hxx>
37 #include <editeng/fontitem.hxx>
38 #include <editeng/flditem.hxx>
39 
40 #include <svtools/rtftoken.h>
41 
42 // alle Werte auf default; wird nach einlesen der Bitmap aufgerufen !
ResetValues()43 void SvxRTFPictureType::ResetValues()
44 {	// setze alle Werte RTF-Defaults
45 	eStyle = RTF_BITMAP;
46 	nMode = HEX_MODE;
47 	nType = nGoalWidth = nGoalHeight = 0;
48 	nWidth = nHeight = nWidthBytes = 0;
49 	uPicLen = 0;
50 	nBitsPerPixel = nPlanes = 1;
51 	nScalX = nScalY = 100;		// Skalierung in Prozent
52 	nCropT = nCropB = nCropL = nCropR = 0;
53     aPropertyPairs.clear();
54 }
55 
ImportInfo(ImportState eSt,SvParser * pPrsrs,const ESelection & rSel)56 ImportInfo::ImportInfo( ImportState eSt, SvParser* pPrsrs, const ESelection& rSel )
57 	: aSelection( rSel )
58 {
59 	pParser 	= pPrsrs,
60 	eState		= eSt;
61 
62 	nToken 		= 0;
63 	nTokenValue	= 0;
64 	pAttrs 		= NULL;
65 }
66 
~ImportInfo()67 ImportInfo::~ImportInfo()
68 {
69 }
70 
EditRTFParser(SvStream & rIn,EditSelection aSel,SfxItemPool & rAttrPool,ImpEditEngine * pImpEE)71 EditRTFParser::EditRTFParser( SvStream& rIn, EditSelection aSel, SfxItemPool& rAttrPool, ImpEditEngine* pImpEE  )
72 	: SvxRTFParser( rAttrPool, rIn, 0 ), aRTFMapMode( MAP_TWIP )
73 {
74 
75 	pImpEditEngine	= pImpEE;
76 	aCurSel 		= aSel;
77 	eDestCharSet	= RTL_TEXTENCODING_DONTKNOW;
78 	nDefFont		= 0;
79 	nDefTab			= 0;
80 	nLastAction		= 0;
81 	nDefFontHeight	= 0;
82 
83 	SetInsPos( EditPosition( pImpEditEngine, &aCurSel ) );
84 
85 	// Umwandeln der Twips-Werte...
86 	SetCalcValue( sal_True );
87 	SetChkStyleAttr( pImpEE->GetStatus().DoImportRTFStyleSheets() );
88 	SetNewDoc( sal_False );		// damit die Pool-Defaults nicht
89 							// ueberschrieben werden...
90 	aEditMapMode = MapMode( pImpEE->GetRefDevice()->GetMapMode().GetMapUnit() );
91 }
92 
~EditRTFParser()93 EditRTFParser::~EditRTFParser()
94 {
95 }
96 
CallParser()97 SvParserState __EXPORT EditRTFParser::CallParser()
98 {
99 	DBG_ASSERT( !aCurSel.HasRange(), "Selection bei CallParser!" );
100 	// Den Teil, in den importiert wird, vom Rest abtrennen.
101 	// Diese Mimik sollte fuer alle Imports verwendet werden.
102 	// aStart1PaM: Letzte Position vor dem importierten Inhalt
103 	// aEnd1PaM: Erste Position nach dem importierten Inhalt
104 	// aStart2PaM: Erste Position des importierten Inhaltes
105 	// aEnd2PaM: Letzte Position des importierten Inhaltes
106 	EditPaM aStart1PaM( aCurSel.Min().GetNode(), aCurSel.Min().GetIndex() );
107 	aCurSel = pImpEditEngine->ImpInsertParaBreak( aCurSel );
108 	EditPaM aStart2PaM = aCurSel.Min();
109 	// Sinnvoll oder nicht?:
110 	aStart2PaM.GetNode()->GetContentAttribs().GetItems().ClearItem();
111     AddRTFDefaultValues( aStart2PaM, aStart2PaM );
112 	EditPaM aEnd1PaM( pImpEditEngine->ImpInsertParaBreak( aCurSel.Max() ) );
113 	// aCurCel zeigt jetzt auf den Zwischenraum
114 
115 	if ( pImpEditEngine->aImportHdl.IsSet() )
116 	{
117 		ImportInfo aImportInfo( RTFIMP_START, this, pImpEditEngine->CreateESel( aCurSel ) );
118 		pImpEditEngine->aImportHdl.Call( &aImportInfo );
119 	}
120 
121 	SvParserState _eState = SvxRTFParser::CallParser();
122 
123 	if ( pImpEditEngine->aImportHdl.IsSet() )
124 	{
125 		ImportInfo aImportInfo( RTFIMP_END, this, pImpEditEngine->CreateESel( aCurSel ) );
126 		pImpEditEngine->aImportHdl.Call( &aImportInfo );
127 	}
128 
129 	if ( nLastAction == ACTION_INSERTPARABRK )
130 	{
131 		ContentNode* pCurNode = aCurSel.Max().GetNode();
132 		sal_uInt32 nPara = pImpEditEngine->GetEditDoc().GetPos( pCurNode );
133 		ContentNode* pPrevNode = pImpEditEngine->GetEditDoc().SaveGetObject( nPara-1 );
134 		DBG_ASSERT( pPrevNode, "Ungueltiges RTF-Dokument ?!" );
135 		EditSelection aSel;
136 		aSel.Min() = EditPaM( pPrevNode, pPrevNode->Len() );
137 		aSel.Max() = EditPaM( pCurNode, 0 );
138 		aCurSel.Max() = pImpEditEngine->ImpDeleteSelection( aSel );
139 	}
140 	EditPaM aEnd2PaM( aCurSel.Max() );
141     //AddRTFDefaultValues( aStart2PaM, aEnd2PaM );
142 	sal_Bool bOnlyOnePara = ( aEnd2PaM.GetNode() == aStart2PaM.GetNode() );
143 	// Den Brocken wieder einfuegen...
144 	// Problem: Absatzattribute duerfen ggf. nicht uebernommen werden
145 	// => Zeichenattribute machen.
146 
147 	sal_Bool bSpecialBackward = aStart1PaM.GetNode()->Len() ? sal_False : sal_True;
148 	if ( bOnlyOnePara || aStart1PaM.GetNode()->Len() )
149 		pImpEditEngine->ParaAttribsToCharAttribs( aStart2PaM.GetNode() );
150 	aCurSel.Min() = pImpEditEngine->ImpConnectParagraphs(
151 		aStart1PaM.GetNode(), aStart2PaM.GetNode(), bSpecialBackward );
152 	bSpecialBackward = aEnd1PaM.GetNode()->Len() ? sal_True : sal_False;
153 	// wenn bOnlyOnePara, dann ist der Node beim Connect verschwunden.
154 	if ( !bOnlyOnePara && aEnd1PaM.GetNode()->Len() )
155 		pImpEditEngine->ParaAttribsToCharAttribs( aEnd2PaM.GetNode() );
156 	aCurSel.Max() = pImpEditEngine->ImpConnectParagraphs(
157 		( bOnlyOnePara ? aStart1PaM.GetNode() : aEnd2PaM.GetNode() ),
158 			aEnd1PaM.GetNode(), bSpecialBackward );
159 
160 	return _eState;
161 }
162 
AddRTFDefaultValues(const EditPaM & rStart,const EditPaM & rEnd)163 void EditRTFParser::AddRTFDefaultValues( const EditPaM& rStart, const EditPaM& rEnd )
164 {
165 	// Problem: DefFont und DefFontHeight
166 	Size aSz( 12, 0 );
167 	MapMode aPntMode( MAP_POINT );
168 	MapMode _aEditMapMode( pImpEditEngine->GetRefDevice()->GetMapMode().GetMapUnit() );
169 	aSz = pImpEditEngine->GetRefDevice()->LogicToLogic( aSz, &aPntMode, &_aEditMapMode );
170 	SvxFontHeightItem aFontHeightItem( aSz.Width(), 100, EE_CHAR_FONTHEIGHT );
171 	Font aDefFont( GetDefFont() );
172 	SvxFontItem aFontItem( aDefFont.GetFamily(), aDefFont.GetName(),
173 					aDefFont.GetStyleName(), aDefFont.GetPitch(), aDefFont.GetCharSet(), EE_CHAR_FONTINFO );
174 
175 	sal_uInt32 nStartPara = pImpEditEngine->GetEditDoc().GetPos( rStart.GetNode() );
176 	sal_uInt32 nEndPara = pImpEditEngine->GetEditDoc().GetPos( rEnd.GetNode() );
177 	for ( sal_uInt32 nPara = nStartPara; nPara <= nEndPara; nPara++ )
178 	{
179 		ContentNode* pNode = pImpEditEngine->GetEditDoc().SaveGetObject( nPara );
180 		DBG_ASSERT( pNode, "AddRTFDefaultValues - Kein Absatz ?!" );
181 		if ( !pNode->GetContentAttribs().HasItem( EE_CHAR_FONTINFO ) )
182 			pNode->GetContentAttribs().GetItems().Put( aFontItem );
183 		if ( !pNode->GetContentAttribs().HasItem( EE_CHAR_FONTHEIGHT ) )
184 			pNode->GetContentAttribs().GetItems().Put( aFontHeightItem );
185 	}
186 }
187 
NextToken(int nToken)188 void __EXPORT EditRTFParser::NextToken( int nToken )
189 {
190 	switch( nToken )
191 	{
192 		case RTF_DEFF:
193 		{
194 			nDefFont = sal_uInt16(nTokenValue);
195 		}
196 		break;
197 		case RTF_DEFTAB:
198 		{
199 			nDefTab = sal_uInt16(nTokenValue);
200 		}
201 		break;
202 		case RTF_CELL:
203 		{
204 			aCurSel = pImpEditEngine->ImpInsertParaBreak( aCurSel );
205 		}
206 		break;
207 		case RTF_LINE:
208 		{
209 			aCurSel = pImpEditEngine->InsertLineBreak( aCurSel );
210 		}
211 		break;
212 		case RTF_FIELD:
213 		{
214 			ReadField();
215 		}
216 		break;
217 		case RTF_PGDSCTBL: // #i29453# ignore \*\pgdsctbl destination
218         case RTF_LISTTEXT:
219         {
220             SkipGroup();
221         }
222         break;
223 		default:
224 		{
225 			SvxRTFParser::NextToken( nToken );
226 			if ( nToken == RTF_STYLESHEET )
227 				CreateStyleSheets();
228 		}
229 		break;
230 	}
231 	if ( pImpEditEngine->aImportHdl.IsSet() )
232 	{
233 		ImportInfo aImportInfo( RTFIMP_NEXTTOKEN, this, pImpEditEngine->CreateESel( aCurSel ) );
234 		aImportInfo.nToken = nToken;
235 		aImportInfo.nTokenValue = short(nTokenValue);
236 		pImpEditEngine->aImportHdl.Call( &aImportInfo );
237 	}
238 }
239 
UnknownAttrToken(int nToken,SfxItemSet *)240 void __EXPORT EditRTFParser::UnknownAttrToken( int nToken, SfxItemSet* )
241 {
242 	// fuer Tokens, die im ReadAttr nicht ausgewertet werden
243 	// Eigentlich nur fuer Calc (RTFTokenHdl), damit RTF_INTBL
244 	if ( pImpEditEngine->aImportHdl.IsSet() )
245 	{
246 		ImportInfo aImportInfo( RTFIMP_UNKNOWNATTR, this, pImpEditEngine->CreateESel( aCurSel ) );
247 		aImportInfo.nToken = nToken;
248 		aImportInfo.nTokenValue = short(nTokenValue);
249 		pImpEditEngine->aImportHdl.Call( &aImportInfo );
250 	}
251 }
252 
InsertText()253 void __EXPORT EditRTFParser::InsertText()
254 {
255 	String aText( aToken );
256 	if ( pImpEditEngine->aImportHdl.IsSet() )
257 	{
258 		ImportInfo aImportInfo( RTFIMP_INSERTTEXT, this, pImpEditEngine->CreateESel( aCurSel ) );
259 		aImportInfo.aText = aText;
260 		pImpEditEngine->aImportHdl.Call( &aImportInfo );
261 	}
262 	aCurSel = pImpEditEngine->ImpInsertText( aCurSel, aText );
263 	nLastAction = ACTION_INSERTTEXT;
264 }
265 
InsertPara()266 void __EXPORT EditRTFParser::InsertPara()
267 {
268 	if ( pImpEditEngine->aImportHdl.IsSet() )
269 	{
270 		ImportInfo aImportInfo( RTFIMP_INSERTPARA, this, pImpEditEngine->CreateESel( aCurSel ) );
271 		pImpEditEngine->aImportHdl.Call( &aImportInfo );
272 	}
273 	aCurSel = pImpEditEngine->ImpInsertParaBreak( aCurSel );
274 	nLastAction = ACTION_INSERTPARABRK;
275 }
276 
MovePos(int bForward)277 void __EXPORT EditRTFParser::MovePos( int bForward )
278 {
279 	if( bForward )
280         aCurSel = pImpEditEngine->CursorRight( aCurSel.Max(), ::com::sun::star::i18n::CharacterIteratorMode::SKIPCHARACTER );
281 	else
282 		aCurSel = pImpEditEngine->CursorLeft( aCurSel.Max(), ::com::sun::star::i18n::CharacterIteratorMode::SKIPCHARACTER );
283 }
284 
SetEndPrevPara(SvxNodeIdx * & rpNodePos,sal_uInt16 & rCntPos)285 void __EXPORT EditRTFParser::SetEndPrevPara( SvxNodeIdx*& rpNodePos,
286 									sal_uInt16& rCntPos )
287 {
288 	//    Gewollt ist: von der aktuellen Einfuegeposition den vorherigen
289 	//              Absatz bestimmen und von dem das Ende setzen.
290 	//              Dadurch wird "\pard" immer auf den richtigen Absatz
291 	//              angewendet.
292 
293 	ContentNode* pN = aCurSel.Max().GetNode();
294 	sal_uInt32 nCurPara = pImpEditEngine->GetEditDoc().GetPos( pN );
295 	DBG_ASSERT( nCurPara != 0, "Absatz gleich 0: SetEnfPrevPara" );
296 	if ( nCurPara )
297 		nCurPara--;
298 	ContentNode* pPrevNode = pImpEditEngine->GetEditDoc().SaveGetObject( nCurPara );
299 	DBG_ASSERT( pPrevNode, "pPrevNode = 0!" );
300 	rpNodePos = new EditNodeIdx( pImpEditEngine, pPrevNode );
301 	rCntPos = pPrevNode->Len();
302 }
303 
IsEndPara(SvxNodeIdx * pNd,sal_uInt16 nCnt) const304 int __EXPORT EditRTFParser::IsEndPara( SvxNodeIdx* pNd, sal_uInt16 nCnt ) const
305 {
306 	return ( nCnt == ( ((EditNodeIdx*)pNd)->GetNode()->Len()) );
307 }
308 
SetAttrInDoc(SvxRTFItemStackType & rSet)309 void __EXPORT EditRTFParser::SetAttrInDoc( SvxRTFItemStackType &rSet )
310 {
311 	ContentNode* pSttNode = ((EditNodeIdx&)rSet.GetSttNode()).GetNode();
312 	ContentNode* pEndNode = ((EditNodeIdx&)rSet.GetEndNode()).GetNode();
313 
314 	EditPaM aStartPaM( pSttNode, rSet.GetSttCnt() );
315 	EditPaM aEndPaM( pEndNode, rSet.GetEndCnt() );
316 
317 	// ggf. noch das Escapemant-Item umbiegen:
318 	const SfxPoolItem* pItem;
319 
320 	// #i66167# adapt font heights to destination MapUnit if necessary
321 	const MapUnit eDestUnit	= ( MapUnit )( pImpEditEngine->GetEditDoc().GetItemPool().GetMetric(0) );
322 	const MapUnit eSrcUnit	= aRTFMapMode.GetMapUnit();
323 	if (eDestUnit != eSrcUnit)
324 	{
325 		sal_uInt16 aFntHeightIems[3] = { EE_CHAR_FONTHEIGHT, EE_CHAR_FONTHEIGHT_CJK, EE_CHAR_FONTHEIGHT_CTL };
326 		for (int i = 0; i < 2; ++i)
327 		{
328 			if (SFX_ITEM_SET == rSet.GetAttrSet().GetItemState( aFntHeightIems[i], sal_False, &pItem ))
329 			{
330 				sal_uInt32 nHeight	= ((SvxFontHeightItem*)pItem)->GetHeight();
331 				long nNewHeight;
332 				nNewHeight = pImpEditEngine->GetRefDevice()->LogicToLogic( (long)nHeight, eSrcUnit, eDestUnit );
333 
334 				SvxFontHeightItem aFntHeightItem( nNewHeight, ((SvxFontHeightItem*)pItem)->GetProp(), aFntHeightIems[i] );
335 				rSet.GetAttrSet().Put( aFntHeightItem );
336 			}
337 		}
338 	}
339 
340 	if( SFX_ITEM_SET == rSet.GetAttrSet().GetItemState( EE_CHAR_ESCAPEMENT, sal_False, &pItem ))
341 	{
342 		// die richtige
343 		long nEsc = ((SvxEscapementItem*)pItem)->GetEsc();
344 
345 		if( ( DFLT_ESC_AUTO_SUPER != nEsc ) && ( DFLT_ESC_AUTO_SUB != nEsc ) )
346 		{
347 			nEsc *= 10;	//HalPoints => Twips wurde in RTFITEM.CXX unterschlagen!
348 			SvxFont aFont;
349 			pImpEditEngine->SeekCursor( aStartPaM.GetNode(), aStartPaM.GetIndex()+1, aFont );
350 			nEsc = nEsc * 100 / aFont.GetSize().Height();
351 
352 			SvxEscapementItem aEscItem( (short) nEsc, ((SvxEscapementItem*)pItem)->GetProp(), EE_CHAR_ESCAPEMENT );
353 			rSet.GetAttrSet().Put( aEscItem );
354 		}
355 	}
356 
357 	if ( pImpEditEngine->aImportHdl.IsSet() )
358 	{
359 		EditSelection aSel( aStartPaM, aEndPaM );
360 		ImportInfo aImportInfo( RTFIMP_SETATTR, this, pImpEditEngine->CreateESel( aSel ) );
361 		aImportInfo.pAttrs = &rSet;
362 		pImpEditEngine->aImportHdl.Call( &aImportInfo );
363 	}
364 
365 	ContentNode* pSN = aStartPaM.GetNode();
366 	ContentNode* pEN = aEndPaM.GetNode();
367 	sal_uInt32 nStartNode = pImpEditEngine->GetEditDoc().GetPos( pSN );
368 	sal_uInt32 nEndNode = pImpEditEngine->GetEditDoc().GetPos( pEN );
369 	sal_Int16 nOutlLevel = 0xff;
370 
371 	if ( rSet.StyleNo() && pImpEditEngine->GetStyleSheetPool() && pImpEditEngine->GetStatus().DoImportRTFStyleSheets() )
372 	{
373 		SvxRTFStyleType* pS = GetStyleTbl().Get( rSet.StyleNo() );
374 		DBG_ASSERT( pS, "Vorlage in RTF nicht definiert!" );
375 		if ( pS )
376 		{
377 			pImpEditEngine->SetStyleSheet( EditSelection( aStartPaM, aEndPaM ), (SfxStyleSheet*)pImpEditEngine->GetStyleSheetPool()->Find( pS->sName, SFX_STYLE_FAMILY_ALL ) );
378 			nOutlLevel = pS->nOutlineNo;
379 		}
380 	}
381 
382 	// Wenn ein Attribut von 0 bis aktuelle Absatzlaenge geht,
383 	// soll es ein Absatz-Attribut sein!
384 
385 	// Achtung: Selektion kann ueber mehrere Absaetze gehen.
386 	// Alle vollstaendigen Absaetze sind Absatzattribute...
387 	for ( sal_uInt32 z = nStartNode+1; z < nEndNode; z++ )
388 	{
389 		DBG_ASSERT( pImpEditEngine->GetEditDoc().SaveGetObject( z ), "Node existiert noch nicht(RTF)" );
390 		pImpEditEngine->SetParaAttribs( z, rSet.GetAttrSet() );
391 	}
392 
393 	if ( aStartPaM.GetNode() != aEndPaM.GetNode() )
394 	{
395 		// Den Rest des StartNodes...
396 		if ( aStartPaM.GetIndex() == 0 )
397 			pImpEditEngine->SetParaAttribs( nStartNode, rSet.GetAttrSet() );
398 		else
399 			pImpEditEngine->SetAttribs( EditSelection( aStartPaM, EditPaM( aStartPaM.GetNode(), aStartPaM.GetNode()->Len() ) ), rSet.GetAttrSet() );
400 
401 		// Den Anfang des EndNodes....
402 		if ( aEndPaM.GetIndex() == aEndPaM.GetNode()->Len() )
403 			pImpEditEngine->SetParaAttribs( nEndNode, rSet.GetAttrSet() );
404 		else
405 			pImpEditEngine->SetAttribs( EditSelection( EditPaM( aEndPaM.GetNode(), 0 ), aEndPaM ), rSet.GetAttrSet() );
406 	}
407 	else
408 	{
409 		if ( ( aStartPaM.GetIndex() == 0 ) && ( aEndPaM.GetIndex() == aEndPaM.GetNode()->Len() ) )
410         {
411             // #96298# When settings char attribs as para attribs, we must merge with existing attribs, not overwrite the ItemSet!
412             SfxItemSet aAttrs = pImpEditEngine->GetParaAttribs( nStartNode );
413             aAttrs.Put( rSet.GetAttrSet() );
414 			pImpEditEngine->SetParaAttribs( nStartNode, aAttrs );
415         }
416 		else
417         {
418 			pImpEditEngine->SetAttribs( EditSelection( aStartPaM, aEndPaM ), rSet.GetAttrSet() );
419         }
420 	}
421 
422 	// OutlLevel...
423 	if ( nOutlLevel != 0xff )
424 	{
425 		for ( sal_uInt32 n = nStartNode; n <= nEndNode; n++ )
426 		{
427 			ContentNode* pNode = pImpEditEngine->GetEditDoc().SaveGetObject( n );
428 			pNode->GetContentAttribs().GetItems().Put( SfxInt16Item( EE_PARA_OUTLLEVEL, nOutlLevel ) );
429 		}
430 	}
431 }
432 
FindStyleSheet(const XubString & rName)433 SvxRTFStyleType* EditRTFParser::FindStyleSheet( const XubString& rName )
434 {
435 	SvxRTFStyleType* pS = GetStyleTbl().First();
436 	while ( pS && ( pS->sName != rName ) )
437 		pS = GetStyleTbl().Next();
438 
439 	return pS;
440 }
441 
CreateStyleSheet(SvxRTFStyleType * pRTFStyle)442 SfxStyleSheet* EditRTFParser::CreateStyleSheet( SvxRTFStyleType* pRTFStyle )
443 {
444 	// Prueffen, ob so eine Vorlage existiert....
445 	// dann wird sie auch nicht geaendert!
446 	SfxStyleSheet* pStyle = (SfxStyleSheet*)pImpEditEngine->GetStyleSheetPool()->Find( pRTFStyle->sName, SFX_STYLE_FAMILY_ALL );
447 	if ( pStyle )
448 		return pStyle;
449 
450 	String aName( pRTFStyle->sName );
451 	String aParent;
452 	if ( pRTFStyle->nBasedOn )
453 	{
454 		SvxRTFStyleType* pS = GetStyleTbl().Get( pRTFStyle->nBasedOn );
455 		if ( pS && ( pS !=pRTFStyle ) )
456 			aParent = pS->sName;
457 	}
458 
459 	pStyle = (SfxStyleSheet*) &pImpEditEngine->GetStyleSheetPool()->Make( aName, SFX_STYLE_FAMILY_PARA );
460 
461 	// 1) Items konvertieren und uebernehmen...
462 	ConvertAndPutItems( pStyle->GetItemSet(), pRTFStyle->aAttrSet );
463 
464 	// 2) Solange Parent nicht im Pool, auch diesen kreieren...
465 	if ( aParent.Len() && ( aParent != aName ) )
466 	{
467 		SfxStyleSheet* pS = (SfxStyleSheet*)pImpEditEngine->GetStyleSheetPool()->Find( aParent, SFX_STYLE_FAMILY_ALL );
468 		if ( !pS )
469 		{
470 			// Wenn nirgendwo gefunden, aus RTF erzeugen...
471 			SvxRTFStyleType* _pRTFStyle = FindStyleSheet( aParent );
472 			if ( _pRTFStyle )
473 				pS = CreateStyleSheet( _pRTFStyle );
474 		}
475 		// 2b) ItemSet mit Parent verknuepfen...
476 		if ( pS )
477 			pStyle->GetItemSet().SetParent( &pS->GetItemSet() );
478 	}
479 	return pStyle;
480 }
481 
CreateStyleSheets()482 void EditRTFParser::CreateStyleSheets()
483 {
484 	// der SvxRTFParser hat jetzt die Vorlagen erzeugt...
485 	if ( pImpEditEngine->GetStyleSheetPool() && pImpEditEngine->GetStatus().DoImportRTFStyleSheets() )
486 	{
487 		SvxRTFStyleType* pRTFStyle = GetStyleTbl().First();
488 		while ( pRTFStyle )
489 		{
490 			CreateStyleSheet( pRTFStyle );
491 
492 			pRTFStyle = GetStyleTbl().Next();
493 		}
494 	}
495 }
496 
CalcValue()497 void __EXPORT EditRTFParser::CalcValue()
498 {
499     const MapUnit eDestUnit = static_cast< MapUnit >( aEditMapMode.GetMapUnit() );
500     const MapUnit eSrcUnit  = aRTFMapMode.GetMapUnit();
501     if (eDestUnit != eSrcUnit)
502         nTokenValue = OutputDevice::LogicToLogic( (long)nTokenValue, eSrcUnit, eDestUnit );
503 }
504 
ReadField()505 void EditRTFParser::ReadField()
506 {
507 	// Aus SwRTFParser::ReadField()
508 	int _nOpenBrakets = 1;		// die erste wurde schon vorher erkannt
509 	sal_Bool bFldInst = sal_False;
510 	sal_Bool bFldRslt = sal_False;
511 	String aFldInst;
512 	String aFldRslt;
513 
514 	while( _nOpenBrakets && IsParserWorking() )
515 	{
516 		switch( GetNextToken() )
517 		{
518 			case '}':
519 			{
520 				_nOpenBrakets--;
521 				if ( _nOpenBrakets == 1 )
522 				{
523 					bFldInst = sal_False;
524 					bFldRslt = sal_False;
525 				}
526 			}
527 			break;
528 
529 			case '{':			_nOpenBrakets++;
530 								break;
531 
532 			case RTF_FIELD:		SkipGroup();
533 								break;
534 
535 			case RTF_FLDINST:	bFldInst = sal_True;
536 								break;
537 
538 			case RTF_FLDRSLT:	bFldRslt = sal_True;
539 								break;
540 
541 			case RTF_TEXTTOKEN:
542 			{
543 				if ( bFldInst )
544 					aFldInst += aToken;
545 				else if ( bFldRslt )
546 					aFldRslt += aToken;
547 			}
548 			break;
549 		}
550 	}
551 	if ( aFldInst.Len() )
552 	{
553 		String aHyperLinkMarker( RTL_CONSTASCII_USTRINGPARAM( "HYPERLINK " ) );
554 		if ( aFldInst.CompareIgnoreCaseToAscii( aHyperLinkMarker, aHyperLinkMarker.Len() ) == COMPARE_EQUAL )
555 		{
556 			aFldInst.Erase( 0, aHyperLinkMarker.Len() );
557 			aFldInst.EraseLeadingChars();
558 			aFldInst.EraseTrailingChars();
559 			aFldInst.Erase( 0, 1 );	// "
560 			aFldInst.Erase( aFldInst.Len()-1, 1 );	// "
561 
562 			if ( !aFldRslt.Len() )
563 				aFldRslt = aFldInst;
564 
565 			SvxFieldItem aField( SvxURLField( aFldInst, aFldRslt, SVXURLFORMAT_REPR ), EE_FEATURE_FIELD  );
566 			aCurSel = pImpEditEngine->InsertField( aCurSel, aField );
567 			pImpEditEngine->UpdateFields();
568 			nLastAction = ACTION_INSERTTEXT;
569 		}
570 	}
571 
572 	SkipToken( -1 );		// die schliesende Klammer wird "oben" ausgewertet
573 }
574 
SkipGroup()575 void EditRTFParser::SkipGroup()
576 {
577 	int _nOpenBrakets = 1;		// die erste wurde schon vorher erkannt
578 
579     while( _nOpenBrakets && IsParserWorking() )
580 	{
581 		switch( GetNextToken() )
582 		{
583 			case '}':
584 			{
585 				_nOpenBrakets--;
586 			}
587 			break;
588 
589 			case '{':
590             {
591                 _nOpenBrakets++;
592             }
593 			break;
594 		}
595 	}
596 
597 	SkipToken( -1 );		// die schliesende Klammer wird "oben" ausgewertet
598 }
599 
GetIdx() const600 sal_uLong __EXPORT EditNodeIdx::GetIdx() const
601 {
602 	return pImpEditEngine->GetEditDoc().GetPos( pNode );
603 }
604 
Clone() const605 SvxNodeIdx* __EXPORT EditNodeIdx::Clone() const
606 {
607 	return new EditNodeIdx( pImpEditEngine, pNode );
608 }
609 
Clone() const610 SvxPosition* __EXPORT EditPosition::Clone() const
611 {
612 	return new EditPosition( pImpEditEngine, pCurSel );
613 }
614 
MakeNodeIdx() const615 SvxNodeIdx* __EXPORT EditPosition::MakeNodeIdx() const
616 {
617 	return new EditNodeIdx( pImpEditEngine, pCurSel->Max().GetNode() );
618 }
619 
GetNodeIdx() const620 sal_uLong __EXPORT EditPosition::GetNodeIdx() const
621 {
622 	ContentNode* pN = pCurSel->Max().GetNode();
623 	return pImpEditEngine->GetEditDoc().GetPos( pN );
624 }
625 
GetCntIdx() const626 sal_uInt16 __EXPORT EditPosition::GetCntIdx() const
627 {
628 	return pCurSel->Max().GetIndex();
629 }
630