Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 :
21 : #include <ctype.h>
22 : #include <tools/diagnose_ex.h>
23 : #include <rtl/tencinfo.h>
24 : #include <svl/itemiter.hxx>
25 : #include <svl/whiter.hxx>
26 : #include <svtools/rtftoken.h>
27 : #include <svl/itempool.hxx>
28 :
29 : #include <comphelper/string.hxx>
30 :
31 : #include <com/sun/star/lang/Locale.hpp>
32 : #include <editeng/scriptspaceitem.hxx>
33 : #include <editeng/fontitem.hxx>
34 : #include <editeng/colritem.hxx>
35 : #include <editeng/svxrtf.hxx>
36 : #include <editeng/editids.hrc>
37 : #include <vcl/svapp.hxx>
38 :
39 : #include <com/sun/star/document/XDocumentProperties.hpp>
40 :
41 :
42 : using namespace ::com::sun::star;
43 :
44 :
45 0 : static CharSet lcl_GetDefaultTextEncodingForRTF()
46 : {
47 :
48 0 : ::rtl::OUString aLangString( Application::GetSettings().GetLanguageTag().getLanguage());
49 :
50 0 : if ( aLangString == "ru" || aLangString == "uk" )
51 0 : return RTL_TEXTENCODING_MS_1251;
52 0 : if ( aLangString == "tr" )
53 0 : return RTL_TEXTENCODING_MS_1254;
54 : else
55 0 : return RTL_TEXTENCODING_MS_1252;
56 : }
57 :
58 : // -------------- Methods --------------------
59 :
60 0 : SvxRTFParser::SvxRTFParser( SfxItemPool& rPool, SvStream& rIn,
61 : uno::Reference<document::XDocumentProperties> i_xDocProps,
62 : int bReadNewDoc )
63 : : SvRTFParser( rIn, 5 ),
64 : rStrm(rIn),
65 : pInsPos( 0 ),
66 : pAttrPool( &rPool ),
67 : m_xDocProps( i_xDocProps ),
68 : pRTFDefaults( 0 ),
69 0 : nVersionNo( 0 )
70 : {
71 0 : bNewDoc = bReadNewDoc;
72 :
73 0 : bChkStyleAttr = bCalcValue = bReadDocInfo = bIsInReadStyleTab = sal_False;
74 0 : bIsLeftToRightDef = sal_True;
75 :
76 : {
77 0 : RTFPlainAttrMapIds aTmp( rPool );
78 : aPlainMap.insert( aPlainMap.begin(), (sal_uInt16*)&aTmp,
79 0 : (sal_uInt16*)&aTmp + (sizeof( RTFPlainAttrMapIds ) / sizeof(sal_uInt16)) );
80 : }
81 : {
82 0 : RTFPardAttrMapIds aTmp( rPool );
83 : aPardMap.insert( aPardMap.begin(), (sal_uInt16*)&aTmp,
84 0 : (sal_uInt16*)&aTmp + (sizeof( RTFPardAttrMapIds ) / sizeof(sal_uInt16)) );
85 : }
86 0 : pDfltFont = new Font;
87 0 : pDfltColor = new Color;
88 0 : }
89 :
90 0 : void SvxRTFParser::EnterEnvironment()
91 : {
92 0 : }
93 :
94 0 : void SvxRTFParser::LeaveEnvironment()
95 : {
96 0 : }
97 :
98 0 : void SvxRTFParser::ResetPard()
99 : {
100 0 : }
101 :
102 0 : SvxRTFParser::~SvxRTFParser()
103 : {
104 0 : if( !aColorTbl.empty() )
105 0 : ClearColorTbl();
106 0 : if( !aAttrStack.empty() )
107 0 : ClearAttrStack();
108 :
109 0 : delete pRTFDefaults;
110 :
111 0 : delete pInsPos;
112 0 : delete pDfltFont;
113 0 : delete pDfltColor;
114 0 : }
115 :
116 0 : void SvxRTFParser::SetInsPos( const SvxPosition& rNew )
117 : {
118 0 : if( pInsPos )
119 0 : delete pInsPos;
120 0 : pInsPos = rNew.Clone();
121 0 : }
122 :
123 0 : SvParserState SvxRTFParser::CallParser()
124 : {
125 : DBG_ASSERT( pInsPos, "no insertion position");
126 :
127 0 : if( !pInsPos )
128 0 : return SVPAR_ERROR;
129 :
130 0 : if( !aColorTbl.empty() )
131 0 : ClearColorTbl();
132 0 : if( !aFontTbl.empty() )
133 0 : ClearFontTbl();
134 0 : if( !aStyleTbl.empty() )
135 0 : ClearStyleTbl();
136 0 : if( !aAttrStack.empty() )
137 0 : ClearAttrStack();
138 :
139 0 : bIsSetDfltTab = sal_False;
140 0 : bNewGroup = sal_False;
141 0 : nDfltFont = 0;
142 :
143 0 : sBaseURL.Erase();
144 :
145 : // generate the correct WhichId table from the set WhichIds.
146 0 : BuildWhichTbl();
147 :
148 0 : return SvRTFParser::CallParser();
149 : }
150 :
151 0 : void SvxRTFParser::Continue( int nToken )
152 : {
153 0 : SvRTFParser::Continue( nToken );
154 :
155 0 : if( SVPAR_PENDING != GetStatus() )
156 : {
157 0 : SetAllAttrOfStk();
158 : //Regardless of what "color 0" is, word defaults to auto as the default colour.
159 : //e.g. see #i7713#
160 : }
161 0 : }
162 :
163 :
164 : // is called for each token that is recognized in CallParser
165 0 : void SvxRTFParser::NextToken( int nToken )
166 : {
167 : sal_Unicode cCh;
168 0 : switch( nToken )
169 : {
170 0 : case RTF_COLORTBL: ReadColorTable(); break;
171 0 : case RTF_FONTTBL: ReadFontTable(); break;
172 0 : case RTF_STYLESHEET: ReadStyleTable(); break;
173 :
174 : case RTF_DEFF:
175 0 : if( bNewDoc )
176 : {
177 0 : if( !aFontTbl.empty() )
178 : // Can immediately be set
179 0 : SetDefault( nToken, nTokenValue );
180 : else
181 : // is set after reading the font table
182 0 : nDfltFont = int(nTokenValue);
183 : }
184 0 : break;
185 :
186 : case RTF_DEFTAB:
187 : case RTF_DEFLANG:
188 0 : if( bNewDoc )
189 0 : SetDefault( nToken, nTokenValue );
190 0 : break;
191 :
192 :
193 0 : case RTF_PICT: ReadBitmapData(); break;
194 :
195 0 : case RTF_LINE: cCh = '\n'; goto INSINGLECHAR;
196 0 : case RTF_TAB: cCh = '\t'; goto INSINGLECHAR;
197 0 : case RTF_SUBENTRYINDEX: cCh = ':'; goto INSINGLECHAR;
198 :
199 0 : case RTF_EMDASH: cCh = 0x2014; goto INSINGLECHAR;
200 0 : case RTF_ENDASH: cCh = 0x2013; goto INSINGLECHAR;
201 0 : case RTF_BULLET: cCh = 0x2022; goto INSINGLECHAR;
202 0 : case RTF_LQUOTE: cCh = 0x2018; goto INSINGLECHAR;
203 0 : case RTF_RQUOTE: cCh = 0x2019; goto INSINGLECHAR;
204 0 : case RTF_LDBLQUOTE: cCh = 0x201C; goto INSINGLECHAR;
205 0 : case RTF_RDBLQUOTE: cCh = 0x201D; goto INSINGLECHAR;
206 : INSINGLECHAR:
207 0 : aToken = rtl::OUString(cCh);
208 : // no Break, aToken is set as Text
209 : case RTF_TEXTTOKEN:
210 : {
211 0 : InsertText();
212 : // all collected Attributes are set
213 0 : for( sal_uInt16 n = aAttrSetList.size(); n; )
214 : {
215 0 : SvxRTFItemStackType* pStkSet = &aAttrSetList[--n];
216 0 : SetAttrSet( *pStkSet );
217 0 : aAttrSetList.pop_back();
218 : }
219 : }
220 0 : break;
221 :
222 :
223 : case RTF_PAR:
224 0 : InsertPara();
225 0 : break;
226 : case '{':
227 0 : if (bNewGroup) // Nesting!
228 0 : _GetAttrSet();
229 0 : EnterEnvironment();
230 0 : bNewGroup = true;
231 0 : break;
232 : case '}':
233 0 : if( !bNewGroup ) // Empty Group ??
234 0 : AttrGroupEnd();
235 0 : LeaveEnvironment();
236 0 : bNewGroup = false;
237 0 : break;
238 : case RTF_INFO:
239 0 : if (bReadDocInfo && bNewDoc && m_xDocProps.is())
240 0 : ReadInfo();
241 : else
242 0 : SkipGroup();
243 0 : break;
244 :
245 : // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
246 : // First overwrite all (all have to be in one group!!)
247 : // Could also appear in the RTF-filewithout the IGNORE-Flag; all Groups
248 : // with the IGNORE-Flag are overwritten in the default branch.
249 :
250 : case RTF_SWG_PRTDATA:
251 : case RTF_FIELD:
252 : case RTF_ATNID:
253 : case RTF_ANNOTATION:
254 :
255 : case RTF_BKMKSTART:
256 : case RTF_BKMKEND:
257 : case RTF_BKMK_KEY:
258 : case RTF_XE:
259 : case RTF_TC:
260 : case RTF_NEXTFILE:
261 : case RTF_TEMPLATE:
262 : // RTF_SHPRSLT disabled for #i19718#
263 0 : SkipGroup();
264 0 : break;
265 : // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
266 :
267 : case RTF_PGDSCNO:
268 : case RTF_PGBRK:
269 : case RTF_SHADOW:
270 0 : if( RTF_IGNOREFLAG != GetStackPtr( -1 )->nTokenId )
271 0 : break;
272 0 : nToken = SkipToken( -1 );
273 0 : if( '{' == GetStackPtr( -1 )->nTokenId )
274 0 : nToken = SkipToken( -1 );
275 :
276 0 : ReadAttr( nToken, &GetAttrSet() );
277 0 : break;
278 :
279 : default:
280 0 : switch( nToken & ~(0xff | RTF_SWGDEFS) )
281 : {
282 : case RTF_PARFMT: // hier gibts keine Swg-Defines
283 0 : ReadAttr( nToken, &GetAttrSet() );
284 0 : break;
285 :
286 : case RTF_CHRFMT:
287 : case RTF_BRDRDEF:
288 : case RTF_TABSTOPDEF:
289 :
290 0 : if( RTF_SWGDEFS & nToken)
291 : {
292 0 : if( RTF_IGNOREFLAG != GetStackPtr( -1 )->nTokenId )
293 0 : break;
294 0 : nToken = SkipToken( -1 );
295 0 : if( '{' == GetStackPtr( -1 )->nTokenId )
296 : {
297 0 : nToken = SkipToken( -1 );
298 : }
299 : }
300 0 : ReadAttr( nToken, &GetAttrSet() );
301 0 : break;
302 : default:
303 : {
304 0 : if( /*( '{' == GetStackPtr( -1 )->nTokenId ) ||*/
305 0 : ( RTF_IGNOREFLAG == GetStackPtr( -1 )->nTokenId &&
306 0 : '{' == GetStackPtr( -2 )->nTokenId ) )
307 0 : SkipGroup();
308 : }
309 0 : break;
310 : }
311 0 : break;
312 : }
313 0 : }
314 :
315 0 : void SvxRTFParser::ReadStyleTable()
316 : {
317 0 : int nToken, bSaveChkStyleAttr = bChkStyleAttr;
318 0 : sal_uInt16 nStyleNo = 0;
319 0 : int _nOpenBrakets = 1; // the first was already detected earlier!!
320 0 : SvxRTFStyleType* pStyle = new SvxRTFStyleType( *pAttrPool, &aWhichMap[0] );
321 0 : pStyle->aAttrSet.Put( GetRTFDefaults() );
322 :
323 0 : bIsInReadStyleTab = sal_True;
324 0 : bChkStyleAttr = sal_False; // Do not check Attribute against the Styles
325 :
326 0 : while( _nOpenBrakets && IsParserWorking() )
327 : {
328 0 : switch( nToken = GetNextToken() )
329 : {
330 0 : case '}': if( --_nOpenBrakets && IsParserWorking() )
331 : // Style has been completely read,
332 : // so this is still a stable status
333 0 : SaveState( RTF_STYLESHEET );
334 0 : break;
335 : case '{':
336 : {
337 0 : if( RTF_IGNOREFLAG != GetNextToken() )
338 0 : nToken = SkipToken( -1 );
339 0 : else if( RTF_UNKNOWNCONTROL != ( nToken = GetNextToken() ) &&
340 : RTF_PN != nToken )
341 0 : nToken = SkipToken( -2 );
342 : else
343 : {
344 : // filter out at once
345 0 : ReadUnknownData();
346 0 : nToken = GetNextToken();
347 0 : if( '}' != nToken )
348 0 : eState = SVPAR_ERROR;
349 0 : break;
350 : }
351 0 : ++_nOpenBrakets;
352 : }
353 0 : break;
354 :
355 0 : case RTF_SBASEDON: pStyle->nBasedOn = sal_uInt16(nTokenValue); pStyle->bBasedOnIsSet=sal_True; break;
356 0 : case RTF_SNEXT: pStyle->nNext = sal_uInt16(nTokenValue); break;
357 : case RTF_OUTLINELEVEL:
358 0 : case RTF_SOUTLVL: pStyle->nOutlineNo = sal_uInt8(nTokenValue); break;
359 0 : case RTF_S: nStyleNo = (short)nTokenValue; break;
360 0 : case RTF_CS: nStyleNo = (short)nTokenValue;
361 0 : pStyle->bIsCharFmt = sal_True;
362 0 : break;
363 :
364 : case RTF_TEXTTOKEN:
365 : {
366 0 : pStyle->sName = DelCharAtEnd( aToken, ';' );
367 :
368 0 : if( !aStyleTbl.empty() )
369 : {
370 0 : aStyleTbl.erase(nStyleNo);
371 : }
372 : // All data from the font is available, so off to the table
373 0 : aStyleTbl.insert( nStyleNo , pStyle);
374 0 : pStyle = new SvxRTFStyleType( *pAttrPool, &aWhichMap[0] );
375 0 : pStyle->aAttrSet.Put( GetRTFDefaults() );
376 0 : nStyleNo = 0;
377 : }
378 0 : break;
379 : default:
380 0 : switch( nToken & ~(0xff | RTF_SWGDEFS) )
381 : {
382 : case RTF_PARFMT: // hier gibts keine Swg-Defines
383 0 : ReadAttr( nToken, &pStyle->aAttrSet );
384 0 : break;
385 :
386 : case RTF_CHRFMT:
387 : case RTF_BRDRDEF:
388 : case RTF_TABSTOPDEF:
389 :
390 0 : if( RTF_SWGDEFS & nToken)
391 : {
392 0 : if( RTF_IGNOREFLAG != GetStackPtr( -1 )->nTokenId )
393 0 : break;
394 0 : nToken = SkipToken( -1 );
395 0 : if( '{' == GetStackPtr( -1 )->nTokenId )
396 : {
397 0 : nToken = SkipToken( -1 );
398 : }
399 : }
400 0 : ReadAttr( nToken, &pStyle->aAttrSet );
401 0 : break;
402 : }
403 0 : break;
404 : }
405 : }
406 0 : delete pStyle; // Delete the Last Style
407 0 : SkipToken( -1 ); // the closing brace is evaluated "above"
408 :
409 : // Flag back to old state
410 0 : bChkStyleAttr = bSaveChkStyleAttr;
411 0 : bIsInReadStyleTab = sal_False;
412 0 : }
413 :
414 0 : void SvxRTFParser::ReadColorTable()
415 : {
416 : int nToken;
417 0 : sal_uInt8 nRed = 0xff, nGreen = 0xff, nBlue = 0xff;
418 :
419 0 : while( '}' != ( nToken = GetNextToken() ) && IsParserWorking() )
420 : {
421 0 : switch( nToken )
422 : {
423 0 : case RTF_RED: nRed = sal_uInt8(nTokenValue); break;
424 0 : case RTF_GREEN: nGreen = sal_uInt8(nTokenValue); break;
425 0 : case RTF_BLUE: nBlue = sal_uInt8(nTokenValue); break;
426 :
427 : case RTF_TEXTTOKEN:
428 0 : if( 1 == aToken.Len()
429 0 : ? aToken.GetChar( 0 ) != ';'
430 0 : : STRING_NOTFOUND == aToken.Search( ';' ) )
431 0 : break; // At least the ';' must be found
432 :
433 : // else no break !!
434 :
435 : case ';':
436 0 : if( IsParserWorking() )
437 : {
438 : // one color is finished, fill in the table
439 : // try to map the values to SV internal names
440 0 : ColorPtr pColor = new Color( nRed, nGreen, nBlue );
441 0 : if( aColorTbl.empty() &&
442 : sal_uInt8(-1) == nRed && sal_uInt8(-1) == nGreen && sal_uInt8(-1) == nBlue )
443 0 : pColor->SetColor( COL_AUTO );
444 0 : aColorTbl.push_back( pColor );
445 0 : nRed = 0, nGreen = 0, nBlue = 0;
446 :
447 : // Color has been completely read,
448 : // so this is still a stable status
449 0 : SaveState( RTF_COLORTBL );
450 : }
451 0 : break;
452 : }
453 : }
454 0 : SkipToken( -1 ); // the closing brace is evaluated "above"
455 0 : }
456 :
457 0 : void SvxRTFParser::ReadFontTable()
458 : {
459 : int nToken;
460 0 : int _nOpenBrakets = 1; // the first was already detected earlier!!
461 0 : Font* pFont = new Font();
462 0 : short nFontNo(0), nInsFontNo (0);
463 0 : String sAltNm, sFntNm;
464 0 : sal_Bool bIsAltFntNm = sal_False, bCheckNewFont;
465 :
466 0 : CharSet nSystemChar = lcl_GetDefaultTextEncodingForRTF();
467 0 : pFont->SetCharSet( nSystemChar );
468 0 : SetEncoding( nSystemChar );
469 :
470 0 : while( _nOpenBrakets && IsParserWorking() )
471 : {
472 0 : bCheckNewFont = sal_False;
473 0 : switch( ( nToken = GetNextToken() ))
474 : {
475 : case '}':
476 0 : bIsAltFntNm = sal_False;
477 : // Style has been completely read,
478 : // so this is still a stable status
479 0 : if( --_nOpenBrakets <= 1 && IsParserWorking() )
480 0 : SaveState( RTF_FONTTBL );
481 0 : bCheckNewFont = sal_True;
482 0 : nInsFontNo = nFontNo;
483 0 : break;
484 : case '{':
485 0 : if( RTF_IGNOREFLAG != GetNextToken() )
486 0 : nToken = SkipToken( -1 );
487 : // immediately skip unknown and all known but non-evaluated
488 : // groups
489 0 : else if( RTF_UNKNOWNCONTROL != ( nToken = GetNextToken() ) &&
490 : RTF_PANOSE != nToken && RTF_FNAME != nToken &&
491 : RTF_FONTEMB != nToken && RTF_FONTFILE != nToken )
492 0 : nToken = SkipToken( -2 );
493 : else
494 : {
495 : // filter out at once
496 0 : ReadUnknownData();
497 0 : nToken = GetNextToken();
498 0 : if( '}' != nToken )
499 0 : eState = SVPAR_ERROR;
500 0 : break;
501 : }
502 0 : ++_nOpenBrakets;
503 0 : break;
504 : case RTF_FROMAN:
505 0 : pFont->SetFamily( FAMILY_ROMAN );
506 0 : break;
507 : case RTF_FSWISS:
508 0 : pFont->SetFamily( FAMILY_SWISS );
509 0 : break;
510 : case RTF_FMODERN:
511 0 : pFont->SetFamily( FAMILY_MODERN );
512 0 : break;
513 : case RTF_FSCRIPT:
514 0 : pFont->SetFamily( FAMILY_SCRIPT );
515 0 : break;
516 : case RTF_FDECOR:
517 0 : pFont->SetFamily( FAMILY_DECORATIVE );
518 0 : break;
519 : // for technical/symbolic font of the CharSet is changed!
520 : case RTF_FTECH:
521 0 : pFont->SetCharSet( RTL_TEXTENCODING_SYMBOL );
522 : // deliberate fall through
523 : case RTF_FNIL:
524 0 : pFont->SetFamily( FAMILY_DONTKNOW );
525 0 : break;
526 : case RTF_FCHARSET:
527 0 : if (-1 != nTokenValue)
528 : {
529 : CharSet nCharSet = rtl_getTextEncodingFromWindowsCharset(
530 0 : (sal_uInt8)nTokenValue);
531 0 : pFont->SetCharSet(nCharSet);
532 : //When we're in a font, the fontname is in the font
533 : //charset, except for symbol fonts I believe
534 0 : if (nCharSet == RTL_TEXTENCODING_SYMBOL)
535 0 : nCharSet = RTL_TEXTENCODING_DONTKNOW;
536 0 : SetEncoding(nCharSet);
537 : }
538 0 : break;
539 : case RTF_FPRQ:
540 0 : switch( nTokenValue )
541 : {
542 : case 1:
543 0 : pFont->SetPitch( PITCH_FIXED );
544 0 : break;
545 : case 2:
546 0 : pFont->SetPitch( PITCH_VARIABLE );
547 0 : break;
548 : }
549 0 : break;
550 : case RTF_F:
551 0 : bCheckNewFont = sal_True;
552 0 : nInsFontNo = nFontNo;
553 0 : nFontNo = (short)nTokenValue;
554 0 : break;
555 : case RTF_FALT:
556 0 : bIsAltFntNm = sal_True;
557 0 : break;
558 : case RTF_TEXTTOKEN:
559 0 : DelCharAtEnd( aToken, ';' );
560 0 : if ( aToken.Len() )
561 : {
562 0 : if( bIsAltFntNm )
563 0 : sAltNm = aToken;
564 : else
565 0 : sFntNm = aToken;
566 : }
567 0 : break;
568 : }
569 :
570 0 : if( bCheckNewFont && 1 >= _nOpenBrakets && sFntNm.Len() ) // one font is ready
571 : {
572 : // All data from the font is available, so off to the table
573 0 : if (sAltNm.Len())
574 0 : (sFntNm += ';' ) += sAltNm;
575 :
576 0 : pFont->SetName( sFntNm );
577 0 : aFontTbl.insert( nInsFontNo, pFont );
578 0 : pFont = new Font();
579 0 : pFont->SetCharSet( nSystemChar );
580 0 : sAltNm.Erase();
581 0 : sFntNm.Erase();
582 : }
583 : }
584 : // the last one we have to delete manually
585 0 : delete pFont;
586 0 : SkipToken( -1 ); // the closing brace is evaluated "above"
587 :
588 : // set the default font in the Document
589 0 : if( bNewDoc && IsParserWorking() )
590 0 : SetDefault( RTF_DEFF, nDfltFont );
591 0 : }
592 :
593 0 : void SvxRTFParser::ReadBitmapData()
594 : {
595 0 : SvRTFParser::ReadBitmapData();
596 0 : }
597 :
598 0 : void SvxRTFParser::ReadOLEData()
599 : {
600 0 : SvRTFParser::ReadOLEData();
601 0 : }
602 :
603 0 : String& SvxRTFParser::GetTextToEndGroup( String& rStr )
604 : {
605 0 : rStr.Erase( 0 );
606 0 : int _nOpenBrakets = 1, nToken; // the first was already detected earlier!!
607 :
608 0 : while( _nOpenBrakets && IsParserWorking() )
609 : {
610 0 : switch( nToken = GetNextToken() )
611 : {
612 0 : case '}': --_nOpenBrakets; break;
613 : case '{':
614 : {
615 0 : if( RTF_IGNOREFLAG != GetNextToken() )
616 0 : nToken = SkipToken( -1 );
617 0 : else if( RTF_UNKNOWNCONTROL != GetNextToken() )
618 0 : nToken = SkipToken( -2 );
619 : else
620 : {
621 : // filter out at once
622 0 : ReadUnknownData();
623 0 : nToken = GetNextToken();
624 0 : if( '}' != nToken )
625 0 : eState = SVPAR_ERROR;
626 0 : break;
627 : }
628 0 : ++_nOpenBrakets;
629 : }
630 0 : break;
631 :
632 : case RTF_TEXTTOKEN:
633 0 : rStr += aToken;
634 0 : break;
635 : }
636 : }
637 0 : SkipToken( -1 ); // the closing brace is evaluated "above"
638 0 : return rStr;
639 : }
640 :
641 0 : util::DateTime SvxRTFParser::GetDateTimeStamp( )
642 : {
643 0 : util::DateTime aDT;
644 0 : sal_Bool bWeiter = sal_True;
645 :
646 0 : while( bWeiter && IsParserWorking() )
647 : {
648 0 : int nToken = GetNextToken();
649 0 : switch( nToken )
650 : {
651 0 : case RTF_YR: aDT.Year = (sal_uInt16)nTokenValue; break;
652 0 : case RTF_MO: aDT.Month = (sal_uInt16)nTokenValue; break;
653 0 : case RTF_DY: aDT.Day = (sal_uInt16)nTokenValue; break;
654 0 : case RTF_HR: aDT.Hours = (sal_uInt16)nTokenValue; break;
655 0 : case RTF_MIN: aDT.Minutes = (sal_uInt16)nTokenValue; break;
656 : default:
657 0 : bWeiter = sal_False;
658 : }
659 : }
660 0 : SkipToken( -1 ); // the closing brace is evaluated "above"
661 0 : return aDT;
662 : }
663 :
664 0 : void SvxRTFParser::ReadInfo( const sal_Char* pChkForVerNo )
665 : {
666 0 : int _nOpenBrakets = 1, nToken; // the first was already detected earlier!!
667 : DBG_ASSERT(m_xDocProps.is(),
668 : "SvxRTFParser::ReadInfo: no DocumentProperties");
669 0 : String sStr, sComment;
670 0 : long nVersNo = 0;
671 :
672 0 : while( _nOpenBrakets && IsParserWorking() )
673 : {
674 0 : switch( nToken = GetNextToken() )
675 : {
676 0 : case '}': --_nOpenBrakets; break;
677 : case '{':
678 : {
679 0 : if( RTF_IGNOREFLAG != GetNextToken() )
680 0 : nToken = SkipToken( -1 );
681 0 : else if( RTF_UNKNOWNCONTROL != GetNextToken() )
682 0 : nToken = SkipToken( -2 );
683 : else
684 : {
685 : // filter out at once
686 0 : ReadUnknownData();
687 0 : nToken = GetNextToken();
688 0 : if( '}' != nToken )
689 0 : eState = SVPAR_ERROR;
690 0 : break;
691 : }
692 0 : ++_nOpenBrakets;
693 : }
694 0 : break;
695 :
696 : case RTF_TITLE:
697 0 : m_xDocProps->setTitle( GetTextToEndGroup( sStr ) );
698 0 : break;
699 : case RTF_SUBJECT:
700 0 : m_xDocProps->setSubject( GetTextToEndGroup( sStr ) );
701 0 : break;
702 : case RTF_AUTHOR:
703 0 : m_xDocProps->setAuthor( GetTextToEndGroup( sStr ) );
704 0 : break;
705 : case RTF_OPERATOR:
706 0 : m_xDocProps->setModifiedBy( GetTextToEndGroup( sStr ) );
707 0 : break;
708 : case RTF_KEYWORDS:
709 : {
710 0 : ::rtl::OUString sTemp = GetTextToEndGroup( sStr );
711 0 : m_xDocProps->setKeywords(
712 0 : ::comphelper::string::convertCommaSeparated(sTemp) );
713 0 : break;
714 : }
715 : case RTF_DOCCOMM:
716 0 : m_xDocProps->setDescription( GetTextToEndGroup( sStr ) );
717 0 : break;
718 :
719 : case RTF_HLINKBASE:
720 0 : sBaseURL = GetTextToEndGroup( sStr ) ;
721 0 : break;
722 :
723 : case RTF_CREATIM:
724 0 : m_xDocProps->setCreationDate( GetDateTimeStamp() );
725 0 : break;
726 :
727 : case RTF_REVTIM:
728 0 : m_xDocProps->setModificationDate( GetDateTimeStamp() );
729 0 : break;
730 :
731 : case RTF_PRINTIM:
732 0 : m_xDocProps->setPrintDate( GetDateTimeStamp() );
733 0 : break;
734 :
735 : case RTF_COMMENT:
736 0 : GetTextToEndGroup( sComment );
737 0 : break;
738 :
739 : case RTF_BUPTIM:
740 0 : SkipGroup();
741 0 : break;
742 :
743 : case RTF_VERN:
744 0 : nVersNo = nTokenValue;
745 0 : break;
746 :
747 : case RTF_EDMINS:
748 : case RTF_ID:
749 : case RTF_VERSION:
750 : case RTF_NOFPAGES:
751 : case RTF_NOFWORDS:
752 : case RTF_NOFCHARS:
753 0 : NextToken( nToken );
754 0 : break;
755 :
756 : // default:
757 : }
758 : }
759 :
760 0 : if( pChkForVerNo &&
761 0 : COMPARE_EQUAL == sComment.CompareToAscii( pChkForVerNo ))
762 0 : nVersionNo = nVersNo;
763 :
764 0 : SkipToken( -1 ); // the closing brace is evaluated "above"
765 0 : }
766 :
767 :
768 0 : void SvxRTFParser::ClearColorTbl()
769 : {
770 0 : while ( !aColorTbl.empty() )
771 : {
772 0 : delete aColorTbl.back();
773 0 : aColorTbl.pop_back();
774 : }
775 0 : }
776 :
777 0 : void SvxRTFParser::ClearFontTbl()
778 : {
779 0 : aFontTbl.clear();
780 0 : }
781 :
782 0 : void SvxRTFParser::ClearStyleTbl()
783 : {
784 0 : aStyleTbl.clear();
785 0 : }
786 :
787 0 : void SvxRTFParser::ClearAttrStack()
788 : {
789 : SvxRTFItemStackType* pTmp;
790 0 : for( size_t nCnt = aAttrStack.size(); nCnt; --nCnt )
791 : {
792 0 : pTmp = aAttrStack.back();
793 0 : aAttrStack.pop_back();
794 0 : delete pTmp;
795 : }
796 0 : }
797 :
798 0 : String& SvxRTFParser::DelCharAtEnd( String& rStr, const sal_Unicode cDel )
799 : {
800 0 : if( rStr.Len() && ' ' == rStr.GetChar( 0 ))
801 0 : rStr = comphelper::string::stripStart(rStr, ' ');
802 0 : if( rStr.Len() && ' ' == rStr.GetChar( rStr.Len()-1 ))
803 0 : rStr = comphelper::string::stripEnd(rStr, ' ');
804 0 : if( rStr.Len() && cDel == rStr.GetChar( rStr.Len()-1 ))
805 0 : rStr.Erase( rStr.Len()-1 );
806 0 : return rStr;
807 : }
808 :
809 :
810 0 : const Font& SvxRTFParser::GetFont( sal_uInt16 nId )
811 : {
812 0 : SvxRTFFontTbl::const_iterator it = aFontTbl.find( nId );
813 : const Font* pFont;
814 0 : if( it == aFontTbl.end() )
815 : {
816 : const SvxFontItem& rDfltFont = (const SvxFontItem&)
817 : pAttrPool->GetDefaultItem(
818 0 : ((RTFPlainAttrMapIds*)&aPlainMap[0])->nFont );
819 0 : pDfltFont->SetName( rDfltFont.GetStyleName() );
820 0 : pDfltFont->SetFamily( rDfltFont.GetFamily() );
821 0 : pFont = pDfltFont;
822 : }
823 : else
824 0 : pFont = it->second;
825 0 : return *pFont;
826 : }
827 :
828 0 : SvxRTFItemStackType* SvxRTFParser::_GetAttrSet( int bCopyAttr )
829 : {
830 0 : SvxRTFItemStackType* pAkt = aAttrStack.empty() ? 0 : aAttrStack.back();
831 : SvxRTFItemStackType* pNew;
832 0 : if( pAkt )
833 0 : pNew = new SvxRTFItemStackType( *pAkt, *pInsPos, bCopyAttr );
834 : else
835 0 : pNew = new SvxRTFItemStackType( *pAttrPool, &aWhichMap[0],
836 0 : *pInsPos );
837 0 : pNew->SetRTFDefaults( GetRTFDefaults() );
838 :
839 0 : aAttrStack.push_back( pNew );
840 0 : bNewGroup = sal_False;
841 0 : return pNew;
842 : }
843 :
844 :
845 0 : void SvxRTFParser::_ClearStyleAttr( SvxRTFItemStackType& rStkType )
846 : {
847 : // check attributes to the attributes of the stylesheet or to
848 : // the default attrs of the document
849 0 : SfxItemSet &rSet = rStkType.GetAttrSet();
850 0 : const SfxItemPool& rPool = *rSet.GetPool();
851 : const SfxPoolItem* pItem;
852 0 : SfxWhichIter aIter( rSet );
853 :
854 0 : if( !IsChkStyleAttr() ||
855 0 : !rStkType.GetAttrSet().Count() ||
856 0 : aStyleTbl.count( rStkType.nStyleNo ) == 0 )
857 : {
858 0 : for( sal_uInt16 nWhich = aIter.GetCurWhich(); nWhich; nWhich = aIter.NextWhich() )
859 : {
860 0 : if( SFX_WHICH_MAX > nWhich &&
861 0 : SFX_ITEM_SET == rSet.GetItemState( nWhich, sal_False, &pItem ) &&
862 0 : rPool.GetDefaultItem( nWhich ) == *pItem )
863 0 : rSet.ClearItem( nWhich ); // delete
864 : }
865 : }
866 : else
867 : {
868 : // Delete all Attributes, which are already defined in the Style,
869 : // from the current AttrSet.
870 0 : SvxRTFStyleType* pStyle = aStyleTbl.find( rStkType.nStyleNo )->second;
871 0 : SfxItemSet &rStyleSet = pStyle->aAttrSet;
872 : const SfxPoolItem* pSItem;
873 0 : for( sal_uInt16 nWhich = aIter.GetCurWhich(); nWhich; nWhich = aIter.NextWhich() )
874 : {
875 0 : if( SFX_ITEM_SET == rStyleSet.GetItemState( nWhich, sal_True, &pSItem ))
876 : {
877 0 : if( SFX_ITEM_SET == rSet.GetItemState( nWhich, sal_False, &pItem )
878 0 : && *pItem == *pSItem )
879 0 : rSet.ClearItem( nWhich ); // delete
880 : }
881 0 : else if( SFX_WHICH_MAX > nWhich &&
882 0 : SFX_ITEM_SET == rSet.GetItemState( nWhich, sal_False, &pItem ) &&
883 0 : rPool.GetDefaultItem( nWhich ) == *pItem )
884 0 : rSet.ClearItem( nWhich ); // delete
885 : }
886 0 : }
887 0 : }
888 :
889 0 : void SvxRTFParser::AttrGroupEnd() // process the current, delete from Stack
890 : {
891 0 : if( !aAttrStack.empty() )
892 : {
893 0 : SvxRTFItemStackType *pOld = aAttrStack.empty() ? 0 : aAttrStack.back();
894 0 : aAttrStack.pop_back();
895 0 : SvxRTFItemStackType *pAkt = aAttrStack.empty() ? 0 : aAttrStack.back();
896 :
897 : do { // middle check loop
898 0 : sal_uLong nOldSttNdIdx = pOld->pSttNd->GetIdx();
899 0 : if( !pOld->pChildList &&
900 0 : ((!pOld->aAttrSet.Count() && !pOld->nStyleNo ) ||
901 0 : (nOldSttNdIdx == pInsPos->GetNodeIdx() &&
902 0 : pOld->nSttCnt == pInsPos->GetCntIdx() )))
903 0 : break; // no attributes or Area
904 :
905 : // set only the attributes that are different from the parent
906 0 : if( pAkt && pOld->aAttrSet.Count() )
907 : {
908 0 : SfxItemIter aIter( pOld->aAttrSet );
909 0 : const SfxPoolItem* pItem = aIter.GetCurItem(), *pGet;
910 0 : while( sal_True )
911 : {
912 0 : if( SFX_ITEM_SET == pAkt->aAttrSet.GetItemState(
913 0 : pItem->Which(), sal_False, &pGet ) &&
914 0 : *pItem == *pGet )
915 0 : pOld->aAttrSet.ClearItem( pItem->Which() );
916 :
917 0 : if( aIter.IsAtEnd() )
918 0 : break;
919 0 : pItem = aIter.NextItem();
920 : }
921 :
922 0 : if( !pOld->aAttrSet.Count() && !pOld->pChildList &&
923 0 : !pOld->nStyleNo )
924 0 : break;
925 : }
926 :
927 : // Set all attributes which have been defined from start until here
928 0 : int bCrsrBack = !pInsPos->GetCntIdx();
929 0 : if( bCrsrBack )
930 : {
931 : // at the beginning of a paragraph? Move back one position
932 0 : sal_uLong nNd = pInsPos->GetNodeIdx();
933 0 : MovePos( sal_False );
934 : // if can not move backward then later dont move forward !
935 0 : bCrsrBack = nNd != pInsPos->GetNodeIdx();
936 : }
937 :
938 0 : if( ( pOld->pSttNd->GetIdx() < pInsPos->GetNodeIdx() ||
939 0 : ( pOld->pSttNd->GetIdx() == pInsPos->GetNodeIdx() &&
940 0 : pOld->nSttCnt <= pInsPos->GetCntIdx() ))
941 : )
942 : {
943 0 : if( !bCrsrBack )
944 : {
945 : // all pard attributes are only valid until the previous
946 : // paragraph !!
947 0 : if( nOldSttNdIdx == pInsPos->GetNodeIdx() )
948 : {
949 : }
950 : else
951 : {
952 : // Now it gets complicated:
953 : // - all character attributes sre keep the area
954 : // - all paragraph attributes to get the area
955 : // up to the previous paragraph
956 : SvxRTFItemStackType* pNew = new SvxRTFItemStackType(
957 0 : *pOld, *pInsPos, sal_True );
958 0 : pNew->aAttrSet.SetParent( pOld->aAttrSet.GetParent() );
959 :
960 : // Delete all paragraph attributes from pNew
961 0 : for( sal_uInt16 n = 0; n < aPardMap.size() &&
962 0 : pNew->aAttrSet.Count(); ++n )
963 0 : if( aPardMap[n] )
964 0 : pNew->aAttrSet.ClearItem( aPardMap[n] );
965 0 : pNew->SetRTFDefaults( GetRTFDefaults() );
966 :
967 : // Were there any?
968 0 : if( pNew->aAttrSet.Count() == pOld->aAttrSet.Count() )
969 0 : delete pNew;
970 : else
971 : {
972 0 : pNew->nStyleNo = 0;
973 :
974 : // Now span the real area of pNew from old
975 0 : SetEndPrevPara( pOld->pEndNd, pOld->nEndCnt );
976 0 : pNew->nSttCnt = 0;
977 :
978 0 : if( IsChkStyleAttr() )
979 : {
980 0 : _ClearStyleAttr( *pOld );
981 0 : _ClearStyleAttr( *pNew ); //#i10381#, methinks.
982 : }
983 :
984 0 : if( pAkt )
985 : {
986 0 : pAkt->Add( pOld );
987 0 : pAkt->Add( pNew );
988 : }
989 : else
990 : {
991 : // Last off the stack, thus cache it until the next text was
992 : // read. (Span no attributes!)
993 :
994 0 : aAttrSetList.push_back( pOld );
995 0 : aAttrSetList.push_back( pNew );
996 : }
997 0 : pOld = 0; // Do not delete pOld
998 0 : break;
999 : }
1000 : }
1001 : }
1002 :
1003 0 : pOld->pEndNd = pInsPos->MakeNodeIdx();
1004 0 : pOld->nEndCnt = pInsPos->GetCntIdx();
1005 :
1006 : /*
1007 : #i21422#
1008 : If the parent (pAkt) sets something e.g. , and the child (pOld)
1009 : unsets it and the style both are based on has it unset then
1010 : clearing the pOld by looking at the style is clearly a disaster
1011 : as the text ends up with pAkts bold and not pOlds no bold, this
1012 : should be rethought out. For the moment its safest to just do
1013 : the clean if we have no parent, all we suffer is too many
1014 : redundant properties.
1015 : */
1016 0 : if (IsChkStyleAttr() && !pAkt)
1017 0 : _ClearStyleAttr( *pOld );
1018 :
1019 0 : if( pAkt )
1020 : {
1021 0 : pAkt->Add( pOld );
1022 : // split up and create new entry, because it make no sense
1023 : // to create a "so long" depend list. Bug 95010
1024 0 : if( bCrsrBack && 50 < pAkt->pChildList->size() )
1025 : {
1026 : // at the beginning of a paragraph? Move back one position
1027 0 : MovePos( sal_True );
1028 0 : bCrsrBack = sal_False;
1029 :
1030 : // Open a new Group.
1031 : SvxRTFItemStackType* pNew = new SvxRTFItemStackType(
1032 0 : *pAkt, *pInsPos, sal_True );
1033 0 : pNew->SetRTFDefaults( GetRTFDefaults() );
1034 :
1035 : // Set all until here valid Attributes
1036 0 : AttrGroupEnd();
1037 0 : pAkt = aAttrStack.empty() ? 0 : aAttrStack.back(); // can be changed after AttrGroupEnd!
1038 0 : pNew->aAttrSet.SetParent( pAkt ? &pAkt->aAttrSet : 0 );
1039 0 : aAttrStack.push_back( pNew );
1040 0 : pAkt = pNew;
1041 : }
1042 : }
1043 : else
1044 : // Last off the stack, thus cache it until the next text was
1045 : // read. (Span no attributes!)
1046 0 : aAttrSetList.push_back( pOld );
1047 :
1048 0 : pOld = 0;
1049 : }
1050 :
1051 0 : if( bCrsrBack )
1052 : // at the beginning of a paragraph? Move back one position
1053 0 : MovePos( sal_True );
1054 :
1055 : } while( sal_False );
1056 :
1057 0 : if( pOld )
1058 0 : delete pOld;
1059 :
1060 0 : bNewGroup = sal_False;
1061 : }
1062 0 : }
1063 :
1064 0 : void SvxRTFParser::SetAllAttrOfStk() // end all Attr. and set it into doc
1065 : {
1066 : // repeat until all attributes will be taken from stack
1067 0 : while( !aAttrStack.empty() )
1068 0 : AttrGroupEnd();
1069 :
1070 0 : for( sal_uInt16 n = aAttrSetList.size(); n; )
1071 : {
1072 0 : SvxRTFItemStackType* pStkSet = &aAttrSetList[--n];
1073 0 : SetAttrSet( *pStkSet );
1074 0 : aAttrSetList.pop_back();
1075 : }
1076 0 : }
1077 :
1078 : // sets all the attributes that are different from the current
1079 0 : void SvxRTFParser::SetAttrSet( SvxRTFItemStackType &rSet )
1080 : {
1081 : // Was DefTab never read? then set to default
1082 0 : if( !bIsSetDfltTab )
1083 0 : SetDefault( RTF_DEFTAB, 720 );
1084 :
1085 0 : if( rSet.pChildList )
1086 0 : rSet.Compress( *this );
1087 0 : if( rSet.aAttrSet.Count() || rSet.nStyleNo )
1088 0 : SetAttrInDoc( rSet );
1089 :
1090 : // then process all the children
1091 0 : if( rSet.pChildList )
1092 0 : for( sal_uInt16 n = 0; n < rSet.pChildList->size(); ++n )
1093 0 : SetAttrSet( (*rSet.pChildList)[ n ] );
1094 0 : }
1095 :
1096 : // Has no Text been inserted yet? (SttPos from the top Stack entry!)
1097 0 : int SvxRTFParser::IsAttrSttPos()
1098 : {
1099 0 : SvxRTFItemStackType* pAkt = aAttrStack.empty() ? 0 : aAttrStack.back();
1100 0 : return !pAkt || (pAkt->pSttNd->GetIdx() == pInsPos->GetNodeIdx() &&
1101 0 : pAkt->nSttCnt == pInsPos->GetCntIdx());
1102 : }
1103 :
1104 :
1105 0 : void SvxRTFParser::SetAttrInDoc( SvxRTFItemStackType & )
1106 : {
1107 0 : }
1108 :
1109 0 : void SvxRTFParser::BuildWhichTbl()
1110 : {
1111 0 : aWhichMap.clear();
1112 0 : aWhichMap.push_back( 0 );
1113 :
1114 : // Building a Which-Map 'rWhichMap' from an Array of
1115 : // 'pWhichIds' frm Which-Ids. It has the long 'nWhichIds'.
1116 : // The Which-Map is not going to be deleted.
1117 0 : SvParser::BuildWhichTbl( aWhichMap, (sal_uInt16*)&aPardMap[0], aPardMap.size() );
1118 0 : SvParser::BuildWhichTbl( aWhichMap, (sal_uInt16*)&aPlainMap[0], aPlainMap.size() );
1119 0 : }
1120 :
1121 0 : const SfxItemSet& SvxRTFParser::GetRTFDefaults()
1122 : {
1123 0 : if( !pRTFDefaults )
1124 : {
1125 0 : pRTFDefaults = new SfxItemSet( *pAttrPool, &aWhichMap[0] );
1126 : sal_uInt16 nId;
1127 0 : if( 0 != ( nId = ((RTFPardAttrMapIds*)&aPardMap[0])->nScriptSpace ))
1128 : {
1129 0 : SvxScriptSpaceItem aItem( sal_False, nId );
1130 0 : if( bNewDoc )
1131 0 : pAttrPool->SetPoolDefaultItem( aItem );
1132 : else
1133 0 : pRTFDefaults->Put( aItem );
1134 : }
1135 : }
1136 0 : return *pRTFDefaults;
1137 : }
1138 :
1139 :
1140 0 : SvxRTFStyleType::SvxRTFStyleType( SfxItemPool& rPool, const sal_uInt16* pWhichRange )
1141 0 : : aAttrSet( rPool, pWhichRange )
1142 : {
1143 0 : nOutlineNo = sal_uInt8(-1); // not set
1144 0 : nBasedOn = 0;
1145 0 : bBasedOnIsSet = sal_False; //$flr #117411#
1146 0 : nNext = 0;
1147 0 : bIsCharFmt = sal_False;
1148 0 : }
1149 :
1150 :
1151 0 : SvxRTFItemStackType::SvxRTFItemStackType(
1152 : SfxItemPool& rPool, const sal_uInt16* pWhichRange,
1153 : const SvxPosition& rPos )
1154 : : aAttrSet( rPool, pWhichRange ),
1155 : pChildList( 0 ),
1156 0 : nStyleNo( 0 )
1157 : {
1158 0 : pSttNd = rPos.MakeNodeIdx();
1159 0 : nSttCnt = rPos.GetCntIdx();
1160 0 : pEndNd = pSttNd;
1161 0 : nEndCnt = nSttCnt;
1162 0 : }
1163 :
1164 0 : SvxRTFItemStackType::SvxRTFItemStackType(
1165 : const SvxRTFItemStackType& rCpy,
1166 : const SvxPosition& rPos,
1167 : int bCopyAttr )
1168 0 : : aAttrSet( *rCpy.aAttrSet.GetPool(), rCpy.aAttrSet.GetRanges() ),
1169 : pChildList( 0 ),
1170 0 : nStyleNo( rCpy.nStyleNo )
1171 : {
1172 0 : pSttNd = rPos.MakeNodeIdx();
1173 0 : nSttCnt = rPos.GetCntIdx();
1174 0 : pEndNd = pSttNd;
1175 0 : nEndCnt = nSttCnt;
1176 :
1177 0 : aAttrSet.SetParent( &rCpy.aAttrSet );
1178 0 : if( bCopyAttr )
1179 0 : aAttrSet.Put( rCpy.aAttrSet );
1180 0 : }
1181 :
1182 0 : SvxRTFItemStackType::~SvxRTFItemStackType()
1183 : {
1184 0 : if( pChildList )
1185 0 : delete pChildList;
1186 0 : if( pSttNd != pEndNd )
1187 0 : delete pEndNd;
1188 0 : delete pSttNd;
1189 0 : }
1190 :
1191 0 : void SvxRTFItemStackType::Add( SvxRTFItemStackType* pIns )
1192 : {
1193 0 : if( !pChildList )
1194 0 : pChildList = new SvxRTFItemStackList();
1195 0 : pChildList->push_back( pIns );
1196 0 : }
1197 :
1198 0 : void SvxRTFItemStackType::SetStartPos( const SvxPosition& rPos )
1199 : {
1200 0 : if (pSttNd != pEndNd)
1201 0 : delete pEndNd;
1202 0 : delete pSttNd;
1203 0 : pSttNd = rPos.MakeNodeIdx();
1204 0 : pEndNd = pSttNd;
1205 0 : nSttCnt = rPos.GetCntIdx();
1206 0 : }
1207 :
1208 0 : void SvxRTFItemStackType::MoveFullNode(const SvxNodeIdx &rOldNode,
1209 : const SvxNodeIdx &rNewNode)
1210 : {
1211 0 : bool bSameEndAsStart = (pSttNd == pEndNd) ? true : false;
1212 :
1213 0 : if (GetSttNodeIdx() == rOldNode.GetIdx())
1214 : {
1215 0 : delete pSttNd;
1216 0 : pSttNd = rNewNode.Clone();
1217 0 : if (bSameEndAsStart)
1218 0 : pEndNd = pSttNd;
1219 : }
1220 :
1221 0 : if (!bSameEndAsStart && GetEndNodeIdx() == rOldNode.GetIdx())
1222 : {
1223 0 : delete pEndNd;
1224 0 : pEndNd = rNewNode.Clone();
1225 : }
1226 :
1227 : //And the same for all the children
1228 0 : sal_uInt16 nCount = pChildList ? pChildList->size() : 0;
1229 0 : for (sal_uInt16 i = 0; i < nCount; ++i)
1230 : {
1231 0 : SvxRTFItemStackType* pStk = &(*pChildList)[i];
1232 0 : pStk->MoveFullNode(rOldNode, rNewNode);
1233 : }
1234 0 : }
1235 :
1236 0 : bool SvxRTFParser::UncompressableStackEntry(const SvxRTFItemStackType &) const
1237 : {
1238 0 : return false;
1239 : }
1240 :
1241 0 : void SvxRTFItemStackType::Compress( const SvxRTFParser& rParser )
1242 : {
1243 0 : ENSURE_OR_RETURN_VOID(pChildList, "Compress: no ChildList" );
1244 0 : ENSURE_OR_RETURN_VOID(!pChildList->empty(), "Compress: ChildList empty");
1245 :
1246 : sal_uInt16 n;
1247 0 : SvxRTFItemStackType* pTmp = &(*pChildList)[0];
1248 :
1249 0 : if( !pTmp->aAttrSet.Count() ||
1250 0 : pSttNd->GetIdx() != pTmp->pSttNd->GetIdx() ||
1251 : nSttCnt != pTmp->nSttCnt )
1252 : return;
1253 :
1254 0 : SvxNodeIdx* pLastNd = pTmp->pEndNd;
1255 0 : xub_StrLen nLastCnt = pTmp->nEndCnt;
1256 :
1257 0 : SfxItemSet aMrgSet( pTmp->aAttrSet );
1258 0 : for( n = 1; n < pChildList->size(); ++n )
1259 : {
1260 0 : pTmp = &(*pChildList)[n];
1261 0 : if( pTmp->pChildList )
1262 0 : pTmp->Compress( rParser );
1263 :
1264 0 : if( !pTmp->nSttCnt
1265 0 : ? (pLastNd->GetIdx()+1 != pTmp->pSttNd->GetIdx() ||
1266 0 : !rParser.IsEndPara( pLastNd, nLastCnt ) )
1267 : : ( pTmp->nSttCnt != nLastCnt ||
1268 0 : pLastNd->GetIdx() != pTmp->pSttNd->GetIdx() ))
1269 : {
1270 0 : while( ++n < pChildList->size() )
1271 0 : if( (pTmp = &(*pChildList)[n])->pChildList )
1272 0 : pTmp->Compress( rParser );
1273 : return;
1274 : }
1275 :
1276 0 : if (rParser.UncompressableStackEntry(*pTmp))
1277 : return;
1278 :
1279 0 : if( n )
1280 : {
1281 : // Search for all which are set over the whole area
1282 0 : SfxItemIter aIter( aMrgSet );
1283 : const SfxPoolItem* pItem;
1284 0 : do {
1285 0 : sal_uInt16 nWhich = aIter.GetCurItem()->Which();
1286 0 : if( SFX_ITEM_SET != pTmp->aAttrSet.GetItemState( nWhich,
1287 0 : sal_False, &pItem ) || *pItem != *aIter.GetCurItem() )
1288 0 : aMrgSet.ClearItem( nWhich );
1289 :
1290 0 : if( aIter.IsAtEnd() )
1291 0 : break;
1292 0 : aIter.NextItem();
1293 : } while( sal_True );
1294 :
1295 0 : if( !aMrgSet.Count() )
1296 0 : return;
1297 : }
1298 :
1299 0 : pLastNd = pTmp->pEndNd;
1300 0 : nLastCnt = pTmp->nEndCnt;
1301 : }
1302 :
1303 0 : if( pEndNd->GetIdx() != pLastNd->GetIdx() || nEndCnt != nLastCnt )
1304 : return;
1305 :
1306 : // It can be merged
1307 0 : aAttrSet.Put( aMrgSet );
1308 :
1309 0 : for( n = 0; n < pChildList->size(); ++n )
1310 : {
1311 0 : pTmp = &(*pChildList)[n];
1312 0 : pTmp->aAttrSet.Differentiate( aMrgSet );
1313 :
1314 0 : if( !pTmp->pChildList && !pTmp->aAttrSet.Count() && !pTmp->nStyleNo )
1315 : {
1316 0 : pChildList->erase( pChildList->begin() + n );
1317 0 : --n;
1318 0 : continue;
1319 : }
1320 : }
1321 0 : if( pChildList->empty() )
1322 : {
1323 0 : delete pChildList;
1324 0 : pChildList = 0;
1325 0 : }
1326 : }
1327 0 : void SvxRTFItemStackType::SetRTFDefaults( const SfxItemSet& rDefaults )
1328 : {
1329 0 : if( rDefaults.Count() )
1330 : {
1331 0 : SfxItemIter aIter( rDefaults );
1332 0 : do {
1333 0 : sal_uInt16 nWhich = aIter.GetCurItem()->Which();
1334 0 : if( SFX_ITEM_SET != aAttrSet.GetItemState( nWhich, sal_False ))
1335 0 : aAttrSet.Put( *aIter.GetCurItem() );
1336 :
1337 0 : if( aIter.IsAtEnd() )
1338 0 : break;
1339 0 : aIter.NextItem();
1340 0 : } while( sal_True );
1341 : }
1342 0 : }
1343 :
1344 :
1345 0 : RTFPlainAttrMapIds::RTFPlainAttrMapIds( const SfxItemPool& rPool )
1346 : {
1347 0 : nCaseMap = rPool.GetTrueWhich( SID_ATTR_CHAR_CASEMAP, sal_False );
1348 0 : nBgColor = rPool.GetTrueWhich( SID_ATTR_BRUSH_CHAR, sal_False );
1349 0 : nColor = rPool.GetTrueWhich( SID_ATTR_CHAR_COLOR, sal_False );
1350 0 : nContour = rPool.GetTrueWhich( SID_ATTR_CHAR_CONTOUR, sal_False );
1351 0 : nCrossedOut = rPool.GetTrueWhich( SID_ATTR_CHAR_STRIKEOUT, sal_False );
1352 0 : nEscapement = rPool.GetTrueWhich( SID_ATTR_CHAR_ESCAPEMENT, sal_False );
1353 0 : nFont = rPool.GetTrueWhich( SID_ATTR_CHAR_FONT, sal_False );
1354 0 : nFontHeight = rPool.GetTrueWhich( SID_ATTR_CHAR_FONTHEIGHT, sal_False );
1355 0 : nKering = rPool.GetTrueWhich( SID_ATTR_CHAR_KERNING, sal_False );
1356 0 : nLanguage = rPool.GetTrueWhich( SID_ATTR_CHAR_LANGUAGE, sal_False );
1357 0 : nPosture = rPool.GetTrueWhich( SID_ATTR_CHAR_POSTURE, sal_False );
1358 0 : nShadowed = rPool.GetTrueWhich( SID_ATTR_CHAR_SHADOWED, sal_False );
1359 0 : nUnderline = rPool.GetTrueWhich( SID_ATTR_CHAR_UNDERLINE, sal_False );
1360 0 : nOverline = rPool.GetTrueWhich( SID_ATTR_CHAR_OVERLINE, sal_False );
1361 0 : nWeight = rPool.GetTrueWhich( SID_ATTR_CHAR_WEIGHT, sal_False );
1362 0 : nWordlineMode = rPool.GetTrueWhich( SID_ATTR_CHAR_WORDLINEMODE, sal_False );
1363 0 : nAutoKerning = rPool.GetTrueWhich( SID_ATTR_CHAR_AUTOKERN, sal_False );
1364 :
1365 0 : nCJKFont = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_FONT, sal_False );
1366 0 : nCJKFontHeight = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_FONTHEIGHT, sal_False );
1367 0 : nCJKLanguage = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_LANGUAGE, sal_False );
1368 0 : nCJKPosture = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_POSTURE, sal_False );
1369 0 : nCJKWeight = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_WEIGHT, sal_False );
1370 0 : nCTLFont = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_FONT, sal_False );
1371 0 : nCTLFontHeight = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_FONTHEIGHT, sal_False );
1372 0 : nCTLLanguage = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_LANGUAGE, sal_False );
1373 0 : nCTLPosture = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_POSTURE, sal_False );
1374 0 : nCTLWeight = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_WEIGHT, sal_False );
1375 0 : nEmphasis = rPool.GetTrueWhich( SID_ATTR_CHAR_EMPHASISMARK, sal_False );
1376 0 : nTwoLines = rPool.GetTrueWhich( SID_ATTR_CHAR_TWO_LINES, sal_False );
1377 0 : nRuby = 0; //rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_RUBY, sal_False );
1378 0 : nCharScaleX = rPool.GetTrueWhich( SID_ATTR_CHAR_SCALEWIDTH, sal_False );
1379 0 : nHorzVert = rPool.GetTrueWhich( SID_ATTR_CHAR_ROTATED, sal_False );
1380 0 : nRelief = rPool.GetTrueWhich( SID_ATTR_CHAR_RELIEF, sal_False );
1381 0 : nHidden = rPool.GetTrueWhich( SID_ATTR_CHAR_HIDDEN, sal_False );
1382 0 : }
1383 :
1384 0 : RTFPardAttrMapIds ::RTFPardAttrMapIds ( const SfxItemPool& rPool )
1385 : {
1386 0 : nLinespacing = rPool.GetTrueWhich( SID_ATTR_PARA_LINESPACE, sal_False );
1387 0 : nAdjust = rPool.GetTrueWhich( SID_ATTR_PARA_ADJUST, sal_False );
1388 0 : nTabStop = rPool.GetTrueWhich( SID_ATTR_TABSTOP, sal_False );
1389 0 : nHyphenzone = rPool.GetTrueWhich( SID_ATTR_PARA_HYPHENZONE, sal_False );
1390 0 : nLRSpace = rPool.GetTrueWhich( SID_ATTR_LRSPACE, sal_False );
1391 0 : nULSpace = rPool.GetTrueWhich( SID_ATTR_ULSPACE, sal_False );
1392 0 : nBrush = rPool.GetTrueWhich( SID_ATTR_BRUSH, sal_False );
1393 0 : nBox = rPool.GetTrueWhich( SID_ATTR_BORDER_OUTER, sal_False );
1394 0 : nShadow = rPool.GetTrueWhich( SID_ATTR_BORDER_SHADOW, sal_False );
1395 0 : nOutlineLvl = rPool.GetTrueWhich( SID_ATTR_PARA_OUTLLEVEL, sal_False );
1396 0 : nSplit = rPool.GetTrueWhich( SID_ATTR_PARA_SPLIT, sal_False );
1397 0 : nKeep = rPool.GetTrueWhich( SID_ATTR_PARA_KEEP, sal_False );
1398 0 : nFontAlign = rPool.GetTrueWhich( SID_PARA_VERTALIGN, sal_False );
1399 0 : nScriptSpace = rPool.GetTrueWhich( SID_ATTR_PARA_SCRIPTSPACE, sal_False );
1400 0 : nHangPunct = rPool.GetTrueWhich( SID_ATTR_PARA_HANGPUNCTUATION, sal_False );
1401 0 : nForbRule = rPool.GetTrueWhich( SID_ATTR_PARA_FORBIDDEN_RULES, sal_False );
1402 0 : nDirection = rPool.GetTrueWhich( SID_ATTR_FRAMEDIRECTION, sal_False );
1403 0 : }
1404 :
1405 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|