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