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 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
28
29
30 #include <ctype.h>
31 #include <tools/datetime.hxx>
32 #include <tools/diagnose_ex.h>
33 #include <rtl/tencinfo.h>
34 #include <svl/itemiter.hxx>
35 #include <svl/whiter.hxx>
36 #include <svtools/rtftoken.h>
37 #include <svl/itempool.hxx>
38
39 #include <comphelper/string.hxx>
40
41 #include <com/sun/star/lang/Locale.hpp>
42 #include <editeng/scriptspaceitem.hxx>
43 #include <editeng/fontitem.hxx>
44 #include <editeng/colritem.hxx>
45 #include <editeng/svxrtf.hxx>
46 #include <editeng/editids.hrc>
47 #include <vcl/svapp.hxx>
48
49 #include <com/sun/star/document/XDocumentProperties.hpp>
50
51
52 using namespace ::com::sun::star;
53
54
SV_IMPL_PTRARR(SvxRTFItemStackList,SvxRTFItemStackType *)55 SV_IMPL_PTRARR( SvxRTFItemStackList, SvxRTFItemStackType* )
56
57 CharSet lcl_GetDefaultTextEncodingForRTF()
58 {
59
60 ::com::sun::star::lang::Locale aLocale;
61 ::rtl::OUString aLangString;
62
63 aLocale = Application::GetSettings().GetLocale();
64 aLangString = aLocale.Language;
65
66 if ( aLangString.equals( ::rtl::OUString::createFromAscii( "ru" ) )
67 || aLangString.equals( ::rtl::OUString::createFromAscii( "uk" ) ) )
68 return RTL_TEXTENCODING_MS_1251;
69 if ( aLangString.equals( ::rtl::OUString::createFromAscii( "tr" ) ) )
70 return RTL_TEXTENCODING_MS_1254;
71 else
72 return RTL_TEXTENCODING_MS_1252;
73 }
74
75 // -------------- Methoden --------------------
76
SvxRTFParser(SfxItemPool & rPool,SvStream & rIn,uno::Reference<document::XDocumentProperties> i_xDocProps,int bReadNewDoc)77 SvxRTFParser::SvxRTFParser( SfxItemPool& rPool, SvStream& rIn,
78 uno::Reference<document::XDocumentProperties> i_xDocProps,
79 int bReadNewDoc )
80 : SvRTFParser( rIn, 5 ),
81 rStrm(rIn),
82 aFontTbl( 16, 4 ),
83 pInsPos( 0 ),
84 pAttrPool( &rPool ),
85 m_xDocProps( i_xDocProps ),
86 pRTFDefaults( 0 ),
87 nVersionNo( 0 )
88 {
89 bNewDoc = bReadNewDoc;
90
91 bChkStyleAttr = bCalcValue = bReadDocInfo = bIsInReadStyleTab = sal_False;
92 bIsLeftToRightDef = sal_True;
93
94 {
95 RTFPlainAttrMapIds aTmp( rPool );
96 aPlainMap.Insert( (sal_uInt16*)&aTmp,
97 sizeof( RTFPlainAttrMapIds ) / sizeof(sal_uInt16), 0 );
98 }
99 {
100 RTFPardAttrMapIds aTmp( rPool );
101 aPardMap.Insert( (sal_uInt16*)&aTmp,
102 sizeof( RTFPardAttrMapIds ) / sizeof(sal_uInt16), 0 );
103 }
104 pDfltFont = new Font;
105 pDfltColor = new Color;
106 }
107
EnterEnvironment()108 void SvxRTFParser::EnterEnvironment()
109 {
110 }
111
LeaveEnvironment()112 void SvxRTFParser::LeaveEnvironment()
113 {
114 }
115
ResetPard()116 void SvxRTFParser::ResetPard()
117 {
118 }
119
~SvxRTFParser()120 SvxRTFParser::~SvxRTFParser()
121 {
122 if( !aColorTbl.empty() )
123 ClearColorTbl();
124 if( aFontTbl.Count() )
125 ClearFontTbl();
126 if( aStyleTbl.Count() )
127 ClearStyleTbl();
128 if( !aAttrStack.empty() )
129 ClearAttrStack();
130
131 delete pRTFDefaults;
132
133 delete pInsPos;
134 delete pDfltFont;
135 delete pDfltColor;
136 }
137
SetInsPos(const SvxPosition & rNew)138 void SvxRTFParser::SetInsPos( const SvxPosition& rNew )
139 {
140 if( pInsPos )
141 delete pInsPos;
142 pInsPos = rNew.Clone();
143 }
144
CallParser()145 SvParserState SvxRTFParser::CallParser()
146 {
147 DBG_ASSERT( pInsPos, "no insertion" );
148
149 if( !pInsPos )
150 return SVPAR_ERROR;
151
152 if( !aColorTbl.empty() )
153 ClearColorTbl();
154 if( aFontTbl.Count() )
155 ClearFontTbl();
156 if( aStyleTbl.Count() )
157 ClearStyleTbl();
158 if( !aAttrStack.empty() )
159 ClearAttrStack();
160
161 bIsSetDfltTab = sal_False;
162 bNewGroup = sal_False;
163 nDfltFont = 0;
164
165 sBaseURL.Erase();
166
167 // erzeuge aus den gesetzten WhichIds die richtige WhichId-Tabelle.
168 BuildWhichTbl();
169
170 return SvRTFParser::CallParser();
171 }
172
Continue(int nToken)173 void SvxRTFParser::Continue( int nToken )
174 {
175 SvRTFParser::Continue( nToken );
176
177 if( SVPAR_PENDING != GetStatus() )
178 {
179 SetAllAttrOfStk();
180 #if 0
181 //Regardless of what "color 0" is, word defaults to auto as the default colour.
182 //e.g. see #i7713#
183 if( bNewDoc && ((RTFPlainAttrMapIds*)aPlainMap.GetData())->nColor )
184 pAttrPool->SetPoolDefaultItem( SvxColorItem( GetColor( 0 ),
185 ((RTFPlainAttrMapIds*)aPlainMap.GetData())->nColor ));
186 #endif
187 }
188 }
189
190
191 // wird fuer jedes Token gerufen, das in CallParser erkannt wird
NextToken(int nToken)192 void SvxRTFParser::NextToken( int nToken )
193 {
194 sal_Unicode cCh;
195 switch( nToken )
196 {
197 case RTF_COLORTBL: ReadColorTable(); break;
198 case RTF_FONTTBL: ReadFontTable(); break;
199 case RTF_STYLESHEET: ReadStyleTable(); break;
200
201 case RTF_DEFF:
202 if( bNewDoc )
203 {
204 if( aFontTbl.Count() )
205 // koennen wir sofort setzen
206 SetDefault( nToken, nTokenValue );
207 else
208 // wird nach einlesen der Fonttabelle gesetzt
209 nDfltFont = int(nTokenValue);
210 }
211 break;
212
213 case RTF_DEFTAB:
214 case RTF_DEFLANG:
215 if( bNewDoc )
216 SetDefault( nToken, nTokenValue );
217 break;
218
219
220 case RTF_PICT: ReadBitmapData(); break;
221
222 case RTF_LINE: cCh = '\n'; goto INSINGLECHAR;
223 case RTF_TAB: cCh = '\t'; goto INSINGLECHAR;
224 case RTF_SUBENTRYINDEX: cCh = ':'; goto INSINGLECHAR;
225
226 case RTF_EMDASH: cCh = 151; goto INSINGLECHAR;
227 case RTF_ENDASH: cCh = 150; goto INSINGLECHAR;
228 case RTF_BULLET: cCh = 149; goto INSINGLECHAR;
229 case RTF_LQUOTE: cCh = 145; goto INSINGLECHAR;
230 case RTF_RQUOTE: cCh = 146; goto INSINGLECHAR;
231 case RTF_LDBLQUOTE: cCh = 147; goto INSINGLECHAR;
232 case RTF_RDBLQUOTE: cCh = 148; goto INSINGLECHAR;
233 INSINGLECHAR:
234 aToken = ByteString::ConvertToUnicode( (sal_Char)cCh,
235 RTL_TEXTENCODING_MS_1252 );
236
237 // kein Break, aToken wird als Text gesetzt
238 case RTF_TEXTTOKEN:
239 {
240 InsertText();
241 // alle angesammelten Attribute setzen
242 for( sal_uInt16 n = aAttrSetList.Count(); n; )
243 {
244 SvxRTFItemStackType* pStkSet = aAttrSetList[--n];
245 SetAttrSet( *pStkSet );
246 aAttrSetList.DeleteAndDestroy( n );
247 }
248 }
249 break;
250
251
252 case RTF_PAR:
253 InsertPara();
254 break;
255 case '{':
256 if (bNewGroup) // Verschachtelung !!
257 _GetAttrSet();
258 EnterEnvironment();
259 bNewGroup = true;
260 break;
261 case '}':
262 if( !bNewGroup ) // leere Gruppe ??
263 AttrGroupEnd();
264 LeaveEnvironment();
265 bNewGroup = false;
266 break;
267 case RTF_INFO:
268 #ifndef SVX_LIGHT
269 if (bReadDocInfo && bNewDoc && m_xDocProps.is())
270 ReadInfo();
271 else
272 #endif
273 SkipGroup();
274 break;
275
276 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
277 // erstmal gesamt ueberlesen (muessen alle in einer Gruppe stehen !!)
278 // Koennen auch ohne dem IGNORE-Flag im RTF-File auftreten; alle Gruppen
279 // mit IGNORE-Flag werden im default-Zweig ueberlesen.
280
281 case RTF_SWG_PRTDATA:
282 case RTF_FIELD:
283 case RTF_ATNID:
284 case RTF_ANNOTATION:
285
286 case RTF_BKMKSTART:
287 case RTF_BKMKEND:
288 case RTF_BKMK_KEY:
289 case RTF_XE:
290 case RTF_TC:
291 case RTF_NEXTFILE:
292 case RTF_TEMPLATE:
293 #if 0
294 //disabled for #i19718#
295 case RTF_SHPRSLT: // RTF_SHP fehlt noch !!
296 #endif
297 SkipGroup();
298 break;
299 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
300
301 case RTF_PGDSCNO:
302 case RTF_PGBRK:
303 case RTF_SHADOW:
304 if( RTF_IGNOREFLAG != GetStackPtr( -1 )->nTokenId )
305 break;
306 nToken = SkipToken( -1 );
307 if( '{' == GetStackPtr( -1 )->nTokenId )
308 nToken = SkipToken( -1 );
309
310 ReadAttr( nToken, &GetAttrSet() );
311 break;
312
313 default:
314 switch( nToken & ~(0xff | RTF_SWGDEFS) )
315 {
316 case RTF_PARFMT: // hier gibts keine Swg-Defines
317 ReadAttr( nToken, &GetAttrSet() );
318 break;
319
320 case RTF_CHRFMT:
321 case RTF_BRDRDEF:
322 case RTF_TABSTOPDEF:
323
324 if( RTF_SWGDEFS & nToken)
325 {
326 if( RTF_IGNOREFLAG != GetStackPtr( -1 )->nTokenId )
327 break;
328 nToken = SkipToken( -1 );
329 if( '{' == GetStackPtr( -1 )->nTokenId )
330 {
331 nToken = SkipToken( -1 );
332 }
333 }
334 ReadAttr( nToken, &GetAttrSet() );
335 break;
336 default:
337 {
338 if( /*( '{' == GetStackPtr( -1 )->nTokenId ) ||*/
339 ( RTF_IGNOREFLAG == GetStackPtr( -1 )->nTokenId &&
340 '{' == GetStackPtr( -2 )->nTokenId ) )
341 SkipGroup();
342 }
343 break;
344 }
345 break;
346 }
347 }
348
ReadStyleTable()349 void SvxRTFParser::ReadStyleTable()
350 {
351 int nToken, bSaveChkStyleAttr = bChkStyleAttr;
352 short nStyleNo = 0;
353 int _nOpenBrakets = 1; // die erste wurde schon vorher erkannt !!
354 SvxRTFStyleType* pStyle = new SvxRTFStyleType( *pAttrPool, aWhichMap.GetData() );
355 pStyle->aAttrSet.Put( GetRTFDefaults() );
356
357 bIsInReadStyleTab = sal_True;
358 bChkStyleAttr = sal_False; // Attribute nicht gegen die Styles checken
359
360 while( _nOpenBrakets && IsParserWorking() )
361 {
362 switch( nToken = GetNextToken() )
363 {
364 case '}': if( --_nOpenBrakets && IsParserWorking() )
365 // Style konnte vollstaendig gelesen werden,
366 // also ist das noch ein stabiler Status
367 SaveState( RTF_STYLESHEET );
368 break;
369 case '{':
370 {
371 if( RTF_IGNOREFLAG != GetNextToken() )
372 nToken = SkipToken( -1 );
373 else if( RTF_UNKNOWNCONTROL != ( nToken = GetNextToken() ) &&
374 RTF_PN != nToken )
375 nToken = SkipToken( -2 );
376 else
377 {
378 // gleich herausfiltern
379 ReadUnknownData();
380 nToken = GetNextToken();
381 if( '}' != nToken )
382 eState = SVPAR_ERROR;
383 break;
384 }
385 ++_nOpenBrakets;
386 }
387 break;
388
389 case RTF_SBASEDON: pStyle->nBasedOn = sal_uInt16(nTokenValue); pStyle->bBasedOnIsSet=sal_True; break;
390 case RTF_SNEXT: pStyle->nNext = sal_uInt16(nTokenValue); break;
391 case RTF_OUTLINELEVEL:
392 case RTF_SOUTLVL: pStyle->nOutlineNo = sal_uInt8(nTokenValue); break;
393 case RTF_S: nStyleNo = (short)nTokenValue; break;
394 case RTF_CS: nStyleNo = (short)nTokenValue;
395 pStyle->bIsCharFmt = sal_True;
396 break;
397
398 case RTF_TEXTTOKEN:
399 {
400 pStyle->sName = DelCharAtEnd( aToken, ';' );
401
402 /*
403 ??? soll man das umsetzen ???
404 if( !pStyle->sName.Len() )
405 pStyle->sName = "Standard";
406 */
407 // sollte die Nummer doppelt vergeben werden ?
408 if( aStyleTbl.Count() )
409 {
410 SvxRTFStyleType* pOldSt = aStyleTbl.Remove( nStyleNo );
411 if( pOldSt )
412 delete pOldSt;
413 }
414 // alle Daten vom Style vorhanden, also ab in die Tabelle
415 aStyleTbl.Insert( nStyleNo, pStyle );
416 pStyle = new SvxRTFStyleType( *pAttrPool, aWhichMap.GetData() );
417 pStyle->aAttrSet.Put( GetRTFDefaults() );
418 nStyleNo = 0;
419 }
420 break;
421 default:
422 switch( nToken & ~(0xff | RTF_SWGDEFS) )
423 {
424 case RTF_PARFMT: // hier gibts keine Swg-Defines
425 ReadAttr( nToken, &pStyle->aAttrSet );
426 break;
427
428 case RTF_CHRFMT:
429 case RTF_BRDRDEF:
430 case RTF_TABSTOPDEF:
431
432 if( RTF_SWGDEFS & nToken)
433 {
434 if( RTF_IGNOREFLAG != GetStackPtr( -1 )->nTokenId )
435 break;
436 nToken = SkipToken( -1 );
437 if( '{' == GetStackPtr( -1 )->nTokenId )
438 {
439 nToken = SkipToken( -1 );
440 #if 0
441 --_nOpenBrakets; // korrigieren!!
442 #endif
443 }
444 }
445 ReadAttr( nToken, &pStyle->aAttrSet );
446 break;
447 }
448 break;
449 }
450 }
451 delete pStyle; // loesche das letze Style
452 SkipToken( -1 ); // die schliesende Klammer wird "oben" ausgewertet
453
454 // Flag wieder auf alten Zustand
455 bChkStyleAttr = bSaveChkStyleAttr;
456 bIsInReadStyleTab = sal_False;
457 }
458
ReadColorTable()459 void SvxRTFParser::ReadColorTable()
460 {
461 int nToken;
462 sal_uInt8 nRed = 0xff, nGreen = 0xff, nBlue = 0xff;
463
464 while( '}' != ( nToken = GetNextToken() ) && IsParserWorking() )
465 {
466 switch( nToken )
467 {
468 case RTF_RED: nRed = sal_uInt8(nTokenValue); break;
469 case RTF_GREEN: nGreen = sal_uInt8(nTokenValue); break;
470 case RTF_BLUE: nBlue = sal_uInt8(nTokenValue); break;
471
472 case RTF_TEXTTOKEN: // oder sollte irgendein Unsin darumstehen?
473 if( 1 == aToken.Len()
474 ? aToken.GetChar( 0 ) != ';'
475 : STRING_NOTFOUND == aToken.Search( ';' ) )
476 break; // es muss zumindestens das ';' gefunden werden
477
478 // else kein break !!
479
480 case ';':
481 if( IsParserWorking() )
482 {
483 // eine Farbe ist Fertig, in die Tabelle eintragen
484 // versuche die Werte auf SV interne Namen zu mappen
485 ColorPtr pColor = new Color( nRed, nGreen, nBlue );
486 if( aColorTbl.empty() &&
487 sal_uInt8(-1) == nRed && sal_uInt8(-1) == nGreen && sal_uInt8(-1) == nBlue )
488 pColor->SetColor( COL_AUTO );
489 aColorTbl.push_back( pColor );
490 nRed = 0, nGreen = 0, nBlue = 0;
491
492 // Color konnte vollstaendig gelesen werden,
493 // also ist das noch ein stabiler Status
494 SaveState( RTF_COLORTBL );
495 }
496 break;
497 }
498 }
499 SkipToken( -1 ); // die schliesende Klammer wird "oben" ausgewertet
500 }
501
ReadFontTable()502 void SvxRTFParser::ReadFontTable()
503 {
504 int nToken;
505 int _nOpenBrakets = 1; // die erste wurde schon vorher erkannt !!
506 Font* pFont = new Font();
507 short nFontNo(0), nInsFontNo (0);
508 String sAltNm, sFntNm;
509 sal_Bool bIsAltFntNm = sal_False, bCheckNewFont;
510
511 CharSet nSystemChar = lcl_GetDefaultTextEncodingForRTF();
512 pFont->SetCharSet( nSystemChar );
513 SetEncoding( nSystemChar );
514
515 while( _nOpenBrakets && IsParserWorking() )
516 {
517 bCheckNewFont = sal_False;
518 switch( ( nToken = GetNextToken() ))
519 {
520 case '}':
521 bIsAltFntNm = sal_False;
522 // Style konnte vollstaendig gelesen werden,
523 // also ist das noch ein stabiler Status
524 if( --_nOpenBrakets <= 1 && IsParserWorking() )
525 SaveState( RTF_FONTTBL );
526 bCheckNewFont = sal_True;
527 nInsFontNo = nFontNo;
528 break;
529 case '{':
530 if( RTF_IGNOREFLAG != GetNextToken() )
531 nToken = SkipToken( -1 );
532 // Unknown und alle bekannten nicht ausgewerteten Gruppen
533 // sofort ueberspringen
534 else if( RTF_UNKNOWNCONTROL != ( nToken = GetNextToken() ) &&
535 RTF_PANOSE != nToken && RTF_FNAME != nToken &&
536 RTF_FONTEMB != nToken && RTF_FONTFILE != nToken )
537 nToken = SkipToken( -2 );
538 else
539 {
540 // gleich herausfiltern
541 ReadUnknownData();
542 nToken = GetNextToken();
543 if( '}' != nToken )
544 eState = SVPAR_ERROR;
545 break;
546 }
547 ++_nOpenBrakets;
548 break;
549 case RTF_FROMAN:
550 pFont->SetFamily( FAMILY_ROMAN );
551 break;
552 case RTF_FSWISS:
553 pFont->SetFamily( FAMILY_SWISS );
554 break;
555 case RTF_FMODERN:
556 pFont->SetFamily( FAMILY_MODERN );
557 break;
558 case RTF_FSCRIPT:
559 pFont->SetFamily( FAMILY_SCRIPT );
560 break;
561 case RTF_FDECOR:
562 pFont->SetFamily( FAMILY_DECORATIVE );
563 break;
564 // bei technischen/symbolischen Font wird der CharSet ungeschaltet!!
565 case RTF_FTECH:
566 pFont->SetCharSet( RTL_TEXTENCODING_SYMBOL );
567 // deliberate fall through
568 case RTF_FNIL:
569 pFont->SetFamily( FAMILY_DONTKNOW );
570 break;
571 case RTF_FCHARSET:
572 if (-1 != nTokenValue)
573 {
574 CharSet nCharSet = rtl_getTextEncodingFromWindowsCharset(
575 (sal_uInt8)nTokenValue);
576 pFont->SetCharSet(nCharSet);
577 //When we're in a font, the fontname is in the font
578 //charset, except for symbol fonts I believe
579 if (nCharSet == RTL_TEXTENCODING_SYMBOL)
580 nCharSet = RTL_TEXTENCODING_DONTKNOW;
581 SetEncoding(nCharSet);
582 }
583 break;
584 case RTF_FPRQ:
585 switch( nTokenValue )
586 {
587 case 1:
588 pFont->SetPitch( PITCH_FIXED );
589 break;
590 case 2:
591 pFont->SetPitch( PITCH_VARIABLE );
592 break;
593 }
594 break;
595 case RTF_F:
596 bCheckNewFont = sal_True;
597 nInsFontNo = nFontNo;
598 nFontNo = (short)nTokenValue;
599 break;
600 case RTF_FALT:
601 bIsAltFntNm = sal_True;
602 break;
603 case RTF_TEXTTOKEN:
604 DelCharAtEnd( aToken, ';' );
605 if ( aToken.Len() )
606 {
607 if( bIsAltFntNm )
608 sAltNm = aToken;
609 else
610 sFntNm = aToken;
611 }
612 break;
613 }
614
615 if( bCheckNewFont && 1 >= _nOpenBrakets && sFntNm.Len() ) // one font is ready
616 {
617 // alle Daten vom Font vorhanden, also ab in die Tabelle
618 if (sAltNm.Len())
619 (sFntNm += ';' ) += sAltNm;
620
621 pFont->SetName( sFntNm );
622 aFontTbl.Insert( nInsFontNo, pFont );
623 pFont = new Font();
624 pFont->SetCharSet( nSystemChar );
625 sAltNm.Erase();
626 sFntNm.Erase();
627 }
628 }
629 // den letzen muessen wir selbst loeschen
630 delete pFont;
631 SkipToken( -1 ); // die schliesende Klammer wird "oben" ausgewertet
632
633 // setze den default Font am Doc
634 if( bNewDoc && IsParserWorking() )
635 SetDefault( RTF_DEFF, nDfltFont );
636 }
637
ReadBitmapData()638 void SvxRTFParser::ReadBitmapData()
639 {
640 SvRTFParser::ReadBitmapData();
641 }
642
ReadOLEData()643 void SvxRTFParser::ReadOLEData()
644 {
645 SvRTFParser::ReadOLEData();
646 }
647
GetTextToEndGroup(String & rStr)648 String& SvxRTFParser::GetTextToEndGroup( String& rStr )
649 {
650 rStr.Erase( 0 );
651 int _nOpenBrakets = 1, nToken; // die erste wurde schon vorher erkannt !!
652
653 while( _nOpenBrakets && IsParserWorking() )
654 {
655 switch( nToken = GetNextToken() )
656 {
657 case '}': --_nOpenBrakets; break;
658 case '{':
659 {
660 if( RTF_IGNOREFLAG != GetNextToken() )
661 nToken = SkipToken( -1 );
662 else if( RTF_UNKNOWNCONTROL != GetNextToken() )
663 nToken = SkipToken( -2 );
664 else
665 {
666 // gleich herausfiltern
667 ReadUnknownData();
668 nToken = GetNextToken();
669 if( '}' != nToken )
670 eState = SVPAR_ERROR;
671 break;
672 }
673 ++_nOpenBrakets;
674 }
675 break;
676
677 case RTF_TEXTTOKEN:
678 rStr += aToken;
679 break;
680 }
681 }
682 SkipToken( -1 ); // die schliesende Klammer wird "oben" ausgewertet
683 return rStr;
684 }
685
GetDateTimeStamp()686 util::DateTime SvxRTFParser::GetDateTimeStamp( )
687 {
688 util::DateTime aDT;
689 sal_Bool bWeiter = sal_True;
690 int nToken;
691 while( bWeiter && IsParserWorking() )
692 {
693 switch( nToken = GetNextToken() )
694 {
695 case RTF_YR: aDT.Year = (sal_uInt16)nTokenValue; break;
696 case RTF_MO: aDT.Month = (sal_uInt16)nTokenValue; break;
697 case RTF_DY: aDT.Day = (sal_uInt16)nTokenValue; break;
698 case RTF_HR: aDT.Hours = (sal_uInt16)nTokenValue; break;
699 case RTF_MIN: aDT.Minutes = (sal_uInt16)nTokenValue; break;
700 default:
701 bWeiter = sal_False;
702 }
703 }
704 SkipToken( -1 ); // die schliesende Klammer wird "oben" ausgewertet
705 return aDT;
706 }
707
ReadInfo(const sal_Char * pChkForVerNo)708 void SvxRTFParser::ReadInfo( const sal_Char* pChkForVerNo )
709 {
710 #ifndef SVX_LIGHT
711 int _nOpenBrakets = 1, nToken; // die erste wurde schon vorher erkannt !!
712 DBG_ASSERT(m_xDocProps.is(),
713 "SvxRTFParser::ReadInfo: no DocumentProperties");
714 String sStr, sComment;
715 long nVersNo = 0;
716
717 while( _nOpenBrakets && IsParserWorking() )
718 {
719 switch( nToken = GetNextToken() )
720 {
721 case '}': --_nOpenBrakets; break;
722 case '{':
723 {
724 if( RTF_IGNOREFLAG != GetNextToken() )
725 nToken = SkipToken( -1 );
726 else if( RTF_UNKNOWNCONTROL != GetNextToken() )
727 nToken = SkipToken( -2 );
728 else
729 {
730 // gleich herausfiltern
731 ReadUnknownData();
732 nToken = GetNextToken();
733 if( '}' != nToken )
734 eState = SVPAR_ERROR;
735 break;
736 }
737 ++_nOpenBrakets;
738 }
739 break;
740
741 case RTF_TITLE:
742 m_xDocProps->setTitle( GetTextToEndGroup( sStr ) );
743 break;
744 case RTF_SUBJECT:
745 m_xDocProps->setSubject( GetTextToEndGroup( sStr ) );
746 break;
747 case RTF_AUTHOR:
748 m_xDocProps->setAuthor( GetTextToEndGroup( sStr ) );
749 break;
750 case RTF_OPERATOR:
751 m_xDocProps->setModifiedBy( GetTextToEndGroup( sStr ) );
752 break;
753 case RTF_KEYWORDS:
754 {
755 ::rtl::OUString sTemp = GetTextToEndGroup( sStr );
756 m_xDocProps->setKeywords(
757 ::comphelper::string::convertCommaSeparated(sTemp) );
758 break;
759 }
760 case RTF_DOCCOMM:
761 m_xDocProps->setDescription( GetTextToEndGroup( sStr ) );
762 break;
763
764 case RTF_HLINKBASE:
765 sBaseURL = GetTextToEndGroup( sStr ) ;
766 break;
767
768 case RTF_CREATIM:
769 m_xDocProps->setCreationDate( GetDateTimeStamp() );
770 break;
771
772 case RTF_REVTIM:
773 m_xDocProps->setModificationDate( GetDateTimeStamp() );
774 break;
775
776 case RTF_PRINTIM:
777 m_xDocProps->setPrintDate( GetDateTimeStamp() );
778 break;
779
780 case RTF_COMMENT:
781 GetTextToEndGroup( sComment );
782 break;
783
784 case RTF_BUPTIM:
785 SkipGroup();
786 break;
787
788 case RTF_VERN:
789 nVersNo = nTokenValue;
790 break;
791
792 case RTF_EDMINS:
793 case RTF_ID:
794 case RTF_VERSION:
795 case RTF_NOFPAGES:
796 case RTF_NOFWORDS:
797 case RTF_NOFCHARS:
798 NextToken( nToken );
799 break;
800
801 // default:
802 }
803 }
804
805 if( pChkForVerNo &&
806 COMPARE_EQUAL == sComment.CompareToAscii( pChkForVerNo ))
807 nVersionNo = nVersNo;
808
809 SkipToken( -1 ); // die schliesende Klammer wird "oben" ausgewertet
810 #endif
811 }
812
813
ClearColorTbl()814 void SvxRTFParser::ClearColorTbl()
815 {
816 while ( !aColorTbl.empty() )
817 {
818 delete aColorTbl.back();
819 aColorTbl.pop_back();
820 }
821 }
822
ClearFontTbl()823 void SvxRTFParser::ClearFontTbl()
824 {
825 for( sal_uInt32 nCnt = aFontTbl.Count(); nCnt; )
826 delete aFontTbl.GetObject( --nCnt );
827 aFontTbl.Clear();
828 }
829
ClearStyleTbl()830 void SvxRTFParser::ClearStyleTbl()
831 {
832 for( sal_uInt32 nCnt = aStyleTbl.Count(); nCnt; )
833 delete aStyleTbl.GetObject( --nCnt );
834 aStyleTbl.Clear();
835 }
836
ClearAttrStack()837 void SvxRTFParser::ClearAttrStack()
838 {
839 SvxRTFItemStackType* pTmp;
840 for( size_t nCnt = aAttrStack.size(); nCnt; --nCnt )
841 {
842 pTmp = aAttrStack.back();
843 aAttrStack.pop_back();
844 delete pTmp;
845 }
846 }
847
DelCharAtEnd(String & rStr,const sal_Unicode cDel)848 String& SvxRTFParser::DelCharAtEnd( String& rStr, const sal_Unicode cDel )
849 {
850 if( rStr.Len() && ' ' == rStr.GetChar( 0 ))
851 rStr.EraseLeadingChars();
852 if( rStr.Len() && ' ' == rStr.GetChar( rStr.Len()-1 ))
853 rStr.EraseTrailingChars();
854 if( rStr.Len() && cDel == rStr.GetChar( rStr.Len()-1 ))
855 rStr.Erase( rStr.Len()-1 );
856 return rStr;
857 }
858
859
GetFont(sal_uInt16 nId)860 const Font& SvxRTFParser::GetFont( sal_uInt16 nId )
861 {
862 const Font* pFont = aFontTbl.Get( nId );
863 if( !pFont )
864 {
865 const SvxFontItem& rDfltFont = (const SvxFontItem&)
866 pAttrPool->GetDefaultItem(
867 ((RTFPlainAttrMapIds*)aPlainMap.GetData())->nFont );
868 pDfltFont->SetName( rDfltFont.GetStyleName() );
869 pDfltFont->SetFamily( rDfltFont.GetFamily() );
870 pFont = pDfltFont;
871 }
872 return *pFont;
873 }
874
_GetAttrSet(int bCopyAttr)875 SvxRTFItemStackType* SvxRTFParser::_GetAttrSet( int bCopyAttr )
876 {
877 SvxRTFItemStackType* pAkt = aAttrStack.empty() ? 0 : aAttrStack.back();
878 SvxRTFItemStackType* pNew;
879 if( pAkt )
880 pNew = new SvxRTFItemStackType( *pAkt, *pInsPos, bCopyAttr );
881 else
882 pNew = new SvxRTFItemStackType( *pAttrPool, aWhichMap.GetData(),
883 *pInsPos );
884 pNew->SetRTFDefaults( GetRTFDefaults() );
885
886 aAttrStack.push_back( pNew );
887 bNewGroup = sal_False;
888 return pNew;
889 }
890
891
_ClearStyleAttr(SvxRTFItemStackType & rStkType)892 void SvxRTFParser::_ClearStyleAttr( SvxRTFItemStackType& rStkType )
893 {
894 // check attributes to the attributes of the stylesheet or to
895 // the default attrs of the document
896 SfxItemSet &rSet = rStkType.GetAttrSet();
897 const SfxItemPool& rPool = *rSet.GetPool();
898 const SfxPoolItem* pItem;
899 SfxWhichIter aIter( rSet );
900
901 SvxRTFStyleType* pStyle;
902 if( !IsChkStyleAttr() ||
903 !rStkType.GetAttrSet().Count() ||
904 0 == ( pStyle = aStyleTbl.Get( rStkType.nStyleNo ) ))
905 {
906 for( sal_uInt16 nWhich = aIter.GetCurWhich(); nWhich; nWhich = aIter.NextWhich() )
907 {
908 if( SFX_WHICH_MAX > nWhich &&
909 SFX_ITEM_SET == rSet.GetItemState( nWhich, sal_False, &pItem ) &&
910 rPool.GetDefaultItem( nWhich ) == *pItem )
911 rSet.ClearItem( nWhich ); // loeschen
912 }
913 }
914 else
915 {
916 // alle Attribute, die schon vom Style definiert sind, aus dem
917 // akt. AttrSet entfernen
918 SfxItemSet &rStyleSet = pStyle->aAttrSet;
919 const SfxPoolItem* pSItem;
920 for( sal_uInt16 nWhich = aIter.GetCurWhich(); nWhich; nWhich = aIter.NextWhich() )
921 {
922 if( SFX_ITEM_SET == rStyleSet.GetItemState( nWhich, sal_True, &pSItem ))
923 {
924 // JP 22.06.99: im Style und im Set gleich gesetzt -> loeschen
925 if( SFX_ITEM_SET == rSet.GetItemState( nWhich, sal_False, &pItem )
926 && *pItem == *pSItem )
927 rSet.ClearItem( nWhich ); // loeschen
928 }
929 // Bug 59571 - falls nicht im Style gesetzt und gleich mit
930 // dem PoolDefault -> auch dann loeschen
931 else if( SFX_WHICH_MAX > nWhich &&
932 SFX_ITEM_SET == rSet.GetItemState( nWhich, sal_False, &pItem ) &&
933 rPool.GetDefaultItem( nWhich ) == *pItem )
934 rSet.ClearItem( nWhich ); // loeschen
935 }
936 }
937 }
938
AttrGroupEnd()939 void SvxRTFParser::AttrGroupEnd() // den akt. Bearbeiten, vom Stack loeschen
940 {
941 if( !aAttrStack.empty() )
942 {
943 SvxRTFItemStackType *pOld = aAttrStack.empty() ? 0 : aAttrStack.back();
944 aAttrStack.pop_back();
945 SvxRTFItemStackType *pAkt = aAttrStack.empty() ? 0 : aAttrStack.back();
946
947 do { // middle check loop
948 sal_uLong nOldSttNdIdx = pOld->pSttNd->GetIdx();
949 if( !pOld->pChildList &&
950 ((!pOld->aAttrSet.Count() && !pOld->nStyleNo ) ||
951 (nOldSttNdIdx == pInsPos->GetNodeIdx() &&
952 pOld->nSttCnt == pInsPos->GetCntIdx() )))
953 break; // keine Attribute oder Bereich
954
955 // setze nur die Attribute, die unterschiedlich zum Parent sind
956 if( pAkt && pOld->aAttrSet.Count() )
957 {
958 SfxItemIter aIter( pOld->aAttrSet );
959 const SfxPoolItem* pItem = aIter.GetCurItem(), *pGet;
960 while( sal_True )
961 {
962 if( SFX_ITEM_SET == pAkt->aAttrSet.GetItemState(
963 pItem->Which(), sal_False, &pGet ) &&
964 *pItem == *pGet )
965 pOld->aAttrSet.ClearItem( pItem->Which() );
966
967 if( aIter.IsAtEnd() )
968 break;
969 pItem = aIter.NextItem();
970 }
971
972 if( !pOld->aAttrSet.Count() && !pOld->pChildList &&
973 !pOld->nStyleNo )
974 break;
975 }
976
977 // setze alle Attribute, die von Start bis hier
978 // definiert sind.
979 int bCrsrBack = !pInsPos->GetCntIdx();
980 if( bCrsrBack )
981 {
982 // am Absatzanfang ? eine Position zurueck
983 sal_uLong nNd = pInsPos->GetNodeIdx();
984 MovePos( sal_False );
985 // if can not move backward then later dont move forward !
986 bCrsrBack = nNd != pInsPos->GetNodeIdx();
987 }
988
989 //Bug #46608#: ungueltige Bereiche ignorieren!
990 if( ( pOld->pSttNd->GetIdx() < pInsPos->GetNodeIdx() ||
991 ( pOld->pSttNd->GetIdx() == pInsPos->GetNodeIdx() &&
992 pOld->nSttCnt <= pInsPos->GetCntIdx() ))
993 #if 0
994 //BUG 68555 - dont test for empty paragraph or any range
995 && ( nOldSttNdIdx != pInsPos->GetNodeIdx() ||
996 pOld->nSttCnt != pInsPos->GetCntIdx() ||
997 !pOld->nSttCnt )
998 #endif
999 )
1000 {
1001 if( !bCrsrBack )
1002 {
1003 // alle pard-Attribute gelten nur bis zum vorherigen
1004 // Absatz !!
1005 if( nOldSttNdIdx == pInsPos->GetNodeIdx() )
1006 {
1007 #if 0
1008 //BUG 68555 - dont reset pard attrs, if the group not begins not at start of
1009 // paragraph
1010 // Bereich innerhalb eines Absatzes:
1011 // alle Absatz-Attribute und StyleNo loeschen
1012 // aber nur wenn mitten drin angefangen wurde
1013 if( pOld->nSttCnt )
1014 {
1015 pOld->nStyleNo = 0;
1016 for( sal_uInt16 n = 0; n < aPardMap.Count() &&
1017 pOld->aAttrSet.Count(); ++n )
1018 if( aPardMap[n] )
1019 pOld->aAttrSet.ClearItem( aPardMap[n] );
1020
1021 if( !pOld->aAttrSet.Count() && !pOld->pChildList &&
1022 !pOld->nStyleNo )
1023 break; // auch dieser verlaesst uns jetzt
1024 }
1025 #endif
1026 }
1027 else
1028 {
1029 // jetzt wirds kompliziert:
1030 // - alle Zeichen-Attribute behalten den Bereich,
1031 // - alle Absatz-Attribute bekommen den Bereich
1032 // bis zum vorherigen Absatz
1033 SvxRTFItemStackType* pNew = new SvxRTFItemStackType(
1034 *pOld, *pInsPos, sal_True );
1035 pNew->aAttrSet.SetParent( pOld->aAttrSet.GetParent() );
1036
1037 // loesche aus pNew alle Absatz Attribute
1038 for( sal_uInt16 n = 0; n < aPardMap.Count() &&
1039 pNew->aAttrSet.Count(); ++n )
1040 if( aPardMap[n] )
1041 pNew->aAttrSet.ClearItem( aPardMap[n] );
1042 pNew->SetRTFDefaults( GetRTFDefaults() );
1043
1044 // gab es ueberhaupt welche ?
1045 if( pNew->aAttrSet.Count() == pOld->aAttrSet.Count() )
1046 delete pNew; // das wars dann
1047 else
1048 {
1049 pNew->nStyleNo = 0;
1050
1051 // spanne jetzt den richtigen Bereich auf
1052 // pNew von alter
1053 SetEndPrevPara( pOld->pEndNd, pOld->nEndCnt );
1054 pNew->nSttCnt = 0;
1055
1056 if( IsChkStyleAttr() )
1057 {
1058 _ClearStyleAttr( *pOld );
1059 _ClearStyleAttr( *pNew ); //#i10381#, methinks.
1060 }
1061
1062 if( pAkt )
1063 {
1064 pAkt->Add( pOld );
1065 pAkt->Add( pNew );
1066 }
1067 else
1068 {
1069 // letzter vom Stack, also zwischenspeichern, bis der
1070 // naechste Text eingelesen wurde. (keine Attribute
1071 // aufspannen!!)
1072 aAttrSetList.Insert( pOld, aAttrSetList.Count() );
1073 aAttrSetList.Insert( pNew, aAttrSetList.Count() );
1074 }
1075 pOld = 0; // pOld nicht loeschen
1076 break; // das wars !!
1077 }
1078 }
1079 }
1080
1081 pOld->pEndNd = pInsPos->MakeNodeIdx();
1082 pOld->nEndCnt = pInsPos->GetCntIdx();
1083
1084 #if 0
1085 if( IsChkStyleAttr() )
1086 _ClearStyleAttr( *pOld );
1087 #else
1088 /*
1089 #i21422#
1090 If the parent (pAkt) sets something e.g. , and the child (pOld)
1091 unsets it and the style both are based on has it unset then
1092 clearing the pOld by looking at the style is clearly a disaster
1093 as the text ends up with pAkts bold and not pOlds no bold, this
1094 should be rethought out. For the moment its safest to just do
1095 the clean if we have no parent, all we suffer is too many
1096 redundant properties.
1097 */
1098 if (IsChkStyleAttr() && !pAkt)
1099 _ClearStyleAttr( *pOld );
1100 #endif
1101
1102 if( pAkt )
1103 {
1104 pAkt->Add( pOld );
1105 // split up and create new entry, because it make no sense
1106 // to create a "so long" depend list. Bug 95010
1107 if( bCrsrBack && 50 < pAkt->pChildList->Count() )
1108 {
1109 // am Absatzanfang ? eine Position zurueck
1110 MovePos( sal_True );
1111 bCrsrBack = sal_False;
1112
1113 // eine neue Gruppe aufmachen
1114 SvxRTFItemStackType* pNew = new SvxRTFItemStackType(
1115 *pAkt, *pInsPos, sal_True );
1116 pNew->SetRTFDefaults( GetRTFDefaults() );
1117
1118 // alle bis hierher gueltigen Attribute "setzen"
1119 AttrGroupEnd();
1120 pAkt = aAttrStack.empty() ? 0 : aAttrStack.back(); // can be changed after AttrGroupEnd!
1121 pNew->aAttrSet.SetParent( pAkt ? &pAkt->aAttrSet : 0 );
1122 aAttrStack.push_back( pNew );
1123 pAkt = pNew;
1124 }
1125 }
1126 else
1127 // letzter vom Stack, also zwischenspeichern, bis der
1128 // naechste Text eingelesen wurde. (keine Attribute
1129 // aufspannen!!)
1130 aAttrSetList.Insert( pOld, aAttrSetList.Count() );
1131
1132 pOld = 0;
1133 }
1134
1135 if( bCrsrBack )
1136 // am Absatzanfang ? eine Position zurueck
1137 MovePos( sal_True );
1138
1139 } while( sal_False );
1140
1141 if( pOld )
1142 delete pOld;
1143
1144 bNewGroup = sal_False;
1145 }
1146 }
1147
SetAllAttrOfStk()1148 void SvxRTFParser::SetAllAttrOfStk() // end all Attr. and set it into doc
1149 {
1150 // repeat until all attributes will be taken from stack
1151 while( !aAttrStack.empty() )
1152 AttrGroupEnd();
1153
1154 for( sal_uInt16 n = aAttrSetList.Count(); n; )
1155 {
1156 SvxRTFItemStackType* pStkSet = aAttrSetList[--n];
1157 SetAttrSet( *pStkSet );
1158 aAttrSetList.DeleteAndDestroy( n );
1159 }
1160 }
1161
1162 // setzt alle Attribute, die unterschiedlich zum aktuellen sind
SetAttrSet(SvxRTFItemStackType & rSet)1163 void SvxRTFParser::SetAttrSet( SvxRTFItemStackType &rSet )
1164 {
1165 // wurde DefTab nie eingelesen? dann setze auf default
1166 if( !bIsSetDfltTab )
1167 SetDefault( RTF_DEFTAB, 720 );
1168
1169 if( rSet.pChildList )
1170 rSet.Compress( *this );
1171 if( rSet.aAttrSet.Count() || rSet.nStyleNo )
1172 SetAttrInDoc( rSet );
1173
1174 // dann mal alle Childs abarbeiten
1175 if( rSet.pChildList )
1176 for( sal_uInt16 n = 0; n < rSet.pChildList->Count(); ++n )
1177 SetAttrSet( *(*rSet.pChildList)[ n ] );
1178 }
1179
1180 // Is text wasn't inserted? (Get SttPos from the top of stack!)
IsAttrSttPos()1181 int SvxRTFParser::IsAttrSttPos()
1182 {
1183 SvxRTFItemStackType* pAkt = aAttrStack.empty() ? 0 : aAttrStack.back();
1184 return !pAkt || (pAkt->pSttNd->GetIdx() == pInsPos->GetNodeIdx() &&
1185 pAkt->nSttCnt == pInsPos->GetCntIdx());
1186 }
1187
1188
SetAttrInDoc(SvxRTFItemStackType &)1189 void SvxRTFParser::SetAttrInDoc( SvxRTFItemStackType & )
1190 {
1191 }
1192
1193 #ifdef USED
SaveState(int nToken)1194 void SvxRTFParser::SaveState( int nToken )
1195 {
1196 SvRTFParser::SaveState( nToken );
1197 }
1198
RestoreState()1199 void SvxRTFParser::RestoreState()
1200 {
1201 SvRTFParser::RestoreState();
1202 }
1203 #endif
1204
BuildWhichTbl()1205 void SvxRTFParser::BuildWhichTbl()
1206 {
1207 if( aWhichMap.Count() )
1208 aWhichMap.Remove( 0, aWhichMap.Count() );
1209 aWhichMap.Insert( (sal_uInt16)0, (sal_uInt16)0 );
1210
1211 // Aufbau einer Which-Map 'rWhichMap' aus einem Array von
1212 // 'pWhichIds' von Which-Ids. Es hat die Lange 'nWhichIds'.
1213 // Die Which-Map wird nicht geloescht.
1214 SvParser::BuildWhichTbl( aWhichMap, (sal_uInt16*)aPardMap.GetData(), aPardMap.Count() );
1215 SvParser::BuildWhichTbl( aWhichMap, (sal_uInt16*)aPlainMap.GetData(), aPlainMap.Count() );
1216 }
1217
GetRTFDefaults()1218 const SfxItemSet& SvxRTFParser::GetRTFDefaults()
1219 {
1220 if( !pRTFDefaults )
1221 {
1222 pRTFDefaults = new SfxItemSet( *pAttrPool, aWhichMap.GetData() );
1223 sal_uInt16 nId;
1224 if( 0 != ( nId = ((RTFPardAttrMapIds*)aPardMap.GetData())->nScriptSpace ))
1225 {
1226 SvxScriptSpaceItem aItem( sal_False, nId );
1227 if( bNewDoc )
1228 pAttrPool->SetPoolDefaultItem( aItem );
1229 else
1230 pRTFDefaults->Put( aItem );
1231 }
1232 }
1233 return *pRTFDefaults;
1234 }
1235
1236 /**/
1237
SvxRTFStyleType(SfxItemPool & rPool,const sal_uInt16 * pWhichRange)1238 SvxRTFStyleType::SvxRTFStyleType( SfxItemPool& rPool, const sal_uInt16* pWhichRange )
1239 : aAttrSet( rPool, pWhichRange )
1240 {
1241 nOutlineNo = sal_uInt8(-1); // nicht gesetzt
1242 nBasedOn = 0;
1243 bBasedOnIsSet = sal_False; //$flr #117411#
1244 nNext = 0;
1245 bIsCharFmt = sal_False;
1246 }
1247
1248
SvxRTFItemStackType(SfxItemPool & rPool,const sal_uInt16 * pWhichRange,const SvxPosition & rPos)1249 SvxRTFItemStackType::SvxRTFItemStackType(
1250 SfxItemPool& rPool, const sal_uInt16* pWhichRange,
1251 const SvxPosition& rPos )
1252 : aAttrSet( rPool, pWhichRange ),
1253 pChildList( 0 ),
1254 nStyleNo( 0 )
1255 {
1256 pSttNd = rPos.MakeNodeIdx();
1257 nSttCnt = rPos.GetCntIdx();
1258 pEndNd = pSttNd;
1259 nEndCnt = nSttCnt;
1260 }
1261
SvxRTFItemStackType(const SvxRTFItemStackType & rCpy,const SvxPosition & rPos,int bCopyAttr)1262 SvxRTFItemStackType::SvxRTFItemStackType(
1263 const SvxRTFItemStackType& rCpy,
1264 const SvxPosition& rPos,
1265 int bCopyAttr )
1266 : aAttrSet( *rCpy.aAttrSet.GetPool(), rCpy.aAttrSet.GetRanges() ),
1267 pChildList( 0 ),
1268 nStyleNo( rCpy.nStyleNo )
1269 {
1270 pSttNd = rPos.MakeNodeIdx();
1271 nSttCnt = rPos.GetCntIdx();
1272 pEndNd = pSttNd;
1273 nEndCnt = nSttCnt;
1274
1275 aAttrSet.SetParent( &rCpy.aAttrSet );
1276 if( bCopyAttr )
1277 aAttrSet.Put( rCpy.aAttrSet );
1278 }
1279
~SvxRTFItemStackType()1280 SvxRTFItemStackType::~SvxRTFItemStackType()
1281 {
1282 if( pChildList )
1283 delete pChildList;
1284 if( pSttNd != pEndNd )
1285 delete pEndNd;
1286 delete pSttNd;
1287 }
1288
Add(SvxRTFItemStackType * pIns)1289 void SvxRTFItemStackType::Add( SvxRTFItemStackType* pIns )
1290 {
1291 if( !pChildList )
1292 pChildList = new SvxRTFItemStackList( 4, 16 );
1293 pChildList->Insert( pIns, pChildList->Count() );
1294 }
1295
1296 #if 0
1297 //cmc: This is the original. nEndCnt is redundantly assigned to itself, and
1298 //pEndNd can leak if not equal to pSttNd.
1299 void SvxRTFItemStackType::SetStartPos( const SvxPosition& rPos )
1300 {
1301 delete pSttNd;
1302 pSttNd = rPos.MakeNodeIdx();
1303 nSttCnt = rPos.GetCntIdx();
1304 pEndNd = pSttNd;
1305 nEndCnt = nEndCnt;
1306 }
1307 #else
SetStartPos(const SvxPosition & rPos)1308 void SvxRTFItemStackType::SetStartPos( const SvxPosition& rPos )
1309 {
1310 if (pSttNd != pEndNd)
1311 delete pEndNd;
1312 delete pSttNd;
1313 pSttNd = rPos.MakeNodeIdx();
1314 pEndNd = pSttNd;
1315 nSttCnt = rPos.GetCntIdx();
1316 }
1317 #endif
1318
MoveFullNode(const SvxNodeIdx & rOldNode,const SvxNodeIdx & rNewNode)1319 void SvxRTFItemStackType::MoveFullNode(const SvxNodeIdx &rOldNode,
1320 const SvxNodeIdx &rNewNode)
1321 {
1322 bool bSameEndAsStart = (pSttNd == pEndNd) ? true : false;
1323
1324 if (GetSttNodeIdx() == rOldNode.GetIdx())
1325 {
1326 delete pSttNd;
1327 pSttNd = rNewNode.Clone();
1328 if (bSameEndAsStart)
1329 pEndNd = pSttNd;
1330 }
1331
1332 if (!bSameEndAsStart && GetEndNodeIdx() == rOldNode.GetIdx())
1333 {
1334 delete pEndNd;
1335 pEndNd = rNewNode.Clone();
1336 }
1337
1338 //And the same for all the children
1339 sal_uInt16 nCount = pChildList ? pChildList->Count() : 0;
1340 for (sal_uInt16 i = 0; i < nCount; ++i)
1341 {
1342 SvxRTFItemStackType* pStk = (*pChildList)[i];
1343 pStk->MoveFullNode(rOldNode, rNewNode);
1344 }
1345 }
1346
UncompressableStackEntry(const SvxRTFItemStackType &) const1347 bool SvxRTFParser::UncompressableStackEntry(const SvxRTFItemStackType &) const
1348 {
1349 return false;
1350 }
1351
Compress(const SvxRTFParser & rParser)1352 void SvxRTFItemStackType::Compress( const SvxRTFParser& rParser )
1353 {
1354 ENSURE_OR_RETURN_VOID(pChildList, "Compress: no ChildList" );
1355 ENSURE_OR_RETURN_VOID(pChildList->Count(), "Compress: ChildList empty");
1356
1357 sal_uInt16 n;
1358 SvxRTFItemStackType* pTmp = (*pChildList)[0];
1359
1360 if( !pTmp->aAttrSet.Count() ||
1361 pSttNd->GetIdx() != pTmp->pSttNd->GetIdx() ||
1362 nSttCnt != pTmp->nSttCnt )
1363 return;
1364
1365 SvxNodeIdx* pLastNd = pTmp->pEndNd;
1366 xub_StrLen nLastCnt = pTmp->nEndCnt;
1367
1368 SfxItemSet aMrgSet( pTmp->aAttrSet );
1369 for( n = 1; n < pChildList->Count(); ++n )
1370 {
1371 pTmp = (*pChildList)[n];
1372 if( pTmp->pChildList )
1373 pTmp->Compress( rParser );
1374
1375 if( !pTmp->nSttCnt
1376 ? (pLastNd->GetIdx()+1 != pTmp->pSttNd->GetIdx() ||
1377 !rParser.IsEndPara( pLastNd, nLastCnt ) )
1378 : ( pTmp->nSttCnt != nLastCnt ||
1379 pLastNd->GetIdx() != pTmp->pSttNd->GetIdx() ))
1380 {
1381 while( ++n < pChildList->Count() )
1382 if( (pTmp = (*pChildList)[n])->pChildList )
1383 pTmp->Compress( rParser );
1384 return;
1385 }
1386
1387 if (rParser.UncompressableStackEntry(*pTmp))
1388 return;
1389
1390 if( n )
1391 {
1392 // suche alle, die ueber den gesamten Bereich gesetzt sind
1393 SfxItemIter aIter( aMrgSet );
1394 const SfxPoolItem* pItem;
1395 do {
1396 sal_uInt16 nWhich = aIter.GetCurItem()->Which();
1397 if( SFX_ITEM_SET != pTmp->aAttrSet.GetItemState( nWhich,
1398 sal_False, &pItem ) || *pItem != *aIter.GetCurItem() )
1399 aMrgSet.ClearItem( nWhich );
1400
1401 if( aIter.IsAtEnd() )
1402 break;
1403 aIter.NextItem();
1404 } while( sal_True );
1405
1406 if( !aMrgSet.Count() )
1407 return;
1408 }
1409
1410 pLastNd = pTmp->pEndNd;
1411 nLastCnt = pTmp->nEndCnt;
1412 }
1413
1414 if( pEndNd->GetIdx() != pLastNd->GetIdx() || nEndCnt != nLastCnt )
1415 return;
1416
1417 // es kann zusammengefasst werden
1418 aAttrSet.Put( aMrgSet );
1419
1420 for( n = 0; n < pChildList->Count(); ++n )
1421 {
1422 pTmp = (*pChildList)[n];
1423 pTmp->aAttrSet.Differentiate( aMrgSet );
1424
1425 if( !pTmp->pChildList && !pTmp->aAttrSet.Count() && !pTmp->nStyleNo )
1426 {
1427 pChildList->Remove( n );
1428 delete pTmp;
1429 --n;
1430 continue;
1431 }
1432 }
1433 if( !pChildList->Count() )
1434 {
1435 delete pChildList;
1436 pChildList = 0;
1437 }
1438 }
SetRTFDefaults(const SfxItemSet & rDefaults)1439 void SvxRTFItemStackType::SetRTFDefaults( const SfxItemSet& rDefaults )
1440 {
1441 if( rDefaults.Count() )
1442 {
1443 SfxItemIter aIter( rDefaults );
1444 do {
1445 sal_uInt16 nWhich = aIter.GetCurItem()->Which();
1446 if( SFX_ITEM_SET != aAttrSet.GetItemState( nWhich, sal_False ))
1447 aAttrSet.Put( *aIter.GetCurItem() );
1448
1449 if( aIter.IsAtEnd() )
1450 break;
1451 aIter.NextItem();
1452 } while( sal_True );
1453 }
1454 }
1455
1456 /**/
1457
RTFPlainAttrMapIds(const SfxItemPool & rPool)1458 RTFPlainAttrMapIds::RTFPlainAttrMapIds( const SfxItemPool& rPool )
1459 {
1460 nCaseMap = rPool.GetTrueWhich( SID_ATTR_CHAR_CASEMAP, sal_False );
1461 nBgColor = rPool.GetTrueWhich( SID_ATTR_BRUSH_CHAR, sal_False );
1462 nColor = rPool.GetTrueWhich( SID_ATTR_CHAR_COLOR, sal_False );
1463 nContour = rPool.GetTrueWhich( SID_ATTR_CHAR_CONTOUR, sal_False );
1464 nCrossedOut = rPool.GetTrueWhich( SID_ATTR_CHAR_STRIKEOUT, sal_False );
1465 nEscapement = rPool.GetTrueWhich( SID_ATTR_CHAR_ESCAPEMENT, sal_False );
1466 nFont = rPool.GetTrueWhich( SID_ATTR_CHAR_FONT, sal_False );
1467 nFontHeight = rPool.GetTrueWhich( SID_ATTR_CHAR_FONTHEIGHT, sal_False );
1468 nKering = rPool.GetTrueWhich( SID_ATTR_CHAR_KERNING, sal_False );
1469 nLanguage = rPool.GetTrueWhich( SID_ATTR_CHAR_LANGUAGE, sal_False );
1470 nPosture = rPool.GetTrueWhich( SID_ATTR_CHAR_POSTURE, sal_False );
1471 nShadowed = rPool.GetTrueWhich( SID_ATTR_CHAR_SHADOWED, sal_False );
1472 nUnderline = rPool.GetTrueWhich( SID_ATTR_CHAR_UNDERLINE, sal_False );
1473 nOverline = rPool.GetTrueWhich( SID_ATTR_CHAR_OVERLINE, sal_False );
1474 nWeight = rPool.GetTrueWhich( SID_ATTR_CHAR_WEIGHT, sal_False );
1475 nWordlineMode = rPool.GetTrueWhich( SID_ATTR_CHAR_WORDLINEMODE, sal_False );
1476 nAutoKerning = rPool.GetTrueWhich( SID_ATTR_CHAR_AUTOKERN, sal_False );
1477
1478 nCJKFont = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_FONT, sal_False );
1479 nCJKFontHeight = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_FONTHEIGHT, sal_False );
1480 nCJKLanguage = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_LANGUAGE, sal_False );
1481 nCJKPosture = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_POSTURE, sal_False );
1482 nCJKWeight = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_WEIGHT, sal_False );
1483 nCTLFont = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_FONT, sal_False );
1484 nCTLFontHeight = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_FONTHEIGHT, sal_False );
1485 nCTLLanguage = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_LANGUAGE, sal_False );
1486 nCTLPosture = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_POSTURE, sal_False );
1487 nCTLWeight = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_WEIGHT, sal_False );
1488 nEmphasis = rPool.GetTrueWhich( SID_ATTR_CHAR_EMPHASISMARK, sal_False );
1489 nTwoLines = rPool.GetTrueWhich( SID_ATTR_CHAR_TWO_LINES, sal_False );
1490 nRuby = 0; //rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_RUBY, sal_False );
1491 nCharScaleX = rPool.GetTrueWhich( SID_ATTR_CHAR_SCALEWIDTH, sal_False );
1492 nHorzVert = rPool.GetTrueWhich( SID_ATTR_CHAR_ROTATED, sal_False );
1493 nRelief = rPool.GetTrueWhich( SID_ATTR_CHAR_RELIEF, sal_False );
1494 nHidden = rPool.GetTrueWhich( SID_ATTR_CHAR_HIDDEN, sal_False );
1495 }
1496
RTFPardAttrMapIds(const SfxItemPool & rPool)1497 RTFPardAttrMapIds ::RTFPardAttrMapIds ( const SfxItemPool& rPool )
1498 {
1499 nLinespacing = rPool.GetTrueWhich( SID_ATTR_PARA_LINESPACE, sal_False );
1500 nAdjust = rPool.GetTrueWhich( SID_ATTR_PARA_ADJUST, sal_False );
1501 nTabStop = rPool.GetTrueWhich( SID_ATTR_TABSTOP, sal_False );
1502 nHyphenzone = rPool.GetTrueWhich( SID_ATTR_PARA_HYPHENZONE, sal_False );
1503 nLRSpace = rPool.GetTrueWhich( SID_ATTR_LRSPACE, sal_False );
1504 nULSpace = rPool.GetTrueWhich( SID_ATTR_ULSPACE, sal_False );
1505 nBrush = rPool.GetTrueWhich( SID_ATTR_BRUSH, sal_False );
1506 nBox = rPool.GetTrueWhich( SID_ATTR_BORDER_OUTER, sal_False );
1507 nShadow = rPool.GetTrueWhich( SID_ATTR_BORDER_SHADOW, sal_False );
1508 nOutlineLvl = rPool.GetTrueWhich( SID_ATTR_PARA_OUTLLEVEL, sal_False );
1509 nSplit = rPool.GetTrueWhich( SID_ATTR_PARA_SPLIT, sal_False );
1510 nKeep = rPool.GetTrueWhich( SID_ATTR_PARA_KEEP, sal_False );
1511 nFontAlign = rPool.GetTrueWhich( SID_PARA_VERTALIGN, sal_False );
1512 nScriptSpace = rPool.GetTrueWhich( SID_ATTR_PARA_SCRIPTSPACE, sal_False );
1513 nHangPunct = rPool.GetTrueWhich( SID_ATTR_PARA_HANGPUNCTUATION, sal_False );
1514 nForbRule = rPool.GetTrueWhich( SID_ATTR_PARA_FORBIDDEN_RULES, sal_False );
1515 nDirection = rPool.GetTrueWhich( SID_ATTR_FRAMEDIRECTION, sal_False );
1516 }
1517
1518 /* vi:set tabstop=4 shiftwidth=4 expandtab: */
1519