Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <ctype.h>
31 : : #include <hintids.hxx>
32 : :
33 : : #include <sal/macros.h>
34 : : #include <com/sun/star/i18n/ScriptType.hpp>
35 : : #include <comphelper/string.hxx>
36 : : #include <vcl/graph.hxx>
37 : : #include <svl/urihelper.hxx>
38 : : #include <svtools/rtftoken.h>
39 : : #include <svl/zforlist.hxx>
40 : : #include <editeng/fontitem.hxx>
41 : : #include <editeng/fhgtitem.hxx>
42 : : #include <editeng/langitem.hxx>
43 : : #include <editeng/brkitem.hxx>
44 : : #include <fmtfld.hxx>
45 : : #include <fmtinfmt.hxx>
46 : : #include <swtypes.hxx>
47 : : #include <doc.hxx>
48 : : #include <pam.hxx>
49 : : #include <ndtxt.hxx>
50 : : #include <shellio.hxx>
51 : : #include <fldbas.hxx>
52 : : #include <swparrtf.hxx>
53 : : #include <txatbase.hxx>
54 : : #include <dbfld.hxx>
55 : : #include <usrfld.hxx>
56 : : #include <docufld.hxx>
57 : : #include <flddat.hxx>
58 : : #include <charfmt.hxx>
59 : : #include <fmtruby.hxx>
60 : : #include <breakit.hxx>
61 : : #include <reffld.hxx>
62 : : #include <SwStyleNameMapper.hxx>
63 : : #include <editeng/charhiddenitem.hxx>
64 : :
65 : :
66 : : // bestimme, ob es sich um ein IMPORT/TOC - Feld handelt.
67 : : // return: 0 - weder noch,
68 : : // 1 - TOC
69 : : // 2 - IMPORT
70 : : // 3 - INDEX
71 : : enum RTF_FLD_TYPES {
72 : : RTFFLD_UNKNOWN = 0,
73 : : RTFFLD_TOC,
74 : : RTFFLD_IMPORT,
75 : : RTFFLD_INDEX,
76 : : RTFFLD_SYMBOL,
77 : : RTFFLD_PAGE,
78 : : RTFFLD_NUMPAGES,
79 : : RTFFLD_DATE,
80 : : RTFFLD_TIME,
81 : : RTFFLD_DATA,
82 : : RTFFLD_MERGEFLD,
83 : : RTFFLD_HYPERLINK,
84 : : RTFFLD_REF,
85 : : RTFFLD_PAGEREF,
86 : : RTFFLD_EQ,
87 : : RTFFLD_INCLUDETEXT
88 : : };
89 : :
90 : 0 : static RTF_FLD_TYPES _WhichFld( String& rName, String& rNext )
91 : : {
92 : : // Strings sind PascalStrings; Laenge steht an 1. Stellen, dadurch wird
93 : : // sich der Aufruf von strlen erspart!!!
94 : 0 : sal_Char const sTOC[]= "\x03""toc";
95 : 0 : sal_Char const sIMPORT[]= "\x06""import";
96 : 0 : sal_Char const sINDEX[]= "\x05""index";
97 : 0 : sal_Char const sSYMBOL[]= "\x06""symbol";
98 : 0 : sal_Char const sPAGE[]= "\x04""page";
99 : 0 : sal_Char const sNUMPAGES[]= "\x08""numpages";
100 : 0 : sal_Char const sDATE[]= "\x04""date";
101 : 0 : sal_Char const sTIME[]= "\x04""time";
102 : 0 : sal_Char const sDATA[]= "\x04""data";
103 : 0 : sal_Char const sMERGEFLD[]= "\x0A""mergefield";
104 : 0 : sal_Char const sIMPORT2[]= "\x0E""includepicture";
105 : 0 : sal_Char const sHYPERLINK[]= "\x09""hyperlink";
106 : 0 : sal_Char const sREF[]= "\x03""ref";
107 : 0 : sal_Char const sPAGEREF[]= "\x07""pageref";
108 : 0 : sal_Char const sEQ[]= "\x02""eq";
109 : 0 : sal_Char const sINCLUDETEXT[]="\x0B""includetext";
110 : :
111 : : struct _Dummy_RTF_FLD_TYPES
112 : : {
113 : : RTF_FLD_TYPES eFldType;
114 : : const sal_Char* pFldNm;
115 : : };
116 : : const _Dummy_RTF_FLD_TYPES aFldNmArr[RTFFLD_INCLUDETEXT + 1] = {
117 : : {RTFFLD_TOC, sTOC},
118 : : {RTFFLD_IMPORT, sIMPORT},
119 : : {RTFFLD_INDEX, sINDEX},
120 : : {RTFFLD_SYMBOL, sSYMBOL},
121 : : {RTFFLD_PAGE, sPAGE},
122 : : {RTFFLD_NUMPAGES, sNUMPAGES},
123 : : {RTFFLD_DATE, sDATE},
124 : : {RTFFLD_TIME, sTIME},
125 : : {RTFFLD_DATA, sDATA},
126 : : {RTFFLD_MERGEFLD, sMERGEFLD},
127 : : {RTFFLD_IMPORT, sIMPORT2},
128 : : {RTFFLD_HYPERLINK, sHYPERLINK},
129 : : {RTFFLD_REF, sREF},
130 : : {RTFFLD_PAGEREF, sPAGEREF},
131 : : {RTFFLD_EQ, sEQ},
132 : : {RTFFLD_INCLUDETEXT, sINCLUDETEXT}
133 : 0 : };
134 : :
135 : :
136 [ # # ]: 0 : if( !rName.Len() )
137 : 0 : return RTFFLD_UNKNOWN;
138 : :
139 [ # # ][ # # ]: 0 : String sNm(comphelper::string::stripStart(rName, ' ').getToken(0, ' '));
[ # # ]
140 : : OSL_ENSURE( sNm.Len(), "Feldname hat keine Laenge!" );
141 [ # # ]: 0 : if( !sNm.Len() )
142 : 0 : return RTFFLD_UNKNOWN;
143 : :
144 [ # # ]: 0 : xub_StrLen nTokenStt = rName.Search( sNm );
145 [ # # ]: 0 : sNm.ToLowerAscii();
146 : :
147 [ # # ]: 0 : for (size_t n = 0; n < sizeof(aFldNmArr) / sizeof(aFldNmArr[0]); ++n)
148 : : {
149 : 0 : const sal_Char* pCmp = aFldNmArr[n].pFldNm;
150 : 0 : int nLen = *pCmp++;
151 [ # # ]: 0 : xub_StrLen nFndPos = sNm.SearchAscii( pCmp );
152 [ # # ][ # # : 0 : if( STRING_NOTFOUND != nFndPos &&
# # # # #
# ][ # # ]
153 : 0 : ( !nFndPos || !isalpha(sNm.GetChar( static_cast< xub_StrLen >(nFndPos-1) )) ) &&
154 : 0 : ( nFndPos+nLen == sNm.Len() || !isalpha(sNm.GetChar( static_cast< xub_StrLen >(nFndPos+nLen) ) ) ) )
155 : : {
156 [ # # ][ # # ]: 0 : rName = rName.Copy( nFndPos, static_cast< xub_StrLen >(nLen) );
[ # # ]
157 : 0 : nFndPos += nTokenStt + static_cast< xub_StrLen >(nLen);
158 [ # # ][ # # ]: 0 : while ((nFndPos < rNext.Len()) && (rNext.GetChar(nFndPos) == ' '))
[ # # ]
159 : : {
160 : 0 : ++nFndPos;
161 : : }
162 [ # # ]: 0 : rNext.Erase( 0, nFndPos );
163 [ # # ][ # # ]: 0 : rNext = comphelper::string::stripEnd(rNext, ' ');
[ # # ]
164 : 0 : return aFldNmArr[n].eFldType;
165 : : }
166 : : }
167 [ # # ]: 0 : return RTFFLD_UNKNOWN; // nichts gefunden.
168 : : }
169 : :
170 : 0 : static sal_uInt16 CheckNumberFmtStr( const String& rNStr )
171 : : {
172 : : const static sal_Char* aNumberTypeTab[] =
173 : : {
174 : : "\x0A""ALPHABETIC", /* CHARS_UPPER_LETTER*/
175 : : "\x0A""alphabetic", /* CHARS_LOWER_LETTER*/
176 : : "\x05""ROMAN", /* ROMAN_UPPER */
177 : : "\x05""roman", /* ROMAN_LOWER */
178 : : "\x06""ARABIC", /* ARABIC */
179 : : "\x04""NONE", /* NUMBER_NONE */
180 : : "\x04""CHAR", /* CHAR_SPECIAL */
181 : : "\x04""PAGE" /* PAGEDESC */
182 : : };
183 : :
184 : : OSL_ENSURE(sizeof(aNumberTypeTab) / sizeof(sal_Char *)
185 : : >= SVX_NUM_PAGEDESC - SVX_NUM_CHARS_UPPER_LETTER, "impossible");
186 : :
187 [ # # ]: 0 : for (sal_uInt16 n = SVX_NUM_CHARS_UPPER_LETTER; n <= SVX_NUM_PAGEDESC; ++n)
188 : : {
189 : 0 : const sal_Char* pCmp = aNumberTypeTab[n - SVX_NUM_CHARS_UPPER_LETTER];
190 : 0 : int nLen = *pCmp++;
191 [ # # ]: 0 : if( rNStr.EqualsAscii( pCmp, 0, static_cast< xub_StrLen >(nLen) ))
192 [ # # ]: 0 : return static_cast< sal_uInt16 >(2 <= n ? n : (n + SVX_NUM_CHARS_UPPER_LETTER_N));
193 : : }
194 : 0 : return SVX_NUM_PAGEDESC; // default-Wert
195 : : }
196 : :
197 : 0 : class RtfFieldSwitch
198 : : {
199 : : String sParam;
200 : : xub_StrLen nCurPos;
201 : : public:
202 : : RtfFieldSwitch( const String& rParam );
203 : : sal_Unicode GetSwitch( String& rParam );
204 : :
205 : 0 : sal_Bool IsAtEnd() const { return nCurPos >= sParam.Len(); }
206 : : xub_StrLen GetCurPos() const { return nCurPos; }
207 : 0 : void Erase( xub_StrLen nEndPos ) { sParam.Erase( 0, nEndPos ); }
208 : 0 : void Insert( const String& rIns ) { sParam.Insert( rIns, 0 ); }
209 : 0 : const String& GetStr() const { return sParam; }
210 : : };
211 : :
212 : 0 : RtfFieldSwitch::RtfFieldSwitch( const String& rParam )
213 : 0 : : nCurPos( 0 )
214 : : {
215 [ # # ][ # # ]: 0 : sParam = comphelper::string::strip(rParam, ' ');
[ # # ]
216 : 0 : }
217 : :
218 : 0 : sal_Unicode RtfFieldSwitch::GetSwitch( String& rParam )
219 : : {
220 : : // beginnt ein Schalter?
221 : 0 : sal_Unicode c, cKey = 0;
222 [ # # ]: 0 : if( '\\' == (c = sParam.GetChar( nCurPos )) )
223 : : {
224 [ # # ]: 0 : if( '\\' == ( c = sParam.GetChar( ++nCurPos )) )
225 : 0 : c = sParam.GetChar( ++nCurPos );
226 : :
227 : 0 : cKey = c;
228 : :
229 [ # # ][ # # ]: 0 : while( ++nCurPos < sParam.Len() &&
[ # # ]
230 : 0 : ' ' == ( c = sParam.GetChar( nCurPos )) )
231 : : ;
232 : : }
233 : :
234 : : // dann alles in Hochkommatas oder bis zum naechsten // als
235 : : // Param returnen
236 : : sal_uInt16 nOffset;
237 [ # # ][ # # ]: 0 : if( '"' != c && '\'' != c )
238 : 0 : c = '\\', nOffset = 0;
239 : : else
240 : 0 : nOffset = 1;
241 : :
242 : 0 : sParam.Erase( 0, nCurPos + nOffset );
243 [ # # ]: 0 : rParam = sParam.GetToken( 0, c );
244 [ # # ][ # # ]: 0 : sParam = comphelper::string::stripStart(sParam.Erase(0, rParam.Len() + nOffset), ' ');
245 [ # # ]: 0 : if( '\\' == c )
246 [ # # ][ # # ]: 0 : rParam = comphelper::string::stripEnd(rParam, ' ');
247 : 0 : nCurPos = 0;
248 : :
249 : 0 : return cKey;
250 : : }
251 : :
252 [ # # ][ # # ]: 0 : struct RTF_EquationData
[ # # ]
253 : : {
254 : : String sFontName, sUp, sDown, sText;
255 : : sal_Int32 nJustificationCode, nFontSize, nUp, nDown, nStyleNo;
256 : :
257 : 0 : inline RTF_EquationData()
258 : : : nJustificationCode(0), nFontSize(0), nUp(0), nDown(0),
259 [ # # ][ # # ]: 0 : nStyleNo( -1 )
[ # # ]
260 : 0 : {}
261 : : };
262 : :
263 : 0 : xub_StrLen lcl_FindEndBracket( const String& rStr )
264 : : {
265 : 0 : xub_StrLen nEnd = rStr.Len(), nRet = STRING_NOTFOUND, nPos = 0;
266 : 0 : int nOpenCnt = 1;
267 : : sal_Unicode cCh;
268 [ # # ]: 0 : for( ; nPos < nEnd; ++nPos )
269 [ # # ][ # # ]: 0 : if( ')' == (cCh = rStr.GetChar( nPos )) && !--nOpenCnt )
[ # # ]
270 : : {
271 : 0 : nRet = nPos;
272 : 0 : break;
273 : : }
274 [ # # ]: 0 : else if( '(' == cCh )
275 : 0 : ++nOpenCnt;
276 : :
277 : 0 : return nRet;
278 : : }
279 : :
280 : 0 : void lcl_ScanEquationField( const String& rStr, RTF_EquationData& rData,
281 : : sal_Unicode nSttKey )
282 : : {
283 : 0 : int nSubSupFlag(0);
284 [ # # ]: 0 : RtfFieldSwitch aRFS( rStr );
285 [ # # ]: 0 : while( !aRFS.IsAtEnd() )
286 : : {
287 [ # # ]: 0 : String sParam;
288 [ # # ]: 0 : sal_Unicode cKey = aRFS.GetSwitch( sParam );
289 [ # # ]: 0 : if( 1 == nSubSupFlag )
290 : 0 : ++nSubSupFlag;
291 [ # # ]: 0 : else if( 1 < nSubSupFlag )
292 : 0 : nSubSupFlag = 0;
293 : :
294 : 0 : sal_Bool bCheckBracket = sal_False;
295 [ # # # # : 0 : switch( cKey )
# # ]
296 : : {
297 : : case 0:
298 [ # # # ]: 0 : switch( nSttKey )
299 : : {
300 [ # # ]: 0 : case 'u': rData.sUp += sParam; break;
301 [ # # ]: 0 : case 'd': rData.sDown += sParam; break;
302 [ # # ]: 0 : default: rData.sText += sParam; break;
303 : : }
304 : 0 : break;
305 : :
306 : : case '*':
307 [ # # ]: 0 : if( sParam.Len() )
308 : : {
309 [ # # ][ # # ]: 0 : if( sParam.EqualsIgnoreCaseAscii( "jc", 0, 2 ) )
310 [ # # ][ # # ]: 0 : rData.nJustificationCode = sParam.Copy( 2 ).ToInt32();
[ # # ]
311 [ # # ][ # # ]: 0 : else if( sParam.EqualsIgnoreCaseAscii( "hps", 0, 3 ) )
312 [ # # ][ # # ]: 0 : rData.nFontSize= sParam.Copy( 3 ).ToInt32();
[ # # ]
313 [ # # ][ # # ]: 0 : else if( sParam.EqualsIgnoreCaseAscii( "Font:", 0, 5 ) )
314 [ # # ][ # # ]: 0 : rData.sFontName = sParam.Copy( 5 );
[ # # ]
315 [ # # ][ # # ]: 0 : else if( sParam.EqualsIgnoreCaseAscii( "cs", 0, 2 ) )
316 [ # # ][ # # ]: 0 : rData.nStyleNo = sParam.Copy( 2 ).ToInt32();
[ # # ]
317 : : }
318 : 0 : break;
319 : : case 's' :
320 : 0 : ++nSubSupFlag;
321 : 0 : break;
322 : :
323 : : case 'u':
324 [ # # ][ # # ]: 0 : if( sParam.Len() && 'p' == sParam.GetChar( 0 ) &&
[ # # ][ # # ]
325 : : 2 == nSubSupFlag )
326 : : {
327 [ # # ][ # # ]: 0 : rData.nUp = sParam.Copy( 1 ).ToInt32();
[ # # ]
328 : 0 : bCheckBracket = sal_True;
329 : : }
330 : 0 : break;
331 : :
332 : : case 'd':
333 [ # # ][ # # ]: 0 : if( sParam.Len() && 'o' == sParam.GetChar( 0 ) &&
[ # # ][ # # ]
334 : : 2 == nSubSupFlag )
335 : : {
336 [ # # ][ # # ]: 0 : rData.nDown = sParam.Copy( 1 ).ToInt32();
[ # # ]
337 : 0 : bCheckBracket = sal_True;
338 : : }
339 : 0 : break;
340 : :
341 : : default:
342 : 0 : bCheckBracket = sal_True;
343 : 0 : cKey = 0;
344 : 0 : break;
345 : : }
346 : :
347 [ # # ][ # # ]: 0 : if( bCheckBracket && sParam.Len() )
[ # # ]
348 : : {
349 [ # # ]: 0 : xub_StrLen nEnd, nStt = sParam.Search( '(' ),
350 : 0 : nLen = sParam.Len();
351 [ # # ]: 0 : if( STRING_NOTFOUND != nStt )
352 : : {
353 [ # # ][ # # ]: 0 : sParam.Erase( 0, nStt + 1 ) += aRFS.GetStr();
354 [ # # ]: 0 : if( STRING_NOTFOUND !=
355 : : (nEnd = ::lcl_FindEndBracket( sParam )) )
356 : : {
357 : : // end in the added string?
358 [ # # ]: 0 : if( (nLen - nStt - 1 ) < nEnd )
359 [ # # ]: 0 : aRFS.Erase( nEnd + 1 - (nLen - nStt - 1));
360 : : else
361 : : {
362 : : // not all handled here, so set new into the RFS
363 : : aRFS.Insert( sParam.Copy( nEnd + 1,
364 [ # # ][ # # ]: 0 : nLen - nStt - nEnd - 2 ));
[ # # ]
365 : : sal_Unicode cCh;
366 [ # # # # ]: 0 : if( aRFS.GetStr().Len() &&
[ # # ][ # # ]
367 : 0 : ( ',' == (cCh = aRFS.GetStr().GetChar(0)) ||
368 : : ';' == cCh ))
369 [ # # ]: 0 : aRFS.Erase( 1 );
370 : : }
371 : :
372 : : ::lcl_ScanEquationField( sParam.Copy( 0, nEnd ),
373 [ # # ][ # # ]: 0 : rData, cKey );
[ # # ]
374 : : }
375 : : }
376 : : }
377 [ # # ][ # # ]: 0 : }
378 : 0 : }
379 : :
380 : 0 : int SwRTFParser::MakeFieldInst( String& rFieldStr )
381 : : {
382 : : // sicher den Original-String fuer die FeldNamen (User/Datenbank)
383 [ # # ]: 0 : String aSaveStr( rFieldStr );
384 : : SwFieldType * pFldType;
385 [ # # ]: 0 : int nRet = _WhichFld(rFieldStr, aSaveStr);
386 : :
387 : : //Strip Mergeformat from fields
388 : 0 : xub_StrLen nPos=0;
389 [ # # ][ # # ]: 0 : while (STRING_NOTFOUND != ( nPos = aSaveStr.SearchAscii("\\*", nPos)))
390 : : {
391 : 0 : xub_StrLen nStartDel = nPos;
392 : 0 : nPos += 2;
393 [ # # ][ # # ]: 0 : while ((nPos < aSaveStr.Len()) && (aSaveStr.GetChar(nPos) == ' '))
[ # # ]
394 : : {
395 : 0 : ++nPos;
396 : : }
397 [ # # ][ # # ]: 0 : if (aSaveStr.EqualsIgnoreCaseAscii("MERGEFORMAT", nPos, 11))
398 : : {
399 : 0 : xub_StrLen nNoDel = (nPos + 11 ) - nStartDel;
400 [ # # ]: 0 : aSaveStr.Erase(nStartDel, nNoDel);
401 : 0 : nPos -= (nStartDel - nPos);
402 : : }
403 : : }
404 : :
405 : 0 : nPos = 0;
406 [ # # # # : 0 : switch (nRet)
# # # # #
# # # #
# ]
407 : : {
408 : : case RTFFLD_INCLUDETEXT:
409 : 0 : break;
410 : : case RTFFLD_IMPORT:
411 : : {
412 : :
413 [ # # ][ # # ]: 0 : aSaveStr = comphelper::string::strip(aSaveStr, ' ');
[ # # ]
414 [ # # ]: 0 : if( aSaveStr.Len() )
415 : : {
416 : 0 : sal_Unicode c = aSaveStr.GetChar( 0 );
417 [ # # ][ # # ]: 0 : if( '"' == c || '\'' == c )
418 : : {
419 [ # # ]: 0 : aSaveStr.Erase( 0, 1 );
420 [ # # ][ # # ]: 0 : aSaveStr = aSaveStr.GetToken( 0, c );
[ # # ]
421 : : }
422 : :
423 : : rFieldStr = URIHelper::SmartRel2Abs(
424 : 0 : INetURLObject(GetBaseURL()), aSaveStr,
425 [ # # ]: 0 : URIHelper::GetMaybeFileHdl() );
[ # # # # ]
[ # # ][ # # ]
[ # # ][ # # ]
426 : : }
427 : :
428 : : }
429 : 0 : break;
430 : :
431 : : case RTFFLD_NUMPAGES:
432 : : {
433 [ # # ]: 0 : SwDocStatField aFld( (SwDocStatFieldType*)pDoc->GetSysFldType( RES_DOCSTATFLD ),
434 [ # # ]: 0 : DS_PAGE, SVX_NUM_ARABIC );
435 [ # # ][ # # ]: 0 : if( STRING_NOTFOUND != ( nPos = aSaveStr.SearchAscii( "\\*" )) )
436 : : {
437 : 0 : nPos += 2;
438 [ # # # # ]: 0 : while ((nPos < aSaveStr.Len()) &&
[ # # ]
439 : 0 : (aSaveStr.GetChar(nPos) == ' '))
440 : 0 : { nPos++; }
441 [ # # ]: 0 : aSaveStr.Erase( 0, nPos );
442 : :
443 : : // steht jetzt geanu auf dem Format-Namen
444 [ # # ][ # # ]: 0 : aFld.ChangeFormat( CheckNumberFmtStr( aSaveStr ));
445 : : }
446 [ # # ][ # # ]: 0 : pDoc->InsertPoolItem( *pPam, SwFmtFld( aFld ), 0 );
[ # # ]
447 [ # # ][ # # ]: 0 : SkipGroup();
448 : : }
449 : 0 : break;
450 : :
451 : : case RTFFLD_PAGE:
452 : : {
453 [ # # ]: 0 : pFldType = pDoc->GetSysFldType( RES_PAGENUMBERFLD );
454 : : SwPageNumberField aPF( (SwPageNumberFieldType*)pFldType,
455 [ # # ]: 0 : PG_RANDOM, SVX_NUM_ARABIC);
456 [ # # ][ # # ]: 0 : if( STRING_NOTFOUND != ( nPos = aSaveStr.SearchAscii( "\\*" )) )
457 : : {
458 : 0 : nPos += 2;
459 [ # # # # ]: 0 : while ((nPos < aSaveStr.Len()) &&
[ # # ]
460 : 0 : (aSaveStr.GetChar(nPos) == ' '))
461 : 0 : { nPos++; }
462 [ # # ]: 0 : aSaveStr.Erase( 0, nPos );
463 : :
464 : : // steht jetzt geanu auf dem Format-Namen
465 [ # # ][ # # ]: 0 : aPF.ChangeFormat( CheckNumberFmtStr( aSaveStr ));
466 : : }
467 [ # # ][ # # ]: 0 : pDoc->InsertPoolItem( *pPam, SwFmtFld( aPF ), 0 );
[ # # ]
468 [ # # ][ # # ]: 0 : SkipGroup(); // ueberlese den Rest
469 : : }
470 : 0 : break;
471 : : case RTFFLD_DATE:
472 : : case RTFFLD_TIME:
473 : : {
474 [ # # ][ # # ]: 0 : if( STRING_NOTFOUND == ( nPos = aSaveStr.SearchAscii( "\\@" )) )
475 : : {
476 : : // es fehlt die Format - Angabe: defaulten auf Datum
477 [ # # ]: 0 : pFldType = pDoc->GetSysFldType( RES_DATETIMEFLD );
478 : : pDoc->InsertPoolItem( *pPam, SwFmtFld( SwDateTimeField(
479 [ # # ][ # # ]: 0 : static_cast<SwDateTimeFieldType*>(pFldType), DATEFLD)), 0);
[ # # ][ # # ]
[ # # ]
480 : : }
481 : : else
482 : : {
483 : : // versuche aus dem Formatstring zu erkennen, ob es ein
484 : : // Datum oder Zeit oder Datum & Zeit Field ist
485 : : // nur das Format interressiert
486 [ # # ][ # # ]: 0 : aSaveStr.Erase( 0, aSaveStr.Search( '\"' )+1 );
487 : : // alles hinter dem Format interressiert auch nicht mehr.
488 [ # # ][ # # ]: 0 : aSaveStr.Erase( aSaveStr.Search( '\"' ) );
489 [ # # ]: 0 : aSaveStr.SearchAndReplaceAscii( "AM", aEmptyStr );
490 [ # # ]: 0 : aSaveStr.SearchAndReplaceAscii( "PM", aEmptyStr );
491 : :
492 : : // Put the word date and time formatter stuff in a common area
493 : : // and get the rtf filter to use it
494 : 0 : SwField *pFld = 0;
495 : 0 : short nNumFmtType = NUMBERFORMAT_UNDEFINED;
496 : 0 : sal_uLong nFmtIdx = NUMBERFORMAT_UNDEFINED;
497 : :
498 : 0 : sal_uInt16 rLang(0);
499 [ # # ]: 0 : RES_CHRATR eLang = maPageDefaults.mbRTLdoc ? RES_CHRATR_CTL_LANGUAGE : RES_CHRATR_LANGUAGE;
500 [ # # ]: 0 : const SvxLanguageItem *pLang = (SvxLanguageItem*)&pDoc->GetAttrPool().GetDefaultItem( static_cast< sal_uInt16 >(eLang) );
501 [ # # ]: 0 : rLang = pLang ? pLang->GetValue() : LANGUAGE_ENGLISH_US;
502 : :
503 [ # # ]: 0 : SvNumberFormatter* pFormatter = pDoc->GetNumberFormatter();
504 : 0 : bool bHijri = false;
505 : :
506 [ # # ]: 0 : if( pFormatter )
507 : : {
508 [ # # ]: 0 : nFmtIdx = sw::ms::MSDateTimeFormatToSwFormat(aSaveStr, pFormatter, rLang, bHijri, rLang);
509 [ # # ]: 0 : if (nFmtIdx)
510 [ # # ]: 0 : nNumFmtType = pFormatter->GetType(nFmtIdx);
511 : : }
512 : :
513 [ # # ]: 0 : pFldType = pDoc->GetSysFldType( RES_DATETIMEFLD );
514 : :
515 [ # # ]: 0 : if(nNumFmtType & NUMBERFORMAT_DATE)
516 [ # # ][ # # ]: 0 : pFld = new SwDateTimeField( (SwDateTimeFieldType*)pFldType, DATEFLD, nFmtIdx );
517 [ # # ]: 0 : else if(nNumFmtType == NUMBERFORMAT_TIME)
518 [ # # ][ # # ]: 0 : pFld = new SwDateTimeField( (SwDateTimeFieldType*)pFldType, TIMEFLD, nFmtIdx );
519 : :
520 [ # # ]: 0 : if( pFld )
521 : : {
522 [ # # ][ # # ]: 0 : pDoc->InsertPoolItem( *pPam, SwFmtFld( *pFld ), 0);
[ # # ]
523 [ # # ][ # # ]: 0 : delete pFld;
524 : : }
525 : : }
526 [ # # ]: 0 : SkipGroup(); // ueberlese den Rest
527 : : }
528 : 0 : break;
529 : :
530 : : case RTFFLD_DATA:
531 : : {
532 : : // Datenbank-FileName: nur der Filename interressiert
533 : : // Zur Zeit werden nur SDF-Files verarbeitet, also suche nach
534 : : // der Extension
535 : :
536 : : // im SWG geben die DATA Felder den Namen der Datenbank
537 : : // an. Dieser kann als Field oder als DBInfo interpretiert
538 : : // werden:
539 : : // \\data -> Datenbank-Name als Field
540 : : // DATA -> Datenbank-Info
541 [ # # ][ # # ]: 0 : bool const bField = rFieldStr.Len() && rFieldStr.GetChar(0) != 'D';
542 : :
543 : : // nur der Name interressiert
544 [ # # ][ # # ]: 0 : if( STRING_NOTFOUND != (nPos = aSaveStr.Search( '.' )) )
545 [ # # ]: 0 : aSaveStr.Erase( nPos );
546 : 0 : SwDBData aData;
547 [ # # ]: 0 : aData.sDataSource = aSaveStr;
548 [ # # ]: 0 : if( bField )
549 : : {
550 [ # # ]: 0 : pFldType = pDoc->GetSysFldType( RES_DBNAMEFLD );
551 : : pDoc->InsertPoolItem( *pPam, SwFmtFld( SwDBNameField(
552 [ # # ][ # # ]: 0 : static_cast<SwDBNameFieldType*>(pFldType), SwDBData())), 0);
[ # # ][ # # ]
[ # # ]
553 : : }
554 : : else
555 [ # # ]: 0 : pDoc->ChgDBData( aData ); // MS: Keine DBInfo verwenden
556 [ # # ]: 0 : SkipGroup(); // ueberlese den Rest
557 : : }
558 : 0 : break;
559 : : case RTFFLD_MERGEFLD:
560 : : {
561 : : // ein Datenbank - Feld: nur der Name interressiert
562 : : // bis zum Ende vom String ist das der Feldname
563 [ # # ]: 0 : SwDBFieldType aTmp( pDoc, aSaveStr, SwDBData() ); //
564 [ # # ][ # # ]: 0 : SwDBField aDBFld( (SwDBFieldType*)pDoc->InsertFldType( aTmp ));
565 : :
566 [ # # ]: 0 : aDBFld.ChangeFormat( UF_STRING );
567 [ # # ][ # # ]: 0 : pDoc->InsertPoolItem(*pPam, SwFmtFld( aDBFld ), 0);
[ # # ]
568 [ # # ][ # # ]: 0 : SkipGroup(); // ueberlese den Rest
[ # # ]
569 : : }
570 : 0 : break;
571 : :
572 : : case RTFFLD_SYMBOL:
573 : : {
574 : : // loesche fuehrende Blanks
575 [ # # ]: 0 : if( IsNewGroup() )
576 [ # # ]: 0 : GetAttrSet();
577 : 0 : SetNewGroup( sal_True );
578 : :
579 [ # # ]: 0 : SfxItemSet& rSet = GetAttrSet();
580 : :
581 : 0 : sal_Bool bCharIns = sal_False;
582 [ # # ]: 0 : RtfFieldSwitch aRFS( aSaveStr );
583 [ # # ]: 0 : while( !aRFS.IsAtEnd() )
584 : : {
585 [ # # ]: 0 : String sParam;
586 [ # # ]: 0 : sal_Unicode cKey = aRFS.GetSwitch( sParam );
587 [ # # ]: 0 : if( sParam.Len() )
588 [ # # # # : 0 : switch( cKey )
# ]
589 : : {
590 : : case 0:
591 [ # # ]: 0 : if( !bCharIns )
592 : : {
593 [ # # ]: 0 : sal_Unicode cChar = (sal_Unicode)sParam.ToInt32();
594 [ # # ]: 0 : if( cChar )
595 : : {
596 [ # # ][ # # ]: 0 : pDoc->InsertString( *pPam, rtl::OUString(cChar) );
[ # # ]
597 : 0 : bCharIns = sal_True;
598 : : }
599 : : }
600 : 0 : break;
601 : :
602 : : case 'f': case 'F':
603 : : // Font setzen
604 : : {
605 : 0 : SvxRTFFontTbl& rTbl = GetFontTbl();
606 : :
607 [ # # ][ # # ]: 0 : for( SvxRTFFontTbl::iterator it = rTbl.begin();
[ # # ][ # # ]
608 [ # # ]: 0 : it != rTbl.end(); ++it )
609 : : {
610 [ # # ]: 0 : Font* pFont = it->second;
611 [ # # ][ # # ]: 0 : if( pFont->GetName() == sParam )
[ # # ]
612 : : {
613 : : rSet.Put( SvxFontItem(
614 : : pFont->GetFamily(),
615 : : sParam,
616 [ # # ]: 0 : pFont->GetStyleName(),
617 : : pFont->GetPitch(),
618 [ # # ]: 0 : pFont->GetCharSet(),
619 [ # # ][ # # ]: 0 : RES_CHRATR_FONT ));
[ # # ][ # # ]
[ # # ]
620 : 0 : break;
621 : : }
622 : : }
623 : : }
624 : 0 : break;
625 : : case 'h': case 'H':
626 : : //??
627 : 0 : break;
628 : : case 's': case 'S':
629 : : // Fontsize setzen
630 : : {
631 [ # # ]: 0 : const sal_uInt16 nVal = (sal_uInt16)(sParam.ToInt32() * 20);
632 : : rSet.Put( SvxFontHeightItem( nVal,
633 [ # # ][ # # ]: 0 : 100, RES_CHRATR_FONTSIZE ));
[ # # ]
634 : : }
635 : 0 : break;
636 : : }
637 [ # # ]: 0 : }
638 : :
639 [ # # ][ # # ]: 0 : if( !IsNewGroup() ) AttrGroupEnd();
640 : 0 : SetNewGroup( sal_False );
641 : :
642 [ # # ][ # # ]: 0 : SkipGroup(); // ueberlese den Rest
643 : : }
644 : 0 : break;
645 : :
646 : : case RTFFLD_HYPERLINK:
647 [ # # ]: 0 : rFieldStr.Erase();
648 [ # # ]: 0 : if( aSaveStr.Len() )
649 : : {
650 : : // return String ist URL, # Mark, \1 Frame
651 [ # # ][ # # ]: 0 : String sMark, sFrame;
652 [ # # ]: 0 : RtfFieldSwitch aRFS( aSaveStr );
653 [ # # ]: 0 : while( !aRFS.IsAtEnd() )
654 : : {
655 [ # # ]: 0 : String sParam;
656 [ # # ]: 0 : sal_Unicode cKey = aRFS.GetSwitch( sParam );
657 [ # # ]: 0 : if( sParam.Len() )
658 [ # # # # ]: 0 : switch( cKey )
659 : : {
660 : : case 0:
661 [ # # ]: 0 : if( !rFieldStr.Len() )
662 : : rFieldStr = URIHelper::SmartRel2Abs(
663 : 0 : INetURLObject(GetBaseURL()), sParam,
664 [ # # ]: 0 : URIHelper::GetMaybeFileHdl() );
[ # # # # ]
[ # # ][ # # ]
[ # # ][ # # ]
665 : 0 : break;
666 : :
667 [ # # ]: 0 : case 'l': case 'L': sMark = sParam; break;
668 [ # # ]: 0 : case 't': case 'T': sFrame = sParam; break;
669 : : }
670 [ # # ]: 0 : }
671 : :
672 [ # # ]: 0 : if( sMark.Len() )
673 [ # # ][ # # ]: 0 : ( rFieldStr += INET_MARK_TOKEN ) += sMark;
674 [ # # ]: 0 : if( sFrame.Len() )
675 [ # # ][ # # ]: 0 : ( rFieldStr += '\1' ) += sFrame;
[ # # ][ # # ]
[ # # ]
676 : : }
677 : 0 : break;
678 : :
679 : : case RTFFLD_EQ:
680 [ # # ]: 0 : rFieldStr.Erase();
681 [ # # ]: 0 : if( aSaveStr.Len() )
682 : : {
683 [ # # ]: 0 : RTF_EquationData aData;
684 [ # # ]: 0 : ::lcl_ScanEquationField( aSaveStr, aData, 0 );
685 : :
686 : : // is it a ruby attr?
687 [ # # ][ # # ]: 0 : if( aData.sText.Len() && aData.sFontName.Len() &&
[ # # # #
# # ][ # # ]
688 : 0 : aData.nFontSize && aData.sUp.Len() && !aData.sDown.Len() )
689 : : {
690 : : //Translate and apply
691 [ # # # # : 0 : switch( aData.nJustificationCode )
# ]
692 : : {
693 : 0 : case 0: aData.nJustificationCode = 1; break;
694 : 0 : case 1: aData.nJustificationCode = 3; break;
695 : 0 : case 2: aData.nJustificationCode = 4; break;
696 : 0 : case 4: aData.nJustificationCode = 2; break;
697 : 0 : default: aData.nJustificationCode = 0; break;
698 : : }
699 : :
700 [ # # ]: 0 : SwFmtRuby aRuby( aData.sUp );
701 : 0 : SwCharFmt * pCharFmt = NULL;
702 : :
703 [ # # ]: 0 : if ( aData.nStyleNo != -1)
704 : : {
705 [ # # ]: 0 : std::map<sal_Int32,SwCharFmt*>::iterator iter = aCharFmtTbl.find(aData.nStyleNo);
706 : :
707 [ # # ][ # # ]: 0 : if (iter != aCharFmtTbl.end())
708 [ # # ]: 0 : pCharFmt = iter->second;
709 : : }
710 : :
711 [ # # ]: 0 : if( !pCharFmt )
712 : : {
713 : : //Make a guess at which of asian of western we should be setting
714 : : sal_uInt16 nScript;
715 [ # # ][ # # ]: 0 : if (pBreakIt->GetBreakIter().is())
716 [ # # ][ # # ]: 0 : nScript = pBreakIt->GetBreakIter()->getScriptType( aData.sUp, 0);
[ # # ][ # # ]
717 : : else
718 : 0 : nScript = i18n::ScriptType::ASIAN;
719 : :
720 [ # # ]: 0 : sal_uInt16 nFntHWhich = GetWhichOfScript( RES_CHRATR_FONTSIZE, nScript ),
721 [ # # ]: 0 : nFntWhich = GetWhichOfScript( RES_CHRATR_FONT, nScript );
722 : :
723 : : //Check to see if we already have a ruby charstyle that this fits
724 [ # # ]: 0 : for(sal_uInt16 i=0; i < aRubyCharFmts.size(); ++i )
725 : : {
726 : 0 : SwCharFmt *pFmt = aRubyCharFmts[i];
727 : : const SvxFontHeightItem &rF = (const SvxFontHeightItem &)
728 [ # # ]: 0 : pFmt->GetFmtAttr( nFntHWhich );
729 [ # # ]: 0 : if( rF.GetHeight() == sal_uInt16(aData.nFontSize * 10 ))
730 : : {
731 : : const SvxFontItem &rFI = (const SvxFontItem &)
732 [ # # ]: 0 : pFmt->GetFmtAttr( nFntWhich );
733 [ # # ][ # # ]: 0 : if( rFI.GetFamilyName().Equals( aData.sFontName ))
734 : : {
735 : 0 : pCharFmt = pFmt;
736 : 0 : break;
737 : : }
738 : : }
739 : : }
740 : :
741 : : //Create a new char style if necessary
742 [ # # ]: 0 : if( !pCharFmt )
743 : : {
744 [ # # ]: 0 : String sNm;
745 : : //Take this as the base name
746 [ # # ]: 0 : SwStyleNameMapper::FillUIName( RES_POOLCHR_RUBYTEXT, sNm );
747 [ # # ][ # # ]: 0 : sNm += String::CreateFromInt32( aRubyCharFmts.size() + 1 );
[ # # ]
748 : : pCharFmt = pDoc->MakeCharFmt( sNm,
749 [ # # ]: 0 : ( SwCharFmt*)pDoc->GetDfltCharFmt() );
750 : :
751 [ # # ]: 0 : SvxFontHeightItem aHeightItem( aData.nFontSize * 10, 100, RES_CHRATR_FONTSIZE );
752 : 0 : aHeightItem.SetWhich( nFntHWhich );
753 : :
754 : : SvxFontItem aFontItem( FAMILY_DONTKNOW, aData.sFontName,
755 [ # # ]: 0 : aEmptyStr, PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, nFntWhich );
756 : :
757 [ # # ]: 0 : pCharFmt->SetFmtAttr( aHeightItem );
758 [ # # ]: 0 : pCharFmt->SetFmtAttr( aFontItem );
759 [ # # ][ # # ]: 0 : aRubyCharFmts.push_back( pCharFmt );
[ # # ][ # # ]
760 : : }
761 : : }
762 : :
763 : : //Set the charstyle and justification
764 [ # # ]: 0 : aRuby.SetCharFmtName( pCharFmt->GetName() );
765 : 0 : aRuby.SetCharFmtId( pCharFmt->GetPoolFmtId() );
766 : 0 : aRuby.SetAdjustment( (sal_uInt16)aData.nJustificationCode );
767 : :
768 : : // im FieldStr steht der anzuzeigenden Text, im
769 [ # # ]: 0 : pDoc->InsertString( *pPam, aData.sText );
770 [ # # ]: 0 : pPam->SetMark();
771 [ # # ]: 0 : pPam->GetMark()->nContent -= aData.sText.Len();
772 : : pDoc->InsertPoolItem( *pPam, aRuby,
773 [ # # ]: 0 : nsSetAttrMode::SETATTR_DONTEXPAND );
774 [ # # ][ # # ]: 0 : pPam->DeleteMark();
775 : : }
776 : : // or a combined character field?
777 [ # # ][ # # : 0 : else if( aData.sUp.Len() && aData.sDown.Len() &&
# # # # ]
[ # # ][ # # ]
778 : 0 : !aData.sText.Len() && !aData.sFontName.Len() &&
779 : 0 : !aData.nFontSize )
780 : : {
781 [ # # ]: 0 : String sFld( aData.sUp );
782 [ # # ]: 0 : sFld += aData.sDown;
783 : : SwCombinedCharField aFld((SwCombinedCharFieldType*)pDoc->
784 [ # # ][ # # ]: 0 : GetSysFldType( RES_COMBINED_CHARS ), sFld );
785 [ # # ][ # # ]: 0 : pDoc->InsertPoolItem( *pPam, SwFmtFld( aFld ), 0);
[ # # ][ # # ]
[ # # ]
786 : :
787 : : }
788 [ # # ][ # # ]: 0 : SkipGroup(); // ueberlese den Rest
789 : : }
790 : 0 : break;
791 : :
792 : : case RTFFLD_PAGEREF:
793 : : {
794 [ # # ]: 0 : String sOrigBkmName;
795 [ # # ]: 0 : RtfFieldSwitch aRFS( aSaveStr );
796 [ # # ]: 0 : while( !aRFS.IsAtEnd() )
797 : : {
798 [ # # ]: 0 : String sParam;
799 [ # # ]: 0 : sal_Unicode cKey = aRFS.GetSwitch( sParam );
800 [ # # ]: 0 : switch( cKey )
801 : : {
802 : : // In the case of pageref the only parameter we are
803 : : // interested in, is the name of the bookmark
804 : : case 0:
805 [ # # ]: 0 : if( !sOrigBkmName.Len() ) // get name of bookmark
806 [ # # ]: 0 : sOrigBkmName = sParam;
807 : 0 : break;
808 : : }
809 [ # # ]: 0 : }
810 : : SwGetRefField aFld(
811 [ # # ]: 0 : (SwGetRefFieldType*)pDoc->GetSysFldType( RES_GETREFFLD ),
812 [ # # ]: 0 : sOrigBkmName,REF_BOOKMARK,0,REF_PAGE);
813 : :
814 [ # # ]: 0 : if(!bNestedField)
815 : : {
816 [ # # ][ # # ]: 0 : pDoc->InsertPoolItem( *pPam, SwFmtFld( aFld ), 0 );
[ # # ]
817 : : }
818 : : else
819 [ # # ][ # # ]: 0 : bNestedField = false;
[ # # ]
820 : : }
821 : 0 : break;
822 : :
823 : : case RTFFLD_REF:
824 : : {
825 [ # # ]: 0 : String sOrigBkmName;
826 : 0 : REFERENCEMARK eFormat = REF_CONTENT;
827 : :
828 [ # # ]: 0 : RtfFieldSwitch aRFS( aSaveStr );
829 [ # # ]: 0 : while( !aRFS.IsAtEnd() )
830 : : {
831 [ # # ]: 0 : String sParam;
832 [ # # ]: 0 : sal_Unicode cKey = aRFS.GetSwitch( sParam );
833 [ # # # # : 0 : switch( cKey )
# # ]
834 : : {
835 : : case 0:
836 [ # # ]: 0 : if( !sOrigBkmName.Len() ) // get name of bookmark
837 [ # # ]: 0 : sOrigBkmName = sParam;
838 : 0 : break;
839 : :
840 : : /* References to numbers in Word could be either to a numbered
841 : : paragraph or to a chapter number. However Word does not seem to
842 : : have the capability we do, of refering to the chapter number some
843 : : other bookmark is in. As a result, cross-references to chapter
844 : : numbers in a word document will be cross-references to a numbered
845 : : paragraph, being the chapter heading paragraph. As it happens, our
846 : : cross-references to numbered paragraphs will do the right thing
847 : : when the target is a numbered chapter heading, so there is no need
848 : : for us to use the REF_CHAPTER bookmark format on import.
849 : : */
850 : : case 'n':
851 : 0 : eFormat = REF_NUMBER_NO_CONTEXT;
852 : 0 : break;
853 : : case 'r':
854 : 0 : eFormat = REF_NUMBER;
855 : 0 : break;
856 : : case 'w':
857 : 0 : eFormat = REF_NUMBER_FULL_CONTEXT;
858 : 0 : break;
859 : :
860 : : case 'p':
861 : 0 : eFormat = REF_UPDOWN;
862 : 0 : break;
863 : : }
864 [ # # ]: 0 : }
865 : : SwGetRefField aFld(
866 [ # # ]: 0 : (SwGetRefFieldType*)pDoc->GetSysFldType( RES_GETREFFLD ),
867 [ # # ]: 0 : sOrigBkmName,REF_BOOKMARK,0,eFormat);
868 [ # # ][ # # ]: 0 : pDoc->InsertPoolItem( *pPam, SwFmtFld( aFld ), 0 );
[ # # ][ # # ]
[ # # ][ # # ]
869 : : }
870 : 0 : break;
871 : :
872 : : case RTFFLD_TOC:
873 : : case RTFFLD_INDEX:
874 : 0 : break;
875 : :
876 : : default:
877 : : {
878 : : // keines von den bekannten Feldern, also eine neues UserField
879 [ # # ][ # # ]: 0 : aSaveStr = comphelper::string::strip(aSaveStr, ' ');
[ # # ]
880 [ # # ]: 0 : SwUserFieldType aTmp( pDoc, aSaveStr );
881 [ # # ][ # # ]: 0 : SwUserField aUFld( (SwUserFieldType*)pDoc->InsertFldType( aTmp ));
882 [ # # ]: 0 : aUFld.ChangeFormat( UF_STRING );
883 [ # # ][ # # ]: 0 : pDoc->InsertPoolItem( *pPam, SwFmtFld( aUFld ), 0);
[ # # ]
884 [ # # ][ # # ]: 0 : nRet = RTFFLD_UNKNOWN;
885 : : }
886 : 0 : break;
887 : : }
888 [ # # ]: 0 : return nRet;
889 : : }
890 : :
891 : :
892 : 0 : void SwRTFParser::ReadXEField()
893 : : {
894 : 0 : bReadSwFly = false; //#it may be that any uses of this need to be removed and replaced
895 : 0 : int nNumOpenBrakets = 1;
896 : 0 : rtl::OUStringBuffer sFieldStr;
897 : : sal_uInt8 cCh;
898 : :
899 : : int nToken;
900 [ # # ][ # # ]: 0 : while (nNumOpenBrakets && IsParserWorking())
[ # # ]
901 : : {
902 [ # # ][ # # : 0 : switch (nToken = GetNextToken())
# # # # #
# # # # #
# # # #
# ]
903 : : {
904 : : case '}':
905 : : {
906 : 0 : --nNumOpenBrakets;
907 : :
908 [ # # ]: 0 : if (sFieldStr.getLength())
909 : : {
910 [ # # ][ # # ]: 0 : String sXE(sFieldStr.makeStringAndClear());
911 [ # # ]: 0 : sXE.Insert('\"', 0);
912 [ # # ]: 0 : sXE.Append('\"');
913 : :
914 : : // we have to make sure the hidden text flag is not on
915 : : // otherwise the index will not see this index mark
916 [ # # ]: 0 : SfxItemSet& rSet = GetAttrSet();
917 : : const SfxPoolItem* pItem;
918 [ # # ][ # # ]: 0 : if( SFX_ITEM_SET == rSet.GetItemState( RES_CHRATR_HIDDEN, sal_True, &pItem ) )
919 : : {
920 [ # # ]: 0 : SvxCharHiddenItem aCharHidden(*(SvxCharHiddenItem*)pItem);
921 : 0 : aCharHidden.SetValue(sal_False);
922 [ # # ][ # # ]: 0 : rSet.Put(aCharHidden);
923 : : }
924 : :
925 [ # # ][ # # ]: 0 : sw::ms::ImportXE(*pDoc, *pPam, sXE);
926 : : }
927 : : }
928 : 0 : break;
929 : :
930 : : case '{':
931 [ # # ][ # # ]: 0 : if( RTF_IGNOREFLAG != GetNextToken() )
932 [ # # ]: 0 : SkipToken( -1 );
933 : : // Unknown und alle bekannten nicht ausgewerteten Gruppen
934 : : // sofort ueberspringen
935 [ # # ][ # # ]: 0 : else if( RTF_UNKNOWNCONTROL != GetNextToken() )
936 [ # # ]: 0 : SkipToken( -2 );
937 : : else
938 : : {
939 : : // gleich herausfiltern
940 [ # # ]: 0 : ReadUnknownData();
941 [ # # ][ # # ]: 0 : if( '}' != GetNextToken() )
942 : 0 : eState = SVPAR_ERROR;
943 : 0 : break;
944 : : }
945 : 0 : ++nNumOpenBrakets;
946 : 0 : break;
947 : :
948 : : case RTF_U:
949 : : {
950 [ # # ]: 0 : if( nTokenValue )
951 [ # # ]: 0 : sFieldStr.append(static_cast<sal_Unicode>(nTokenValue));
952 : : else
953 [ # # ][ # # ]: 0 : sFieldStr.append(aToken);
954 : : }
955 : 0 : break;
956 : :
957 : 0 : case RTF_LINE: cCh = '\n'; goto INSINGLECHAR;
958 : 0 : case RTF_TAB: cCh = '\t'; goto INSINGLECHAR;
959 : 0 : case RTF_SUBENTRYINDEX: cCh = ':'; goto INSINGLECHAR;
960 : 0 : case RTF_EMDASH: cCh = 151; goto INSINGLECHAR;
961 : 0 : case RTF_ENDASH: cCh = 150; goto INSINGLECHAR;
962 : 0 : case RTF_BULLET: cCh = 149; goto INSINGLECHAR;
963 : 0 : case RTF_LQUOTE: cCh = 145; goto INSINGLECHAR;
964 : 0 : case RTF_RQUOTE: cCh = 146; goto INSINGLECHAR;
965 : 0 : case RTF_LDBLQUOTE: cCh = 147; goto INSINGLECHAR;
966 : 0 : case RTF_RDBLQUOTE: cCh = 148; goto INSINGLECHAR;
967 : : INSINGLECHAR:
968 : : //convert single byte from MS1252 to unicode and append
969 : : sFieldStr.append(rtl::OUString(
970 : : reinterpret_cast<const sal_Char*>(&cCh), 1,
971 [ # # ][ # # ]: 0 : RTL_TEXTENCODING_MS_1252));
972 : 0 : break;
973 : :
974 : : // kein Break, aToken wird als Text gesetzt
975 : : case RTF_TEXTTOKEN:
976 [ # # ][ # # ]: 0 : sFieldStr.append(aToken);
977 : 0 : break;
978 : :
979 : : case RTF_BKMK_KEY:
980 : : case RTF_TC:
981 : : case RTF_NEXTFILE:
982 : : case RTF_TEMPLATE:
983 : : case RTF_SHPRSLT:
984 [ # # ]: 0 : SkipGroup();
985 : 0 : break;
986 : :
987 : : case RTF_PAR:
988 [ # # ]: 0 : sFieldStr.append(static_cast<sal_Unicode>('\x0a'));
989 : 0 : break;
990 : : default:
991 [ # # ]: 0 : SvxRTFParser::NextToken( nToken );
992 : 0 : break;
993 : : }
994 : : }
995 : :
996 [ # # ]: 0 : SkipToken( -1 ); // die schliesende Klammer wird "oben" ausgewertet
997 : 0 : }
998 : :
999 : :
1000 : 0 : void SwRTFParser::ReadField()
1001 : : {
1002 : 0 : bReadSwFly = false; //#it may be that any uses of this need to be removed and replaced
1003 : 0 : int nRet = 0;
1004 : 0 : int nNumOpenBrakets = 1; // die erste wurde schon vorher erkannt !!
1005 : 0 : int bFldInst = sal_False, bFldRslt = sal_False;
1006 [ # # ][ # # ]: 0 : String sFieldStr, sFieldNm;
1007 : : sal_Unicode cCh;
1008 : :
1009 : : int nToken;
1010 [ # # ][ # # ]: 0 : while (nNumOpenBrakets && IsParserWorking())
[ # # ]
1011 : : {
1012 [ # # ][ # # : 0 : switch (nToken = GetNextToken())
# # # # #
# # # # #
# # # # #
# # # # #
# # ]
1013 : : {
1014 : : case '}':
1015 : : {
1016 : 0 : --nNumOpenBrakets;
1017 [ # # ][ # # ]: 0 : if( 1 != nNumOpenBrakets || !bFldInst )
1018 : 0 : break;
1019 : :
1020 [ # # ]: 0 : if( !bFldRslt )
1021 : : {
1022 : : // FieldInst vollstaendig eingelesen, was ist es denn?
1023 [ # # ]: 0 : nRet = MakeFieldInst( sFieldStr );
1024 [ # # # ]: 0 : switch ( nRet )
1025 : : {
1026 : : case RTFFLD_INCLUDETEXT:
1027 : : case RTFFLD_TOC:
1028 : : case RTFFLD_INDEX:
1029 : : // erstmal Index/Inhaltsverzeichniss ueberspringen
1030 : : // und als normalen Text einfuegen. Spaeter mal auch dem
1031 : : // SwPaM darum aufspannen.
1032 : 0 : return ;
1033 : :
1034 : : case RTFFLD_IMPORT:
1035 : : case RTFFLD_HYPERLINK:
1036 [ # # ]: 0 : sFieldNm = sFieldStr;
1037 : 0 : break;
1038 : : }
1039 [ # # ]: 0 : sFieldStr.Erase();
1040 : : }
1041 [ # # ]: 0 : else if (RTFFLD_UNKNOWN == nRet)
1042 : : {
1043 : : // FieldResult wurde eingelesen
1044 [ # # ]: 0 : if (SwTxtNode* pTxtNd = pPam->GetPoint()->nNode.GetNode().GetTxtNode())
1045 : : {
1046 : : SwTxtAttr* const pFldAttr =
1047 : : pTxtNd->GetTxtAttrForCharAt(
1048 [ # # ]: 0 : pPam->GetPoint()->nContent.GetIndex()-1 );
1049 : :
1050 [ # # ]: 0 : if (pFldAttr)
1051 : : {
1052 : 0 : const SwField *pFld = pFldAttr->GetFld().GetFld();
1053 [ # # ]: 0 : SwFieldType *pTyp = pFld ? pFld->GetTyp() : 0;
1054 : : OSL_ENSURE(pTyp->Which() == RES_USERFLD, "expected a user field");
1055 [ # # ]: 0 : if (pTyp->Which() == RES_USERFLD)
1056 : : {
1057 : 0 : SwUserFieldType *pUsrTyp = (SwUserFieldType*)pTyp;
1058 [ # # ]: 0 : pUsrTyp->SetContent(sFieldStr);
1059 : : }
1060 : : }
1061 : : }
1062 : : }
1063 [ # # ]: 0 : else if( sFieldNm.Len() )
1064 : : {
1065 [ # # # ]: 0 : switch ( nRet )
1066 : : {
1067 : : case RTFFLD_IMPORT:
1068 : : // Grafik einfuegen
1069 [ # # ]: 0 : InsPicture( sFieldNm );
1070 : 0 : nRet = INT_MAX;
1071 : 0 : break;
1072 : : case RTFFLD_HYPERLINK:
1073 [ # # ]: 0 : if( sFieldStr.Len() )
1074 : : {
1075 [ # # ]: 0 : if(sNestedFieldStr.Len())
1076 [ # # ]: 0 : sFieldStr.Insert(sNestedFieldStr);
1077 : :
1078 [ # # ]: 0 : sNestedFieldStr.Erase();
1079 : : // im FieldStr steht der anzuzeigenden Text, im
1080 [ # # ]: 0 : pDoc->InsertString( *pPam, sFieldStr );
1081 : :
1082 [ # # ]: 0 : String sTarget( sFieldNm.GetToken( 1, '\1' ));
1083 [ # # ]: 0 : if( sTarget.Len() )
1084 [ # # ]: 0 : sFieldNm.Erase( sFieldNm.Len() - sTarget.Len() -1 );
1085 : :
1086 : : // oder ueber den Stack setzen??
1087 [ # # ]: 0 : pPam->SetMark();
1088 [ # # ]: 0 : pPam->GetMark()->nContent -= sFieldStr.Len();
1089 : : pDoc->InsertPoolItem( *pPam,
1090 : : SwFmtINetFmt( sFieldNm, sTarget ),
1091 [ # # ][ # # ]: 0 : nsSetAttrMode::SETATTR_DONTEXPAND );
[ # # ]
1092 [ # # ]: 0 : pPam->DeleteMark();
1093 : :
1094 : : // #i117947#: insert result only once in case
1095 : : // field result is followed by invalid tokens
1096 [ # # ][ # # ]: 0 : sFieldStr.Erase();
1097 : : }
1098 : 0 : break;
1099 : : }
1100 : : }
1101 [ # # ]: 0 : else if(bNestedField)
1102 : : {
1103 [ # # ]: 0 : if(nRet == RTFFLD_PAGEREF)
1104 : : {
1105 : : // Nasty hack to get a pageref within a hyperlink working
1106 [ # # ]: 0 : sNestedFieldStr = sFieldStr;
1107 : : }
1108 : :
1109 : : }
1110 : :
1111 : : }
1112 : 0 : break;
1113 : :
1114 : : case '{':
1115 [ # # ][ # # ]: 0 : if( RTF_IGNOREFLAG != GetNextToken() )
1116 [ # # ]: 0 : SkipToken( -1 );
1117 : : // Unknown und alle bekannten nicht ausgewerteten Gruppen
1118 : : // sofort ueberspringen
1119 [ # # ][ # # ]: 0 : else if( RTF_UNKNOWNCONTROL != GetNextToken() )
1120 [ # # ]: 0 : SkipToken( -2 );
1121 : : else
1122 : : {
1123 : : // gleich herausfiltern
1124 [ # # ]: 0 : ReadUnknownData();
1125 [ # # ][ # # ]: 0 : if( '}' != GetNextToken() )
1126 : 0 : eState = SVPAR_ERROR;
1127 : 0 : break;
1128 : : }
1129 : 0 : ++nNumOpenBrakets;
1130 : 0 : break;
1131 : :
1132 : : case RTF_DATAFIELD:
1133 [ # # ]: 0 : SkipGroup();
1134 : 0 : break;
1135 : :
1136 : : case RTF_FIELD:
1137 : 0 : bNestedField = true;
1138 [ # # ]: 0 : ReadField();
1139 : 0 : break;
1140 : :
1141 : : case RTF_FLDINST:
1142 : 0 : bFldInst = sal_True;
1143 : 0 : break;
1144 : :
1145 : : case RTF_FLDRSLT:
1146 : 0 : bFldRslt = sal_True;
1147 : 0 : break;
1148 : :
1149 : : case RTF_U:
1150 : : {
1151 [ # # ]: 0 : if( nTokenValue )
1152 [ # # ]: 0 : sFieldStr += (sal_Unicode)nTokenValue;
1153 : : else
1154 [ # # ]: 0 : sFieldStr += aToken;
1155 : : }
1156 : 0 : break;
1157 : :
1158 : 0 : case RTF_LINE: cCh = '\n'; goto INSINGLECHAR;
1159 : 0 : case RTF_TAB: cCh = '\t'; goto INSINGLECHAR;
1160 : 0 : case RTF_SUBENTRYINDEX: cCh = ':'; goto INSINGLECHAR;
1161 : 0 : case RTF_EMDASH: cCh = 0x2014; goto INSINGLECHAR;
1162 : 0 : case RTF_ENDASH: cCh = 0x2013; goto INSINGLECHAR;
1163 : 0 : case RTF_BULLET: cCh = 0x2022; goto INSINGLECHAR;
1164 : 0 : case RTF_LQUOTE: cCh = 0x2018; goto INSINGLECHAR;
1165 : 0 : case RTF_RQUOTE: cCh = 0x2019; goto INSINGLECHAR;
1166 : 0 : case RTF_LDBLQUOTE: cCh = 0x201C; goto INSINGLECHAR;
1167 : 0 : case RTF_RDBLQUOTE: cCh = 0x201D; goto INSINGLECHAR;
1168 : : INSINGLECHAR:
1169 [ # # ]: 0 : sFieldStr += cCh;
1170 : 0 : break;
1171 : :
1172 : : // kein Break, aToken wird als Text gesetzt
1173 : : case RTF_TEXTTOKEN:
1174 [ # # ]: 0 : sFieldStr += aToken;
1175 : 0 : break;
1176 : :
1177 : : case RTF_PICT: // Pic-Daten einlesen!
1178 [ # # ]: 0 : if( RTFFLD_IMPORT == nRet )
1179 : : {
1180 [ # # ]: 0 : Graphic aGrf;
1181 [ # # ]: 0 : SvxRTFPictureType aPicType;
1182 [ # # ][ # # ]: 0 : if( ReadBmpData( aGrf, aPicType ) )
1183 : : {
1184 [ # # ]: 0 : InsPicture( sFieldNm, &aGrf, &aPicType );
1185 : 0 : nRet = INT_MAX;
1186 : : }
1187 [ # # ][ # # ]: 0 : SkipGroup();
1188 : : }
1189 : 0 : break;
1190 : :
1191 : : case RTF_BKMK_KEY:
1192 : : case RTF_XE:
1193 : : case RTF_TC:
1194 : : case RTF_NEXTFILE:
1195 : : case RTF_TEMPLATE:
1196 : : case RTF_SHPRSLT:
1197 [ # # ]: 0 : SkipGroup();
1198 : 0 : break;
1199 : :
1200 : : case RTF_CS:
1201 : : // we write every time "EQ "
1202 [ # # ][ # # ]: 0 : if( bFldInst && 0 == sFieldStr.SearchAscii( "EQ " ))
[ # # ][ # # ]
1203 : : {
1204 : : // insert behind the EQ the "\*cs<NO> " string. This is utilize
1205 : : // in the MakeFieldInst
1206 [ # # ]: 0 : String sTmp;
1207 [ # # ]: 0 : (sTmp.AssignAscii( "\\* cs" )
1208 [ # # ][ # # ]: 0 : += String::CreateFromInt32( nTokenValue )) += ' ';
[ # # ][ # # ]
1209 [ # # ][ # # ]: 0 : sFieldStr.Insert( sTmp, 3 );
1210 : : }
1211 : 0 : break;
1212 : : case RTF_FFNAME:
1213 : : case RTF_FORMFIELD:
1214 : 0 : break;
1215 : : case RTF_PAR:
1216 [ # # ]: 0 : sFieldStr.Append('\x0a');
1217 : 0 : break;
1218 : : default:
1219 [ # # ]: 0 : SvxRTFParser::NextToken( nToken );
1220 : 0 : break;
1221 : : }
1222 : : }
1223 : :
1224 : : // Grafik einfuegen
1225 [ # # ][ # # ]: 0 : if (RTFFLD_IMPORT == nRet && sFieldNm.Len())
[ # # ]
1226 [ # # ]: 0 : InsPicture( sFieldNm );
1227 : :
1228 [ # # ][ # # ]: 0 : SkipToken( -1 ); // die schliesende Klammer wird "oben" ausgewertet
[ # # ][ # # ]
[ # # ]
1229 : : }
1230 : :
1231 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|