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> // tolower
22 : #include <stdio.h> // sscanf()
23 :
24 : #include <sal/types.h>
25 : #include <tools/solar.h>
26 : #include <comphelper/processfactory.hxx>
27 : #include <comphelper/storagehelper.hxx>
28 : #include <comphelper/string.hxx>
29 : #include <sot/storinfo.hxx>
30 : #include <com/sun/star/embed/XStorage.hpp>
31 : #include <com/sun/star/embed/ElementModes.hpp>
32 : #include <com/sun/star/embed/XTransactedObject.hpp>
33 : #include <com/sun/star/io/XStream.hpp>
34 :
35 : #include <com/sun/star/ucb/XCommandEnvironment.hpp>
36 : #include <svl/urihelper.hxx>
37 : #include <svl/zforlist.hxx>
38 : #include <svl/zformat.hxx>
39 : #include <sfx2/linkmgr.hxx>
40 :
41 : #include <ucbhelper/content.hxx>
42 :
43 : #include <com/sun/star/i18n/ScriptType.hpp>
44 : #include <hintids.hxx>
45 : #include <editeng/fontitem.hxx>
46 : #include <editeng/fhgtitem.hxx>
47 : #include <editeng/langitem.hxx>
48 : #include <fmtfld.hxx>
49 : #include <fmtanchr.hxx>
50 : #include <pam.hxx> // fuer SwPam
51 : #include <doc.hxx>
52 : #include <charatr.hxx> // class SwFmtFld
53 : #include <flddat.hxx> // class SwDateTimeField
54 : #include <docufld.hxx> // class SwPageNumberField
55 : #include <reffld.hxx> // class SwGetRefField
56 : #include <IMark.hxx>
57 : #include <expfld.hxx> // class SwSetExpField
58 : #include <dbfld.hxx> // class SwDBField
59 : #include <usrfld.hxx>
60 : #include <tox.hxx>
61 : #include <section.hxx> // class SwSection
62 : #include <ndtxt.hxx>
63 : #include <fmtinfmt.hxx>
64 : #include <chpfld.hxx>
65 : #include <ftnidx.hxx>
66 : #include <txtftn.hxx>
67 : #include <viewsh.hxx>
68 : #include <shellres.hxx>
69 : #include <fmtruby.hxx>
70 : #include <charfmt.hxx>
71 : #include <txtatr.hxx>
72 : #include <breakit.hxx>
73 : #include <fmtclds.hxx>
74 : #include <pagedesc.hxx>
75 : #include <SwStyleNameMapper.hxx>
76 :
77 : #include "ww8scan.hxx" // WW8FieldDesc
78 : #include "ww8par.hxx"
79 : #include "ww8par2.hxx"
80 : #include "writerhelper.hxx"
81 : #include "fields.hxx"
82 : #include <unotools/fltrcfg.hxx>
83 : #include <xmloff/odffields.hxx>
84 :
85 : #include <algorithm> // #i24377#
86 :
87 : #define MAX_FIELDLEN 64000
88 :
89 : #define WW8_TOX_LEVEL_DELIM ':'
90 :
91 : using namespace ::com::sun::star;
92 : using namespace sw::util;
93 : using namespace sw::mark;
94 : using namespace std; // #i24377#
95 : using namespace nsSwDocInfoSubType;
96 :
97 :
98 : class WW8ReadFieldParams
99 : {
100 : private:
101 : String aData;
102 : xub_StrLen nLen, nFnd, nNext, nSavPtr;
103 : public:
104 : WW8ReadFieldParams( const String& rData );
105 : ~WW8ReadFieldParams();
106 :
107 : xub_StrLen GoToTokenParam();
108 : long SkipToNextToken();
109 0 : xub_StrLen GetTokenSttPtr() const { return nFnd; }
110 :
111 : xub_StrLen FindNextStringPiece( xub_StrLen _nStart = STRING_NOTFOUND );
112 : bool GetTokenSttFromTo(xub_StrLen* _pFrom, xub_StrLen* _pTo,
113 : xub_StrLen _nMax);
114 :
115 : String GetResult() const;
116 : };
117 :
118 :
119 7 : WW8ReadFieldParams::WW8ReadFieldParams( const String& _rData )
120 7 : : aData( _rData ), nLen( _rData.Len() ), nNext( 0 )
121 : {
122 : /*
123 : erstmal nach einer oeffnenden Klammer oder einer Leerstelle oder einem
124 : Anfuehrungszeichen oder einem Backslash suchen, damit der Feldbefehl
125 : (also INCLUDEPICTURE bzw EINFUeGENGRAFIK bzw ...) ueberlesen wird
126 : */
127 20 : while( (nLen > nNext) && (aData.GetChar( nNext ) == ' ') )
128 6 : ++nNext;
129 :
130 : sal_Unicode c;
131 178 : while( nLen > nNext
132 85 : && (c = aData.GetChar( nNext )) != ' '
133 : && c != '"'
134 : && c != '\\'
135 : && c != 132
136 : && c != 0x201c )
137 79 : ++nNext;
138 :
139 7 : nFnd = nNext;
140 7 : nSavPtr = nNext;
141 7 : }
142 :
143 :
144 7 : WW8ReadFieldParams::~WW8ReadFieldParams()
145 : {
146 :
147 7 : }
148 :
149 :
150 6 : String WW8ReadFieldParams::GetResult() const
151 : {
152 : return (STRING_NOTFOUND == nFnd)
153 : ? aEmptyStr
154 6 : : aData.Copy( nFnd, (nSavPtr - nFnd) );
155 : }
156 :
157 :
158 0 : xub_StrLen WW8ReadFieldParams::GoToTokenParam()
159 : {
160 0 : xub_StrLen nOld = nNext;
161 0 : if( -2 == SkipToNextToken() )
162 0 : return GetTokenSttPtr();
163 0 : nNext = nOld;
164 0 : return STRING_NOTFOUND;
165 : }
166 :
167 : // ret: -2: NOT a '\' parameter but normal Text
168 14 : long WW8ReadFieldParams::SkipToNextToken()
169 : {
170 14 : long nRet = -1; // Ende
171 27 : if (
172 : (STRING_NOTFOUND != nNext) && (nLen > nNext) &&
173 13 : STRING_NOTFOUND != (nFnd = FindNextStringPiece(nNext))
174 : )
175 : {
176 7 : nSavPtr = nNext;
177 :
178 7 : if ('\\' == aData.GetChar(nFnd) && '\\' != aData.GetChar(nFnd + 1))
179 : {
180 1 : nRet = aData.GetChar(++nFnd);
181 1 : nNext = ++nFnd; // und dahinter setzen
182 : }
183 : else
184 : {
185 6 : nRet = -2;
186 16 : if (
187 : (STRING_NOTFOUND != nSavPtr ) &&
188 : (
189 6 : ('"' == aData.GetChar(nSavPtr - 1)) ||
190 4 : (0x201d == aData.GetChar(nSavPtr - 1))
191 : )
192 : )
193 : {
194 2 : --nSavPtr;
195 : }
196 : }
197 : }
198 14 : return nRet;
199 : }
200 :
201 : // FindNextPara sucht naechsten Backslash-Parameter oder naechste Zeichenkette
202 : // bis zum Blank oder naechsten "\" oder zum schliessenden Anfuehrungszeichen
203 : // oder zum String-Ende von pStr.
204 : //
205 : // Ausgabe ppNext (falls ppNext != 0) Suchbeginn fuer naechsten Parameter bzw. 0
206 : //
207 : // Returnwert: 0 falls String-Ende erreicht,
208 : // ansonsten Anfang des Paramters bzw. der Zeichenkette
209 : //
210 13 : xub_StrLen WW8ReadFieldParams::FindNextStringPiece(const xub_StrLen nStart)
211 : {
212 13 : xub_StrLen n = ( STRING_NOTFOUND == nStart ) ? nFnd : nStart; // Anfang
213 : xub_StrLen n2; // Ende
214 :
215 13 : nNext = STRING_NOTFOUND; // Default fuer nicht gefunden
216 :
217 42 : while( (nLen > n) && (aData.GetChar( n ) == ' ') )
218 16 : ++n;
219 :
220 13 : if ( aData.GetChar( n ) == 0x13 )
221 : {
222 : // Skip the nested field code since it's not supported
223 0 : while ( ( nLen > n ) && ( aData.GetChar( n ) != 0x14 ) )
224 0 : n++;
225 : }
226 :
227 13 : if( nLen == n )
228 6 : return STRING_NOTFOUND; // String End reached!
229 :
230 22 : if( (aData.GetChar( n ) == '"') // Anfuehrungszeichen vor Para?
231 5 : || (aData.GetChar( n ) == 0x201c)
232 5 : || (aData.GetChar( n ) == 132)
233 5 : || (aData.GetChar( n ) == 0x14) )
234 : {
235 2 : n++; // Anfuehrungszeichen ueberlesen
236 2 : n2 = n; // ab hier nach Ende suchen
237 301 : while( (nLen > n2)
238 61 : && (aData.GetChar( n2 ) != '"')
239 59 : && (aData.GetChar( n2 ) != 0x201d)
240 59 : && (aData.GetChar( n2 ) != 147)
241 59 : && (aData.GetChar( n2 ) != 0x15) )
242 59 : n2++; // Ende d. Paras suchen
243 : }
244 : else // keine Anfuehrungszeichen
245 : {
246 5 : n2 = n; // ab hier nach Ende suchen
247 88 : while( (nLen > n2) && (aData.GetChar( n2 ) != ' ') ) // Ende d. Paras suchen
248 : {
249 79 : if( aData.GetChar( n2 ) == '\\' )
250 : {
251 1 : if( aData.GetChar( n2+1 ) == '\\' )
252 0 : n2 += 2; // Doppel-Backslash -> OK
253 : else
254 : {
255 1 : if( n2 > n )
256 0 : n2--;
257 1 : break; // einfach-Backslash -> Ende
258 : }
259 : }
260 : else
261 78 : n2++; // kein Backslash -> OK
262 : }
263 : }
264 7 : if( nLen > n2 )
265 : {
266 7 : if(aData.GetChar( n2 ) != ' ') n2++;
267 7 : nNext = n2;
268 : }
269 7 : return n;
270 : }
271 :
272 :
273 :
274 : // read parameters "1-3" or 1-3 with both values between 1 and nMax
275 0 : bool WW8ReadFieldParams::GetTokenSttFromTo(sal_uInt16* pFrom, sal_uInt16* pTo, sal_uInt16 nMax)
276 : {
277 0 : sal_uInt16 nStart = 0;
278 0 : sal_uInt16 nEnd = 0;
279 0 : xub_StrLen n = GoToTokenParam();
280 0 : if( STRING_NOTFOUND != n )
281 : {
282 :
283 0 : String sParams( GetResult() );
284 :
285 0 : xub_StrLen nIndex = 0;
286 0 : String sStart( sParams.GetToken(0, '-', nIndex) );
287 0 : if( STRING_NOTFOUND != nIndex )
288 : {
289 0 : nStart = static_cast<sal_uInt16>(sStart.ToInt32());
290 0 : nEnd = static_cast<sal_uInt16>(sParams.Copy(nIndex).ToInt32());
291 0 : }
292 : }
293 0 : if( pFrom ) *pFrom = nStart;
294 0 : if( pTo ) *pTo = nEnd;
295 :
296 0 : return nStart && nEnd && (nMax >= nStart) && (nMax >= nEnd);
297 : }
298 :
299 : //----------------------------------------
300 : // Bookmarks
301 : //----------------------------------------
302 :
303 12 : long SwWW8ImplReader::Read_Book(WW8PLCFManResult*)
304 : {
305 : // muesste auch ueber pRes.nCo2OrIdx gehen
306 12 : WW8PLCFx_Book* pB = pPlcxMan->GetBook();
307 12 : if( !pB )
308 : {
309 : OSL_ENSURE( pB, "WW8PLCFx_Book - Pointer nicht da" );
310 0 : return 0;
311 : }
312 :
313 12 : eBookStatus eB = pB->GetStatus();
314 12 : if (eB & BOOK_IGNORE)
315 0 : return 0; // Bookmark zu ignorieren
316 :
317 12 : if (pB->GetIsEnd())
318 : {
319 6 : pReffedStck->SetAttr(*pPaM->GetPoint(), RES_FLTR_BOOKMARK, true,
320 12 : pB->GetHandle(), (eB & BOOK_FIELD)!=0);
321 6 : return 0;
322 : }
323 :
324 : //"_Toc*" and "_Hlt*" are unnecessary
325 6 : const String* pName = pB->GetName();
326 : #if !defined(WW_NATIVE_TOC)
327 12 : if( !pName || pName->EqualsIgnoreCaseAscii( "_Toc", 0, 4 )
328 6 : || pName->EqualsIgnoreCaseAscii( "_Hlt", 0, 4 ) )
329 0 : return 0;
330 : #endif
331 :
332 : //ToUpper darf auf keinen Fall gemacht werden, weil der Bookmark- name ein Hyperlink-Ziel sein kann!
333 :
334 6 : String aVal;
335 6 : if( SwFltGetFlag( nFieldFlags, SwFltControlStack::BOOK_TO_VAR_REF ) )
336 : {
337 : // Fuer UEbersetzung Bookmark -> Variable setzen
338 0 : long nLen = pB->GetLen();
339 0 : if( nLen > MAX_FIELDLEN )
340 0 : nLen = MAX_FIELDLEN;
341 :
342 0 : long nOldPos = pStrm->Tell();
343 : nLen = pSBase->WW8ReadString( *pStrm, aVal, pB->GetStartPos(), nLen,
344 0 : eStructCharSet );
345 0 : pStrm->Seek( nOldPos );
346 :
347 : // now here the implementation of the old "QuoteString" and
348 : // I hope with a better performance as before. It's also only
349 : // needed if the filterflags say we will convert bookmarks
350 : // to SetExpFields! And this the exception!
351 :
352 0 : rtl::OUString sHex("\\x");
353 : bool bSetAsHex;
354 : bool bAllowCr = SwFltGetFlag(nFieldFlags,
355 0 : SwFltControlStack::ALLOW_FLD_CR) ? true : false;
356 :
357 : sal_Unicode cChar;
358 :
359 0 : for( xub_StrLen nI = 0;
360 0 : nI < aVal.Len() && aVal.Len() < (MAX_FIELDLEN - 4); ++nI )
361 : {
362 0 : switch( cChar = aVal.GetChar( nI ) )
363 : {
364 : case 0x0b:
365 : case 0x0c:
366 : case 0x0d:
367 0 : if( bAllowCr )
368 0 : aVal.SetChar( nI, '\n' ), bSetAsHex = false;
369 : else
370 0 : bSetAsHex = true;
371 0 : break;
372 :
373 : case 0xFE:
374 : case 0xFF:
375 0 : bSetAsHex = true;
376 0 : break;
377 :
378 : default:
379 0 : bSetAsHex = 0x20 > cChar;
380 0 : break;
381 : }
382 :
383 0 : if( bSetAsHex )
384 : {
385 : //all Hex-Numbers with \x before
386 0 : String sTmp( sHex );
387 0 : if( cChar < 0x10 )
388 0 : sTmp += '0';
389 0 : sTmp += String::CreateFromInt32( cChar, 16 );
390 0 : aVal.Replace( nI, 1 , sTmp );
391 0 : nI += sTmp.Len() - 1;
392 : }
393 : }
394 :
395 0 : if( aVal.Len() > (MAX_FIELDLEN - 4))
396 0 : aVal.Erase( MAX_FIELDLEN - 4 );
397 : }
398 :
399 : //e.g. inserting bookmark around field result, so we need to put
400 : //it around the entire writer field, as we don't have the seperation
401 : //of field and field result of word, see #i16941#
402 6 : SwPosition aStart(*pPaM->GetPoint());
403 6 : if (!maFieldStack.empty())
404 : {
405 3 : const WW8FieldEntry &rTest = maFieldStack.back();
406 3 : aStart = rTest.maStartPos;
407 : }
408 :
409 : pReffedStck->NewAttr(aStart, SwFltBookmark(BookmarkToWriter(*pName), aVal,
410 6 : pB->GetHandle(), 0));
411 6 : return 0;
412 : }
413 :
414 : //----------------------------------------------------------------------
415 : // allgemeine Hilfsroutinen zum Auseinanderdroeseln der Parameter
416 : //----------------------------------------------------------------------
417 :
418 : // ConvertFFileName uebersetzt FeldParameter-Namen u. ae. in den
419 : // System-Zeichensatz.
420 : // Gleichzeitig werden doppelte Backslashes in einzelne uebersetzt.
421 2 : void SwWW8ImplReader::ConvertFFileName( String& rName, const String& rOrg )
422 : {
423 2 : rName = rOrg;
424 2 : rName.SearchAndReplaceAllAscii( "\\\\", rtl::OUString( '\\' ));
425 2 : rName.SearchAndReplaceAllAscii( "%20", rtl::OUString( ' ' ));
426 :
427 : // ggfs. anhaengende Anfuehrungszeichen entfernen
428 2 : if( rName.Len() && '"' == rName.GetChar( rName.Len()-1 ))
429 0 : rName.Erase( rName.Len()-1, 1);
430 :
431 : // Need the more sophisticated url converter. cmc
432 2 : if (rName.Len())
433 : rName = URIHelper::SmartRel2Abs(
434 2 : INetURLObject(sBaseURL), rName, Link(), false);
435 2 : }
436 :
437 : // ConvertUFNneme uebersetzt FeldParameter-Namen u. ae. in den
438 : // System-Zeichensatz und Upcased sie ( z.B. fuer Ref-Felder )
439 : namespace
440 : {
441 0 : void ConvertUFName( String& rName )
442 : {
443 0 : rName = GetAppCharClass().uppercase( rName );
444 0 : }
445 : }
446 :
447 0 : static void lcl_ConvertSequenceName(String& rSequenceName)
448 : {
449 0 : ConvertUFName(rSequenceName);
450 0 : if ('0' <= rSequenceName.GetChar(0) && '9' >= rSequenceName.GetChar(0))
451 0 : rSequenceName.Insert('_', 0);
452 0 : }
453 :
454 : // FindParaStart() finds 1st Parameter that follows '\' and cToken
455 : // and returns start of this parameter or STRING_NOT_FOUND.
456 5 : xub_StrLen FindParaStart( const String& rStr, sal_Unicode cToken, sal_Unicode cToken2 )
457 : {
458 5 : bool bStr = false; // innerhalb String ignorieren
459 :
460 36 : for( xub_StrLen nBuf=0; nBuf+1 < rStr.Len(); nBuf++ )
461 : {
462 33 : if( rStr.GetChar( nBuf ) == '"' )
463 0 : bStr = !bStr;
464 :
465 68 : if( !bStr
466 33 : && rStr.GetChar( nBuf ) == '\\'
467 2 : && ( rStr.GetChar( nBuf + 1 ) == cToken
468 0 : || rStr.GetChar( nBuf + 1 ) == cToken2 ) )
469 : {
470 2 : nBuf += 2;
471 : // skip spaces between cToken and it's parameters
472 10 : while( nBuf < rStr.Len()
473 4 : && rStr.GetChar( nBuf ) == ' ' )
474 2 : nBuf++;
475 : // return start of parameters
476 2 : return nBuf < rStr.Len() ? nBuf : STRING_NOTFOUND;
477 : }
478 : }
479 3 : return STRING_NOTFOUND;
480 : }
481 :
482 : // FindPara() findet den ersten Parameter mit '\' und cToken. Es wird
483 : // ein neuer String allokiert ( der vom Aufrufer deallokiert werden muss )
484 : // und alles, was zum Parameter gehoert, wird in ihm zurueckgeliefert.
485 5 : String FindPara( const String& rStr, sal_Unicode cToken, sal_Unicode cToken2 )
486 : {
487 : xub_StrLen n2; // Ende
488 5 : xub_StrLen n = FindParaStart( rStr, cToken, cToken2 ); // Anfang
489 5 : if( STRING_NOTFOUND == n )
490 3 : return aEmptyStr;
491 :
492 4 : if( rStr.GetChar( n ) == '"'
493 2 : || rStr.GetChar( n ) == 132 )
494 : { // Anfuehrungszeichen vor Para
495 0 : n++; // Anfuehrungszeichen ueberlesen
496 0 : n2 = n; // ab hier nach Ende suchen
497 0 : while( n2 < rStr.Len()
498 0 : && rStr.GetChar( n2 ) != 147
499 0 : && rStr.GetChar( n2 ) != '"' )
500 0 : n2++; // Ende d. Paras suchen
501 : }
502 : else
503 : { // keine Anfuehrungszeichen
504 2 : n2 = n; // ab hier nach Ende suchen
505 50 : while( n2 < rStr.Len()
506 24 : && rStr.GetChar( n2 ) != ' ' )
507 22 : n2++; // Ende d. Paras suchen
508 : }
509 2 : return rStr.Copy( n, n2-n );
510 : }
511 :
512 :
513 5 : static SvxExtNumType GetNumTypeFromName(const String& rStr,
514 : bool bAllowPageDesc = false)
515 : {
516 5 : SvxExtNumType eTyp = bAllowPageDesc ? SVX_NUM_PAGEDESC : SVX_NUM_ARABIC;
517 5 : if( rStr.EqualsIgnoreCaseAscii( "Arabi", 0, 5 ) ) // Arabisch, Arabic
518 0 : eTyp = SVX_NUM_ARABIC;
519 5 : else if( rStr.EqualsAscii( "misch", 2, 5 ) ) // r"omisch
520 0 : eTyp = SVX_NUM_ROMAN_LOWER;
521 5 : else if( rStr.EqualsAscii( "MISCH", 2, 5 ) ) // R"OMISCH
522 0 : eTyp = SVX_NUM_ROMAN_UPPER;
523 5 : else if( rStr.EqualsIgnoreCaseAscii( "alphabeti", 0, 9 ) )// alphabetisch, alphabetic
524 0 : eTyp = ( rStr.GetChar( 0 ) == 'A' )
525 : ? SVX_NUM_CHARS_UPPER_LETTER_N
526 0 : : SVX_NUM_CHARS_LOWER_LETTER_N;
527 5 : else if( rStr.EqualsIgnoreCaseAscii( "roman", 0, 5 ) ) // us
528 0 : eTyp = ( rStr.GetChar( 0 ) == 'R' )
529 : ? SVX_NUM_ROMAN_UPPER
530 0 : : SVX_NUM_ROMAN_LOWER;
531 5 : return eTyp;
532 : }
533 :
534 5 : static SvxExtNumType GetNumberPara(String& rStr, bool bAllowPageDesc = false)
535 : {
536 5 : String s( FindPara( rStr, '*', '*' ) ); // Ziffernart
537 5 : SvxExtNumType aType = GetNumTypeFromName( s, bAllowPageDesc );
538 5 : return aType;
539 : }
540 :
541 :
542 :
543 :
544 0 : bool SwWW8ImplReader::ForceFieldLanguage(SwField &rFld, sal_uInt16 nLang)
545 : {
546 0 : bool bRet(false);
547 :
548 : const SvxLanguageItem *pLang =
549 0 : (const SvxLanguageItem*)GetFmtAttr(RES_CHRATR_LANGUAGE);
550 : OSL_ENSURE(pLang, "impossible");
551 0 : sal_uInt16 nDefault = pLang ? pLang->GetValue() : LANGUAGE_ENGLISH_US;
552 :
553 0 : if (nLang != nDefault)
554 : {
555 0 : rFld.SetAutomaticLanguage(false);
556 0 : rFld.SetLanguage(nLang);
557 0 : bRet = true;
558 : }
559 :
560 0 : return bRet;
561 : }
562 :
563 0 : String GetWordDefaultDateStringAsUS(SvNumberFormatter* pFormatter, sal_uInt16 nLang)
564 : {
565 : //Get the system date in the correct final language layout, convert to
566 : //a known language and modify the 2 digit year part to be 4 digit, and
567 : //convert back to the correct language layout.
568 0 : sal_uLong nIndex = pFormatter->GetFormatIndex(NF_DATE_SYSTEM_SHORT, nLang);
569 :
570 : SvNumberformat aFormat = const_cast<SvNumberformat &>
571 0 : (*(pFormatter->GetEntry(nIndex)));
572 0 : aFormat.ConvertLanguage(*pFormatter, nLang, LANGUAGE_ENGLISH_US);
573 :
574 0 : String sParams(aFormat.GetFormatstring());
575 : // #i36594#
576 : // Fix provided by mloiseleur@openoffice.org.
577 : // A default date can have already 4 year digits, in some case
578 0 : const xub_StrLen pos = sParams.Search(rtl::OUString("YYYY"));
579 0 : if ( pos == STRING_NOTFOUND )
580 : {
581 0 : sParams.SearchAndReplace(rtl::OUString("YY"), rtl::OUString("YYYY"));
582 : }
583 0 : return sParams;
584 : }
585 :
586 0 : short SwWW8ImplReader::GetTimeDatePara(String& rStr, sal_uInt32& rFormat,
587 : sal_uInt16 &rLang, int nWhichDefault, bool bHijri)
588 : {
589 0 : bool bRTL = false;
590 0 : if (pPlcxMan && !bVer67)
591 : {
592 0 : const sal_uInt8 *pResult = pPlcxMan->HasCharSprm(0x85A);
593 0 : if (pResult && *pResult)
594 0 : bRTL = true;
595 : }
596 0 : RES_CHRATR eLang = bRTL ? RES_CHRATR_CTL_LANGUAGE : RES_CHRATR_LANGUAGE;
597 0 : const SvxLanguageItem *pLang = (SvxLanguageItem*)GetFmtAttr( static_cast< sal_uInt16 >(eLang));
598 : OSL_ENSURE(pLang, "impossible");
599 0 : rLang = pLang ? pLang->GetValue() : LANGUAGE_ENGLISH_US;
600 :
601 0 : SvNumberFormatter* pFormatter = rDoc.GetNumberFormatter();
602 0 : String sParams( FindPara( rStr, '@', '@' ) );// Date/Time
603 0 : if (!sParams.Len())
604 : {
605 0 : bool bHasTime = false;
606 0 : switch (nWhichDefault)
607 : {
608 : case ww::ePRINTDATE:
609 : case ww::eSAVEDATE:
610 0 : sParams = GetWordDefaultDateStringAsUS(pFormatter, rLang);
611 0 : sParams.AppendAscii(" HH:MM:SS AM/PM");
612 0 : bHasTime = true;
613 0 : break;
614 : case ww::eCREATEDATE:
615 0 : sParams.AssignAscii("DD/MM/YYYY HH:MM:SS");
616 0 : bHasTime = true;
617 0 : break;
618 : default:
619 : case ww::eDATE:
620 0 : sParams = GetWordDefaultDateStringAsUS(pFormatter, rLang);
621 0 : break;
622 : }
623 :
624 0 : if (bHijri)
625 0 : sParams.Insert(rtl::OUString("[~hijri]"), 0);
626 :
627 0 : sal_Int32 nCheckPos = 0;
628 0 : short nType = NUMBERFORMAT_DEFINED;
629 0 : rFormat = 0;
630 :
631 0 : OUString sTemp(sParams);
632 : pFormatter->PutandConvertEntry(sTemp, nCheckPos, nType, rFormat,
633 0 : LANGUAGE_ENGLISH_US, rLang);
634 0 : sParams = sTemp;
635 :
636 0 : return bHasTime ? NUMBERFORMAT_DATETIME : NUMBERFORMAT_DATE;
637 : }
638 :
639 : sal_uLong nFmtIdx =
640 : sw::ms::MSDateTimeFormatToSwFormat(sParams, pFormatter, rLang, bHijri,
641 0 : GetFib().lid);
642 0 : short nNumFmtType = NUMBERFORMAT_UNDEFINED;
643 0 : if (nFmtIdx)
644 0 : nNumFmtType = pFormatter->GetType(nFmtIdx);
645 0 : rFormat = nFmtIdx;
646 :
647 0 : return nNumFmtType;
648 : }
649 :
650 : //-----------------------------------------
651 : // Felder
652 : //-----------------------------------------
653 : // Am Ende des Einlesens entsprechende Felder updaten ( z.Zt. die Referenzen )
654 37 : void SwWW8ImplReader::UpdateFields()
655 : {
656 37 : rDoc.SetUpdateExpFldStat(true); // JP: neu fuer alles wichtige
657 37 : rDoc.SetInitDBFields(true); // Datenbank-Felder auch
658 37 : }
659 :
660 35 : sal_uInt16 SwWW8ImplReader::End_Field()
661 : {
662 35 : sal_uInt16 nRet = 0;
663 35 : WW8PLCFx_FLD* pF = pPlcxMan->GetFld();
664 : OSL_ENSURE(pF, "WW8PLCFx_FLD - Pointer nicht da");
665 35 : if (!pF || !pF->EndPosIsFieldEnd())
666 20 : return nRet;
667 :
668 15 : const SvtFilterOptions &rOpt = SvtFilterOptions::Get();
669 15 : sal_Bool bUseEnhFields = rOpt.IsUseEnhancedFields();
670 :
671 : OSL_ENSURE(!maFieldStack.empty(), "Empty field stack\n");
672 15 : if (!maFieldStack.empty())
673 : {
674 : /*
675 : only hyperlinks currently need to be handled like this, for the other
676 : cases we have inserted a field not an attribute with an unknown end
677 : point
678 : */
679 15 : nRet = maFieldStack.back().mnFieldId;
680 15 : switch (nRet)
681 : {
682 : case 70:
683 0 : if (bUseEnhFields && pPaM!=NULL && pPaM->GetPoint()!=NULL) {
684 0 : SwPosition aEndPos = *pPaM->GetPoint();
685 0 : SwPaM aFldPam( maFieldStack.back().GetPtNode(), maFieldStack.back().GetPtCntnt(), aEndPos.nNode, aEndPos.nContent.GetIndex());
686 0 : IDocumentMarkAccess* pMarksAccess = rDoc.getIDocumentMarkAccess( );
687 : IFieldmark *pFieldmark = dynamic_cast<IFieldmark*>( pMarksAccess->makeFieldBookmark(
688 0 : aFldPam, maFieldStack.back().GetBookmarkName(), ODF_FORMTEXT ) );
689 : OSL_ENSURE(pFieldmark!=NULL, "hmmm; why was the bookmark not created?");
690 0 : if (pFieldmark!=NULL) {
691 0 : const IFieldmark::parameter_map_t& pParametersToAdd = maFieldStack.back().getParameters();
692 0 : pFieldmark->GetParameters()->insert(pParametersToAdd.begin(), pParametersToAdd.end());
693 0 : }
694 : }
695 : break;
696 : #if defined(WW_NATIVE_TOC)
697 : case 8: // TOX_INDEX
698 : case 13: // TOX_CONTENT
699 : case 88: // HYPERLINK
700 : case 37: // REF
701 : if (pPaM!=NULL && pPaM->GetPoint()!=NULL) {
702 :
703 : SwPosition aEndPos = *pPaM->GetPoint();
704 : SwPaM aFldPam( maFieldStack.back().GetPtNode(), maFieldStack.back().GetPtCntnt(), aEndPos.nNode, aEndPos.nContent.GetIndex());
705 : SwFieldBookmark *pFieldmark=(SwFieldBookmark*)rDoc.makeFieldBookmark(aFldPam, maFieldStack.back().GetBookmarkName(), maFieldStack.back().GetBookmarkType());
706 : OSL_ENSURE(pFieldmark!=NULL, "hmmm; why was the bookmark not created?");
707 : if (pFieldmark!=NULL) {
708 : const IFieldmark::parameter_map_t& pParametersToAdd = maFieldStack.back().getParameters();
709 : pFieldmark->GetParameters()->insert(pParameters.begin(), pParameters.end());
710 : }
711 : }
712 : break;
713 : #else
714 : case 88:
715 3 : pCtrlStck->SetAttr(*pPaM->GetPoint(),RES_TXTATR_INETFMT);
716 : break;
717 : #endif
718 : case 36:
719 : case 68:
720 : //Move outside the section associated with this type of field
721 0 : *pPaM->GetPoint() = maFieldStack.back().maStartPos;
722 : break;
723 : default:
724 12 : rtl::OUString aCode = maFieldStack.back().GetBookmarkCode();
725 12 : if ( !aCode.isEmpty() )
726 : {
727 : // Unhandled field with stored code
728 0 : SwPosition aEndPos = *pPaM->GetPoint();
729 : SwPaM aFldPam(
730 0 : maFieldStack.back().GetPtNode(), maFieldStack.back().GetPtCntnt(),
731 0 : aEndPos.nNode, aEndPos.nContent.GetIndex());
732 :
733 0 : IDocumentMarkAccess* pMarksAccess = rDoc.getIDocumentMarkAccess( );
734 :
735 : IFieldmark* pFieldmark = pMarksAccess->makeFieldBookmark(
736 : aFldPam,
737 0 : maFieldStack.back().GetBookmarkName(),
738 0 : ODF_UNHANDLED );
739 0 : if ( pFieldmark )
740 : {
741 0 : const IFieldmark::parameter_map_t& pParametersToAdd = maFieldStack.back().getParameters();
742 0 : pFieldmark->GetParameters()->insert(pParametersToAdd.begin(), pParametersToAdd.end());
743 0 : rtl::OUString sFieldId = rtl::OUString::valueOf( sal_Int32( maFieldStack.back().mnFieldId ) );
744 0 : pFieldmark->GetParameters()->insert(
745 : std::pair< rtl::OUString, uno::Any > (
746 : ODF_ID_PARAM,
747 0 : uno::makeAny( sFieldId ) ) );
748 0 : pFieldmark->GetParameters()->insert(
749 : std::pair< rtl::OUString, uno::Any > (
750 : ODF_CODE_PARAM,
751 0 : uno::makeAny( aCode ) ) );
752 :
753 0 : if ( maFieldStack.back().mnObjLocFc > 0 )
754 : {
755 : // Store the OLE object as an internal link
756 0 : String sOleId = rtl::OUString('_');
757 0 : sOleId += String::CreateFromInt32( maFieldStack.back().mnObjLocFc );
758 :
759 0 : SvStorageRef xSrc0 = pStg->OpenSotStorage(rtl::OUString(SL::aObjectPool));
760 0 : SvStorageRef xSrc1 = xSrc0->OpenSotStorage( sOleId, STREAM_READ );
761 :
762 : // Store it now!
763 0 : uno::Reference< embed::XStorage > xDocStg = GetDoc().GetDocStorage();
764 0 : if (xDocStg.is())
765 : {
766 0 : uno::Reference< embed::XStorage > xOleStg = xDocStg->openStorageElement(
767 0 : "OLELinks", embed::ElementModes::WRITE );
768 0 : SotStorageRef xObjDst = SotStorage::OpenOLEStorage( xOleStg, sOleId );
769 :
770 0 : if ( xObjDst.Is() )
771 : {
772 0 : xSrc1->CopyTo( xObjDst );
773 :
774 0 : if ( !xObjDst->GetError() )
775 0 : xObjDst->Commit();
776 : }
777 :
778 0 : uno::Reference< embed::XTransactedObject > xTransact( xOleStg, uno::UNO_QUERY );
779 0 : if ( xTransact.is() )
780 0 : xTransact->commit();
781 : }
782 :
783 : // Store the OLE Id as a parameter
784 0 : pFieldmark->GetParameters()->insert(
785 : std::pair< rtl::OUString, uno::Any >(
786 0 : ODF_OLE_PARAM, uno::makeAny( rtl::OUString( sOleId ) ) ) );
787 0 : }
788 :
789 0 : }
790 : }
791 :
792 12 : break;
793 : }
794 15 : maFieldStack.pop_back();
795 : }
796 15 : return nRet;
797 : }
798 :
799 0 : bool AcceptableNestedField(sal_uInt16 nFieldCode)
800 : {
801 0 : switch (nFieldCode)
802 : {
803 : #if defined(WW_NATIVE_TOC)
804 : case 8: // allow recursive field in TOC...
805 : case 13: // allow recursive field in TOC...
806 : #endif
807 : case 36:
808 : case 68:
809 : case 79:
810 : case 88:
811 : // Accept AutoTextList field as nested field.
812 : // Thus, the field result is imported as plain text.
813 : case 89:
814 0 : return true;
815 : default:
816 0 : return false;
817 : }
818 : }
819 :
820 15 : WW8FieldEntry::WW8FieldEntry(SwPosition &rPos, sal_uInt16 nFieldId) throw()
821 15 : : maStartPos(rPos), mnFieldId(nFieldId), mnObjLocFc(0)
822 : {
823 15 : }
824 :
825 15 : WW8FieldEntry::WW8FieldEntry(const WW8FieldEntry &rOther) throw()
826 15 : : maStartPos(rOther.maStartPos), mnFieldId(rOther.mnFieldId), mnObjLocFc(rOther.mnObjLocFc)
827 : {
828 15 : }
829 :
830 0 : void WW8FieldEntry::Swap(WW8FieldEntry &rOther) throw()
831 : {
832 0 : std::swap(maStartPos, rOther.maStartPos);
833 0 : std::swap(mnFieldId, rOther.mnFieldId);
834 0 : }
835 :
836 0 : WW8FieldEntry &WW8FieldEntry::operator=(const WW8FieldEntry &rOther) throw()
837 : {
838 0 : WW8FieldEntry aTemp(rOther);
839 0 : Swap(aTemp);
840 0 : return *this;
841 : }
842 :
843 0 : ::rtl::OUString WW8FieldEntry::GetBookmarkName()
844 : {
845 0 : return msBookmarkName;
846 : }
847 :
848 12 : ::rtl::OUString WW8FieldEntry::GetBookmarkCode()
849 : {
850 12 : return msMarkCode;
851 : }
852 :
853 0 : void WW8FieldEntry::SetBookmarkName(::rtl::OUString bookmarkName)
854 : {
855 0 : msBookmarkName=bookmarkName;
856 0 : }
857 :
858 0 : void WW8FieldEntry::SetBookmarkType(::rtl::OUString bookmarkType)
859 : {
860 0 : msMarkType=bookmarkType;
861 0 : }
862 :
863 0 : void WW8FieldEntry::SetBookmarkCode(::rtl::OUString bookmarkCode)
864 : {
865 0 : msMarkCode = bookmarkCode;
866 0 : }
867 :
868 :
869 0 : ::sw::mark::IFieldmark::parameter_map_t& WW8FieldEntry::getParameters() {
870 0 : return maParams;
871 : }
872 :
873 :
874 : // Read_Field liest ein Feld ein oder, wenn es nicht gelesen werden kann,
875 : // wird 0 zurueckgegeben, so dass das Feld vom Aufrufer textuell gelesen wird.
876 : // Returnwert: Gesamtlaenge des Feldes ( zum UEberlesen )
877 36 : long SwWW8ImplReader::Read_Field(WW8PLCFManResult* pRes)
878 : {
879 : typedef eF_ResT (SwWW8ImplReader:: *FNReadField)( WW8FieldDesc*, String& );
880 : enum Limits {eMax = 96};
881 : static FNReadField aWW8FieldTab[eMax+1] =
882 : {
883 : 0,
884 : &SwWW8ImplReader::Read_F_Input,
885 : 0,
886 : &SwWW8ImplReader::Read_F_Ref, // 3
887 : 0,
888 : 0,
889 : &SwWW8ImplReader::Read_F_Set, // 6
890 : 0,
891 : &SwWW8ImplReader::Read_F_Tox, // 8
892 : 0,
893 : 0,
894 : 0,
895 : &SwWW8ImplReader::Read_F_Seq, // 12
896 : &SwWW8ImplReader::Read_F_Tox, // 13
897 : &SwWW8ImplReader::Read_F_DocInfo, // 14
898 : &SwWW8ImplReader::Read_F_DocInfo, // 15
899 : &SwWW8ImplReader::Read_F_DocInfo, // 16
900 : &SwWW8ImplReader::Read_F_Author, // 17
901 : &SwWW8ImplReader::Read_F_DocInfo, // 18
902 : &SwWW8ImplReader::Read_F_DocInfo, // 19
903 : &SwWW8ImplReader::Read_F_DocInfo, // 20
904 : &SwWW8ImplReader::Read_F_DocInfo, // 21
905 : &SwWW8ImplReader::Read_F_DocInfo, // 22
906 : &SwWW8ImplReader::Read_F_DocInfo, // 23
907 : &SwWW8ImplReader::Read_F_DocInfo, // 24
908 : &SwWW8ImplReader::Read_F_DocInfo, // 25
909 : &SwWW8ImplReader::Read_F_Anz, // 26
910 : &SwWW8ImplReader::Read_F_Anz, // 27
911 : &SwWW8ImplReader::Read_F_Anz, // 28
912 : &SwWW8ImplReader::Read_F_FileName, // 29
913 : &SwWW8ImplReader::Read_F_TemplName, // 30
914 : &SwWW8ImplReader::Read_F_DateTime, // 31
915 : &SwWW8ImplReader::Read_F_DateTime, // 32
916 : &SwWW8ImplReader::Read_F_CurPage, // 33
917 : 0,
918 : 0,
919 : &SwWW8ImplReader::Read_F_IncludeText, // 36
920 : &SwWW8ImplReader::Read_F_PgRef, // 37
921 : &SwWW8ImplReader::Read_F_InputVar, // 38
922 : &SwWW8ImplReader::Read_F_Input, // 39
923 : 0,
924 : &SwWW8ImplReader::Read_F_DBNext, // 41
925 : 0,
926 : 0,
927 : &SwWW8ImplReader::Read_F_DBNum, // 44
928 : 0,
929 : 0,
930 : 0,
931 : 0,
932 : &SwWW8ImplReader::Read_F_Equation, // 49
933 : 0,
934 : &SwWW8ImplReader::Read_F_Macro, // 51
935 : &SwWW8ImplReader::Read_F_ANumber, // 52
936 : &SwWW8ImplReader::Read_F_ANumber, // 53
937 : &SwWW8ImplReader::Read_F_ANumber, // 54
938 : 0,
939 :
940 :
941 : 0, // 56
942 :
943 :
944 : &SwWW8ImplReader::Read_F_Symbol, // 57
945 : &SwWW8ImplReader::Read_F_Embedd, // 58
946 : &SwWW8ImplReader::Read_F_DBField, // 59
947 : 0,
948 : 0,
949 : 0,
950 : 0,
951 : &SwWW8ImplReader::Read_F_DocInfo, // 64 - DOCVARIABLE
952 : 0,
953 : 0,
954 : &SwWW8ImplReader::Read_F_IncludePicture, // 67
955 : &SwWW8ImplReader::Read_F_IncludeText, // 68
956 : 0,
957 : &SwWW8ImplReader::Read_F_FormTextBox, // 70
958 : &SwWW8ImplReader::Read_F_FormCheckBox, // 71
959 : &SwWW8ImplReader::Read_F_NoteReference, // 72
960 : 0, /*&SwWW8ImplReader::Read_F_Tox*/
961 : 0,
962 : 0,
963 : 0,
964 : 0,
965 : 0,
966 : 0,
967 : 0,
968 : 0,
969 : 0,
970 : &SwWW8ImplReader::Read_F_FormListBox, // 83
971 : 0, // 84
972 : &SwWW8ImplReader::Read_F_DocInfo, // 85
973 : 0, // 86
974 : &SwWW8ImplReader::Read_F_OCX, // 87
975 : &SwWW8ImplReader::Read_F_Hyperlink, // 88
976 : 0, // 89
977 : 0, // 90
978 : &SwWW8ImplReader::Read_F_HTMLControl, // 91
979 : 0, // 92
980 : 0, // 93
981 : 0, // 94
982 : &SwWW8ImplReader::Read_F_Shape, // 95
983 : 0 // eMax - Dummy leer Methode
984 : };
985 : OSL_ENSURE( ( sizeof( aWW8FieldTab ) / sizeof( *aWW8FieldTab ) == eMax+1 ),
986 : "FeldFunc-Tabelle stimmt nicht" );
987 :
988 36 : WW8PLCFx_FLD* pF = pPlcxMan->GetFld();
989 : OSL_ENSURE(pF, "WW8PLCFx_FLD - Pointer nicht da");
990 :
991 36 : if (!pF || !pF->StartPosIsFieldStart())
992 21 : return 0;
993 :
994 15 : bool bNested = false;
995 15 : if (!maFieldStack.empty())
996 : {
997 0 : mycFieldIter aEnd = maFieldStack.end();
998 0 : for(mycFieldIter aIter = maFieldStack.begin(); aIter != aEnd; ++aIter)
999 : {
1000 0 : bNested = !AcceptableNestedField(aIter->mnFieldId);
1001 0 : if (bNested)
1002 0 : break;
1003 : }
1004 : }
1005 :
1006 : WW8FieldDesc aF;
1007 15 : bool bOk = pF->GetPara(pRes->nCp2OrIdx, aF);
1008 :
1009 : OSL_ENSURE(bOk, "WW8: Bad Field!\n");
1010 15 : if (aF.nId == 33) aF.bCodeNest=false; // do not recurse into nested page fields
1011 15 : bool bCodeNest = aF.bCodeNest;
1012 15 : if ( aF.nId == 6 ) bCodeNest = false; // We can handle them and loose the inner data
1013 :
1014 15 : maFieldStack.push_back(WW8FieldEntry(*pPaM->GetPoint(), aF.nId));
1015 :
1016 15 : if (bNested)
1017 0 : return 0;
1018 :
1019 15 : sal_uInt16 n = (aF.nId <= eMax) ? aF.nId : static_cast<sal_uInt16>(eMax);
1020 15 : sal_uInt16 nI = n / 32; // # des sal_uInt32
1021 15 : sal_uLong nMask = 1 << ( n % 32 ); // Maske fuer Bits
1022 :
1023 15 : if ((sizeof(nFieldTagAlways)/sizeof(nFieldTagAlways[0])) <= nI)
1024 : { // if indexes larger than 95 are needed, then a new configuration
1025 : // item has to be added, and nFieldTagAlways/nFieldTagBad expanded!
1026 0 : return aF.nLen;
1027 : }
1028 :
1029 15 : if( nFieldTagAlways[nI] & nMask ) // Flag: Tag it
1030 0 : return Read_F_Tag( &aF ); // Resultat nicht als Text
1031 :
1032 15 : if( !bOk || !aF.nId ) // Feld kaputt
1033 0 : return aF.nLen; // -> ignorieren
1034 :
1035 15 : if( aF.nId > eMax - 1) // WW: Nested Field
1036 : {
1037 0 : if( nFieldTagBad[nI] & nMask ) // Flag: Tag it when bad
1038 0 : return Read_F_Tag( &aF ); // Resultat nicht als Text
1039 : else
1040 0 : return aF.nLen;
1041 : }
1042 :
1043 : //Only one type of field (hyperlink) in drawing textboxes exists
1044 15 : if (aF.nId != 88 && pPlcxMan && pPlcxMan->GetDoingDrawTextBox())
1045 0 : return aF.nLen;
1046 :
1047 : // keine Routine vorhanden
1048 15 : if (bNested || !aWW8FieldTab[aF.nId] || bCodeNest)
1049 : {
1050 0 : if( nFieldTagBad[nI] & nMask ) // Flag: Tag it when bad
1051 0 : return Read_F_Tag( &aF ); // Resultat nicht als Text
1052 : // Lese nur Resultat
1053 0 : if (aF.bResNest && !AcceptableNestedField(aF.nId))
1054 0 : return aF.nLen; // Result nested -> nicht brauchbar
1055 :
1056 0 : long nOldPos = pStrm->Tell();
1057 0 : String aStr;
1058 0 : aF.nLCode = pSBase->WW8ReadString( *pStrm, aStr, pPlcxMan->GetCpOfs()+
1059 0 : aF.nSCode, aF.nLCode, eTextCharSet );
1060 0 : pStrm->Seek( nOldPos );
1061 :
1062 : // field codes which contain '/' or '.' are not displayed in WinWord
1063 0 : xub_StrLen nSpacePos = aStr.Search( ' ', 1 );
1064 0 : if ( STRING_NOTFOUND == nSpacePos )
1065 0 : nSpacePos = aStr.Len( );
1066 0 : xub_StrLen nSearchPos = STRING_NOTFOUND;
1067 0 : if ( !( aStr.EqualsAscii( "=", 1, 1 ) ) && (
1068 : ( ( nSearchPos = aStr.Search('.') ) != STRING_NOTFOUND && nSearchPos < nSpacePos ) ||
1069 : ( ( nSearchPos = aStr.Search('/') ) != STRING_NOTFOUND && nSearchPos < nSpacePos ) ) )
1070 0 : return aF.nLen;
1071 : else
1072 : {
1073 : // Link fields aren't supported, but they are bound to an OLE object
1074 : // that needs to be roundtripped
1075 0 : if ( aF.nId == 56 )
1076 0 : bEmbeddObj = true;
1077 : // Field not supported: store the field code for later use
1078 0 : maFieldStack.back().SetBookmarkCode( aStr );
1079 0 : return aF.nLen - aF.nLRes - 1; // so viele ueberlesen, das Resultfeld
1080 : // wird wie Haupttext eingelesen
1081 0 : }
1082 : }
1083 : else
1084 : { // Lies Feld
1085 15 : long nOldPos = pStrm->Tell();
1086 15 : String aStr;
1087 15 : if ( aF.nId == 6 && aF.bCodeNest )
1088 : {
1089 : // TODO Extract the whole code string using the nested codes
1090 0 : aF.nLCode = pSBase->WW8ReadString( *pStrm, aStr, pPlcxMan->GetCpOfs() +
1091 0 : aF.nSCode, aF.nSRes - aF.nSCode - 1, eTextCharSet );
1092 : }
1093 : else
1094 : {
1095 15 : aF.nLCode = pSBase->WW8ReadString( *pStrm, aStr, pPlcxMan->GetCpOfs()+
1096 30 : aF.nSCode, aF.nLCode, eTextCharSet );
1097 : }
1098 :
1099 : // #i51312# - graphics inside field code not supported by Writer.
1100 : // Thus, delete character 0x01, which stands for such a graphic.
1101 15 : if (aF.nId==51) //#i56768# only do it for the MACROBUTTON field, since DropListFields need the 0x01.
1102 : {
1103 0 : aStr = comphelper::string::remove(aStr, 0x01);
1104 : }
1105 :
1106 15 : eF_ResT eRes = (this->*aWW8FieldTab[aF.nId])( &aF, aStr );
1107 15 : pStrm->Seek( nOldPos );
1108 :
1109 15 : switch ( eRes )
1110 : {
1111 : case FLD_OK:
1112 5 : return aF.nLen; // alles OK
1113 : case FLD_TAGTXT:
1114 0 : if ((nFieldTagBad[nI] & nMask)) // Flag: Tag bad
1115 0 : return Read_F_Tag(&aF); // Taggen
1116 : //fall through...
1117 : case FLD_TEXT:
1118 : // so viele ueberlesen, das Resultfeld wird wie Haupttext
1119 : // eingelesen
1120 : // attributes can start at char 0x14 so skip one
1121 : // char more back == "-2"
1122 10 : if (aF.nLRes)
1123 10 : return aF.nLen - aF.nLRes - 2;
1124 : else
1125 0 : return aF.nLen;
1126 : case FLD_TAGIGN:
1127 0 : if( ( nFieldTagBad[nI] & nMask ) ) // Flag: Tag bad
1128 0 : return Read_F_Tag( &aF ); // Taggen
1129 0 : return aF.nLen; // oder ignorieren
1130 : case FLD_READ_FSPA:
1131 0 : return aF.nLen - aF.nLRes - 2; // auf Char 1 positionieren
1132 : default:
1133 0 : return aF.nLen; // ignorieren
1134 15 : }
1135 : }
1136 : }
1137 :
1138 : //-----------------------------------------
1139 : // Felder Taggen
1140 : //-----------------------------------------
1141 :
1142 : // MakeTagString() gibt als Returnwert die Position des ersten
1143 : // CR / Zeilenende / Seitenumbruch in pText und wandelt auch nur bis dort
1144 : // Wenn keins dieser Sonderzeichen enthalten ist, wird 0 zurueckgeliefert.
1145 0 : void SwWW8ImplReader::MakeTagString( String& rStr, const String& rOrg )
1146 : {
1147 0 : rtl::OUString sHex("\\x");
1148 0 : bool bAllowCr = SwFltGetFlag( nFieldFlags, SwFltControlStack::TAGS_IN_TEXT )
1149 0 : || SwFltGetFlag( nFieldFlags, SwFltControlStack::ALLOW_FLD_CR );
1150 : sal_Unicode cChar;
1151 0 : rStr = rOrg;
1152 :
1153 0 : for( xub_StrLen nI = 0;
1154 0 : nI < rStr.Len() && rStr.Len() < (MAX_FIELDLEN - 4); ++nI )
1155 : {
1156 0 : bool bSetAsHex = false;
1157 0 : switch( cChar = rStr.GetChar( nI ) )
1158 : {
1159 : case 132: // Typographische Anfuehrungszeichen
1160 : case 148: // gegen normale tauschen
1161 : case 147:
1162 0 : rStr.SetChar( nI, '"' );
1163 0 : break;
1164 : case 19:
1165 0 : rStr.SetChar( nI, '{' );
1166 0 : break; // 19..21 zu {|}
1167 : case 20:
1168 0 : rStr.SetChar( nI, '|' );
1169 0 : break;
1170 : case 21:
1171 0 : rStr.SetChar( nI, '}' );
1172 0 : break;
1173 : case '\\': // \{|} per \ Taggen
1174 : case '{':
1175 : case '|':
1176 : case '}':
1177 0 : rStr.Insert( nI, '\\' );
1178 0 : ++nI;
1179 0 : break;
1180 : case 0x0b:
1181 : case 0x0c:
1182 : case 0x0d:
1183 0 : if( bAllowCr )
1184 0 : rStr.SetChar( nI, '\n' );
1185 : else
1186 0 : bSetAsHex = true;
1187 0 : break;
1188 : case 0xFE:
1189 : case 0xFF:
1190 0 : bSetAsHex = true;
1191 0 : break;
1192 : default:
1193 0 : bSetAsHex = 0x20 > cChar;
1194 0 : break;
1195 : }
1196 :
1197 0 : if( bSetAsHex )
1198 : {
1199 : //all Hex-Numbers with \x before
1200 0 : String sTmp( sHex );
1201 0 : if( cChar < 0x10 )
1202 0 : sTmp += '0';
1203 0 : sTmp += String::CreateFromInt32( cChar, 16 );
1204 0 : rStr.Replace( nI, 1 , sTmp );
1205 0 : nI += sTmp.Len() - 1;
1206 : }
1207 : }
1208 :
1209 0 : if( rStr.Len() > (MAX_FIELDLEN - 4))
1210 0 : rStr.Erase( MAX_FIELDLEN - 4 );
1211 0 : }
1212 :
1213 0 : void SwWW8ImplReader::InsertTagField( const sal_uInt16 nId, const String& rTagText )
1214 : {
1215 0 : String aName(rtl::OUString("WwFieldTag"));
1216 0 : if( SwFltGetFlag( nFieldFlags, SwFltControlStack::TAGS_DO_ID ) ) // Nummer?
1217 0 : aName += String::CreateFromInt32( nId ); // ausgeben ?
1218 :
1219 0 : if( SwFltGetFlag(nFieldFlags, SwFltControlStack::TAGS_IN_TEXT))
1220 : {
1221 0 : aName += rTagText; // als Txt taggen
1222 : rDoc.InsertString(*pPaM, aName,
1223 0 : IDocumentContentOperations::INS_NOHINTEXPAND);
1224 : }
1225 : else
1226 : { // normal tagggen
1227 :
1228 : SwFieldType* pFT = rDoc.InsertFldType(
1229 0 : SwSetExpFieldType( &rDoc, aName, nsSwGetSetExpType::GSE_STRING ) );
1230 0 : SwSetExpField aFld( (SwSetExpFieldType*)pFT, rTagText ); // SUB_INVISIBLE
1231 0 : sal_uInt16 nSubType = ( SwFltGetFlag( nFieldFlags, SwFltControlStack::TAGS_VISIBLE ) ) ? 0 : nsSwExtendedSubType::SUB_INVISIBLE;
1232 0 : aFld.SetSubType(nSubType | nsSwGetSetExpType::GSE_STRING);
1233 :
1234 0 : rDoc.InsertPoolItem( *pPaM, SwFmtFld( aFld ), 0 );
1235 0 : }
1236 0 : }
1237 :
1238 0 : long SwWW8ImplReader::Read_F_Tag( WW8FieldDesc* pF )
1239 : {
1240 0 : long nOldPos = pStrm->Tell();
1241 :
1242 0 : WW8_CP nStart = pF->nSCode - 1; // mit 0x19 am Anfang
1243 0 : long nL = pF->nLen; // Gesamtlaenge mit Resultat u. Nest
1244 0 : if( nL > MAX_FIELDLEN )
1245 0 : nL = MAX_FIELDLEN; // MaxLaenge, durch Quoten
1246 : // max. 4* so gross
1247 0 : String sFTxt;
1248 : nL = pSBase->WW8ReadString( *pStrm, sFTxt,
1249 0 : pPlcxMan->GetCpOfs() + nStart, nL, eStructCharSet);
1250 :
1251 :
1252 0 : String aTagText;
1253 0 : MakeTagString( aTagText, sFTxt );
1254 0 : InsertTagField( pF->nId, aTagText );
1255 :
1256 0 : pStrm->Seek( nOldPos );
1257 0 : return pF->nLen;
1258 : }
1259 :
1260 :
1261 : //-----------------------------------------
1262 : // normale Felder
1263 : //-----------------------------------------
1264 :
1265 0 : eF_ResT SwWW8ImplReader::Read_F_Input( WW8FieldDesc* pF, String& rStr )
1266 : {
1267 0 : String aDef;
1268 0 : String aQ;
1269 : long nRet;
1270 0 : WW8ReadFieldParams aReadParam( rStr );
1271 0 : while( -1 != ( nRet = aReadParam.SkipToNextToken() ))
1272 : {
1273 0 : switch( nRet )
1274 : {
1275 : case -2:
1276 0 : if( !aQ.Len() )
1277 0 : aQ = aReadParam.GetResult();
1278 0 : break;
1279 : case 'd':
1280 : case 'D':
1281 : {
1282 0 : xub_StrLen n = aReadParam.GoToTokenParam();
1283 0 : if( STRING_NOTFOUND != n )
1284 0 : aDef = aReadParam.GetResult();
1285 : }
1286 0 : break;
1287 : }
1288 : }
1289 0 : if( !aDef.Len() )
1290 0 : aDef = GetFieldResult( pF );
1291 :
1292 0 : if ( pF->nId != 0x01 ) // 0x01 fields have no result
1293 : {
1294 0 : SwInputField aFld( (SwInputFieldType*)rDoc.GetSysFldType( RES_INPUTFLD ),
1295 0 : aDef, aQ, INP_TXT, 0 ); // sichtbar ( geht z.Zt. nicht anders )
1296 0 : rDoc.InsertPoolItem( *pPaM, SwFmtFld( aFld ), 0 );
1297 : }
1298 :
1299 0 : return FLD_OK;
1300 : }
1301 :
1302 : // GetFieldResult alloziert einen String und liest das Feld-Resultat ein
1303 0 : String SwWW8ImplReader::GetFieldResult( WW8FieldDesc* pF )
1304 : {
1305 0 : long nOldPos = pStrm->Tell();
1306 :
1307 0 : WW8_CP nStart = pF->nSRes; // Start Resultat
1308 0 : long nL = pF->nLRes; // Laenge Resultat
1309 0 : if( !nL )
1310 0 : return aEmptyStr; // kein Resultat
1311 :
1312 0 : if( nL > MAX_FIELDLEN )
1313 0 : nL = MAX_FIELDLEN; // MaxLaenge, durch Quoten
1314 : // max. 4* so gross
1315 :
1316 0 : String sRes;
1317 0 : nL = pSBase->WW8ReadString( *pStrm, sRes, pPlcxMan->GetCpOfs() + nStart,
1318 0 : nL, eStructCharSet );
1319 :
1320 0 : pStrm->Seek( nOldPos );
1321 :
1322 : //replace CR 0x0D with LF 0x0A
1323 0 : sRes.SearchAndReplaceAll(0x0D, 0x0A);
1324 : //replace VT 0x0B with LF 0x0A
1325 0 : sRes.SearchAndReplaceAll(0x0B, 0x0A);
1326 0 : return sRes;
1327 : }
1328 :
1329 : /*
1330 : Bookmarks can be set with fields SET and ASK, and they can be referenced with
1331 : REF. When set, they behave like variables in writer, otherwise they behave
1332 : like normal bookmarks. We can check whether we should use a show variable
1333 : instead of a normal bookmark ref by converting to "show variable" at the end
1334 : of the document those refs which look for the content of a bookmark but whose
1335 : bookmarks were set with SET or ASK. (See SwWW8FltRefStack)
1336 :
1337 : The other piece of the puzzle is that refs that point to the "location" of the
1338 : bookmark will in word actually point to the last location where the bookmark
1339 : was set with SET or ASK, not the actual bookmark. This is only noticable when
1340 : a document sets the bookmark more than once. This is because word places the
1341 : true bookmark at the location of the last set, but the refs will display the
1342 : position of the first set before the ref.
1343 :
1344 : So what we will do is
1345 :
1346 : 1) keep a list of all bookmarks that were set, any bookmark names mentioned
1347 : here that are refed by content will be converted to show variables.
1348 :
1349 : 2) create pseudo bookmarks for every position that a bookmark is set with SET
1350 : or ASK but has no existing bookmark. We can then keep a map from the original
1351 : bookmark name to the new one. As we parse the document new pseudo names will
1352 : replace the older ones, so the map always contains the bookmark of the
1353 : location that msword itself would use.
1354 :
1355 : 3) word's bookmarks are case insensitive, writers are not. So we need to
1356 : map case different versions together, regardless of whether they are
1357 : variables or not.
1358 :
1359 : 4) when a reference is (first) SET or ASK, the bookmark associated with it
1360 : is placed around the 0x14 0x15 result part of the field. We will fiddle
1361 : the placement to be the writer equivalent of directly before and after
1362 : the field, which gives the same effect and meaning, to do so we must
1363 : get any bookmarks in the field range, and begin them immediately before
1364 : the set/ask field, and end them directly afterwards. MapBookmarkVariables
1365 : returns an identifier of the bookmark attribute to close after inserting
1366 : the appropriate set/ask field.
1367 : */
1368 0 : long SwWW8ImplReader::MapBookmarkVariables(const WW8FieldDesc* pF,
1369 : String &rOrigName, const String &rData)
1370 : {
1371 : OSL_ENSURE(pPlcxMan,"No pPlcxMan");
1372 : long nNo;
1373 : /*
1374 : If there was no bookmark associated with this set field, then we create a
1375 : pseudo one and insert it in the document.
1376 : */
1377 : sal_uInt16 nIndex;
1378 0 : pPlcxMan->GetBook()->MapName(rOrigName);
1379 : String sName = pPlcxMan->GetBook()->GetBookmark(
1380 0 : pF->nSCode, pF->nSCode + pF->nLen, nIndex);
1381 0 : if (sName.Len())
1382 : {
1383 0 : pPlcxMan->GetBook()->SetStatus(nIndex, BOOK_IGNORE);
1384 0 : nNo = nIndex;
1385 : }
1386 : else
1387 : {
1388 0 : sName = rtl::OUString("WWSetBkmk");
1389 0 : nNo = pReffingStck->aFieldVarNames.size()+1;
1390 0 : sName += String::CreateFromInt32(nNo);
1391 0 : nNo += pPlcxMan->GetBook()->GetIMax();
1392 : }
1393 0 : pReffedStck->NewAttr(*pPaM->GetPoint(),
1394 0 : SwFltBookmark(BookmarkToWriter(sName), rData, nNo, 0));
1395 0 : pReffingStck->aFieldVarNames[rOrigName] = sName;
1396 0 : return nNo;
1397 : }
1398 :
1399 : /*
1400 : Word can set a bookmark with set or with ask, such a bookmark is equivalent to
1401 : our variables, but until the end of a document we cannot be sure if a bookmark
1402 : is a variable or not, at the end we will have a list of reference names which
1403 : were set or asked, all bookmarks using the content of those bookmarks are
1404 : converted to show variables, those that reference the position of the field
1405 : can be left as references, because a bookmark is also inserted at the position
1406 : of a set or ask field, either by word, or in some special cases by the import
1407 : filter itself.
1408 : */
1409 0 : SwFltStackEntry *SwWW8FltRefStack::RefToVar(const SwField* pFld,
1410 : SwFltStackEntry &rEntry)
1411 : {
1412 0 : SwFltStackEntry *pRet=0;
1413 0 : if (pFld && RES_GETREFFLD == pFld->Which())
1414 : {
1415 : //Get the name of the ref field, and see if actually a variable
1416 0 : const String &rName = pFld->GetPar1();
1417 : ::std::map<String,String,SwWW8FltRefStack::ltstr>::const_iterator
1418 0 : aResult = aFieldVarNames.find(rName);
1419 :
1420 0 : if (aResult != aFieldVarNames.end())
1421 : {
1422 : SwGetExpField aFld( (SwGetExpFieldType*)
1423 0 : pDoc->GetSysFldType(RES_GETEXPFLD), rName, nsSwGetSetExpType::GSE_STRING, 0);
1424 0 : delete rEntry.pAttr;
1425 0 : SwFmtFld aTmp(aFld);
1426 0 : rEntry.pAttr = aTmp.Clone();
1427 0 : pRet = &rEntry;
1428 0 : }
1429 : }
1430 0 : return pRet;
1431 : }
1432 :
1433 0 : String SwWW8ImplReader::GetMappedBookmark(const String &rOrigName)
1434 : {
1435 0 : String sName(BookmarkToWriter(rOrigName));
1436 : OSL_ENSURE(pPlcxMan,"no pPlcxMan");
1437 0 : pPlcxMan->GetBook()->MapName(sName);
1438 :
1439 : //See if there has been a variable set with this name, if so get
1440 : //the pseudo bookmark name that was set with it.
1441 : ::std::map<String,String,SwWW8FltRefStack::ltstr>::const_iterator aResult =
1442 0 : pReffingStck->aFieldVarNames.find(sName);
1443 :
1444 0 : const String &rBkmName = (aResult == pReffingStck->aFieldVarNames.end())
1445 0 : ? sName : (*aResult).second;
1446 :
1447 0 : return rBkmName;
1448 : }
1449 :
1450 : // "ASK"
1451 0 : eF_ResT SwWW8ImplReader::Read_F_InputVar( WW8FieldDesc* pF, String& rStr )
1452 : {
1453 0 : String sOrigName;
1454 0 : String aQ;
1455 0 : String aDef;
1456 : long nRet;
1457 0 : WW8ReadFieldParams aReadParam( rStr );
1458 0 : while( -1 != ( nRet = aReadParam.SkipToNextToken() ))
1459 : {
1460 0 : switch( nRet )
1461 : {
1462 : case -2:
1463 0 : if (!sOrigName.Len())
1464 0 : sOrigName = aReadParam.GetResult();
1465 0 : else if( !aQ.Len() )
1466 0 : aQ = aReadParam.GetResult();
1467 0 : break;
1468 : case 'd':
1469 : case 'D':
1470 0 : if (STRING_NOTFOUND != aReadParam.GoToTokenParam())
1471 0 : aDef = aReadParam.GetResult();
1472 0 : break;
1473 : }
1474 : }
1475 :
1476 0 : if( !sOrigName.Len() )
1477 0 : return FLD_TAGIGN; // macht ohne Textmarke keinen Sinn
1478 :
1479 0 : String aResult(GetFieldResult(pF));
1480 :
1481 : //#i24377#, munge Default Text into title as we have only one slot
1482 : //available for aResult and aDef otherwise
1483 0 : if (aDef.Len())
1484 : {
1485 0 : if (aQ.Len())
1486 0 : aQ.AppendAscii(" - ");
1487 0 : aQ.Append(aDef);
1488 : }
1489 :
1490 0 : long nNo = MapBookmarkVariables(pF, sOrigName, aResult);
1491 :
1492 : SwSetExpFieldType* pFT = (SwSetExpFieldType*)rDoc.InsertFldType(
1493 0 : SwSetExpFieldType(&rDoc, sOrigName, nsSwGetSetExpType::GSE_STRING));
1494 0 : SwSetExpField aFld(pFT, aResult);
1495 0 : aFld.SetSubType(nsSwExtendedSubType::SUB_INVISIBLE | nsSwGetSetExpType::GSE_STRING);
1496 0 : aFld.SetInputFlag(true);
1497 0 : aFld.SetPromptText( aQ );
1498 :
1499 0 : rDoc.InsertPoolItem( *pPaM, SwFmtFld( aFld ), 0 );
1500 :
1501 0 : pReffedStck->SetAttr(*pPaM->GetPoint(), RES_FLTR_BOOKMARK, true, nNo);
1502 0 : return FLD_OK;
1503 : }
1504 :
1505 : // "AUTONR"
1506 0 : eF_ResT SwWW8ImplReader::Read_F_ANumber( WW8FieldDesc*, String& rStr )
1507 : {
1508 0 : if( !pNumFldType ){ // 1. Mal
1509 0 : SwSetExpFieldType aT( &rDoc, rtl::OUString("AutoNr"), nsSwGetSetExpType::GSE_SEQ );
1510 0 : pNumFldType = rDoc.InsertFldType( aT );
1511 : }
1512 : SwSetExpField aFld( (SwSetExpFieldType*)pNumFldType, aEmptyStr,
1513 0 : GetNumberPara( rStr ) );
1514 0 : aFld.SetValue( ++nFldNum );
1515 0 : rDoc.InsertPoolItem( *pPaM, SwFmtFld( aFld ), 0 );
1516 0 : return FLD_OK;
1517 : }
1518 :
1519 : // "SEQ"
1520 0 : eF_ResT SwWW8ImplReader::Read_F_Seq( WW8FieldDesc*, String& rStr )
1521 : {
1522 0 : String aSequenceName;
1523 0 : String aBook;
1524 0 : bool bCountOn = true;
1525 0 : String sStart;
1526 0 : SvxExtNumType eNumFormat = SVX_NUM_ARABIC;
1527 : long nRet;
1528 0 : WW8ReadFieldParams aReadParam( rStr );
1529 0 : while( -1 != ( nRet = aReadParam.SkipToNextToken() ))
1530 : {
1531 0 : switch( nRet )
1532 : {
1533 : case -2:
1534 0 : if( !aSequenceName.Len() )
1535 0 : aSequenceName = aReadParam.GetResult();
1536 0 : else if( !aBook.Len() )
1537 0 : aBook = aReadParam.GetResult();
1538 0 : break;
1539 :
1540 : case 'h':
1541 0 : break;
1542 :
1543 : case '*':
1544 0 : nRet = aReadParam.SkipToNextToken();
1545 0 : if( -2 == nRet )
1546 0 : eNumFormat = GetNumTypeFromName( aReadParam.GetResult() );
1547 0 : break;
1548 :
1549 : case 'r':
1550 0 : bCountOn = false;
1551 0 : nRet = aReadParam.SkipToNextToken();
1552 0 : if( -2 == nRet )
1553 0 : sStart = aReadParam.GetResult();
1554 0 : break;
1555 :
1556 : case 'c':
1557 0 : bCountOn = false;
1558 0 : break;
1559 :
1560 : case 'n':
1561 0 : bCountOn = true; // Nummer um eins erhoehen (default)
1562 0 : break;
1563 :
1564 : case 's': // Outline Level
1565 : //#i19682, what am I to do with this value
1566 0 : break;
1567 : }
1568 : }
1569 0 : if (!aSequenceName.Len() && !aBook.Len())
1570 0 : return FLD_TAGIGN;
1571 :
1572 : SwSetExpFieldType* pFT = (SwSetExpFieldType*)rDoc.InsertFldType(
1573 0 : SwSetExpFieldType( &rDoc, aSequenceName, nsSwGetSetExpType::GSE_SEQ ) );
1574 0 : SwSetExpField aFld( pFT, aEmptyStr, eNumFormat );
1575 :
1576 0 : if (sStart.Len())
1577 0 : aFld.SetFormula( ( aSequenceName += '=' ) += sStart );
1578 0 : else if (!bCountOn)
1579 0 : aFld.SetFormula(aSequenceName);
1580 :
1581 0 : rDoc.InsertPoolItem(*pPaM, SwFmtFld(aFld), 0);
1582 0 : return FLD_OK;
1583 : }
1584 :
1585 0 : eF_ResT SwWW8ImplReader::Read_F_DocInfo( WW8FieldDesc* pF, String& rStr )
1586 : {
1587 0 : sal_uInt16 nSub=0;
1588 : // RegInfoFormat, DefaultFormat fuer DocInfoFelder
1589 0 : sal_uInt16 nReg = DI_SUB_AUTHOR;
1590 0 : bool bDateTime = false;
1591 :
1592 0 : if( 85 == pF->nId )
1593 : {
1594 0 : String aDocProperty;
1595 0 : WW8ReadFieldParams aReadParam( rStr );
1596 : long nRet;
1597 0 : while( -1 != ( nRet = aReadParam.SkipToNextToken() ))
1598 : {
1599 0 : switch( nRet )
1600 : {
1601 : case -2:
1602 0 : if( !aDocProperty.Len() )
1603 0 : aDocProperty = aReadParam.GetResult();
1604 0 : break;
1605 : case '*':
1606 : //Skip over MERGEFORMAT
1607 0 : aReadParam.SkipToNextToken();
1608 0 : break;
1609 : }
1610 : }
1611 :
1612 0 : aDocProperty = comphelper::string::remove(aDocProperty, '"');
1613 :
1614 : /*
1615 : There are up to 26 fields that may be meant by 'DocumentProperty'.
1616 : Which of them is to be inserted here ?
1617 : This Problem can only be solved by implementing a name matching
1618 : method that compares the given Parameter String with the four
1619 : possible name sets (english, german, french, spanish)
1620 : */
1621 :
1622 : static const sal_Char* aName10 = "\x0F"; // SW field code
1623 : static const sal_Char* aName11 // German
1624 : = "TITEL";
1625 : static const sal_Char* aName12 // French
1626 : = "TITRE";
1627 : static const sal_Char* aName13 // English
1628 : = "TITLE";
1629 : static const sal_Char* aName14 // Spanish
1630 : = "TITRO";
1631 : static const sal_Char* aName20 = "\x15"; // SW filed code
1632 : static const sal_Char* aName21 // German
1633 : = "ERSTELLDATUM";
1634 : static const sal_Char* aName22 // French
1635 : = "CR\xC9\xC9";
1636 : static const sal_Char* aName23 // English
1637 : = "CREATED";
1638 : static const sal_Char* aName24 // Spanish
1639 : = "CREADO";
1640 : static const sal_Char* aName30 = "\x16"; // SW filed code
1641 : static const sal_Char* aName31 // German
1642 : = "ZULETZTGESPEICHERTZEIT";
1643 : static const sal_Char* aName32 // French
1644 : = "DERNIERENREGISTREMENT";
1645 : static const sal_Char* aName33 // English
1646 : = "SAVED";
1647 : static const sal_Char* aName34 // Spanish
1648 : = "MODIFICADO";
1649 : static const sal_Char* aName40 = "\x17"; // SW filed code
1650 : static const sal_Char* aName41 // German
1651 : = "ZULETZTGEDRUCKT";
1652 : static const sal_Char* aName42 // French
1653 : = "DERNI\xC8" "REIMPRESSION";
1654 : static const sal_Char* aName43 // English
1655 : = "LASTPRINTED";
1656 : static const sal_Char* aName44 // Spanish
1657 : = "HUPS PUPS";
1658 : static const sal_Char* aName50 = "\x18"; // SW filed code
1659 : static const sal_Char* aName51 // German
1660 : = "\xDC" "BERARBEITUNGSNUMMER";
1661 : static const sal_Char* aName52 // French
1662 : = "NUM\xC9" "RODEREVISION";
1663 : static const sal_Char* aName53 // English
1664 : = "REVISIONNUMBER";
1665 : static const sal_Char* aName54 // Spanish
1666 : = "SNUBBEL BUBBEL";
1667 : static const sal_uInt16 nFldCnt = 5;
1668 :
1669 : // additional fields are to be coded soon! :-)
1670 :
1671 : static const sal_uInt16 nLangCnt = 4;
1672 : static const sal_Char *aNameSet_26[nFldCnt][nLangCnt+1] =
1673 : {
1674 : {aName10, aName11, aName12, aName13, aName14},
1675 : {aName20, aName21, aName22, aName23, aName24},
1676 : {aName30, aName31, aName32, aName33, aName34},
1677 : {aName40, aName41, aName42, aName43, aName44},
1678 : {aName50, aName51, aName52, aName53, aName54}
1679 0 : };
1680 :
1681 0 : bool bFldFound= false;
1682 : sal_uInt16 nFIdx;
1683 0 : for(sal_uInt16 nLIdx=1; !bFldFound && (nLangCnt > nLIdx); ++nLIdx)
1684 : {
1685 0 : for(nFIdx = 0; !bFldFound && (nFldCnt > nFIdx); ++nFIdx)
1686 : {
1687 0 : if( aDocProperty.Equals( String( aNameSet_26[nFIdx][nLIdx],
1688 0 : RTL_TEXTENCODING_MS_1252 ) ) )
1689 : {
1690 0 : bFldFound = true;
1691 0 : pF->nId = aNameSet_26[nFIdx][0][0];
1692 : }
1693 : }
1694 : }
1695 :
1696 0 : if( !bFldFound )
1697 : {
1698 : SwDocInfoField aFld( (SwDocInfoFieldType*)
1699 0 : rDoc.GetSysFldType( RES_DOCINFOFLD ), DI_CUSTOM|nReg, aDocProperty, GetFieldResult( pF ) );
1700 0 : rDoc.InsertPoolItem(*pPaM, SwFmtFld(aFld), 0);
1701 :
1702 0 : return FLD_OK;
1703 0 : }
1704 : }
1705 :
1706 0 : switch( pF->nId )
1707 : {
1708 : case 14:
1709 : /* kann alle INFO-Vars!! */
1710 0 : nSub = DI_KEYS;
1711 0 : break;
1712 : case 15:
1713 0 : nSub = DI_TITEL;
1714 0 : break;
1715 : case 16:
1716 0 : nSub = DI_THEMA;
1717 0 : break;
1718 : case 18:
1719 0 : nSub = DI_KEYS;
1720 0 : break;
1721 : case 19:
1722 0 : nSub = DI_COMMENT;
1723 0 : break;
1724 : case 20:
1725 0 : nSub = DI_CHANGE;
1726 0 : nReg = DI_SUB_AUTHOR;
1727 0 : break;
1728 : case 21:
1729 0 : nSub = DI_CREATE;
1730 0 : nReg = DI_SUB_DATE;
1731 0 : bDateTime = true;
1732 0 : break;
1733 : case 23:
1734 0 : nSub = DI_PRINT;
1735 0 : nReg = DI_SUB_DATE;
1736 0 : bDateTime = true;
1737 0 : break;
1738 : case 24:
1739 0 : nSub = DI_DOCNO;
1740 0 : break;
1741 : case 22:
1742 0 : nSub = DI_CHANGE;
1743 0 : nReg = DI_SUB_DATE;
1744 0 : bDateTime = true;
1745 0 : break;
1746 : case 25:
1747 0 : nSub = DI_CHANGE;
1748 0 : nReg = DI_SUB_TIME;
1749 0 : bDateTime = true;
1750 0 : break;
1751 : case 64: // DOCVARIABLE
1752 0 : nSub = DI_CUSTOM;
1753 0 : break;
1754 : }
1755 :
1756 0 : sal_uInt32 nFormat = 0;
1757 :
1758 0 : sal_uInt16 nLang(0);
1759 0 : if (bDateTime)
1760 : {
1761 0 : short nDT = GetTimeDatePara(rStr, nFormat, nLang, pF->nId);
1762 0 : switch (nDT)
1763 : {
1764 : case NUMBERFORMAT_DATE:
1765 0 : nReg = DI_SUB_DATE;
1766 0 : break;
1767 : case NUMBERFORMAT_TIME:
1768 0 : nReg = DI_SUB_TIME;
1769 0 : break;
1770 : case NUMBERFORMAT_DATETIME:
1771 0 : nReg = DI_SUB_DATE;
1772 0 : break;
1773 : default:
1774 0 : nReg = DI_SUB_DATE;
1775 0 : break;
1776 : }
1777 : }
1778 :
1779 0 : String aData;
1780 : // Extract DOCVARIABLE varname
1781 0 : if ( 64 == pF->nId )
1782 : {
1783 0 : WW8ReadFieldParams aReadParam( rStr );
1784 : long nRet;
1785 0 : while( -1 != ( nRet = aReadParam.SkipToNextToken() ))
1786 : {
1787 0 : switch( nRet )
1788 : {
1789 : case -2:
1790 0 : if( !aData.Len() )
1791 0 : aData = aReadParam.GetResult();
1792 0 : break;
1793 : case '*':
1794 : //Skip over MERGEFORMAT
1795 0 : aReadParam.SkipToNextToken();
1796 0 : break;
1797 : }
1798 : }
1799 :
1800 0 : aData = comphelper::string::remove(aData, '"');
1801 : }
1802 :
1803 : SwDocInfoField aFld( (SwDocInfoFieldType*)
1804 0 : rDoc.GetSysFldType( RES_DOCINFOFLD ), nSub|nReg, aData, nFormat );
1805 0 : if (bDateTime)
1806 0 : ForceFieldLanguage(aFld, nLang);
1807 0 : rDoc.InsertPoolItem(*pPaM, SwFmtFld(aFld), 0);
1808 :
1809 0 : return FLD_OK;
1810 : }
1811 :
1812 0 : eF_ResT SwWW8ImplReader::Read_F_Author( WW8FieldDesc*, String& )
1813 : {
1814 : // SH: Das SwAuthorField bezeichnet nicht den urspruenglichen
1815 : // Autor, sondern den aktuellen Benutzer, also besser ueber DocInfo
1816 : SwDocInfoField aFld( (SwDocInfoFieldType*)
1817 0 : rDoc.GetSysFldType( RES_DOCINFOFLD ),
1818 0 : DI_CREATE|DI_SUB_AUTHOR, String() );
1819 0 : rDoc.InsertPoolItem( *pPaM, SwFmtFld( aFld ), 0 );
1820 0 : return FLD_OK;
1821 : }
1822 :
1823 0 : eF_ResT SwWW8ImplReader::Read_F_TemplName( WW8FieldDesc*, String& )
1824 : {
1825 : SwTemplNameField aFld( (SwTemplNameFieldType*)
1826 0 : rDoc.GetSysFldType( RES_TEMPLNAMEFLD ), FF_NAME );
1827 0 : rDoc.InsertPoolItem( *pPaM, SwFmtFld( aFld ), 0 );
1828 0 : return FLD_OK;
1829 : }
1830 :
1831 : // Sowohl das Datum- wie auch das Uhrzeit-Feld kann fuer Datum, fuer Uhrzeit
1832 : // oder fuer beides benutzt werden.
1833 0 : eF_ResT SwWW8ImplReader::Read_F_DateTime( WW8FieldDesc*pF, String& rStr )
1834 : {
1835 0 : bool bHijri = false;
1836 0 : WW8ReadFieldParams aReadParam(rStr);
1837 : long nTok;
1838 0 : while (-1 != (nTok = aReadParam.SkipToNextToken()))
1839 : {
1840 0 : switch (nTok)
1841 : {
1842 : default:
1843 : case 'l':
1844 : case -2:
1845 0 : break;
1846 : case 'h':
1847 0 : bHijri = true;
1848 0 : break;
1849 : case 's':
1850 : //Saka Calendar, should we do something with this ?
1851 0 : break;
1852 : }
1853 : }
1854 :
1855 0 : sal_uInt32 nFormat = 0;
1856 :
1857 0 : sal_uInt16 nLang(0);
1858 0 : short nDT = GetTimeDatePara(rStr, nFormat, nLang, ww::eDATE, bHijri);
1859 :
1860 0 : if( NUMBERFORMAT_UNDEFINED == nDT ) // no D/T-Formatstring
1861 : {
1862 0 : if (32 == pF->nId)
1863 : {
1864 0 : nDT = NUMBERFORMAT_TIME;
1865 : nFormat = rDoc.GetNumberFormatter()->GetFormatIndex(
1866 0 : NF_TIME_START, LANGUAGE_SYSTEM );
1867 : }
1868 : else
1869 : {
1870 0 : nDT = NUMBERFORMAT_DATE;
1871 : nFormat = rDoc.GetNumberFormatter()->GetFormatIndex(
1872 0 : NF_DATE_START, LANGUAGE_SYSTEM );
1873 : }
1874 : }
1875 :
1876 0 : if (nDT & NUMBERFORMAT_DATE)
1877 : {
1878 : SwDateTimeField aFld((SwDateTimeFieldType*)
1879 0 : rDoc.GetSysFldType(RES_DATETIMEFLD ), DATEFLD, nFormat);
1880 0 : ForceFieldLanguage(aFld, nLang);
1881 0 : rDoc.InsertPoolItem( *pPaM, SwFmtFld( aFld ), 0 );
1882 : }
1883 0 : else if (nDT == NUMBERFORMAT_TIME)
1884 : {
1885 : SwDateTimeField aFld((SwDateTimeFieldType*)
1886 0 : rDoc.GetSysFldType(RES_DATETIMEFLD), TIMEFLD, nFormat);
1887 0 : ForceFieldLanguage(aFld, nLang);
1888 0 : rDoc.InsertPoolItem( *pPaM, SwFmtFld( aFld ), 0 );
1889 : }
1890 :
1891 0 : return FLD_OK;
1892 : }
1893 :
1894 0 : eF_ResT SwWW8ImplReader::Read_F_FileName(WW8FieldDesc*, String &rStr)
1895 : {
1896 0 : SwFileNameFormat eType = FF_NAME;
1897 : long nRet;
1898 0 : WW8ReadFieldParams aReadParam(rStr);
1899 0 : while (-1 != (nRet = aReadParam.SkipToNextToken()))
1900 : {
1901 0 : switch (nRet)
1902 : {
1903 : case 'p':
1904 0 : eType = FF_PATHNAME;
1905 0 : break;
1906 : case '*':
1907 : //Skip over MERGEFORMAT
1908 0 : aReadParam.SkipToNextToken();
1909 0 : break;
1910 : default:
1911 : OSL_ENSURE(!this, "unknown option in FileName field");
1912 0 : break;
1913 : }
1914 : }
1915 :
1916 : SwFileNameField aFld(
1917 0 : (SwFileNameFieldType*)rDoc.GetSysFldType(RES_FILENAMEFLD), eType);
1918 0 : rDoc.InsertPoolItem(*pPaM, SwFmtFld(aFld), 0);
1919 0 : return FLD_OK;
1920 : }
1921 :
1922 0 : eF_ResT SwWW8ImplReader::Read_F_Anz( WW8FieldDesc* pF, String& rStr )
1923 : { // SeitenZahl - Feld
1924 0 : sal_uInt16 nSub = DS_PAGE;
1925 0 : switch ( pF->nId ){
1926 0 : case 27: nSub = DS_WORD; break; // Wordzahl
1927 0 : case 28: nSub = DS_CHAR; break; // Zeichenzahl
1928 : }
1929 : SwDocStatField aFld( (SwDocStatFieldType*)
1930 0 : rDoc.GetSysFldType( RES_DOCSTATFLD ), nSub,
1931 0 : GetNumberPara( rStr ) );
1932 0 : rDoc.InsertPoolItem( *pPaM, SwFmtFld( aFld ), 0 );
1933 0 : return FLD_OK;
1934 : }
1935 :
1936 5 : eF_ResT SwWW8ImplReader::Read_F_CurPage( WW8FieldDesc*, String& rStr )
1937 : {
1938 : // Seitennummer
1939 : SwPageNumberField aFld( (SwPageNumberFieldType*)
1940 5 : rDoc.GetSysFldType( RES_PAGENUMBERFLD ), PG_RANDOM,
1941 10 : GetNumberPara(rStr, true));
1942 :
1943 5 : rDoc.InsertPoolItem( *pPaM, SwFmtFld( aFld ), 0 );
1944 5 : return FLD_OK;
1945 : }
1946 :
1947 0 : eF_ResT SwWW8ImplReader::Read_F_Symbol( WW8FieldDesc*, String& rStr )
1948 : {
1949 : //e.g. #i20118#
1950 0 : String aQ;
1951 0 : String aName;
1952 0 : sal_Int32 nSize = 0;
1953 : long nRet;
1954 0 : WW8ReadFieldParams aReadParam( rStr );
1955 0 : while( -1 != ( nRet = aReadParam.SkipToNextToken() ))
1956 : {
1957 0 : switch( nRet )
1958 : {
1959 : case -2:
1960 0 : if( !aQ.Len() )
1961 0 : aQ = aReadParam.GetResult();
1962 0 : break;
1963 : case 'f':
1964 : case 'F':
1965 : {
1966 0 : xub_StrLen n = aReadParam.GoToTokenParam();
1967 0 : if( STRING_NOTFOUND != n )
1968 0 : aName = aReadParam.GetResult();
1969 : }
1970 0 : break;
1971 : case 's':
1972 : case 'S':
1973 : {
1974 0 : String aSiz;
1975 0 : xub_StrLen n = aReadParam.GoToTokenParam();
1976 0 : if (STRING_NOTFOUND != n)
1977 0 : aSiz = aReadParam.GetResult();
1978 0 : if (aSiz.Len())
1979 0 : nSize = aSiz.ToInt32() * 20; // pT -> twip
1980 : }
1981 0 : break;
1982 : }
1983 : }
1984 0 : if( !aQ.Len() )
1985 0 : return FLD_TAGIGN; // -> kein 0-Zeichen in Text
1986 :
1987 0 : if (sal_Unicode cChar = static_cast<sal_Unicode>(aQ.ToInt32()))
1988 : {
1989 0 : if (aName.Len()) // Font Name set ?
1990 : {
1991 : SvxFontItem aFont(FAMILY_DONTKNOW, aName, aEmptyStr,
1992 0 : PITCH_DONTKNOW, RTL_TEXTENCODING_SYMBOL, RES_CHRATR_FONT);
1993 0 : NewAttr(aFont); // new Font
1994 : }
1995 :
1996 0 : if (nSize > 0) //#i20118#
1997 : {
1998 0 : SvxFontHeightItem aSz(nSize, 100, RES_CHRATR_FONTSIZE);
1999 0 : NewAttr(aSz);
2000 : }
2001 :
2002 0 : rDoc.InsertString(*pPaM, rtl::OUString(cChar));
2003 :
2004 0 : if (nSize > 0)
2005 0 : pCtrlStck->SetAttr(*pPaM->GetPoint(), RES_CHRATR_FONTSIZE);
2006 0 : if (aName.Len())
2007 0 : pCtrlStck->SetAttr(*pPaM->GetPoint(), RES_CHRATR_FONT);
2008 : }
2009 : else
2010 : {
2011 0 : rDoc.InsertString(*pPaM, rtl::OUString("###"));
2012 : }
2013 :
2014 0 : return FLD_OK;
2015 : }
2016 :
2017 : // "EINBETTEN"
2018 4 : eF_ResT SwWW8ImplReader::Read_F_Embedd( WW8FieldDesc*, String& rStr )
2019 : {
2020 4 : String sHost;
2021 :
2022 : long nRet;
2023 4 : WW8ReadFieldParams aReadParam( rStr );
2024 13 : while( -1 != ( nRet = aReadParam.SkipToNextToken() ))
2025 : {
2026 5 : switch( nRet )
2027 : {
2028 : case -2:
2029 4 : sHost = aReadParam.GetResult();
2030 4 : break;
2031 :
2032 : case 's':
2033 : // use ObjectSize
2034 1 : break;
2035 : }
2036 : }
2037 :
2038 4 : if( bObj && nPicLocFc )
2039 0 : nObjLocFc = nPicLocFc;
2040 4 : bEmbeddObj = true;
2041 4 : return FLD_TEXT;
2042 : }
2043 :
2044 :
2045 : // "SET"
2046 0 : eF_ResT SwWW8ImplReader::Read_F_Set( WW8FieldDesc* pF, String& rStr )
2047 : {
2048 0 : String sOrigName;
2049 0 : String sVal;
2050 : long nRet;
2051 0 : WW8ReadFieldParams aReadParam( rStr );
2052 0 : while( -1 != ( nRet = aReadParam.SkipToNextToken() ))
2053 : {
2054 0 : switch( nRet )
2055 : {
2056 : case -2:
2057 0 : if( !sOrigName.Len() )
2058 0 : sOrigName = aReadParam.GetResult();
2059 0 : else if( !sVal.Len() )
2060 0 : sVal = aReadParam.GetResult();
2061 0 : break;
2062 : }
2063 : }
2064 :
2065 0 : long nNo = MapBookmarkVariables(pF,sOrigName,sVal);
2066 :
2067 : SwFieldType* pFT = rDoc.InsertFldType( SwSetExpFieldType( &rDoc, sOrigName,
2068 0 : nsSwGetSetExpType::GSE_STRING ) );
2069 0 : SwSetExpField aFld( (SwSetExpFieldType*)pFT, sVal, ULONG_MAX );
2070 0 : aFld.SetSubType(nsSwExtendedSubType::SUB_INVISIBLE | nsSwGetSetExpType::GSE_STRING);
2071 :
2072 0 : rDoc.InsertPoolItem( *pPaM, SwFmtFld( aFld ), 0 );
2073 :
2074 0 : pReffedStck->SetAttr(*pPaM->GetPoint(), RES_FLTR_BOOKMARK, true, nNo);
2075 :
2076 0 : return FLD_OK;
2077 : }
2078 :
2079 : // "REF"
2080 0 : eF_ResT SwWW8ImplReader::Read_F_Ref( WW8FieldDesc*, String& rStr )
2081 : { // Reference - Field
2082 0 : String sOrigBkmName;
2083 0 : REFERENCEMARK eFormat = REF_CONTENT;
2084 :
2085 : long nRet;
2086 0 : WW8ReadFieldParams aReadParam( rStr );
2087 0 : while( -1 != ( nRet = aReadParam.SkipToNextToken() ))
2088 : {
2089 0 : switch( nRet )
2090 : {
2091 : case -2:
2092 0 : if( !sOrigBkmName.Len() ) // get name of bookmark
2093 0 : sOrigBkmName = aReadParam.GetResult();
2094 0 : break;
2095 :
2096 : /* References to numbers in Word could be either to a numbered
2097 : paragraph or to a chapter number. However Word does not seem to
2098 : have the capability we do, of refering to the chapter number some
2099 : other bookmark is in. As a result, cross-references to chapter
2100 : numbers in a word document will be cross-references to a numbered
2101 : paragraph, being the chapter heading paragraph. As it happens, our
2102 : cross-references to numbered paragraphs will do the right thing
2103 : when the target is a numbered chapter heading, so there is no need
2104 : for us to use the REF_CHAPTER bookmark format on import.
2105 : */
2106 : case 'n':
2107 0 : eFormat = REF_NUMBER_NO_CONTEXT;
2108 0 : break;
2109 : case 'r':
2110 0 : eFormat = REF_NUMBER;
2111 0 : break;
2112 : case 'w':
2113 0 : eFormat = REF_NUMBER_FULL_CONTEXT;
2114 0 : break;
2115 :
2116 : case 'p':
2117 0 : eFormat = REF_UPDOWN;
2118 0 : break;
2119 : case 'h':
2120 0 : break;
2121 : default:
2122 : // unimplemented switch: just do 'nix nought nothing' :-)
2123 0 : break;
2124 : }
2125 : }
2126 :
2127 0 : String sBkmName(GetMappedBookmark(sOrigBkmName));
2128 :
2129 : SwGetRefField aFld(
2130 0 : (SwGetRefFieldType*)rDoc.GetSysFldType( RES_GETREFFLD ),
2131 0 : sBkmName,REF_BOOKMARK,0,eFormat);
2132 :
2133 0 : if (eFormat == REF_CONTENT)
2134 : {
2135 : /*
2136 : If we are just inserting the contents of the bookmark, then it
2137 : is possible that the bookmark is actually a variable, so we
2138 : must store it until the end of the document to see if it was,
2139 : in which case we'll turn it into a show variable
2140 : */
2141 0 : pReffingStck->NewAttr( *pPaM->GetPoint(), SwFmtFld(aFld) );
2142 0 : pReffingStck->SetAttr( *pPaM->GetPoint(), RES_TXTATR_FIELD);
2143 : }
2144 : else
2145 : {
2146 0 : rDoc.InsertPoolItem(*pPaM, SwFmtFld(aFld), 0);
2147 : }
2148 0 : return FLD_OK;
2149 : }
2150 :
2151 : // Note Reference - Field
2152 0 : eF_ResT SwWW8ImplReader::Read_F_NoteReference( WW8FieldDesc*, String& rStr )
2153 : {
2154 0 : String aBkmName;
2155 0 : bool bAboveBelow = false;
2156 :
2157 : long nRet;
2158 0 : WW8ReadFieldParams aReadParam( rStr );
2159 0 : while( -1 != ( nRet = aReadParam.SkipToNextToken() ))
2160 : {
2161 0 : switch( nRet )
2162 : {
2163 : case -2:
2164 0 : if( !aBkmName.Len() ) // get name of foot/endnote
2165 0 : aBkmName = aReadParam.GetResult();
2166 0 : break;
2167 : case 'r':
2168 : // activate flag 'Chapter Number'
2169 0 : break;
2170 : case 'p':
2171 0 : bAboveBelow = true;
2172 0 : break;
2173 : case 'h':
2174 0 : break;
2175 : default:
2176 : // unimplemented switch: just do 'nix nought nothing' :-)
2177 0 : break;
2178 : }
2179 : }
2180 :
2181 : // set Sequence No of corresponding Foot-/Endnote to Zero
2182 : // (will be corrected in
2183 : SwGetRefField aFld( (SwGetRefFieldType*)
2184 0 : rDoc.GetSysFldType( RES_GETREFFLD ), aBkmName, REF_FOOTNOTE, 0,
2185 0 : REF_ONLYNUMBER );
2186 0 : pReffingStck->NewAttr(*pPaM->GetPoint(), SwFmtFld(aFld));
2187 0 : pReffingStck->SetAttr(*pPaM->GetPoint(), RES_TXTATR_FIELD);
2188 0 : if (bAboveBelow)
2189 : {
2190 : SwGetRefField aFld2( (SwGetRefFieldType*)
2191 0 : rDoc.GetSysFldType( RES_GETREFFLD ),aBkmName, REF_FOOTNOTE, 0,
2192 0 : REF_UPDOWN );
2193 0 : pReffingStck->NewAttr(*pPaM->GetPoint(), SwFmtFld(aFld2));
2194 0 : pReffingStck->SetAttr(*pPaM->GetPoint(), RES_TXTATR_FIELD);
2195 : }
2196 0 : return FLD_OK;
2197 : }
2198 :
2199 : // "SEITENREF"
2200 0 : eF_ResT SwWW8ImplReader::Read_F_PgRef( WW8FieldDesc*, String& rStr )
2201 : {
2202 0 : String sOrigName;
2203 : long nRet;
2204 0 : WW8ReadFieldParams aReadParam( rStr );
2205 0 : while( -1 != ( nRet = aReadParam.SkipToNextToken() ))
2206 : {
2207 0 : switch( nRet )
2208 : {
2209 : case -2:
2210 0 : if( !sOrigName.Len() )
2211 0 : sOrigName = aReadParam.GetResult();
2212 0 : break;
2213 : }
2214 : }
2215 :
2216 0 : String sName(GetMappedBookmark(sOrigName));
2217 :
2218 : #if defined(WW_NATIVE_TOC)
2219 : if (1) {
2220 : ::rtl::OUString aBookmarkName("_REF");
2221 : maFieldStack.back().SetBookmarkName(aBookmarkName);
2222 : maFieldStack.back().SetBookmarkType(ODF_PAGEREF);
2223 : maFieldStack.back().AddParam(rtl::OUString(), sName);
2224 : return FLD_TEXT;
2225 : }
2226 : #endif
2227 :
2228 :
2229 : SwGetRefField aFld(
2230 0 : (SwGetRefFieldType*)rDoc.GetSysFldType( RES_GETREFFLD ), sName,
2231 0 : REF_BOOKMARK, 0, REF_PAGE );
2232 :
2233 0 : rDoc.InsertPoolItem( *pPaM, SwFmtFld( aFld ), 0 );
2234 0 : return FLD_OK;
2235 : }
2236 :
2237 : // "MACROSCHALTFL"ACHE"
2238 0 : eF_ResT SwWW8ImplReader::Read_F_Macro( WW8FieldDesc*, String& rStr)
2239 : {
2240 0 : String aName;
2241 0 : String aVText;
2242 : long nRet;
2243 0 : bool bNewVText = true;
2244 0 : bool bBracket = false;
2245 0 : WW8ReadFieldParams aReadParam( rStr );
2246 :
2247 0 : xub_StrLen nOffset = 0;
2248 :
2249 0 : while( -1 != ( nRet = aReadParam.SkipToNextToken() ))
2250 : {
2251 0 : switch( nRet )
2252 : {
2253 : case -2:
2254 0 : if( !aName.Len() )
2255 0 : aName = aReadParam.GetResult();
2256 0 : else if( !aVText.Len() || bBracket )
2257 : {
2258 0 : nOffset = aReadParam.GetTokenSttPtr() + 1;
2259 :
2260 0 : if( bBracket )
2261 0 : aVText += ' ';
2262 0 : aVText += aReadParam.GetResult();
2263 0 : if (bNewVText)
2264 : {
2265 0 : bBracket = aVText.EqualsIgnoreCaseAscii(rtl::OUString('['), 1, 0)
2266 0 : ? true : false;
2267 0 : bNewVText = false;
2268 : }
2269 0 : else if( aVText.GetChar( aVText.Len()-1 ) == ']' )
2270 0 : bBracket = false;
2271 : }
2272 0 : break;
2273 : }
2274 : }
2275 0 : if( !aName.Len() )
2276 0 : return FLD_TAGIGN; // makes no sense without Makro-Name
2277 :
2278 0 : aName.InsertAscii( "StarOffice.Standard.Modul1.", 0 );
2279 :
2280 : SwMacroField aFld( (SwMacroFieldType*)
2281 0 : rDoc.GetSysFldType( RES_MACROFLD ), aName, aVText );
2282 0 : rDoc.InsertPoolItem( *pPaM, SwFmtFld( aFld ), 0 );
2283 :
2284 :
2285 0 : WW8_CP nOldCp = pPlcxMan->Where();
2286 0 : WW8_CP nCp = nOldCp + nOffset;
2287 :
2288 0 : SwPaM aPaM(*pPaM);
2289 0 : aPaM.SetMark();
2290 0 : aPaM.Move(fnMoveBackward);
2291 0 : aPaM.Exchange();
2292 :
2293 0 : mpPostProcessAttrsInfo = new WW8PostProcessAttrsInfo(nCp, nCp, aPaM);
2294 :
2295 0 : return FLD_OK;
2296 : }
2297 :
2298 0 : WW8PostProcessAttrsInfo::WW8PostProcessAttrsInfo(WW8_CP nCpStart, WW8_CP nCpEnd,
2299 : SwPaM & rPaM)
2300 : : mbCopy(false),
2301 : mnCpStart(nCpStart),
2302 : mnCpEnd(nCpEnd),
2303 0 : mPaM(*rPaM.GetPoint(), *rPaM.GetMark()),
2304 0 : mItemSet(rPaM.GetDoc()->GetAttrPool(), RES_CHRATR_BEGIN, RES_PARATR_END - 1)
2305 : {
2306 0 : }
2307 :
2308 0 : bool CanUseRemoteLink(const String &rGrfName)
2309 : {
2310 0 : bool bUseRemote = false;
2311 : try
2312 : {
2313 : ::ucbhelper::Content aCnt(rGrfName,
2314 : uno::Reference< ucb::XCommandEnvironment >(),
2315 0 : comphelper::getProcessComponentContext() );
2316 0 : rtl::OUString aTitle;
2317 :
2318 0 : aCnt.getPropertyValue("Title") >>= aTitle;
2319 0 : bUseRemote = !aTitle.isEmpty();
2320 : }
2321 0 : catch ( ... )
2322 : {
2323 : // this file did not exist, so we will not set this as graphiclink
2324 0 : bUseRemote = false;
2325 : }
2326 0 : return bUseRemote;
2327 : }
2328 :
2329 : // "EINF"UGENGRAFIK"
2330 0 : eF_ResT SwWW8ImplReader::Read_F_IncludePicture( WW8FieldDesc*, String& rStr )
2331 : {
2332 0 : String aGrfName;
2333 0 : bool bEmbedded = true;
2334 :
2335 : long nRet;
2336 0 : WW8ReadFieldParams aReadParam( rStr );
2337 0 : while( -1 != ( nRet = aReadParam.SkipToNextToken() ))
2338 : {
2339 0 : switch( nRet )
2340 : {
2341 : case -2:
2342 0 : if (!aGrfName.Len())
2343 0 : ConvertFFileName(aGrfName, aReadParam.GetResult());
2344 0 : break;
2345 :
2346 : case 'd':
2347 0 : bEmbedded = false; // Embedded-Flag deaktivieren
2348 0 : break;
2349 :
2350 : case 'c':// den Converter-Namen ueberlesen
2351 0 : aReadParam.FindNextStringPiece();
2352 0 : break;
2353 : }
2354 : }
2355 :
2356 0 : if (!bEmbedded)
2357 0 : bEmbedded = !CanUseRemoteLink(aGrfName);
2358 :
2359 0 : if (!bEmbedded)
2360 : {
2361 : /*
2362 : Besonderheit:
2363 :
2364 : Wir setzen jetzt den Link ins Doc und merken uns den SwFlyFrmFmt.
2365 : Da wir ja unten auf jjeden Fall mit Return-Wert FLD_READ_FSPA enden,
2366 : wird der Skip-Wert so bemessen, dass das folgende Char-1 eingelesen
2367 : wird.
2368 : Wenn wir dann in SwWW8ImplReader::ImportGraf() reinlaufen, wird
2369 : erkannt, dass wir soeben einen Grafik-Link inserted haben und
2370 : das passende SwAttrSet wird ins Frame-Format eingesetzt.
2371 : */
2372 0 : SfxItemSet aFlySet( rDoc.GetAttrPool(), RES_FRMATR_BEGIN,
2373 0 : RES_FRMATR_END-1 );
2374 0 : aFlySet.Put( SwFmtAnchor( FLY_AS_CHAR ) );
2375 0 : aFlySet.Put( SwFmtVertOrient( 0, text::VertOrientation::TOP, text::RelOrientation::FRAME ));
2376 : pFlyFmtOfJustInsertedGraphic = rDoc.Insert( *pPaM,
2377 : aGrfName,
2378 : aEmptyStr,
2379 : 0, // Graphic*
2380 : &aFlySet,
2381 0 : 0, 0); // SwFrmFmt*
2382 : maGrfNameGenerator.SetUniqueGraphName(pFlyFmtOfJustInsertedGraphic,
2383 0 : INetURLObject(aGrfName).GetBase());
2384 : }
2385 0 : return FLD_READ_FSPA;
2386 : }
2387 :
2388 :
2389 0 : String wwSectionNamer::UniqueName()
2390 : {
2391 0 : String aName(msFileLinkSeed);
2392 0 : aName += String::CreateFromInt32(++mnFileSectionNo);
2393 0 : return mrDoc.GetUniqueSectionName(&aName);
2394 : }
2395 :
2396 : // "EINFUEGENTEXT"
2397 0 : eF_ResT SwWW8ImplReader::Read_F_IncludeText( WW8FieldDesc* /*pF*/, String& rStr )
2398 : {
2399 0 : String aPara;
2400 0 : String aBook;
2401 : long nRet;
2402 0 : WW8ReadFieldParams aReadParam( rStr );
2403 0 : while( -1 != ( nRet = aReadParam.SkipToNextToken() ))
2404 : {
2405 0 : switch( nRet )
2406 : {
2407 : case -2:
2408 0 : if( !aPara.Len() )
2409 0 : aPara = aReadParam.GetResult();
2410 0 : else if( !aBook.Len() )
2411 0 : aBook = aReadParam.GetResult();
2412 0 : break;
2413 : case '*':
2414 : //Skip over MERGEFORMAT
2415 0 : aReadParam.SkipToNextToken();
2416 0 : break;
2417 : }
2418 : }
2419 0 : ConvertFFileName(aPara, aPara);
2420 :
2421 0 : if (aBook.Len() && aBook.GetChar( 0 ) != '\\')
2422 : {
2423 : // Bereich aus Quelle ( kein Switch ) ?
2424 0 : ConvertUFName(aBook);
2425 0 : aPara += sfx2::cTokenSeperator;
2426 0 : aPara += sfx2::cTokenSeperator;
2427 0 : aPara += aBook;
2428 : }
2429 :
2430 : /*
2431 : ##509##
2432 : What we will do is insert a section to be linked to a file, but just in
2433 : case the file is not available we will fill in the section with the stored
2434 : content of this winword field as a fallback.
2435 : */
2436 0 : SwPosition aTmpPos(*pPaM->GetPoint());
2437 :
2438 : SwSectionData aSection(FILE_LINK_SECTION,
2439 0 : maSectionNameGenerator.UniqueName());
2440 0 : aSection.SetLinkFileName( aPara );
2441 0 : aSection.SetProtectFlag(true);
2442 :
2443 : SwSection *const pSection =
2444 0 : rDoc.InsertSwSection(*pPaM, aSection, 0, 0, false);
2445 : OSL_ENSURE(pSection, "no section inserted");
2446 0 : if (!pSection)
2447 0 : return FLD_TEXT;
2448 0 : const SwSectionNode* pSectionNode = pSection->GetFmt()->GetSectionNode();
2449 : OSL_ENSURE(pSectionNode, "no section node!");
2450 0 : if (!pSectionNode)
2451 0 : return FLD_TEXT;
2452 :
2453 0 : pPaM->GetPoint()->nNode = pSectionNode->GetIndex()+1;
2454 0 : pPaM->GetPoint()->nContent.Assign(pPaM->GetCntntNode(), 0 );
2455 :
2456 : //we have inserted a section before this point, so adjust pos
2457 : //for future page/section segment insertion
2458 0 : maSectionManager.PrependedInlineNode(aTmpPos, *pPaM->GetNode());
2459 :
2460 0 : return FLD_TEXT;
2461 : }
2462 :
2463 : // "SERIENDRUCKFELD"
2464 0 : eF_ResT SwWW8ImplReader::Read_F_DBField( WW8FieldDesc* pF, String& rStr )
2465 : {
2466 0 : String aName;
2467 : long nRet;
2468 0 : WW8ReadFieldParams aReadParam( rStr );
2469 0 : while( -1 != ( nRet = aReadParam.SkipToNextToken() ))
2470 : {
2471 0 : switch( nRet )
2472 : {
2473 : case -2:
2474 0 : if( !aName.Len() )
2475 0 : aName = aReadParam.GetResult();
2476 0 : break;
2477 : }
2478 : }
2479 0 : SwDBFieldType aD( &rDoc, aName, SwDBData() ); // Datenbank: Nichts
2480 :
2481 0 : SwFieldType* pFT = rDoc.InsertFldType( aD );
2482 0 : SwDBField aFld( (SwDBFieldType*)pFT );
2483 0 : aFld.SetFieldCode( rStr );
2484 :
2485 0 : String aResult;
2486 0 : pSBase->WW8ReadString( *pStrm, aResult, pPlcxMan->GetCpOfs()+
2487 0 : pF->nSRes, pF->nLRes, eTextCharSet );
2488 :
2489 0 : aFld.InitContent(aResult);
2490 :
2491 0 : rDoc.InsertPoolItem(*pPaM, SwFmtFld( aFld ), 0);
2492 :
2493 0 : return FLD_OK;
2494 : }
2495 :
2496 : // "N"ACHSTER"
2497 0 : eF_ResT SwWW8ImplReader::Read_F_DBNext( WW8FieldDesc*, String& )
2498 : {
2499 0 : SwDBNextSetFieldType aN;
2500 0 : SwFieldType* pFT = rDoc.InsertFldType( aN );
2501 : SwDBNextSetField aFld( (SwDBNextSetFieldType*)pFT, aEmptyStr, aEmptyStr,
2502 0 : SwDBData() ); // Datenbank: Nichts
2503 0 : rDoc.InsertPoolItem( *pPaM, SwFmtFld( aFld ), 0 );
2504 0 : return FLD_OK;
2505 : }
2506 :
2507 : // "DATENSATZ"
2508 0 : eF_ResT SwWW8ImplReader::Read_F_DBNum( WW8FieldDesc*, String& )
2509 : {
2510 0 : SwDBSetNumberFieldType aN;
2511 0 : SwFieldType* pFT = rDoc.InsertFldType( aN );
2512 : SwDBSetNumberField aFld( (SwDBSetNumberFieldType*)pFT,
2513 0 : SwDBData() ); // Datenbank: Nichts
2514 0 : rDoc.InsertPoolItem( *pPaM, SwFmtFld( aFld ), 0 );
2515 0 : return FLD_OK;
2516 : }
2517 :
2518 : /*
2519 : EQ , only the usage for
2520 : a. Combined Characters supported, must be exactly in the form that word
2521 : only accepts as combined charactersm, i.e.
2522 : eq \o(\s\up Y(XXX),\s\do Y(XXX))
2523 : b. Ruby Text supported, must be in the form that word recognizes as being
2524 : ruby text
2525 : ...
2526 : */
2527 0 : eF_ResT SwWW8ImplReader::Read_F_Equation( WW8FieldDesc*, String& rStr )
2528 : {
2529 0 : WW8ReadFieldParams aReadParam( rStr );
2530 0 : long cChar = aReadParam.SkipToNextToken();
2531 0 : if ('o' == cChar)
2532 0 : Read_SubF_Combined(aReadParam);
2533 0 : else if ('*' == cChar)
2534 0 : Read_SubF_Ruby(aReadParam);
2535 0 : return FLD_OK;
2536 : }
2537 :
2538 0 : void SwWW8ImplReader::Read_SubF_Combined( WW8ReadFieldParams& rReadParam)
2539 : {
2540 0 : String sCombinedCharacters;
2541 0 : if ((-2 == rReadParam.SkipToNextToken()) &&
2542 0 : rReadParam.GetResult().EqualsIgnoreCaseAscii(rtl::OUString('('), 1, 0))
2543 : {
2544 0 : for (int i=0;i<2;i++)
2545 : {
2546 0 : if ('s' == rReadParam.SkipToNextToken())
2547 : {
2548 0 : long cChar = rReadParam.SkipToNextToken();
2549 0 : if (-2 != rReadParam.SkipToNextToken())
2550 : break;
2551 0 : String sF = rReadParam.GetResult();
2552 0 : if ((('u' == cChar) && sF.EqualsIgnoreCaseAscii(rtl::OUString('p'), 1, 0))
2553 0 : || (('d' == cChar) && sF.EqualsIgnoreCaseAscii(rtl::OUString('o'), 1, 0)))
2554 : {
2555 0 : if (-2 == rReadParam.SkipToNextToken())
2556 : {
2557 0 : String sPart = rReadParam.GetResult();
2558 0 : xub_StrLen nBegin = sPart.Search('(');
2559 :
2560 : //Word disallows brackets in this field, which
2561 : //aids figuring out the case of an end of )) vs )
2562 0 : xub_StrLen nEnd = sPart.Search(')');
2563 :
2564 0 : if ((nBegin != STRING_NOTFOUND) &&
2565 : (nEnd != STRING_NOTFOUND))
2566 : {
2567 : sCombinedCharacters +=
2568 0 : sPart.Copy(nBegin+1,nEnd-nBegin-1);
2569 0 : }
2570 : }
2571 0 : }
2572 : }
2573 : }
2574 : }
2575 0 : if (sCombinedCharacters.Len())
2576 : {
2577 : SwCombinedCharField aFld((SwCombinedCharFieldType*)
2578 0 : rDoc.GetSysFldType(RES_COMBINED_CHARS),sCombinedCharacters);
2579 0 : rDoc.InsertPoolItem(*pPaM, SwFmtFld(aFld), 0);
2580 0 : }
2581 0 : }
2582 :
2583 0 : void SwWW8ImplReader::Read_SubF_Ruby( WW8ReadFieldParams& rReadParam)
2584 : {
2585 0 : sal_uInt16 nJustificationCode=0;
2586 0 : String sFontName;
2587 0 : sal_uInt32 nFontSize=0;
2588 0 : String sRuby;
2589 0 : String sText;
2590 : long nRet;
2591 0 : while( -1 != ( nRet = rReadParam.SkipToNextToken() ))
2592 : {
2593 0 : switch( nRet )
2594 : {
2595 : case -2:
2596 : {
2597 0 : String sTemp = rReadParam.GetResult();
2598 0 : if( sTemp.EqualsIgnoreCaseAscii( "jc", 0, 2 ) )
2599 : {
2600 0 : sTemp.Erase(0,2);
2601 0 : nJustificationCode = static_cast<sal_uInt16>(sTemp.ToInt32());
2602 : }
2603 0 : else if( sTemp.EqualsIgnoreCaseAscii( "hps", 0, 3 ) )
2604 : {
2605 0 : sTemp.Erase(0,3);
2606 0 : nFontSize= static_cast<sal_uInt32>(sTemp.ToInt32());
2607 : }
2608 0 : else if( sTemp.EqualsIgnoreCaseAscii( "Font:", 0, 5 ) )
2609 : {
2610 0 : sTemp.Erase(0,5);
2611 0 : sFontName = sTemp;
2612 0 : }
2613 : }
2614 0 : break;
2615 : case '*':
2616 0 : break;
2617 : case 'o':
2618 0 : while( -1 != ( nRet = rReadParam.SkipToNextToken() ))
2619 : {
2620 0 : if ('u' == nRet)
2621 : {
2622 0 : if (-2 == rReadParam.SkipToNextToken() &&
2623 0 : (rReadParam.GetResult().EqualsIgnoreCaseAscii(rtl::OUString('p'), 1, 0)))
2624 : {
2625 0 : if (-2 == rReadParam.SkipToNextToken())
2626 : {
2627 0 : String sPart = rReadParam.GetResult();
2628 0 : xub_StrLen nBegin = sPart.Search('(');
2629 :
2630 : //Word disallows brackets in this field,
2631 0 : xub_StrLen nEnd = sPart.Search(')');
2632 :
2633 0 : if ((nBegin != STRING_NOTFOUND) &&
2634 : (nEnd != STRING_NOTFOUND))
2635 : {
2636 0 : sRuby = sPart.Copy(nBegin+1,nEnd-nBegin-1);
2637 : }
2638 0 : if (STRING_NOTFOUND ==
2639 0 : (nBegin = sPart.Search(',',nEnd)))
2640 : {
2641 0 : nBegin = sPart.Search(';',nEnd);
2642 : }
2643 0 : nEnd = sPart.SearchBackward(')');
2644 0 : if ((nBegin != STRING_NOTFOUND) &&
2645 : (nEnd != STRING_NOTFOUND))
2646 : {
2647 0 : sText = sPart.Copy(nBegin+1,nEnd-nBegin-1);
2648 0 : }
2649 : }
2650 : }
2651 : }
2652 :
2653 : }
2654 0 : break;
2655 : }
2656 : }
2657 :
2658 : //Translate and apply
2659 0 : if (sRuby.Len() && sText.Len() && sFontName.Len() && nFontSize)
2660 : {
2661 0 : switch (nJustificationCode)
2662 : {
2663 : case 0:
2664 0 : nJustificationCode=1;
2665 0 : break;
2666 : case 1:
2667 0 : nJustificationCode=3;
2668 0 : break;
2669 : case 2:
2670 0 : nJustificationCode=4;
2671 0 : break;
2672 : default:
2673 : case 3:
2674 0 : nJustificationCode=0;
2675 0 : break;
2676 : case 4:
2677 0 : nJustificationCode=2;
2678 0 : break;
2679 : }
2680 :
2681 0 : SwFmtRuby aRuby(sRuby);
2682 0 : const SwCharFmt *pCharFmt=0;
2683 : //Make a guess at which of asian of western we should be setting
2684 : sal_uInt16 nScript;
2685 0 : if (pBreakIt->GetBreakIter().is())
2686 0 : nScript = pBreakIt->GetBreakIter()->getScriptType(sRuby, 0);
2687 : else
2688 0 : nScript = i18n::ScriptType::ASIAN;
2689 :
2690 : //Check to see if we already have a ruby charstyle that this fits
2691 : std::vector<const SwCharFmt*>::const_iterator aEnd =
2692 0 : aRubyCharFmts.end();
2693 0 : for(std::vector<const SwCharFmt*>::const_iterator aIter
2694 0 : = aRubyCharFmts.begin(); aIter != aEnd; ++aIter)
2695 : {
2696 : const SvxFontHeightItem &rFH =
2697 0 : ItemGet<SvxFontHeightItem>(*(*aIter),
2698 0 : GetWhichOfScript(RES_CHRATR_FONTSIZE,nScript));
2699 0 : if (rFH.GetHeight() == nFontSize*10)
2700 : {
2701 0 : const SvxFontItem &rF = ItemGet<SvxFontItem>(*(*aIter),
2702 0 : GetWhichOfScript(RES_CHRATR_FONT,nScript));
2703 0 : if (rF.GetFamilyName().Equals(sFontName))
2704 : {
2705 0 : pCharFmt=*aIter;
2706 0 : break;
2707 : }
2708 : }
2709 : }
2710 :
2711 : //Create a new char style if necessary
2712 0 : if (!pCharFmt)
2713 : {
2714 0 : SwCharFmt *pFmt=0;
2715 0 : String aNm;
2716 : //Take this as the base name
2717 0 : SwStyleNameMapper::FillUIName(RES_POOLCHR_RUBYTEXT,aNm);
2718 0 : aNm+=String::CreateFromInt32(aRubyCharFmts.size()+1);
2719 0 : pFmt = rDoc.MakeCharFmt(aNm,(SwCharFmt*)rDoc.GetDfltCharFmt());
2720 0 : SvxFontHeightItem aHeightItem(nFontSize*10, 100, RES_CHRATR_FONTSIZE);
2721 : SvxFontItem aFontItem(FAMILY_DONTKNOW,sFontName,
2722 0 : aEmptyStr,PITCH_DONTKNOW,RTL_TEXTENCODING_DONTKNOW, RES_CHRATR_FONT);
2723 0 : aHeightItem.SetWhich(GetWhichOfScript(RES_CHRATR_FONTSIZE,nScript));
2724 0 : aFontItem.SetWhich(GetWhichOfScript(RES_CHRATR_FONT,nScript));
2725 0 : pFmt->SetFmtAttr(aHeightItem);
2726 0 : pFmt->SetFmtAttr(aFontItem);
2727 0 : aRubyCharFmts.push_back(pFmt);
2728 0 : pCharFmt = pFmt;
2729 : }
2730 :
2731 : //Set the charstyle and justification
2732 0 : aRuby.SetCharFmtName(pCharFmt->GetName());
2733 0 : aRuby.SetCharFmtId(pCharFmt->GetPoolFmtId());
2734 0 : aRuby.SetAdjustment(nJustificationCode);
2735 :
2736 0 : NewAttr(aRuby);
2737 0 : rDoc.InsertString( *pPaM, sText );
2738 0 : pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_TXTATR_CJK_RUBY );
2739 0 : }
2740 0 : }
2741 :
2742 : //-----------------------------------------
2743 : // Verzeichnis-Felder
2744 : //-----------------------------------------
2745 :
2746 0 : static void lcl_toxMatchACSwitch( SwWW8ImplReader& /*rReader*/,
2747 : SwDoc& rDoc,
2748 : SwTOXBase& rBase,
2749 : WW8ReadFieldParams& rParam,
2750 : SwCaptionDisplay eCaptionType)
2751 : {
2752 0 : xub_StrLen n = rParam.GoToTokenParam();
2753 0 : if( STRING_NOTFOUND != n )
2754 : {
2755 0 : SwTOXType* pType = (SwTOXType*)rDoc.GetTOXType( TOX_ILLUSTRATIONS, 0);
2756 0 : rBase.RegisterToTOXType( *pType );
2757 0 : rBase.SetCaptionDisplay( eCaptionType );
2758 : // Read Sequence Name and store in TOXBase
2759 0 : String sSeqName( rParam.GetResult() );
2760 0 : lcl_ConvertSequenceName( sSeqName );
2761 0 : rBase.SetSequenceName( sSeqName );
2762 : }
2763 0 : }
2764 :
2765 : //For all outline styles that are not in the outline numbering add them here as
2766 : //custom extra styles
2767 0 : bool SwWW8ImplReader::AddExtraOutlinesAsExtraStyles(SwTOXBase& rBase)
2768 : {
2769 0 : bool bExtras = false;
2770 : //This is the case if the winword outline numbering is set while the
2771 : //writer one is not
2772 0 : for (sal_uInt16 nI = 0; nI < vColl.size(); ++nI)
2773 : {
2774 0 : SwWW8StyInf& rSI = vColl[nI];
2775 0 : if (rSI.IsOutline())
2776 : {
2777 0 : const SwTxtFmtColl *pFmt = (const SwTxtFmtColl*)(rSI.pFmt);
2778 0 : sal_uInt16 nStyleLevel = rSI.nOutlineLevel;
2779 0 : sal_uInt16 nMaxLevel = rBase.GetLevel();
2780 0 : if (
2781 0 : nStyleLevel != (pFmt->GetAttrOutlineLevel()-1) && //<-end,zhaojianwei
2782 : nStyleLevel < nMaxLevel
2783 : )
2784 : {
2785 0 : String sStyles(rBase.GetStyleNames(rSI.nOutlineLevel));
2786 0 : if( sStyles.Len())
2787 0 : sStyles += TOX_STYLE_DELIMITER;
2788 0 : sStyles += pFmt->GetName();
2789 0 : rBase.SetStyleNames(sStyles, rSI.nOutlineLevel);
2790 0 : bExtras = true;
2791 : }
2792 : }
2793 : }
2794 0 : return bExtras;
2795 : }
2796 :
2797 0 : static void EnsureMaxLevelForTemplates(SwTOXBase& rBase)
2798 : {
2799 : //If the TOC contains Template entries at levels > the evaluation level
2800 : //that was initially taken from the max normal outline level of the word TOC
2801 : //then we cannot use that for the evaluation level because writer cuts off
2802 : //all styles above that level, while word just cuts off the "standard"
2803 : //outline styles, we have no option but to expand to the highest level
2804 : //Word included.
2805 0 : if ((rBase.GetLevel() != MAXLEVEL) && (nsSwTOXElement::TOX_TEMPLATE & rBase.GetCreateType()))
2806 : {
2807 0 : for (sal_uInt16 nI = MAXLEVEL; nI > 0; --nI)
2808 : {
2809 0 : if (rBase.GetStyleNames(nI-1).Len())
2810 : {
2811 0 : rBase.SetLevel(nI);
2812 0 : break;
2813 : }
2814 : }
2815 : }
2816 0 : }
2817 :
2818 0 : static void lcl_toxMatchTSwitch(SwWW8ImplReader& rReader, SwTOXBase& rBase,
2819 : WW8ReadFieldParams& rParam)
2820 : {
2821 0 : xub_StrLen n = rParam.GoToTokenParam();
2822 0 : if( STRING_NOTFOUND != n )
2823 : {
2824 0 : String sParams( rParam.GetResult() );
2825 0 : if( sParams.Len() )
2826 : {
2827 0 : xub_StrLen nIndex = 0;
2828 :
2829 : // Delimiters between styles and style levels appears to allow both ; and ,
2830 :
2831 0 : String sTemplate( sParams.GetToken(0, ';', nIndex) );
2832 0 : if( STRING_NOTFOUND == nIndex )
2833 : {
2834 0 : nIndex=0;
2835 0 : sTemplate = sParams.GetToken(0, ',', nIndex);
2836 : }
2837 0 : if( STRING_NOTFOUND == nIndex )
2838 : {
2839 0 : const SwFmt* pStyle = rReader.GetStyleWithOrgWWName(sTemplate);
2840 0 : if( pStyle )
2841 0 : sTemplate = pStyle->GetName();
2842 : // Store Style for Level 0 into TOXBase
2843 0 : rBase.SetStyleNames( sTemplate, 0 );
2844 : }
2845 0 : else while( STRING_NOTFOUND != nIndex )
2846 : {
2847 0 : xub_StrLen nOldIndex=nIndex;
2848 : sal_uInt16 nLevel = static_cast<sal_uInt16>(
2849 0 : sParams.GetToken(0, ';', nIndex).ToInt32());
2850 0 : if( STRING_NOTFOUND == nIndex )
2851 : {
2852 0 : nIndex = nOldIndex;
2853 : nLevel = static_cast<sal_uInt16>(
2854 0 : sParams.GetToken(0, ',', nIndex).ToInt32());
2855 : }
2856 :
2857 0 : if( (0 < nLevel) && (MAXLEVEL >= nLevel) )
2858 : {
2859 0 : nLevel--;
2860 : // Store Style and Level into TOXBase
2861 : const SwFmt* pStyle
2862 0 : = rReader.GetStyleWithOrgWWName( sTemplate );
2863 :
2864 0 : if( pStyle )
2865 0 : sTemplate = pStyle->GetName();
2866 :
2867 0 : String sStyles( rBase.GetStyleNames( nLevel ) );
2868 0 : if( sStyles.Len() )
2869 0 : sStyles += TOX_STYLE_DELIMITER;
2870 0 : sStyles += sTemplate;
2871 0 : rBase.SetStyleNames( sStyles, nLevel );
2872 : }
2873 : // read next style name...
2874 0 : nOldIndex = nIndex;
2875 0 : sTemplate = sParams.GetToken(0, ';', nIndex);
2876 0 : if( STRING_NOTFOUND == nIndex )
2877 : {
2878 0 : nIndex=nOldIndex;
2879 0 : sTemplate = sParams.GetToken(0, ',', nIndex);
2880 : }
2881 0 : }
2882 0 : }
2883 : }
2884 0 : }
2885 :
2886 0 : sal_uInt16 wwSectionManager::CurrentSectionColCount() const
2887 : {
2888 0 : sal_uInt16 nIndexCols = 1;
2889 0 : if (!maSegments.empty())
2890 0 : nIndexCols = maSegments.back().maSep.ccolM1 + 1;
2891 0 : return nIndexCols;
2892 : }
2893 :
2894 : //Will there be a new pagebreak at this position (don't know what type
2895 : //until later)
2896 0 : bool wwSectionManager::WillHavePageDescHere(SwNodeIndex aIdx) const
2897 : {
2898 0 : bool bRet = false;
2899 0 : if (!maSegments.empty())
2900 : {
2901 0 : if (!maSegments.back().IsContinous() &&
2902 0 : maSegments.back().maStart == aIdx)
2903 : {
2904 0 : bRet = true;
2905 : }
2906 : }
2907 0 : return bRet;
2908 : }
2909 :
2910 0 : static sal_uInt16 lcl_GetMaxValidWordTOCLevel(const SwForm &rForm)
2911 : {
2912 : // GetFormMax() returns level + 1, hence the -1
2913 0 : sal_uInt16 nRet = rForm.GetFormMax()-1;
2914 :
2915 : // If the max of this type of TOC is greater than the max of a word
2916 : // possible toc, then clip to the word max
2917 0 : if (nRet > WW8ListManager::nMaxLevel)
2918 0 : nRet = WW8ListManager::nMaxLevel;
2919 :
2920 0 : return nRet;
2921 : }
2922 :
2923 0 : eF_ResT SwWW8ImplReader::Read_F_Tox( WW8FieldDesc* pF, String& rStr )
2924 : {
2925 : #if defined(WW_NATIVE_TOC)
2926 : if (1) {
2927 : ::rtl::OUString aBookmarkName("_TOC");
2928 : maFieldStack.back().SetBookmarkName(aBookmarkName);
2929 : maFieldStack.back().SetBookmarkType(ODF_TOC);
2930 : return FLD_TEXT;
2931 : }
2932 : #endif
2933 :
2934 0 : if (pF->nLRes < 3)
2935 0 : return FLD_TEXT; // ignore (#i25440#)
2936 :
2937 : TOXTypes eTox; // Baue ToxBase zusammen
2938 0 : switch( pF->nId )
2939 : {
2940 : case 8:
2941 0 : eTox = TOX_INDEX;
2942 0 : break;
2943 : case 13:
2944 0 : eTox = TOX_CONTENT;
2945 0 : break;
2946 : default:
2947 0 : eTox = TOX_USER;
2948 0 : break;
2949 : }
2950 :
2951 0 : sal_uInt16 nCreateOf = (eTox == TOX_CONTENT) ? nsSwTOXElement::TOX_OUTLINELEVEL : nsSwTOXElement::TOX_MARK;
2952 :
2953 0 : sal_uInt16 nIndexCols = 1;
2954 :
2955 0 : const SwTOXType* pType = rDoc.GetTOXType( eTox, 0 );
2956 0 : SwForm aOrigForm(eTox);
2957 0 : SwTOXBase* pBase = new SwTOXBase( pType, aOrigForm, nCreateOf, aEmptyStr );
2958 0 : pBase->SetProtected(maSectionManager.CurrentSectionIsProtected());
2959 0 : switch( eTox ){
2960 : case TOX_INDEX:
2961 : {
2962 0 : sal_uInt16 eOptions = nsSwTOIOptions::TOI_SAME_ENTRY | nsSwTOIOptions::TOI_CASE_SENSITIVE;
2963 :
2964 : // TOX_OUTLINELEVEL setzen wir genau dann, wenn
2965 : // die Parameter \o in 1 bis 9 liegen
2966 : // oder der Parameter \f existiert
2967 : // oder GARKEINE Switches Parameter angegeben sind.
2968 : long nRet;
2969 0 : WW8ReadFieldParams aReadParam( rStr );
2970 0 : while( -1 != ( nRet = aReadParam.SkipToNextToken() ))
2971 : {
2972 0 : switch( nRet )
2973 : {
2974 : case 'c':
2975 : {
2976 0 : xub_StrLen n = aReadParam.GoToTokenParam();
2977 0 : if( STRING_NOTFOUND != n )
2978 : {
2979 0 : String sParams( aReadParam.GetResult() );
2980 : // if NO String just ignore the \c
2981 0 : if( sParams.Len() )
2982 : {
2983 : nIndexCols =
2984 0 : static_cast<sal_uInt16>(sParams.ToInt32());
2985 0 : }
2986 : }
2987 : }
2988 0 : break;
2989 : case 'e':
2990 : {
2991 0 : xub_StrLen n = aReadParam.GoToTokenParam();
2992 0 : if( STRING_NOTFOUND != n ) // if NO String just ignore the \e
2993 : {
2994 0 : String sDelimiter( aReadParam.GetResult() );
2995 0 : SwForm aForm( pBase->GetTOXForm() );
2996 :
2997 : // Attention: if TOX_CONTENT brave
2998 : // GetFormMax() returns MAXLEVEL + 1 !!
2999 0 : sal_uInt16 nEnd = aForm.GetFormMax()-1;
3000 :
3001 0 : for(sal_uInt16 nLevel = 1;
3002 : nLevel <= nEnd;
3003 : ++nLevel)
3004 : {
3005 : // Levels count from 1
3006 : // Level 0 is reserved for CAPTION
3007 :
3008 : // Delimiter statt Tabstop vor der Seitenzahl einsetzen,
3009 : // falls es eine Seitenzahl gibt:
3010 0 : FormTokenType ePrevType = TOKEN_END;
3011 : FormTokenType eType;
3012 : // -> #i21237#
3013 : SwFormTokens aPattern =
3014 0 : aForm.GetPattern(nLevel);
3015 0 : SwFormTokens::iterator aIt = aPattern.begin();
3016 0 : do
3017 : {
3018 0 : eType = ++aIt == aPattern.end() ? TOKEN_END : aIt->eTokenType;
3019 :
3020 0 : if (eType == TOKEN_PAGE_NUMS)
3021 : {
3022 0 : if (TOKEN_TAB_STOP == ePrevType)
3023 : {
3024 0 : --aIt;
3025 :
3026 0 : if(0x09 == sDelimiter.GetChar(0))
3027 0 : aIt->eTabAlign = SVX_TAB_ADJUST_END;
3028 : else
3029 : {
3030 0 : SwFormToken aToken(TOKEN_TEXT);
3031 0 : aToken.sText = sDelimiter;
3032 0 : *aIt = aToken;
3033 : }
3034 0 : aForm.SetPattern(nLevel, aPattern);
3035 : }
3036 :
3037 0 : eType = TOKEN_END;
3038 : }
3039 :
3040 0 : ePrevType = eType;
3041 : }
3042 : while (TOKEN_END != eType);
3043 : // <- #i21237#
3044 0 : }
3045 0 : pBase->SetTOXForm( aForm );
3046 : }
3047 : }
3048 0 : break;
3049 : case 'h':
3050 : {
3051 0 : eOptions |= nsSwTOIOptions::TOI_ALPHA_DELIMITTER;
3052 : }
3053 0 : break;
3054 : }
3055 : }
3056 0 : pBase->SetOptions( eOptions );
3057 : }
3058 0 : break;
3059 :
3060 : case TOX_CONTENT:
3061 : {
3062 0 : bool bIsHyperlink = false;
3063 : // TOX_OUTLINELEVEL setzen wir genau dann, wenn
3064 : // die Parameter \o in 1 bis 9 liegen
3065 : // oder der Parameter \f existiert
3066 : // oder GARKEINE Switches Parameter angegeben sind.
3067 0 : sal_uInt16 eCreateFrom = 0;
3068 0 : sal_uInt16 nMaxLevel = 0;
3069 : long nRet;
3070 0 : WW8ReadFieldParams aReadParam( rStr );
3071 0 : while( -1 != ( nRet = aReadParam.SkipToNextToken() ))
3072 : {
3073 0 : switch( nRet )
3074 : {
3075 : case 'h':
3076 0 : bIsHyperlink = true;
3077 0 : break;
3078 : case 'a':
3079 : case 'c':
3080 : lcl_toxMatchACSwitch(*this, rDoc, *pBase, aReadParam,
3081 : ('c' == nRet)
3082 : ? CAPTION_COMPLETE
3083 0 : : CAPTION_TEXT );
3084 0 : break;
3085 : case 'o':
3086 : {
3087 : sal_uInt16 nVal;
3088 0 : if( !aReadParam.GetTokenSttFromTo(0, &nVal, WW8ListManager::nMaxLevel) )
3089 0 : nVal = lcl_GetMaxValidWordTOCLevel(aOrigForm);
3090 0 : if( nMaxLevel < nVal )
3091 0 : nMaxLevel = nVal;
3092 0 : eCreateFrom |= nsSwTOXElement::TOX_OUTLINELEVEL;
3093 : }
3094 0 : break;
3095 : case 'f':
3096 0 : eCreateFrom |= nsSwTOXElement::TOX_MARK;
3097 0 : break;
3098 : case 'l':
3099 : {
3100 : sal_uInt16 nVal;
3101 0 : if( aReadParam.GetTokenSttFromTo(0, &nVal, WW8ListManager::nMaxLevel) )
3102 : {
3103 0 : if( nMaxLevel < nVal )
3104 0 : nMaxLevel = nVal;
3105 0 : eCreateFrom |= nsSwTOXElement::TOX_MARK;
3106 : }
3107 : }
3108 0 : break;
3109 : case 't': // paragraphs using special styles shall
3110 : // provide the TOX's content
3111 0 : lcl_toxMatchTSwitch(*this, *pBase, aReadParam);
3112 0 : eCreateFrom |= nsSwTOXElement::TOX_TEMPLATE;
3113 0 : break;
3114 : case 'p':
3115 : {
3116 0 : xub_StrLen n = aReadParam.GoToTokenParam();
3117 0 : if( STRING_NOTFOUND != n ) // if NO String just ignore the \p
3118 : {
3119 0 : String sDelimiter( aReadParam.GetResult() );
3120 0 : SwForm aForm( pBase->GetTOXForm() );
3121 :
3122 : // Attention: if TOX_CONTENT brave
3123 : // GetFormMax() returns MAXLEVEL + 1 !!
3124 0 : sal_uInt16 nEnd = aForm.GetFormMax()-1;
3125 :
3126 0 : for(sal_uInt16 nLevel = 1;
3127 : nLevel <= nEnd;
3128 : ++nLevel)
3129 : {
3130 : // Levels count from 1
3131 : // Level 0 is reserved for CAPTION
3132 :
3133 : // Delimiter statt Tabstop vor der Seitenzahl einsetzen,
3134 : // falls es eine Seitenzahl gibt:
3135 0 : FormTokenType ePrevType = TOKEN_END;
3136 : FormTokenType eType;
3137 :
3138 : // -> #i21237#
3139 0 : SwFormTokens aPattern = aForm.GetPattern(nLevel);
3140 0 : SwFormTokens::iterator aIt = aPattern.begin();
3141 0 : do
3142 : {
3143 0 : eType = ++aIt == aPattern.end() ? TOKEN_END : aIt->eTokenType;
3144 :
3145 0 : if (eType == TOKEN_PAGE_NUMS)
3146 : {
3147 0 : if (TOKEN_TAB_STOP == ePrevType)
3148 : {
3149 0 : --aIt;
3150 :
3151 0 : SwFormToken aToken(TOKEN_TEXT);
3152 0 : aToken.sText = sDelimiter;
3153 :
3154 0 : *aIt = aToken;
3155 : aForm.SetPattern(nLevel,
3156 0 : aPattern);
3157 : }
3158 0 : eType = TOKEN_END;
3159 : }
3160 0 : ePrevType = eType;
3161 : }
3162 : while( TOKEN_END != eType );
3163 : // <- #i21237#
3164 0 : }
3165 0 : pBase->SetTOXForm( aForm );
3166 : }
3167 : }
3168 0 : break;
3169 : case 'n': // don't print page numbers
3170 : {
3171 : // read START and END param
3172 : sal_uInt16 nStart, nEnd;
3173 0 : if( !aReadParam.GetTokenSttFromTo( &nStart, &nEnd,
3174 0 : WW8ListManager::nMaxLevel ) )
3175 : {
3176 0 : nStart = 1;
3177 0 : nEnd = aOrigForm.GetFormMax()-1;
3178 : }
3179 : // remove page numbers from this levels
3180 0 : SwForm aForm( pBase->GetTOXForm() );
3181 0 : if (aForm.GetFormMax() <= nEnd)
3182 0 : nEnd = aForm.GetFormMax()-1;
3183 0 : for (
3184 0 : sal_uInt16 nLevel = nStart; nLevel <= nEnd;
3185 : ++nLevel
3186 : )
3187 : {
3188 : // Levels count from 1
3189 : // Level 0 is reserved for CAPTION
3190 :
3191 : // Seitenzahl und ggfs. davorstehenden Tabstop
3192 : // entfernen:
3193 : FormTokenType eType;
3194 : // -> #i21237#
3195 0 : SwFormTokens aPattern = aForm.GetPattern(nLevel);
3196 0 : SwFormTokens::iterator aIt = aPattern.begin();
3197 0 : do
3198 : {
3199 0 : eType = ++aIt == aPattern.end() ? TOKEN_END : aIt->eTokenType;
3200 :
3201 0 : if (eType == TOKEN_PAGE_NUMS)
3202 : {
3203 0 : aIt = aPattern.erase(aIt);
3204 0 : --aIt;
3205 0 : if (
3206 : TOKEN_TAB_STOP ==
3207 0 : aIt->eTokenType
3208 : )
3209 : {
3210 0 : aPattern.erase(aIt);
3211 0 : aForm.SetPattern(nLevel, aPattern);
3212 : }
3213 0 : eType = TOKEN_END;
3214 : }
3215 : }
3216 : while (TOKEN_END != eType);
3217 : // <- #i21237#
3218 0 : }
3219 0 : pBase->SetTOXForm( aForm );
3220 : }
3221 0 : break;
3222 :
3223 : /*
3224 : // the following switches are not (yet) supported
3225 : // by good old StarWriter:
3226 : case 'b':
3227 : case 's':
3228 : case 'd':
3229 : break;
3230 : */
3231 : }
3232 : }
3233 :
3234 0 : if (bIsHyperlink)
3235 : {
3236 0 : SwForm aForm(pBase->GetTOXForm());
3237 0 : sal_uInt16 nEnd = aForm.GetFormMax()-1;
3238 0 : SwFormToken aLinkStart(TOKEN_LINK_START);
3239 0 : SwFormToken aLinkEnd(TOKEN_LINK_END);
3240 :
3241 : // -> #i21237#
3242 0 : for(sal_uInt16 nLevel = 1; nLevel <= nEnd; ++nLevel)
3243 : {
3244 0 : SwFormTokens aPattern = aForm.GetPattern(nLevel);
3245 :
3246 0 : aPattern.insert(aPattern.begin(), aLinkStart);
3247 0 : aPattern.push_back(aLinkEnd);
3248 :
3249 0 : aForm.SetPattern(nLevel, aPattern);
3250 :
3251 0 : }
3252 : // <- #i21237#
3253 0 : pBase->SetTOXForm(aForm);
3254 : }
3255 :
3256 0 : if (!nMaxLevel)
3257 0 : nMaxLevel = WW8ListManager::nMaxLevel;
3258 0 : pBase->SetLevel(nMaxLevel);
3259 :
3260 0 : const TOXTypes eType = pBase->GetTOXType()->GetType();
3261 0 : switch( eType )
3262 : {
3263 : case TOX_CONTENT:
3264 : {
3265 : //If we would be created from outlines, either explictly or by default
3266 : //then see if we need extra styles added to the outlines
3267 0 : sal_uInt16 eEffectivelyFrom = eCreateFrom ? eCreateFrom : nsSwTOXElement::TOX_OUTLINELEVEL;
3268 0 : if (eEffectivelyFrom & nsSwTOXElement::TOX_OUTLINELEVEL)
3269 : {
3270 0 : if (AddExtraOutlinesAsExtraStyles(*pBase))
3271 0 : eCreateFrom |= (nsSwTOXElement::TOX_TEMPLATE | nsSwTOXElement::TOX_OUTLINELEVEL);
3272 :
3273 : // #i19683# Insert a text token " " between the number and entry token.
3274 : // In an ideal world we could handle the tab stop between the number and
3275 : // the entry correctly, but I currently have no clue how to obtain
3276 : // the tab stop position. It is _not_ set at the paragraph style.
3277 0 : SwForm* pForm = 0;
3278 0 : for (sal_uInt16 nI = 0; nI < vColl.size(); ++nI)
3279 : {
3280 0 : const SwWW8StyInf& rSI = vColl[nI];
3281 0 : if (rSI.IsOutlineNumbered())
3282 : {
3283 0 : sal_uInt16 nStyleLevel = rSI.nOutlineLevel;
3284 0 : const SwNumFmt& rFmt = rSI.GetOutlineNumrule()->Get( nStyleLevel );
3285 0 : if ( SVX_NUM_NUMBER_NONE != rFmt.GetNumberingType() )
3286 : {
3287 0 : ++nStyleLevel;
3288 :
3289 0 : if ( !pForm )
3290 0 : pForm = new SwForm( pBase->GetTOXForm() );
3291 :
3292 0 : SwFormTokens aPattern = pForm->GetPattern(nStyleLevel);
3293 : SwFormTokens::iterator aIt =
3294 : find_if(aPattern.begin(), aPattern.end(),
3295 0 : SwFormTokenEqualToFormTokenType(TOKEN_ENTRY_NO));
3296 :
3297 0 : if ( aIt != aPattern.end() )
3298 : {
3299 0 : SwFormToken aNumberEntrySeparator( TOKEN_TEXT );
3300 0 : aNumberEntrySeparator.sText = rtl::OUString(" ");
3301 0 : aPattern.insert( ++aIt, aNumberEntrySeparator );
3302 0 : pForm->SetPattern( nStyleLevel, aPattern );
3303 0 : }
3304 : }
3305 : }
3306 : }
3307 0 : if ( pForm )
3308 0 : pBase->SetTOXForm( *pForm );
3309 : }
3310 :
3311 0 : if (eCreateFrom)
3312 0 : pBase->SetCreate(eCreateFrom);
3313 0 : EnsureMaxLevelForTemplates(*pBase);
3314 : }
3315 0 : break;
3316 : case TOX_ILLUSTRATIONS:
3317 : {
3318 0 : if( !eCreateFrom )
3319 0 : eCreateFrom = nsSwTOXElement::TOX_SEQUENCE;
3320 0 : pBase->SetCreate( eCreateFrom );
3321 :
3322 : /*
3323 : We don't know until here if we are an illustration
3324 : or not, and so have being used a TOX_CONTENT so far
3325 : which has 10 levels, while TOX has only two, this
3326 : level is set only in the constructor of SwForm, so
3327 : create a new one and copy over anything that could
3328 : be set in the old one, and remove entries from the
3329 : pattern which do not apply to illustration indices
3330 : */
3331 0 : SwForm aOldForm( pBase->GetTOXForm() );
3332 0 : SwForm aForm( eType );
3333 0 : sal_uInt16 nEnd = aForm.GetFormMax()-1;
3334 :
3335 : // #i21237#
3336 0 : for(sal_uInt16 nLevel = 1; nLevel <= nEnd; ++nLevel)
3337 : {
3338 0 : SwFormTokens aPattern = aOldForm.GetPattern(nLevel);
3339 :
3340 : SwFormTokens::iterator new_end=remove_if(aPattern.begin(), aPattern.end(),
3341 0 : SwFormTokenEqualToFormTokenType(TOKEN_ENTRY_NO));
3342 :
3343 : // table index imported with wrong page number format
3344 0 : aPattern.erase (new_end, aPattern.end() );
3345 :
3346 0 : aForm.SetPattern(nLevel, aPattern);
3347 :
3348 : aForm.SetTemplate( nLevel,
3349 0 : aOldForm.GetTemplate(nLevel));
3350 0 : }
3351 :
3352 0 : pBase->SetTOXForm( aForm );
3353 : }
3354 0 : break;
3355 : default:
3356 : OSL_ENSURE(!this, "Unhandled toc options!");
3357 0 : break;
3358 0 : }
3359 : }
3360 0 : break;
3361 : case TOX_USER:
3362 0 : break;
3363 : default:
3364 : OSL_ENSURE(!this, "Unhandled toc options!");
3365 0 : break;
3366 : } // ToxBase fertig
3367 :
3368 : // Update fuer TOX anstossen
3369 0 : rDoc.SetUpdateTOX(true);
3370 :
3371 : // #i21237# - propagate tab stops from paragraph styles
3372 : // used in TOX to patterns of the TOX
3373 :
3374 0 : pBase->AdjustTabStops(rDoc, sal_True);
3375 :
3376 : // #i10028# - inserting a toc implicltly acts like a parabreak in word and writer
3377 0 : if (pPaM->GetPoint()->nContent.GetIndex())
3378 0 : AppendTxtNode(*pPaM->GetPoint());
3379 :
3380 0 : const SwPosition* pPos = pPaM->GetPoint();
3381 :
3382 0 : SwFltTOX aFltTOX( pBase, nIndexCols );
3383 :
3384 : // test if there is already a break item on this node
3385 0 : if(SwCntntNode* pNd = pPos->nNode.GetNode().GetCntntNode())
3386 : {
3387 0 : const SfxItemSet* pSet = pNd->GetpSwAttrSet();
3388 0 : if( pSet )
3389 : {
3390 0 : if (SFX_ITEM_SET == pSet->GetItemState(RES_BREAK, false))
3391 0 : aFltTOX.SetHadBreakItem(true);
3392 0 : if (SFX_ITEM_SET == pSet->GetItemState(RES_PAGEDESC, false))
3393 0 : aFltTOX.SetHadPageDescItem(true);
3394 : }
3395 : }
3396 :
3397 : //Will there be a new pagebreak at this position (don't know what type
3398 : //until later)
3399 0 : if (maSectionManager.WillHavePageDescHere(pPos->nNode))
3400 0 : aFltTOX.SetHadPageDescItem(true);
3401 :
3402 : // Setze Anfang in Stack
3403 0 : pReffedStck->NewAttr( *pPos, aFltTOX );
3404 :
3405 0 : rDoc.InsertTableOf(*pPaM->GetPoint(), *aFltTOX.GetBase());
3406 :
3407 : //inserting a toc inserts a section before this point, so adjust pos
3408 : //for future page/section segment insertion
3409 0 : SwPaM aRegion(*pPaM);
3410 0 : aRegion.Move(fnMoveBackward);
3411 : OSL_ENSURE(rDoc.GetCurTOX(*aRegion.GetPoint()), "Misunderstood how toc works");
3412 0 : if (SwTOXBase* pBase2 = (SwTOXBase*)rDoc.GetCurTOX(*aRegion.GetPoint()))
3413 : {
3414 0 : if(nIndexCols>1)
3415 : {
3416 : // Set the column number for index
3417 0 : SfxItemSet aSet( rDoc.GetAttrPool(), RES_COL, RES_COL );
3418 0 : SwFmtCol aCol;
3419 0 : aCol.Init( nIndexCols, 708, USHRT_MAX );
3420 0 : aSet.Put( aCol );
3421 0 : pBase2->SetAttrSet( aSet );
3422 : }
3423 :
3424 0 : maSectionManager.PrependedInlineNode(*pPaM->GetPoint(),
3425 0 : *aRegion.GetNode());
3426 : }
3427 :
3428 : // Setze Ende in Stack
3429 0 : pReffedStck->SetAttr( *pPos, RES_FLTR_TOX );
3430 :
3431 0 : if (!maApos.back()) //a para end in apo doesn't count
3432 0 : bWasParaEnd = true;
3433 0 : return FLD_OK;
3434 : }
3435 :
3436 3 : eF_ResT SwWW8ImplReader::Read_F_Shape(WW8FieldDesc* /*pF*/, String& /*rStr*/)
3437 : {
3438 : /*
3439 : #i3958# 0x8 followed by 0x1 where the shape is the 0x8 and its anchoring
3440 : to be ignored followed by a 0x1 with an empty drawing. Detect in inserting
3441 : the drawing that we are in the Shape field and respond accordingly
3442 : */
3443 3 : return FLD_TEXT;
3444 : }
3445 :
3446 3 : eF_ResT SwWW8ImplReader::Read_F_Hyperlink( WW8FieldDesc* /*pF*/, String& rStr )
3447 : {
3448 : #if defined(WW_NATIVE_TOC)
3449 : if (1) {
3450 : ::rtl::OUString aBookmarkName("_HYPERLINK");
3451 : maFieldStack.back().SetBookmarkName(aBookmarkName);
3452 : maFieldStack.back().SetBookmarkType(ODF_HYPERLINK);
3453 : return FLD_TEXT;
3454 : }
3455 : #endif
3456 :
3457 3 : String sURL, sTarget, sMark;
3458 3 : bool bDataImport = false;
3459 : //HYPERLINK "filename" [switches]
3460 :
3461 3 : rStr = comphelper::string::stripEnd(rStr, 1);
3462 :
3463 3 : if (!bDataImport)
3464 : {
3465 3 : bool bOptions = false;
3466 : long nRet;
3467 3 : WW8ReadFieldParams aReadParam( rStr );
3468 8 : while( -1 != ( nRet = aReadParam.SkipToNextToken() ))
3469 : {
3470 2 : switch( nRet )
3471 : {
3472 : case -2:
3473 2 : if (!sURL.Len() && !bOptions)
3474 2 : ConvertFFileName(sURL, aReadParam.GetResult());
3475 2 : break;
3476 :
3477 : case 'n':
3478 0 : sTarget.AssignAscii( "_blank" );
3479 0 : bOptions = true;
3480 0 : break;
3481 :
3482 : case 'l':
3483 0 : nRet = aReadParam.SkipToNextToken();
3484 0 : bOptions = true;
3485 0 : if( -2 == nRet )
3486 : {
3487 0 : sMark = aReadParam.GetResult();
3488 0 : if( sMark.Len() && '"' == sMark.GetChar( sMark.Len()-1 ))
3489 0 : sMark.Erase( sMark.Len() - 1 );
3490 :
3491 : }
3492 0 : break;
3493 : case 't':
3494 0 : nRet = aReadParam.SkipToNextToken();
3495 0 : bOptions = true;
3496 0 : if (-2 == nRet)
3497 0 : sTarget = aReadParam.GetResult();
3498 0 : break;
3499 : case 'h':
3500 : case 'm':
3501 : OSL_ENSURE( !this, "Auswertung fehlt noch - Daten unbekannt" );
3502 : case 's': //worthless fake anchor option
3503 0 : bOptions = true;
3504 0 : break;
3505 : }
3506 3 : }
3507 : }
3508 :
3509 : // das Resultat uebernehmen
3510 : OSL_ENSURE((sURL.Len() || sMark.Len()), "WW8: Empty URL");
3511 :
3512 3 : if( sMark.Len() )
3513 0 : ( sURL += INET_MARK_TOKEN ) += sMark;
3514 :
3515 3 : SwFmtINetFmt aURL( sURL, sTarget );
3516 :
3517 : //As an attribute this needs to be closed, and that'll happen from
3518 : //EndExtSprm in conjunction with the maFieldStack If there are are flyfrms
3519 : //between the start and begin, their hyperlinks will be set at that time
3520 : //as well.
3521 3 : pCtrlStck->NewAttr( *pPaM->GetPoint(), aURL );
3522 3 : return FLD_TEXT;
3523 : }
3524 :
3525 0 : static void lcl_ImportTox(SwDoc &rDoc, SwPaM &rPaM, const String &rStr, bool bIdx)
3526 : {
3527 0 : TOXTypes eTox = ( !bIdx ) ? TOX_CONTENT : TOX_INDEX; // Default
3528 :
3529 0 : sal_uInt16 nLevel = 1;
3530 :
3531 : xub_StrLen n;
3532 0 : String sFldTxt;
3533 : long nRet;
3534 0 : WW8ReadFieldParams aReadParam(rStr);
3535 0 : while( -1 != ( nRet = aReadParam.SkipToNextToken() ))
3536 0 : switch( nRet )
3537 : {
3538 : case -2:
3539 0 : if( !sFldTxt.Len() )
3540 : {
3541 : // PrimaryKey ohne ":", 2nd dahinter
3542 0 : sFldTxt = aReadParam.GetResult();
3543 : }
3544 0 : break;
3545 :
3546 : case 'f':
3547 0 : n = aReadParam.GoToTokenParam();
3548 0 : if( STRING_NOTFOUND != n )
3549 : {
3550 0 : String sParams( aReadParam.GetResult() );
3551 0 : if( 'C' != sParams.GetChar(0) && 'c' != sParams.GetChar(0) )
3552 0 : eTox = TOX_USER;
3553 : }
3554 0 : break;
3555 :
3556 : case 'l':
3557 0 : n = aReadParam.GoToTokenParam();
3558 0 : if( STRING_NOTFOUND != n )
3559 : {
3560 0 : String sParams( aReadParam.GetResult() );
3561 0 : if( sParams.Len() // if NO String just ignore the \l
3562 0 : && sParams.GetChar( 0 ) > '0'
3563 0 : && sParams.GetChar( 0 ) <= '9' )
3564 : {
3565 0 : nLevel = (sal_uInt16)sParams.ToInt32();
3566 0 : }
3567 : }
3568 0 : break;
3569 : }
3570 :
3571 : OSL_ENSURE( rDoc.GetTOXTypeCount( eTox ), "Doc.GetTOXTypeCount() == 0 :-(" );
3572 :
3573 0 : const SwTOXType* pT = rDoc.GetTOXType( eTox, 0 );
3574 0 : SwTOXMark aM( pT );
3575 :
3576 0 : if( eTox != TOX_INDEX )
3577 0 : aM.SetLevel( nLevel );
3578 : else
3579 : {
3580 0 : xub_StrLen nFnd = sFldTxt.Search( WW8_TOX_LEVEL_DELIM );
3581 0 : if( STRING_NOTFOUND != nFnd ) // it exist levels
3582 : {
3583 0 : aM.SetPrimaryKey( sFldTxt.Copy( 0, nFnd ) );
3584 : xub_StrLen nScndFnd =
3585 0 : sFldTxt.Search( WW8_TOX_LEVEL_DELIM, nFnd+1 );
3586 0 : if( STRING_NOTFOUND != nScndFnd )
3587 : {
3588 0 : aM.SetSecondaryKey( sFldTxt.Copy( nFnd+1, nScndFnd - nFnd - 1 ));
3589 0 : nFnd = nScndFnd;
3590 : }
3591 0 : sFldTxt.Erase( 0, nFnd+1 );
3592 : }
3593 : }
3594 :
3595 0 : if (sFldTxt.Len())
3596 : {
3597 0 : aM.SetAlternativeText( sFldTxt );
3598 0 : rDoc.InsertPoolItem( rPaM, aM, 0 );
3599 0 : }
3600 0 : }
3601 :
3602 0 : void sw::ms::ImportXE(SwDoc &rDoc, SwPaM &rPaM, const String &rStr)
3603 : {
3604 0 : lcl_ImportTox(rDoc, rPaM, rStr, true);
3605 0 : }
3606 :
3607 0 : void SwWW8ImplReader::ImportTox( int nFldId, String aStr )
3608 : {
3609 0 : bool bIdx = (nFldId != 9);
3610 0 : lcl_ImportTox(rDoc, *pPaM, aStr, bIdx);
3611 0 : }
3612 :
3613 6 : void SwWW8ImplReader::Read_FldVanish( sal_uInt16, const sal_uInt8*, short nLen )
3614 : {
3615 : //Meaningless in a style
3616 6 : if (pAktColl || !pPlcxMan)
3617 : return;
3618 :
3619 6 : const int nChunk = 64; //number of characters to read at one time
3620 :
3621 : // Vorsicht: Bei Feldnamen mit Umlauten geht das MEMICMP nicht!
3622 : const static sal_Char *aFldNames[] = { "\x06""INHALT", "\x02""XE", // dt.
3623 : "\x02""TC" }; // us
3624 : const static sal_uInt8 aFldId[] = { 9, 4, 9 };
3625 :
3626 6 : if( nLen < 0 )
3627 : {
3628 3 : bIgnoreText = false;
3629 : return;
3630 : }
3631 :
3632 : // our methode was called from
3633 : // ''Skip attributes of field contents'' loop within ReadTextAttr()
3634 3 : if( bIgnoreText )
3635 : return;
3636 :
3637 1 : bIgnoreText = true;
3638 1 : long nOldPos = pStrm->Tell();
3639 :
3640 1 : WW8_CP nStartCp = pPlcxMan->Where() + pPlcxMan->GetCpOfs();
3641 :
3642 1 : String sFieldName;
3643 : sal_uInt16 nFieldLen = pSBase->WW8ReadString( *pStrm, sFieldName, nStartCp,
3644 1 : nChunk, eStructCharSet );
3645 1 : nStartCp+=nFieldLen;
3646 :
3647 1 : xub_StrLen nC = 0;
3648 : //If the first chunk did not start with a field start then
3649 : //reset the stream position and give up
3650 1 : if( !nFieldLen || (0x13 != sFieldName.GetChar( nC ))) // Field Start Mark
3651 : {
3652 : // If Field End Mark found
3653 1 : if( nFieldLen && (0x15 == sFieldName.GetChar( nC )))
3654 0 : bIgnoreText = false;
3655 1 : pStrm->Seek( nOldPos );
3656 : return; // kein Feld zu finden
3657 : }
3658 :
3659 : xub_StrLen nFnd;
3660 : //If this chunk does not contain a field end, keep reading chunks
3661 : //until we find one, or we run out of text,
3662 0 : while (STRING_NOTFOUND == (nFnd = sFieldName.Search(0x15)))
3663 : {
3664 0 : String sTemp;
3665 : nFieldLen = pSBase->WW8ReadString( *pStrm, sTemp,
3666 0 : nStartCp, nChunk, eStructCharSet );
3667 0 : sFieldName+=sTemp;
3668 0 : nStartCp+=nFieldLen;
3669 0 : if (!nFieldLen)
3670 : break;
3671 0 : }
3672 :
3673 0 : pStrm->Seek( nOldPos );
3674 :
3675 : //if we have no 0x15 give up, otherwise erase everything from the 0x15
3676 : //onwards
3677 0 : if (STRING_NOTFOUND == nFnd)
3678 : return;
3679 : else
3680 0 : sFieldName.Erase(nFnd);
3681 :
3682 0 : nC++;
3683 0 : while( ' ' == sFieldName.GetChar( nC ))
3684 0 : nC++;
3685 :
3686 0 : for( int i = 0; i < 3; i++ )
3687 : {
3688 0 : const sal_Char* pName = aFldNames[i];
3689 0 : sal_uInt16 nNameLen = *pName++;
3690 0 : if( sFieldName.EqualsIgnoreCaseAscii( pName, nC, nNameLen ) )
3691 : {
3692 0 : ImportTox( aFldId[i], sFieldName.Copy( nC + nNameLen ) );
3693 0 : break; // keine Mehrfachnennungen moeglich
3694 : }
3695 : }
3696 0 : bIgnoreText = true;
3697 0 : pStrm->Seek( nOldPos );
3698 18 : }
3699 :
3700 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|