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