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