xref: /AOO41X/main/editeng/source/rtf/svxrtf.cxx (revision b264d727df3f2f855962c46c6c4fbcd5e27e6a7e)
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