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