1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ww8par5.cxx,v $
10 * $Revision: 1.110.40.4 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
33 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
36 #include <ctype.h> // tolower
37 #include <stdio.h> // sscanf()
39 #include <sal/types.h>
40 #include <tools/solar.h>
42 #include <com/sun/star/ucb/XCommandEnvironment.hpp>
43 #include <svtools/urihelper.hxx>
44 #include <svtools/zforlist.hxx>
45 #include <svtools/zformat.hxx>
46 #include <sfx2/linkmgr.hxx>
48 #ifndef _UCBHELPER_CONTENT_HXX_
49 #include <ucbhelper/content.hxx>
51 #ifndef _UCBHELPER_CONTENTBROKER_HXX_
52 #include <ucbhelper/contentbroker.hxx>
54 #include <ucbhelper/commandenvironment.hxx>
56 #ifndef _COM_SUN_STAR_I18N_SCRIPTTYPE_HDL_
57 #include <com/sun/star/i18n/ScriptType.hdl>
59 #include <hintids.hxx>
60 #include <svx/fontitem.hxx>
61 #include <svx/fhgtitem.hxx>
62 #include <svx/langitem.hxx>
64 #include <fmtanchr.hxx>
65 #include <pam.hxx> // fuer SwPam
67 #include <charatr.hxx> // class SwFmtFld
68 #include <flddat.hxx> // class SwDateTimeField
69 #include <docufld.hxx> // class SwPageNumberField
70 #include <reffld.hxx> // class SwGetRefField
72 #include <expfld.hxx> // class SwSetExpField
73 #include <dbfld.hxx> // class SwDBField
76 #include <section.hxx> // class SwSection
78 #include <fmtinfmt.hxx>
83 #include <shellres.hxx>
84 #include <fmtruby.hxx>
85 #include <charfmt.hxx>
87 #include <breakit.hxx>
88 #include <fmtclds.hxx>
89 #include <pagedesc.hxx>
90 #include <SwStyleNameMapper.hxx>
93 #include "ww8scan.hxx" // WW8FieldDesc
95 #include "ww8par2.hxx"
96 #include "writerhelper.hxx"
98 #include <svtools/fltrcfg.hxx>
100 #include <algorithm> // #i24377#
102 //#define WW_NATIVE_TOC 0
104 #define MAX_FIELDLEN 64000
106 #define WW8_TOX_LEVEL_DELIM ':'
108 using namespace ::com::sun::star
;
109 using namespace sw::util
;
110 using namespace sw::mark
;
111 using namespace std
; // #i24377#
112 using namespace nsSwDocInfoSubType
;
115 class _ReadFieldParams
119 xub_StrLen nLen
, nFnd
, nNext
, nSavPtr
;
121 _ReadFieldParams( const String
& rData
);
124 xub_StrLen
GoToTokenParam();
125 long SkipToNextToken();
126 xub_StrLen
GetTokenSttPtr() const { return nFnd
; }
128 xub_StrLen
FindNextStringPiece( xub_StrLen _nStart
= STRING_NOTFOUND
);
129 bool GetTokenSttFromTo(xub_StrLen
* _pFrom
, xub_StrLen
* _pTo
,
132 String
GetResult() const;
136 _ReadFieldParams::_ReadFieldParams( const String
& _rData
)
137 : aData( _rData
), nLen( _rData
.Len() ), nNext( 0 )
140 erstmal nach einer oeffnenden Klammer oder einer Leerstelle oder einem
141 Anfuehrungszeichen oder einem Backslash suchen, damit der Feldbefehl
142 (also INCLUDEPICTURE bzw EINFUeGENGRAFIK bzw ...) ueberlesen wird
144 while( (nLen
> nNext
) && (aData
.GetChar( nNext
) == ' ') )
149 && (c
= aData
.GetChar( nNext
)) != ' '
158 // cLastChar = aData.GetChar( nSavPtr );
162 _ReadFieldParams::~_ReadFieldParams()
164 // aData.SetChar( nSavPtr, cLastChar );
168 String
_ReadFieldParams::GetResult() const
170 return (STRING_NOTFOUND
== nFnd
)
172 : aData
.Copy( nFnd
, (nSavPtr
- nFnd
) );
176 xub_StrLen
_ReadFieldParams::GoToTokenParam()
178 xub_StrLen nOld
= nNext
;
179 if( -2 == SkipToNextToken() )
180 return GetTokenSttPtr();
182 return STRING_NOTFOUND
;
185 // ret: -2: NOT a '\' parameter but normal Text
186 long _ReadFieldParams::SkipToNextToken()
188 long nRet
= -1; // Ende
190 (STRING_NOTFOUND
!= nNext
) && (nLen
> nNext
) &&
191 STRING_NOTFOUND
!= (nFnd
= FindNextStringPiece(nNext
))
196 if ('\\' == aData
.GetChar(nFnd
) && '\\' != aData
.GetChar(nFnd
+ 1))
198 nRet
= aData
.GetChar(++nFnd
);
199 nNext
= ++nFnd
; // und dahinter setzen
205 (STRING_NOTFOUND
!= nSavPtr
) &&
207 ('"' == aData
.GetChar(nSavPtr
- 1)) ||
208 (0x201d == aData
.GetChar(nSavPtr
- 1))
219 // FindNextPara sucht naechsten Backslash-Parameter oder naechste Zeichenkette
220 // bis zum Blank oder naechsten "\" oder zum schliessenden Anfuehrungszeichen
221 // oder zum String-Ende von pStr.
223 // Ausgabe ppNext (falls ppNext != 0) Suchbeginn fuer naechsten Parameter bzw. 0
225 // Returnwert: 0 falls String-Ende erreicht,
226 // ansonsten Anfang des Paramters bzw. der Zeichenkette
228 xub_StrLen
_ReadFieldParams::FindNextStringPiece(const xub_StrLen nStart
)
230 xub_StrLen n
= ( STRING_NOTFOUND
== nStart
) ? nFnd
: nStart
; // Anfang
231 xub_StrLen n2
; // Ende
233 nNext
= STRING_NOTFOUND
; // Default fuer nicht gefunden
235 while( (nLen
> n
) && (aData
.GetChar( n
) == ' ') )
239 return STRING_NOTFOUND
; // String End reached!
241 if( (aData
.GetChar( n
) == '"') // Anfuehrungszeichen vor Para?
242 || (aData
.GetChar( n
) == 0x201c)
243 || (aData
.GetChar( n
) == 132) )
245 n
++; // Anfuehrungszeichen ueberlesen
246 n2
= n
; // ab hier nach Ende suchen
248 && (aData
.GetChar( n2
) != '"')
249 && (aData
.GetChar( n2
) != 0x201d)
250 && (aData
.GetChar( n2
) != 147) )
251 n2
++; // Ende d. Paras suchen
253 else // keine Anfuehrungszeichen
255 n2
= n
; // ab hier nach Ende suchen
256 while( (nLen
> n2
) && (aData
.GetChar( n2
) != ' ') ) // Ende d. Paras suchen
258 if( aData
.GetChar( n2
) == '\\' )
260 if( aData
.GetChar( n2
+1 ) == '\\' )
261 n2
+= 2; // Doppel-Backslash -> OK
266 break; // einfach-Backslash -> Ende
270 n2
++; // kein Backslash -> OK
275 if(aData
.GetChar( n2
) != ' ') n2
++;
283 // read parameters "1-3" or 1-3 with both values between 1 and nMax
284 bool _ReadFieldParams::GetTokenSttFromTo(USHORT
* pFrom
, USHORT
* pTo
, USHORT nMax
)
288 xub_StrLen n
= GoToTokenParam();
289 if( STRING_NOTFOUND
!= n
)
292 String
sParams( GetResult() );
294 xub_StrLen nIndex
= 0;
295 String
sStart( sParams
.GetToken(0, '-', nIndex
) );
296 if( STRING_NOTFOUND
!= nIndex
)
298 nStart
= static_cast<USHORT
>(sStart
.ToInt32());
299 nEnd
= static_cast<USHORT
>(sParams
.Copy(nIndex
).ToInt32());
302 if( pFrom
) *pFrom
= nStart
;
303 if( pTo
) *pTo
= nEnd
;
305 return nStart
&& nEnd
&& (nMax
>= nStart
) && (nMax
>= nEnd
);
308 //----------------------------------------
310 //----------------------------------------
312 long SwWW8ImplReader::Read_Book(WW8PLCFManResult
*)
314 // muesste auch ueber pRes.nCo2OrIdx gehen
315 WW8PLCFx_Book
* pB
= pPlcxMan
->GetBook();
318 ASSERT( pB
, "WW8PLCFx_Book - Pointer nicht da" );
322 eBookStatus eB
= pB
->GetStatus();
323 if (eB
& BOOK_IGNORE
)
324 return 0; // Bookmark zu ignorieren
328 pReffedStck
->SetAttr(*pPaM
->GetPoint(), RES_FLTR_BOOKMARK
, true,
329 pB
->GetHandle(), (eB
& BOOK_FIELD
)!=0);
333 //"_Toc*" and "_Hlt*" are unnecessary
334 const String
* pName
= pB
->GetName();
335 #if !defined(WW_NATIVE_TOC)
336 if( !pName
|| pName
->EqualsIgnoreCaseAscii( "_Toc", 0, 4 )
337 || pName
->EqualsIgnoreCaseAscii( "_Hlt", 0, 4 ) )
341 //JP 16.11.98: ToUpper darf auf keinen Fall gemacht werden, weil der
342 //Bookmark- name ein Hyperlink-Ziel sein kann!
345 if( SwFltGetFlag( nFieldFlags
, SwFltControlStack::BOOK_TO_VAR_REF
) )
347 // Fuer UEbersetzung Bookmark -> Variable setzen
348 long nLen
= pB
->GetLen();
349 if( nLen
> MAX_FIELDLEN
)
352 long nOldPos
= pStrm
->Tell();
353 nLen
= pSBase
->WW8ReadString( *pStrm
, aVal
, pB
->GetStartPos(), nLen
,
355 pStrm
->Seek( nOldPos
);
357 // JP 19.03.2001 - now here the implementation of the old
358 // "QuoteString" and I hope with a better performance
359 // as before. It's also only needed if the filterflags
360 // say we will convert bookmarks to SetExpFields! And
361 // this the exception!
363 String
sHex(CREATE_CONST_ASC( "\\x" ));
365 bool bAllowCr
= SwFltGetFlag(nFieldFlags
,
366 SwFltControlStack::ALLOW_FLD_CR
) ? true : false;
370 for( xub_StrLen nI
= 0;
371 nI
< aVal
.Len() && aVal
.Len() < (MAX_FIELDLEN
- 4); ++nI
)
373 switch( cChar
= aVal
.GetChar( nI
) )
379 aVal
.SetChar( nI
, '\n' ), bSetAsHex
= false;
390 bSetAsHex
= 0x20 > cChar
;
396 //all Hex-Numbers with \x before
400 sTmp
+= String::CreateFromInt32( cChar
, 16 );
401 aVal
.Replace( nI
, 1 , sTmp
);
402 nI
+= sTmp
.Len() - 1;
406 if( aVal
.Len() > (MAX_FIELDLEN
- 4))
407 aVal
.Erase( MAX_FIELDLEN
- 4 );
410 //e.g. inserting bookmark around field result, so we need to put
411 //it around the entire writer field, as we don't have the seperation
412 //of field and field result of word, see #i16941#
413 SwPosition
aStart(*pPaM
->GetPoint());
414 if (!maFieldStack
.empty())
416 const FieldEntry
&rTest
= maFieldStack
.back();
417 aStart
= rTest
.maStartPos
;
420 pReffedStck
->NewAttr(aStart
, SwFltBookmark(BookmarkToWriter(*pName
), aVal
,
421 pB
->GetHandle(), 0));
425 //----------------------------------------------------------------------
426 // allgemeine Hilfsroutinen zum Auseinanderdroeseln der Parameter
427 //----------------------------------------------------------------------
429 // ConvertFFileName uebersetzt FeldParameter-Namen u. ae. in den
430 // System-Zeichensatz.
431 // Gleichzeitig werden doppelte Backslashes in einzelne uebersetzt.
432 void SwWW8ImplReader::ConvertFFileName( String
& rName
, const String
& rOrg
)
435 rName
.SearchAndReplaceAllAscii( "\\\\", String( '\\' ));
436 rName
.SearchAndReplaceAllAscii( "%20", String( ' ' ));
438 // ggfs. anhaengende Anfuehrungszeichen entfernen
439 if( rName
.Len() && '"' == rName
.GetChar( rName
.Len()-1 ))
440 rName
.Erase( rName
.Len()-1, 1);
442 //#82900# Need the more sophisticated url converter. cmc
444 rName
= URIHelper::SmartRel2Abs(
445 INetURLObject(sBaseURL
), rName
, Link(), false);
448 // ConvertUFNneme uebersetzt FeldParameter-Namen u. ae. in den
449 // System-Zeichensatz und Upcased sie ( z.B. fuer Ref-Felder )
452 void ConvertUFName( String
& rName
)
454 GetAppCharClass().toUpper( rName
);
458 static void lcl_ConvertSequenceName(String
& rSequenceName
)
460 ConvertUFName(rSequenceName
);
461 if ('0' <= rSequenceName
.GetChar(0) && '9' >= rSequenceName
.GetChar(0))
462 rSequenceName
.Insert('_', 0);
465 // FindParaStart() finds 1st Parameter that follows '\' and cToken
466 // and returns start of this parameter or STRING_NOT_FOUND.
467 xub_StrLen
FindParaStart( const String
& rStr
, sal_Unicode cToken
, sal_Unicode cToken2
)
469 bool bStr
= false; // innerhalb String ignorieren
471 for( xub_StrLen nBuf
=0; nBuf
+1 < rStr
.Len(); nBuf
++ )
473 if( rStr
.GetChar( nBuf
) == '"' )
477 && rStr
.GetChar( nBuf
) == '\\'
478 && ( rStr
.GetChar( nBuf
+ 1 ) == cToken
479 || rStr
.GetChar( nBuf
+ 1 ) == cToken2
) )
482 // skip spaces between cToken and it's parameters
483 while( nBuf
< rStr
.Len()
484 && rStr
.GetChar( nBuf
) == ' ' )
486 // return start of parameters
487 return nBuf
< rStr
.Len() ? nBuf
: STRING_NOTFOUND
;
490 return STRING_NOTFOUND
;
493 // FindPara() findet den ersten Parameter mit '\' und cToken. Es wird
494 // ein neuer String allokiert ( der vom Aufrufer deallokiert werden muss )
495 // und alles, was zum Parameter gehoert, wird in ihm zurueckgeliefert.
496 String
FindPara( const String
& rStr
, sal_Unicode cToken
, sal_Unicode cToken2
)
498 xub_StrLen n2
; // Ende
499 xub_StrLen n
= FindParaStart( rStr
, cToken
, cToken2
); // Anfang
500 if( STRING_NOTFOUND
== n
)
503 if( rStr
.GetChar( n
) == '"'
504 || rStr
.GetChar( n
) == 132 )
505 { // Anfuehrungszeichen vor Para
506 n
++; // Anfuehrungszeichen ueberlesen
507 n2
= n
; // ab hier nach Ende suchen
508 while( n2
< rStr
.Len()
509 && rStr
.GetChar( n2
) != 147
510 && rStr
.GetChar( n2
) != '"' )
511 n2
++; // Ende d. Paras suchen
514 { // keine Anfuehrungszeichen
515 n2
= n
; // ab hier nach Ende suchen
516 while( n2
< rStr
.Len()
517 && rStr
.GetChar( n2
) != ' ' )
518 n2
++; // Ende d. Paras suchen
520 return rStr
.Copy( n
, n2
-n
);
524 static SvxExtNumType
GetNumTypeFromName(const String
& rStr
,
525 bool bAllowPageDesc
= false)
527 SvxExtNumType eTyp
= bAllowPageDesc
? SVX_NUM_PAGEDESC
: SVX_NUM_ARABIC
;
528 if( rStr
.EqualsIgnoreCaseAscii( "Arabi", 0, 5 ) ) // Arabisch, Arabic
529 eTyp
= SVX_NUM_ARABIC
;
530 else if( rStr
.EqualsAscii( "misch", 2, 5 ) ) // r"omisch
531 eTyp
= SVX_NUM_ROMAN_LOWER
;
532 else if( rStr
.EqualsAscii( "MISCH", 2, 5 ) ) // R"OMISCH
533 eTyp
= SVX_NUM_ROMAN_UPPER
;
534 else if( rStr
.EqualsIgnoreCaseAscii( "alphabeti", 0, 9 ) )// alphabetisch, alphabetic
535 eTyp
= ( rStr
.GetChar( 0 ) == 'A' )
536 ? SVX_NUM_CHARS_UPPER_LETTER_N
537 : SVX_NUM_CHARS_LOWER_LETTER_N
;
538 else if( rStr
.EqualsIgnoreCaseAscii( "roman", 0, 5 ) ) // us
539 eTyp
= ( rStr
.GetChar( 0 ) == 'R' )
540 ? SVX_NUM_ROMAN_UPPER
541 : SVX_NUM_ROMAN_LOWER
;
545 static SvxExtNumType
GetNumberPara(String
& rStr
, bool bAllowPageDesc
= false)
547 String
s( FindPara( rStr
, '*', '*' ) ); // Ziffernart
548 SvxExtNumType aType
= GetNumTypeFromName( s
, bAllowPageDesc
);
555 bool SwWW8ImplReader::ForceFieldLanguage(SwField
&rFld
, USHORT nLang
)
559 const SvxLanguageItem
*pLang
=
560 (const SvxLanguageItem
*)GetFmtAttr(RES_CHRATR_LANGUAGE
);
561 ASSERT(pLang
, "impossible");
562 USHORT nDefault
= pLang
? pLang
->GetValue() : LANGUAGE_ENGLISH_US
;
564 if (nLang
!= nDefault
)
566 rFld
.SetAutomaticLanguage(false);
567 rFld
.SetLanguage(nLang
);
574 String
GetWordDefaultDateStringAsUS(SvNumberFormatter
* pFormatter
, USHORT nLang
)
576 //Get the system date in the correct final language layout, convert to
577 //a known language and modify the 2 digit year part to be 4 digit, and
578 //convert back to the correct language layout.
579 ULONG nIndex
= pFormatter
->GetFormatIndex(NF_DATE_SYSTEM_SHORT
, nLang
);
581 SvNumberformat aFormat
= const_cast<SvNumberformat
&>
582 (*(pFormatter
->GetEntry(nIndex
)));
583 aFormat
.ConvertLanguage(*pFormatter
, nLang
, LANGUAGE_ENGLISH_US
);
585 String
sParams(aFormat
.GetFormatstring());
586 // --> OD 2007-02-09 #i36594#
587 // Fix provided by mloiseleur@openoffice.org.
588 // A default date can have already 4 year digits, in some case
589 const xub_StrLen pos
= sParams
.Search( CREATE_CONST_ASC("YYYY") );
590 if ( pos
== STRING_NOTFOUND
)
592 sParams
.SearchAndReplace(CREATE_CONST_ASC("YY"), CREATE_CONST_ASC("YYYY"));
598 short SwWW8ImplReader::GetTimeDatePara(String
& rStr
, sal_uInt32
& rFormat
,
599 USHORT
&rLang
, int nWhichDefault
, bool bHijri
)
602 if (pPlcxMan
&& !bVer67
)
604 const BYTE
*pResult
= pPlcxMan
->HasCharSprm(0x85A);
605 if (pResult
&& *pResult
)
608 RES_CHRATR eLang
= bRTL
? RES_CHRATR_CTL_LANGUAGE
: RES_CHRATR_LANGUAGE
;
609 const SvxLanguageItem
*pLang
= (SvxLanguageItem
*)GetFmtAttr( static_cast< USHORT
>(eLang
));
610 ASSERT(pLang
, "impossible");
611 rLang
= pLang
? pLang
->GetValue() : LANGUAGE_ENGLISH_US
;
613 SvNumberFormatter
* pFormatter
= rDoc
.GetNumberFormatter();
614 String
sParams( FindPara( rStr
, '@', '@' ) );// Date/Time
617 bool bHasTime
= false;
618 switch (nWhichDefault
)
622 sParams
= GetWordDefaultDateStringAsUS(pFormatter
, rLang
);
623 sParams
.APPEND_CONST_ASC(" HH:MM:SS AM/PM");
626 case ww::eCREATEDATE
:
627 sParams
.ASSIGN_CONST_ASC("DD/MM/YYYY HH:MM:SS");
632 sParams
= GetWordDefaultDateStringAsUS(pFormatter
, rLang
);
637 sParams
.Insert(CREATE_CONST_ASC("[~hijri]"), 0);
639 UINT16 nCheckPos
= 0;
640 INT16 nType
= NUMBERFORMAT_DEFINED
;
643 pFormatter
->PutandConvertEntry(sParams
, nCheckPos
, nType
, rFormat
,
644 LANGUAGE_ENGLISH_US
, rLang
);
646 return bHasTime
? NUMBERFORMAT_DATETIME
: NUMBERFORMAT_DATE
;
650 sw::ms::MSDateTimeFormatToSwFormat(sParams
, pFormatter
, rLang
, bHijri
);
651 short nNumFmtType
= NUMBERFORMAT_UNDEFINED
;
653 nNumFmtType
= pFormatter
->GetType(nFmtIdx
);
659 //-----------------------------------------
661 //-----------------------------------------
662 // Am Ende des Einlesens entsprechende Felder updaten ( z.Zt. die Referenzen )
663 void SwWW8ImplReader::UpdateFields()
665 // rDoc.GetSysFldType( RES_GETREFFLD )->UpdateFlds(); // Referenzen
666 // rDoc.UpdateFlds(); // SetExp-Fields
667 // rDoc.UpdateFlds(); // alles ???
668 // rDoc.UpdateExpFlds(); // SetExp-Fields
669 rDoc
.SetUpdateExpFldStat(true); // JP: neu fuer alles wichtige
670 rDoc
.SetInitDBFields(true); // Datenbank-Felder auch
673 sal_uInt16
SwWW8ImplReader::End_Field()
676 WW8PLCFx_FLD
* pF
= pPlcxMan
->GetFld();
677 ASSERT(pF
, "WW8PLCFx_FLD - Pointer nicht da");
678 if (!pF
|| !pF
->EndPosIsFieldEnd())
681 const SvtFilterOptions
* pOpt
= SvtFilterOptions::Get();
682 sal_Bool bUseEnhFields
=(pOpt
&& pOpt
->IsUseEnhancedFields());
684 ASSERT(!maFieldStack
.empty(), "Empty field stack\n");
685 if (!maFieldStack
.empty())
688 only hyperlinks currently need to be handled like this, for the other
689 cases we have inserted a field not an attribute with an unknown end
692 nRet
= maFieldStack
.back().mnFieldId
;
696 if (bUseEnhFields
&& pPaM
!=NULL
&& pPaM
->GetPoint()!=NULL
) {
697 SwPosition aEndPos
= *pPaM
->GetPoint();
698 SwPaM
aFldPam( maFieldStack
.back().GetPtNode(), maFieldStack
.back().GetPtCntnt(), aEndPos
.nNode
, aEndPos
.nContent
.GetIndex());
699 IDocumentMarkAccess
* pMarksAccess
= rDoc
.getIDocumentMarkAccess( );
700 IFieldmark
*pFieldmark
= dynamic_cast<IFieldmark
*>( pMarksAccess
->makeFieldBookmark(
701 aFldPam
, maFieldStack
.back().GetBookmarkName(), ::rtl::OUString::createFromAscii(ECMA_FORMTEXT
) ) );
702 ASSERT(pFieldmark
!=NULL
, "hmmm; why was the bookmark not created?");
703 if (pFieldmark
!=NULL
) {
704 pFieldmark
->addParams(maFieldStack
.back().getParams());
708 #if defined(WW_NATIVE_TOC)
710 case 13: // TOX_CONTENT
711 case 88: // HYPERLINK
713 if (pPaM
!=NULL
&& pPaM
->GetPoint()!=NULL
) {
715 SwPosition aEndPos
= *pPaM
->GetPoint();
716 SwPaM
aFldPam( maFieldStack
.back().GetPtNode(), maFieldStack
.back().GetPtCntnt(), aEndPos
.nNode
, aEndPos
.nContent
.GetIndex());
717 SwFieldBookmark
*pFieldmark
=(SwFieldBookmark
*)rDoc
.makeFieldBookmark(aFldPam
, maFieldStack
.back().GetBookmarkName(), maFieldStack
.back().GetBookmarkType());
718 ASSERT(pFieldmark
!=NULL
, "hmmm; why was the bookmark not created?");
719 if (pFieldmark
!=NULL
) {
720 pFieldmark
->addParams(maFieldStack
.back().getParams());
726 pCtrlStck
->SetAttr(*pPaM
->GetPoint(),RES_TXTATR_INETFMT
);
731 //Move outside the section associated with this type of field
732 *pPaM
->GetPoint() = maFieldStack
.back().maStartPos
;
737 maFieldStack
.pop_back();
742 bool AcceptableNestedField(sal_uInt16 nFieldCode
)
746 #if defined(WW_NATIVE_TOC)
747 case 8: // allow recursive field in TOC...
748 case 13: // allow recursive field in TOC...
754 // --> OD 2007-01-02 #b6504125#
755 // Accept AutoTextList field as nested field.
756 // Thus, the field result is imported as plain text.
765 FieldEntry::FieldEntry(SwPosition
&rPos
, sal_uInt16 nFieldId
) throw()
766 : maStartPos(rPos
), mnFieldId(nFieldId
)
770 FieldEntry::FieldEntry(const FieldEntry
&rOther
) throw()
771 : maStartPos(rOther
.maStartPos
), mnFieldId(rOther
.mnFieldId
)
775 void FieldEntry::Swap(FieldEntry
&rOther
) throw()
777 std::swap(maStartPos
, rOther
.maStartPos
);
778 std::swap(mnFieldId
, rOther
.mnFieldId
);
781 FieldEntry
&FieldEntry::operator=(const FieldEntry
&rOther
) throw()
783 FieldEntry
aTemp(rOther
);
788 ::rtl::OUString
FieldEntry::GetBookmarkName()
790 return msBookmarkName
;
793 ::rtl::OUString
FieldEntry::GetBookmarkType()
798 void FieldEntry::SetBookmarkName(::rtl::OUString bookmarkName
)
800 msBookmarkName
=bookmarkName
;
803 void FieldEntry::SetBookmarkType(::rtl::OUString bookmarkType
)
805 msMarkType
=bookmarkType
;
808 void FieldEntry::AddParam(::rtl::OUString name
, ::rtl::OUString value
)
810 maParams
.push_back( IFieldmark::ParamPair_t( name
, value
) );
813 FieldEntry::Params_t
&FieldEntry::getParams() {
818 // Read_Field liest ein Feld ein oder, wenn es nicht gelesen werden kann,
819 // wird 0 zurueckgegeben, so dass das Feld vom Aufrufer textuell gelesen wird.
820 // Returnwert: Gesamtlaenge des Feldes ( zum UEberlesen )
821 long SwWW8ImplReader::Read_Field(WW8PLCFManResult
* pRes
)
823 typedef eF_ResT (SwWW8ImplReader:: *FNReadField
)( WW8FieldDesc
*, String
& );
824 enum Limits
{eMax
= 96};
825 static FNReadField aWW8FieldTab
[eMax
+1] =
830 &SwWW8ImplReader::Read_F_Ref
, // 3
833 &SwWW8ImplReader::Read_F_Set
, // 6
835 &SwWW8ImplReader::Read_F_Tox
, // 8
839 &SwWW8ImplReader::Read_F_Seq
, // 12
840 &SwWW8ImplReader::Read_F_Tox
, // 13
841 &SwWW8ImplReader::Read_F_DocInfo
, // 14
842 &SwWW8ImplReader::Read_F_DocInfo
, // 15
843 &SwWW8ImplReader::Read_F_DocInfo
, // 16
844 &SwWW8ImplReader::Read_F_Author
, // 17
845 &SwWW8ImplReader::Read_F_DocInfo
, // 18
846 &SwWW8ImplReader::Read_F_DocInfo
, // 19
847 &SwWW8ImplReader::Read_F_DocInfo
, // 20
848 &SwWW8ImplReader::Read_F_DocInfo
, // 21
849 &SwWW8ImplReader::Read_F_DocInfo
, // 22
850 &SwWW8ImplReader::Read_F_DocInfo
, // 23
851 &SwWW8ImplReader::Read_F_DocInfo
, // 24
852 &SwWW8ImplReader::Read_F_DocInfo
, // 25
853 &SwWW8ImplReader::Read_F_Anz
, // 26
854 &SwWW8ImplReader::Read_F_Anz
, // 27
855 &SwWW8ImplReader::Read_F_Anz
, // 28
856 &SwWW8ImplReader::Read_F_FileName
, // 29
857 &SwWW8ImplReader::Read_F_TemplName
, // 30
858 &SwWW8ImplReader::Read_F_DateTime
, // 31
859 &SwWW8ImplReader::Read_F_DateTime
, // 32
860 &SwWW8ImplReader::Read_F_CurPage
, // 33
863 &SwWW8ImplReader::Read_F_IncludeText
, // 36
864 &SwWW8ImplReader::Read_F_PgRef
, // 37
865 &SwWW8ImplReader::Read_F_InputVar
, // 38
866 &SwWW8ImplReader::Read_F_Input
, // 39
868 &SwWW8ImplReader::Read_F_DBNext
, // 41
871 &SwWW8ImplReader::Read_F_DBNum
, // 44
876 &SwWW8ImplReader::Read_F_Equation
, // 49
878 &SwWW8ImplReader::Read_F_Macro
, // 51
879 &SwWW8ImplReader::Read_F_ANumber
, // 52
880 &SwWW8ImplReader::Read_F_ANumber
, // 53
881 &SwWW8ImplReader::Read_F_ANumber
, // 54
885 0, // 56: VERKNUePFUNG // fehlt noch !!!!!!!!!!!!!!!!!!!!!!!
888 &SwWW8ImplReader::Read_F_Symbol
, // 57
889 &SwWW8ImplReader::Read_F_Embedd
, // 58
890 &SwWW8ImplReader::Read_F_DBField
, // 59
898 &SwWW8ImplReader::Read_F_IncludePicture
, // 67
899 &SwWW8ImplReader::Read_F_IncludeText
, // 68
901 &SwWW8ImplReader::Read_F_FormTextBox
, // 70
902 &SwWW8ImplReader::Read_F_FormCheckBox
, // 71
903 &SwWW8ImplReader::Read_F_NoteReference
, // 72
904 0, /*&SwWW8ImplReader::Read_F_Tox*/
914 &SwWW8ImplReader::Read_F_FormListBox
, // 83
916 &SwWW8ImplReader::Read_F_DocInfo
, // 85
918 &SwWW8ImplReader::Read_F_OCX
, // 87
919 &SwWW8ImplReader::Read_F_Hyperlink
, // 88
922 &SwWW8ImplReader::Read_F_HTMLControl
, // 91
926 &SwWW8ImplReader::Read_F_Shape
, // 95
927 0 // eMax - Dummy leer Methode
929 ASSERT( ( sizeof( aWW8FieldTab
) / sizeof( *aWW8FieldTab
) == eMax
+1 ),
930 "FeldFunc-Tabelle stimmt nicht" );
932 WW8PLCFx_FLD
* pF
= pPlcxMan
->GetFld();
933 ASSERT(pF
, "WW8PLCFx_FLD - Pointer nicht da");
935 if (!pF
|| !pF
->StartPosIsFieldStart())
938 bool bNested
= false;
939 if (!maFieldStack
.empty())
941 mycFieldIter aEnd
= maFieldStack
.end();
942 for(mycFieldIter aIter
= maFieldStack
.begin(); aIter
!= aEnd
; ++aIter
)
944 bNested
= !AcceptableNestedField(aIter
->mnFieldId
);
951 bool bOk
= pF
->GetPara(pRes
->nCp2OrIdx
, aF
);
953 ASSERT(bOk
, "WW8: Bad Field!\n");
954 if (aF
.nId
== 33) aF
.bCodeNest
=false; //#124716#: do not recurse into nested page fields
956 maFieldStack
.push_back(FieldEntry(*pPaM
->GetPoint(), aF
.nId
));
961 USHORT n
= ( aF
.nId
<= eMax
) ? aF
.nId
: static_cast< USHORT
>(eMax
); // alle > 91 werden 92
962 USHORT nI
= n
/ 32; // # des UINT32
963 ULONG nMask
= 1 << ( n
% 32 ); // Maske fuer Bits
965 if( nFieldTagAlways
[nI
] & nMask
) // Flag: Tag it
966 return Read_F_Tag( &aF
); // Resultat nicht als Text
968 if( !bOk
|| !aF
.nId
) // Feld kaputt
969 return aF
.nLen
; // -> ignorieren
971 if( aF
.nId
> eMax
- 1) // WW: Nested Field
973 if( nFieldTagBad
[nI
] & nMask
) // Flag: Tag it when bad
974 return Read_F_Tag( &aF
); // Resultat nicht als Text
979 //Only one type of field (hyperlink) in drawing textboxes exists
980 if (aF
.nId
!= 88 && pPlcxMan
&& pPlcxMan
->GetDoingDrawTextBox())
983 // keine Routine vorhanden
984 if (bNested
|| !aWW8FieldTab
[aF
.nId
] || aF
.bCodeNest
)
986 if( nFieldTagBad
[nI
] & nMask
) // Flag: Tag it when bad
987 return Read_F_Tag( &aF
); // Resultat nicht als Text
989 if (aF
.bResNest
&& !AcceptableNestedField(aF
.nId
))
990 return aF
.nLen
; // Result nested -> nicht brauchbar
992 long nOldPos
= pStrm
->Tell();
994 aF
.nLCode
= pSBase
->WW8ReadString( *pStrm
, aStr
, pPlcxMan
->GetCpOfs()+
995 aF
.nSCode
, aF
.nLCode
, eTextCharSet
);
996 pStrm
->Seek( nOldPos
);
998 //#124725# field codes which contain '/' or '.' are not displayed in WinWord
999 xub_StrLen nSpacePos
= aStr
.Search( ' ', 1 );
1000 if ( STRING_NOTFOUND
== nSpacePos
)
1001 nSpacePos
= aStr
.Len( );
1002 xub_StrLen nSearchPos
= STRING_NOTFOUND
;
1003 if ( ( ( nSearchPos
= aStr
.Search('.') ) != STRING_NOTFOUND
&& nSearchPos
< nSpacePos
) ||
1004 ( ( nSearchPos
= aStr
.Search('/') ) != STRING_NOTFOUND
&& nSearchPos
< nSpacePos
) )
1007 return aF
.nLen
- aF
.nLRes
- 1; // so viele ueberlesen, das Resultfeld
1008 // wird wie Haupttext eingelesen
1012 long nOldPos
= pStrm
->Tell();
1014 aF
.nLCode
= pSBase
->WW8ReadString( *pStrm
, aStr
, pPlcxMan
->GetCpOfs()+
1015 aF
.nSCode
, aF
.nLCode
, eTextCharSet
);
1017 // --> OD 2005-07-25 #i51312# - graphics inside field code not supported
1018 // by Writer. Thus, delete character 0x01, which stands for such a graphic.
1019 if (aF
.nId
==51) //#i56768# only do it for the MACROBUTTON field, since DropListFields need the 0x01.
1021 aStr
.EraseAllChars( 0x01 );
1025 eF_ResT eRes
= (this->*aWW8FieldTab
[aF
.nId
])( &aF
, aStr
);
1026 pStrm
->Seek( nOldPos
);
1031 return aF
.nLen
; // alles OK
1033 if ((nFieldTagBad
[nI
] & nMask
)) // Flag: Tag bad
1034 return Read_F_Tag(&aF
); // Taggen
1037 // so viele ueberlesen, das Resultfeld wird wie Haupttext
1039 // JP 15.07.99: attributes can start at char 0x14 so skip one
1040 // char more back == "-2"
1042 return aF
.nLen
- aF
.nLRes
- 2;
1046 if( ( nFieldTagBad
[nI
] & nMask
) ) // Flag: Tag bad
1047 return Read_F_Tag( &aF
); // Taggen
1048 return aF
.nLen
; // oder ignorieren
1050 return aF
.nLen
- aF
.nLRes
- 2; // auf Char 1 positionieren
1052 return aF
.nLen
; // ignorieren
1057 //-----------------------------------------
1059 //-----------------------------------------
1061 // MakeTagString() gibt als Returnwert die Position des ersten
1062 // CR / Zeilenende / Seitenumbruch in pText und wandelt auch nur bis dort
1063 // Wenn keins dieser Sonderzeichen enthalten ist, wird 0 zurueckgeliefert.
1064 void SwWW8ImplReader::MakeTagString( String
& rStr
, const String
& rOrg
)
1066 String
sHex( CREATE_CONST_ASC( "\\x" ));
1067 bool bAllowCr
= SwFltGetFlag( nFieldFlags
, SwFltControlStack::TAGS_IN_TEXT
)
1068 || SwFltGetFlag( nFieldFlags
, SwFltControlStack::ALLOW_FLD_CR
);
1072 for( xub_StrLen nI
= 0;
1073 nI
< rStr
.Len() && rStr
.Len() < (MAX_FIELDLEN
- 4); ++nI
)
1075 bool bSetAsHex
= false;
1076 switch( cChar
= rStr
.GetChar( nI
) )
1078 case 132: // Typographische Anfuehrungszeichen
1079 case 148: // gegen normale tauschen
1081 rStr
.SetChar( nI
, '"' );
1084 rStr
.SetChar( nI
, '{' );
1085 break; // 19..21 zu {|}
1087 rStr
.SetChar( nI
, '|' );
1090 rStr
.SetChar( nI
, '}' );
1092 case '\\': // \{|} per \ Taggen
1096 rStr
.Insert( nI
, '\\' );
1103 rStr
.SetChar( nI
, '\n' );
1112 bSetAsHex
= 0x20 > cChar
;
1118 //all Hex-Numbers with \x before
1119 String
sTmp( sHex
);
1122 sTmp
+= String::CreateFromInt32( cChar
, 16 );
1123 rStr
.Replace( nI
, 1 , sTmp
);
1124 nI
+= sTmp
.Len() - 1;
1128 if( rStr
.Len() > (MAX_FIELDLEN
- 4))
1129 rStr
.Erase( MAX_FIELDLEN
- 4 );
1132 void SwWW8ImplReader::InsertTagField( const USHORT nId
, const String
& rTagText
)
1134 String
aName( CREATE_CONST_ASC( "WwFieldTag" ) );
1135 if( SwFltGetFlag( nFieldFlags
, SwFltControlStack::TAGS_DO_ID
) ) // Nummer?
1136 aName
+= String::CreateFromInt32( nId
); // ausgeben ?
1138 if( SwFltGetFlag(nFieldFlags
, SwFltControlStack::TAGS_IN_TEXT
))
1140 aName
+= rTagText
; // als Txt taggen
1141 rDoc
.InsertString(*pPaM
, aName
,
1142 IDocumentContentOperations::INS_NOHINTEXPAND
);
1147 SwFieldType
* pFT
= rDoc
.InsertFldType(
1148 SwSetExpFieldType( &rDoc
, aName
, nsSwGetSetExpType::GSE_STRING
) );
1149 SwSetExpField
aFld( (SwSetExpFieldType
*)pFT
, rTagText
); // SUB_INVISIBLE
1150 USHORT nSubType
= ( SwFltGetFlag( nFieldFlags
, SwFltControlStack::TAGS_VISIBLE
) ) ? 0 : nsSwExtendedSubType::SUB_INVISIBLE
;
1151 aFld
.SetSubType(nSubType
| nsSwGetSetExpType::GSE_STRING
);
1153 rDoc
.InsertPoolItem( *pPaM
, SwFmtFld( aFld
), 0 );
1157 long SwWW8ImplReader::Read_F_Tag( WW8FieldDesc
* pF
)
1159 long nOldPos
= pStrm
->Tell();
1161 WW8_CP nStart
= pF
->nSCode
- 1; // mit 0x19 am Anfang
1162 long nL
= pF
->nLen
; // Gesamtlaenge mit Resultat u. Nest
1163 if( nL
> MAX_FIELDLEN
)
1164 nL
= MAX_FIELDLEN
; // MaxLaenge, durch Quoten
1167 nL
= pSBase
->WW8ReadString( *pStrm
, sFTxt
,
1168 pPlcxMan
->GetCpOfs() + nStart
, nL
, eStructCharSet
);
1172 MakeTagString( aTagText
, sFTxt
);
1173 InsertTagField( pF
->nId
, aTagText
);
1175 pStrm
->Seek( nOldPos
);
1180 //-----------------------------------------
1182 //-----------------------------------------
1184 eF_ResT
SwWW8ImplReader::Read_F_Input( WW8FieldDesc
* pF
, String
& rStr
)
1189 _ReadFieldParams
aReadParam( rStr
);
1190 while( -1 != ( nRet
= aReadParam
.SkipToNextToken() ))
1196 aQ
= aReadParam
.GetResult();
1201 xub_StrLen n
= aReadParam
.GoToTokenParam();
1202 if( STRING_NOTFOUND
!= n
)
1203 aDef
= aReadParam
.GetResult();
1209 aDef
= GetFieldResult( pF
);
1211 SwInputField
aFld( (SwInputFieldType
*)rDoc
.GetSysFldType( RES_INPUTFLD
),
1212 aDef
, aQ
, INP_TXT
, 0 ); // sichtbar ( geht z.Zt. nicht anders )
1213 rDoc
.InsertPoolItem( *pPaM
, SwFmtFld( aFld
), 0 );
1218 // GetFieldResult alloziert einen String und liest das Feld-Resultat ein
1219 String
SwWW8ImplReader::GetFieldResult( WW8FieldDesc
* pF
)
1221 long nOldPos
= pStrm
->Tell();
1223 WW8_CP nStart
= pF
->nSRes
; // Start Resultat
1224 long nL
= pF
->nLRes
; // Laenge Resultat
1226 return aEmptyStr
; // kein Resultat
1228 if( nL
> MAX_FIELDLEN
)
1229 nL
= MAX_FIELDLEN
; // MaxLaenge, durch Quoten
1233 nL
= pSBase
->WW8ReadString( *pStrm
, sRes
, pPlcxMan
->GetCpOfs() + nStart
,
1234 nL
, eStructCharSet
);
1236 pStrm
->Seek( nOldPos
);
1238 //replace CR 0x0D with LF 0x0A
1239 sRes
.SearchAndReplaceAll(0x0D, 0x0A);
1240 //replace VT 0x0B with LF 0x0A
1241 sRes
.SearchAndReplaceAll(0x0B, 0x0A);
1246 Bookmarks can be set with fields SET and ASK, and they can be referenced with
1247 REF. When set, they behave like variables in writer, otherwise they behave
1248 like normal bookmarks. We can check whether we should use a show variable
1249 instead of a normal bookmark ref by converting to "show variable" at the end
1250 of the document those refs which look for the content of a bookmark but whose
1251 bookmarks were set with SET or ASK. (See SwWW8FltRefStack)
1253 The other piece of the puzzle is that refs that point to the "location" of the
1254 bookmark will in word actually point to the last location where the bookmark
1255 was set with SET or ASK, not the actual bookmark. This is only noticable when
1256 a document sets the bookmark more than once. This is because word places the
1257 true bookmark at the location of the last set, but the refs will display the
1258 position of the first set before the ref.
1260 So what we will do is
1262 1) keep a list of all bookmarks that were set, any bookmark names mentioned
1263 here that are refed by content will be converted to show variables.
1265 2) create pseudo bookmarks for every position that a bookmark is set with SET
1266 or ASK but has no existing bookmark. We can then keep a map from the original
1267 bookmark name to the new one. As we parse the document new pseudo names will
1268 replace the older ones, so the map always contains the bookmark of the
1269 location that msword itself would use.
1271 3) word's bookmarks are case insensitive, writers are not. So we need to
1272 map case different versions together, regardless of whether they are
1275 4) when a reference is (first) SET or ASK, the bookmark associated with it
1276 is placed around the 0x14 0x15 result part of the field. We will fiddle
1277 the placement to be the writer equivalent of directly before and after
1278 the field, which gives the same effect and meaning, to do so we must
1279 get any bookmarks in the field range, and begin them immediately before
1280 the set/ask field, and end them directly afterwards. MapBookmarkVariables
1281 returns an identifier of the bookmark attribute to close after inserting
1282 the appropiate set/ask field.
1284 long SwWW8ImplReader::MapBookmarkVariables(const WW8FieldDesc
* pF
,
1285 String
&rOrigName
, const String
&rData
)
1287 ASSERT(pPlcxMan
,"No pPlcxMan");
1290 If there was no bookmark associated with this set field, then we create a
1291 pseudo one and insert it in the document.
1294 pPlcxMan
->GetBook()->MapName(rOrigName
);
1295 String sName
= pPlcxMan
->GetBook()->GetBookmark(
1296 pF
->nSCode
, pF
->nSCode
+ pF
->nLen
, nIndex
);
1299 pPlcxMan
->GetBook()->SetStatus(nIndex
, BOOK_IGNORE
);
1304 sName
= CREATE_CONST_ASC("WWSetBkmk");
1305 nNo
= pReffingStck
->aFieldVarNames
.size()+1;
1306 sName
+= String::CreateFromInt32(nNo
);
1307 nNo
+= pPlcxMan
->GetBook()->GetIMax();
1309 pReffedStck
->NewAttr(*pPaM
->GetPoint(),
1310 SwFltBookmark(BookmarkToWriter(sName
), rData
, nNo
, 0));
1311 pReffingStck
->aFieldVarNames
[rOrigName
] = sName
;
1316 Word can set a bookmark with set or with ask, such a bookmark is equivalent to
1317 our variables, but until the end of a document we cannot be sure if a bookmark
1318 is a variable or not, at the end we will have a list of reference names which
1319 were set or asked, all bookmarks using the content of those bookmarks are
1320 converted to show variables, those that reference the position of the field
1321 can be left as references, because a bookmark is also inserted at the position
1322 of a set or ask field, either by word, or in some special cases by the import
1325 SwFltStackEntry
*SwWW8FltRefStack::RefToVar(const SwField
* pFld
,
1326 SwFltStackEntry
*pEntry
)
1328 SwFltStackEntry
*pRet
=0;
1329 if (pFld
&& RES_GETREFFLD
== pFld
->Which())
1331 //Get the name of the ref field, and see if actually a variable
1332 const String
&rName
= pFld
->GetPar1();
1333 ::std::map
<String
,String
,SwWW8FltRefStack::ltstr
>::const_iterator
1334 aResult
= aFieldVarNames
.find(rName
);
1336 if (aResult
!= aFieldVarNames
.end())
1338 SwGetExpField
aFld( (SwGetExpFieldType
*)
1339 pDoc
->GetSysFldType(RES_GETEXPFLD
), rName
, nsSwGetSetExpType::GSE_STRING
, 0);
1340 delete pEntry
->pAttr
;
1341 SwFmtFld
aTmp(aFld
);
1342 pEntry
->pAttr
= aTmp
.Clone();
1349 String
SwWW8ImplReader::GetMappedBookmark(const String
&rOrigName
)
1351 String
sName(BookmarkToWriter(rOrigName
));
1352 ASSERT(pPlcxMan
,"no pPlcxMan");
1353 pPlcxMan
->GetBook()->MapName(sName
);
1355 //See if there has been a variable set with this name, if so get
1356 //the pseudo bookmark name that was set with it.
1357 ::std::map
<String
,String
,SwWW8FltRefStack::ltstr
>::const_iterator aResult
=
1358 pReffingStck
->aFieldVarNames
.find(sName
);
1360 const String
&rBkmName
= (aResult
== pReffingStck
->aFieldVarNames
.end())
1361 ? sName
: (*aResult
).second
;
1367 eF_ResT
SwWW8ImplReader::Read_F_InputVar( WW8FieldDesc
* pF
, String
& rStr
)
1373 _ReadFieldParams
aReadParam( rStr
);
1374 while( -1 != ( nRet
= aReadParam
.SkipToNextToken() ))
1379 if (!sOrigName
.Len())
1380 sOrigName
= aReadParam
.GetResult();
1381 else if( !aQ
.Len() )
1382 aQ
= aReadParam
.GetResult();
1386 if (STRING_NOTFOUND
!= aReadParam
.GoToTokenParam())
1387 aDef
= aReadParam
.GetResult();
1392 if( !sOrigName
.Len() )
1393 return FLD_TAGIGN
; // macht ohne Textmarke keinen Sinn
1395 String
aResult(GetFieldResult(pF
));
1397 //#i24377#, munge Default Text into title as we have only one slot
1398 //available for aResult and aDef otherwise
1402 aQ
.APPEND_CONST_ASC(" - ");
1406 long nNo
= MapBookmarkVariables(pF
, sOrigName
, aResult
);
1408 SwSetExpFieldType
* pFT
= (SwSetExpFieldType
*)rDoc
.InsertFldType(
1409 SwSetExpFieldType(&rDoc
, sOrigName
, nsSwGetSetExpType::GSE_STRING
));
1410 SwSetExpField
aFld(pFT
, aResult
);
1411 aFld
.SetSubType(nsSwExtendedSubType::SUB_INVISIBLE
| nsSwGetSetExpType::GSE_STRING
);
1412 aFld
.SetInputFlag(true);
1413 aFld
.SetPromptText( aQ
);
1415 rDoc
.InsertPoolItem( *pPaM
, SwFmtFld( aFld
), 0 );
1417 pReffedStck
->SetAttr(*pPaM
->GetPoint(), RES_FLTR_BOOKMARK
, true, nNo
);
1422 eF_ResT
SwWW8ImplReader::Read_F_ANumber( WW8FieldDesc
*, String
& rStr
)
1424 if( !pNumFldType
){ // 1. Mal
1425 SwSetExpFieldType
aT( &rDoc
, CREATE_CONST_ASC("AutoNr"), nsSwGetSetExpType::GSE_SEQ
);
1426 pNumFldType
= rDoc
.InsertFldType( aT
);
1428 SwSetExpField
aFld( (SwSetExpFieldType
*)pNumFldType
, aEmptyStr
,
1429 GetNumberPara( rStr
) );
1430 aFld
.SetValue( ++nFldNum
);
1431 rDoc
.InsertPoolItem( *pPaM
, SwFmtFld( aFld
), 0 );
1436 eF_ResT
SwWW8ImplReader::Read_F_Seq( WW8FieldDesc
*, String
& rStr
)
1438 String aSequenceName
;
1440 bool bHidden
= false;
1441 bool bFormat
= false;
1442 bool bShowLast
= false;
1443 bool bCountOn
= true;
1445 SvxExtNumType eNumFormat
= SVX_NUM_ARABIC
;
1447 _ReadFieldParams
aReadParam( rStr
);
1448 while( -1 != ( nRet
= aReadParam
.SkipToNextToken() ))
1453 if( !aSequenceName
.Len() )
1454 aSequenceName
= aReadParam
.GetResult();
1455 else if( !aBook
.Len() )
1456 aBook
= aReadParam
.GetResult();
1461 bHidden
= true; // Hidden-Flag aktivieren
1465 bFormat
= true; // Format-Flag aktivieren
1466 bHidden
= false; // Hidden-Flag deaktivieren
1467 nRet
= aReadParam
.SkipToNextToken();
1469 eNumFormat
= GetNumTypeFromName( aReadParam
.GetResult() );
1473 bShowLast
= false; // Zaehler neu setzen
1475 nRet
= aReadParam
.SkipToNextToken();
1477 sStart
= aReadParam
.GetResult();
1481 bShowLast
= true; // zuletzt verwendete Nummer anzeigen
1486 bCountOn
= true; // Nummer um eins erhoehen (default)
1490 case 's': // Outline Level
1491 //#i19682, what am I to do with this value
1495 if (!aSequenceName
.Len() && !aBook
.Len())
1498 SwSetExpFieldType
* pFT
= (SwSetExpFieldType
*)rDoc
.InsertFldType(
1499 SwSetExpFieldType( &rDoc
, aSequenceName
, nsSwGetSetExpType::GSE_SEQ
) );
1500 SwSetExpField
aFld( pFT
, aEmptyStr
, eNumFormat
);
1503 aFld
.SetFormula( ( aSequenceName
+= '=' ) += sStart
);
1505 aFld
.SetFormula(aSequenceName
);
1507 rDoc
.InsertPoolItem(*pPaM
, SwFmtFld(aFld
), 0);
1511 eF_ResT
SwWW8ImplReader::Read_F_DocInfo( WW8FieldDesc
* pF
, String
& rStr
)
1514 // RegInfoFormat, DefaultFormat fuer DocInfoFelder
1515 USHORT nReg
= DI_SUB_AUTHOR
;
1516 bool bDateTime
= false;
1520 String aDocProperty
;
1521 _ReadFieldParams
aReadParam( rStr
);
1523 while( -1 != ( nRet
= aReadParam
.SkipToNextToken() ))
1528 if( !aDocProperty
.Len() )
1529 aDocProperty
= aReadParam
.GetResult();
1532 //Skip over MERGEFORMAT
1533 aReadParam
.SkipToNextToken();
1537 aDocProperty
.EraseAllChars('"');
1540 There are up to 26 fields that may be meant by 'DocumentProperty'.
1541 Which of them is to be inserted here ?
1542 This Problem can only be solved by implementing a name matching
1543 method that compares the given Parameter String with the four
1544 possible name sets (english, german, french, spanish)
1547 static const sal_Char
* aName10
= "\x0F"; // SW field code
1548 static const sal_Char
* aName11
// German
1550 static const sal_Char
* aName12
// French
1552 static const sal_Char
* aName13
// English
1554 static const sal_Char
* aName14
// Spanish
1556 static const sal_Char
* aName20
= "\x15"; // SW filed code
1557 static const sal_Char
* aName21
// German
1559 static const sal_Char
* aName22
// French
1561 static const sal_Char
* aName23
// English
1563 static const sal_Char
* aName24
// Spanish
1565 static const sal_Char
* aName30
= "\x16"; // SW filed code
1566 static const sal_Char
* aName31
// German
1567 = "ZULETZTGESPEICHERTZEIT";
1568 static const sal_Char
* aName32
// French
1569 = "DERNIERENREGISTREMENT";
1570 static const sal_Char
* aName33
// English
1572 static const sal_Char
* aName34
// Spanish
1574 static const sal_Char
* aName40
= "\x17"; // SW filed code
1575 static const sal_Char
* aName41
// German
1576 = "ZULETZTGEDRUCKT";
1577 static const sal_Char
* aName42
// French
1578 = "DERNI\xC8" "REIMPRESSION";
1579 static const sal_Char
* aName43
// English
1581 static const sal_Char
* aName44
// Spanish
1583 static const sal_Char
* aName50
= "\x18"; // SW filed code
1584 static const sal_Char
* aName51
// German
1585 = "\xDC" "BERARBEITUNGSNUMMER";
1586 static const sal_Char
* aName52
// French
1587 = "NUM\xC9" "RODEREVISION";
1588 static const sal_Char
* aName53
// English
1590 static const sal_Char
* aName54
// Spanish
1592 static const USHORT nFldCnt
= 5;
1594 // additional fields are to be coded soon! :-)
1596 static const USHORT nLangCnt
= 4;
1597 static const sal_Char
*aNameSet_26
[nFldCnt
][nLangCnt
+1] =
1599 {aName10
, aName11
, aName12
, aName13
, aName14
},
1600 {aName20
, aName21
, aName22
, aName23
, aName24
},
1601 {aName30
, aName31
, aName32
, aName33
, aName34
},
1602 {aName40
, aName41
, aName42
, aName43
, aName44
},
1603 {aName50
, aName51
, aName52
, aName53
, aName54
}
1606 bool bFldFound
= false;
1608 for(USHORT nLIdx
=1; !bFldFound
&& (nLangCnt
> nLIdx
); ++nLIdx
)
1610 for(nFIdx
= 0; !bFldFound
&& (nFldCnt
> nFIdx
); ++nFIdx
)
1612 if( aDocProperty
.Equals( String( aNameSet_26
[nFIdx
][nLIdx
],
1613 RTL_TEXTENCODING_MS_1252
) ) )
1616 pF
->nId
= aNameSet_26
[nFIdx
][0][0];
1624 SwUserFieldType aTmp( &rDoc, aDocProperty );
1625 aTmp.SetContent(GetFieldResult( pF ));
1626 SwUserField aUFld( (SwUserFieldType*)rDoc.InsertFldType( aTmp ));
1627 aUFld.ChangeFormat( UF_STRING );
1628 rDoc.Insert( *pPaM, SwFmtFld( aUFld ), 0);
1630 SwDocInfoField
aFld( (SwDocInfoFieldType
*)
1631 rDoc
.GetSysFldType( RES_DOCINFOFLD
), DI_CUSTOM
|nReg
, aDocProperty
, GetFieldResult( pF
) );
1632 rDoc
.InsertPoolItem(*pPaM
, SwFmtFld(aFld
), 0);
1641 /* kann alle INFO-Vars!! */
1658 nReg
= DI_SUB_AUTHOR
;
1685 sal_uInt32 nFormat
= 0;
1690 short nDT
= GetTimeDatePara(rStr
, nFormat
, nLang
, pF
->nId
);
1693 case NUMBERFORMAT_DATE
:
1696 case NUMBERFORMAT_TIME
:
1699 case NUMBERFORMAT_DATETIME
:
1708 SwDocInfoField
aFld( (SwDocInfoFieldType
*)
1709 rDoc
.GetSysFldType( RES_DOCINFOFLD
), nSub
|nReg
, String(), nFormat
);
1711 ForceFieldLanguage(aFld
, nLang
);
1712 rDoc
.InsertPoolItem(*pPaM
, SwFmtFld(aFld
), 0);
1717 eF_ResT
SwWW8ImplReader::Read_F_Author( WW8FieldDesc
*, String
& )
1719 // SH: Das SwAuthorField bezeichnet nicht den urspruenglichen
1720 // Autor, sondern den aktuellen Benutzer, also besser ueber DocInfo
1722 SwDocInfoField
aFld( (SwDocInfoFieldType
*)
1723 rDoc
.GetSysFldType( RES_DOCINFOFLD
),
1724 DI_CREATE
|DI_SUB_AUTHOR
, String() );
1725 rDoc
.InsertPoolItem( *pPaM
, SwFmtFld( aFld
), 0 );
1729 eF_ResT
SwWW8ImplReader::Read_F_TemplName( WW8FieldDesc
*, String
& )
1731 SwTemplNameField
aFld( (SwTemplNameFieldType
*)
1732 rDoc
.GetSysFldType( RES_TEMPLNAMEFLD
), FF_NAME
);
1733 rDoc
.InsertPoolItem( *pPaM
, SwFmtFld( aFld
), 0 );
1737 // Sowohl das Datum- wie auch das Uhrzeit-Feld kann fuer Datum, fuer Uhrzeit
1738 // oder fuer beides benutzt werden.
1739 eF_ResT
SwWW8ImplReader::Read_F_DateTime( WW8FieldDesc
*pF
, String
& rStr
)
1741 bool bHijri
= false;
1743 _ReadFieldParams
aReadParam(rStr
);
1745 while (-1 != (nTok
= aReadParam
.SkipToNextToken()))
1762 sal_uInt32 nFormat
= 0;
1765 short nDT
= GetTimeDatePara(rStr
, nFormat
, nLang
, ww::eDATE
, bHijri
);
1767 if( NUMBERFORMAT_UNDEFINED
== nDT
) // no D/T-Formatstring
1771 nDT
= NUMBERFORMAT_TIME
;
1772 nFormat
= rDoc
.GetNumberFormatter()->GetFormatIndex(
1773 NF_TIME_START
, LANGUAGE_SYSTEM
);
1777 nDT
= NUMBERFORMAT_DATE
;
1778 nFormat
= rDoc
.GetNumberFormatter()->GetFormatIndex(
1779 NF_DATE_START
, LANGUAGE_SYSTEM
);
1783 if (nDT
& NUMBERFORMAT_DATE
)
1785 SwDateTimeField
aFld((SwDateTimeFieldType
*)
1786 rDoc
.GetSysFldType(RES_DATETIMEFLD
), DATEFLD
, nFormat
);
1787 ForceFieldLanguage(aFld
, nLang
);
1788 rDoc
.InsertPoolItem( *pPaM
, SwFmtFld( aFld
), 0 );
1790 else if (nDT
== NUMBERFORMAT_TIME
)
1792 SwDateTimeField
aFld((SwDateTimeFieldType
*)
1793 rDoc
.GetSysFldType(RES_DATETIMEFLD
), TIMEFLD
, nFormat
);
1794 ForceFieldLanguage(aFld
, nLang
);
1795 rDoc
.InsertPoolItem( *pPaM
, SwFmtFld( aFld
), 0 );
1801 eF_ResT
SwWW8ImplReader::Read_F_FileName(WW8FieldDesc
*, String
&rStr
)
1803 SwFileNameFormat eType
= FF_NAME
;
1805 _ReadFieldParams
aReadParam(rStr
);
1806 while (-1 != (nRet
= aReadParam
.SkipToNextToken()))
1811 eType
= FF_PATHNAME
;
1814 //Skip over MERGEFORMAT
1815 aReadParam
.SkipToNextToken();
1818 ASSERT(!this, "unknown option in FileName field");
1823 SwFileNameField
aFld(
1824 (SwFileNameFieldType
*)rDoc
.GetSysFldType(RES_FILENAMEFLD
), eType
);
1825 rDoc
.InsertPoolItem(*pPaM
, SwFmtFld(aFld
), 0);
1829 eF_ResT
SwWW8ImplReader::Read_F_Anz( WW8FieldDesc
* pF
, String
& rStr
)
1830 { // SeitenZahl - Feld
1831 USHORT nSub
= DS_PAGE
;
1833 case 27: nSub
= DS_WORD
; break; // Wordzahl
1834 case 28: nSub
= DS_CHAR
; break; // Zeichenzahl
1836 SwDocStatField
aFld( (SwDocStatFieldType
*)
1837 rDoc
.GetSysFldType( RES_DOCSTATFLD
), nSub
,
1838 GetNumberPara( rStr
) );
1839 rDoc
.InsertPoolItem( *pPaM
, SwFmtFld( aFld
), 0 );
1843 eF_ResT
SwWW8ImplReader::Read_F_CurPage( WW8FieldDesc
*, String
& rStr
)
1845 // zusaetzlich mit Kapitelnummer?
1848 SwChapterField
aFld( (SwChapterFieldType
*)
1849 rDoc
.GetSysFldType( RES_CHAPTERFLD
), CF_NUMBER
);
1850 aFld
.SetLevel( nPgChpLevel
);
1851 rDoc
.InsertPoolItem( *pPaM
, SwFmtFld( aFld
), 0 );
1853 static const sal_Char aDelim
[] = "-.:\x97\x96";
1854 BYTE nDelim
= nPgChpDelim
;
1858 sal_Unicode c
= ByteString::ConvertToUnicode( aDelim
[ nDelim
],
1859 RTL_TEXTENCODING_MS_1252
);
1862 rDoc
.InsertString( *pPaM
, CHAR_HARDHYPHEN
);
1866 rDoc
.InsertString( *pPaM
, c
); // maybe insert ZWNBSP?
1871 SwPageNumberField
aFld( (SwPageNumberFieldType
*)
1872 rDoc
.GetSysFldType( RES_PAGENUMBERFLD
), PG_RANDOM
,
1873 GetNumberPara(rStr
, true));
1875 rDoc
.InsertPoolItem( *pPaM
, SwFmtFld( aFld
), 0 );
1879 eF_ResT
SwWW8ImplReader::Read_F_Symbol( WW8FieldDesc
*, String
& rStr
)
1884 sal_Int32 nSize
= 0;
1886 _ReadFieldParams
aReadParam( rStr
);
1887 while( -1 != ( nRet
= aReadParam
.SkipToNextToken() ))
1893 aQ
= aReadParam
.GetResult();
1898 xub_StrLen n
= aReadParam
.GoToTokenParam();
1899 if( STRING_NOTFOUND
!= n
)
1900 aName
= aReadParam
.GetResult();
1907 xub_StrLen n
= aReadParam
.GoToTokenParam();
1908 if (STRING_NOTFOUND
!= n
)
1909 aSiz
= aReadParam
.GetResult();
1911 nSize
= aSiz
.ToInt32() * 20; // pT -> twip
1917 return FLD_TAGIGN
; // -> kein 0-Zeichen in Text
1919 if (sal_Unicode cChar
= static_cast<sal_Unicode
>(aQ
.ToInt32()))
1921 if (aName
.Len()) // Font Name set ?
1923 SvxFontItem
aFont(FAMILY_DONTKNOW
, aName
, aEmptyStr
,
1924 PITCH_DONTKNOW
, RTL_TEXTENCODING_SYMBOL
, RES_CHRATR_FONT
);
1925 NewAttr(aFont
); // new Font
1928 if (nSize
> 0) //#i20118#
1930 SvxFontHeightItem
aSz(nSize
, 100, RES_CHRATR_FONTSIZE
);
1934 rDoc
.InsertString(*pPaM
, cChar
);
1937 pCtrlStck
->SetAttr(*pPaM
->GetPoint(), RES_CHRATR_FONTSIZE
);
1939 pCtrlStck
->SetAttr(*pPaM
->GetPoint(), RES_CHRATR_FONT
);
1943 rDoc
.InsertString(*pPaM
, CREATE_CONST_ASC("###"));
1950 eF_ResT
SwWW8ImplReader::Read_F_Embedd( WW8FieldDesc
*, String
& rStr
)
1955 _ReadFieldParams
aReadParam( rStr
);
1956 while( -1 != ( nRet
= aReadParam
.SkipToNextToken() ))
1961 sHost
= aReadParam
.GetResult();
1970 if( bObj
&& nPicLocFc
)
1971 nObjLocFc
= nPicLocFc
;
1978 eF_ResT
SwWW8ImplReader::Read_F_Set( WW8FieldDesc
* pF
, String
& rStr
)
1983 _ReadFieldParams
aReadParam( rStr
);
1984 while( -1 != ( nRet
= aReadParam
.SkipToNextToken() ))
1989 if( !sOrigName
.Len() )
1990 sOrigName
= aReadParam
.GetResult();
1991 else if( !sVal
.Len() )
1992 sVal
= aReadParam
.GetResult();
1997 long nNo
= MapBookmarkVariables(pF
,sOrigName
,sVal
);
1999 SwFieldType
* pFT
= rDoc
.InsertFldType( SwSetExpFieldType( &rDoc
, sOrigName
,
2000 nsSwGetSetExpType::GSE_STRING
) );
2001 SwSetExpField
aFld( (SwSetExpFieldType
*)pFT
, sVal
, ULONG_MAX
);
2002 aFld
.SetSubType(nsSwExtendedSubType::SUB_INVISIBLE
| nsSwGetSetExpType::GSE_STRING
);
2004 rDoc
.InsertPoolItem( *pPaM
, SwFmtFld( aFld
), 0 );
2006 pReffedStck
->SetAttr(*pPaM
->GetPoint(), RES_FLTR_BOOKMARK
, true, nNo
);
2012 eF_ResT
SwWW8ImplReader::Read_F_Ref( WW8FieldDesc
*, String
& rStr
)
2013 { // Reference - Field
2014 String sOrigBkmName
;
2015 bool bChapterNr
= false;
2016 bool bAboveBelow
= false;
2019 _ReadFieldParams
aReadParam( rStr
);
2020 while( -1 != ( nRet
= aReadParam
.SkipToNextToken() ))
2025 if( !sOrigBkmName
.Len() ) // get name of bookmark
2026 sOrigBkmName
= aReadParam
.GetResult();
2031 bChapterNr
= true; // activate flag 'Chapter Number'
2040 // unimplemented switch: just do 'nix nought nothing' :-)
2045 String
sBkmName(GetMappedBookmark(sOrigBkmName
));
2047 if (!bAboveBelow
|| bChapterNr
)
2052 (SwGetRefFieldType
*)rDoc
.GetSysFldType( RES_GETREFFLD
),
2053 sBkmName
,REF_BOOKMARK
,0,REF_CHAPTER
);
2054 rDoc
.InsertPoolItem( *pPaM
, SwFmtFld( aFld
), 0 );
2059 If we are just inserting the contents of the bookmark, then it
2060 is possible that the bookmark is actually a variable, so we
2061 must store it until the end of the document to see if it was,
2062 in which case we'll turn it into a show variable
2065 (SwGetRefFieldType
*)rDoc
.GetSysFldType( RES_GETREFFLD
),
2066 sOrigBkmName
,REF_BOOKMARK
,0,REF_CONTENT
);
2067 pReffingStck
->NewAttr( *pPaM
->GetPoint(), SwFmtFld(aFld
) );
2068 pReffingStck
->SetAttr( *pPaM
->GetPoint(), RES_TXTATR_FIELD
);
2074 SwGetRefField
aFld( (SwGetRefFieldType
*)
2075 rDoc
.GetSysFldType( RES_GETREFFLD
), sBkmName
, REF_BOOKMARK
, 0,
2077 rDoc
.InsertPoolItem(*pPaM
, SwFmtFld(aFld
), 0);
2082 // Note Reference - Field
2083 eF_ResT
SwWW8ImplReader::Read_F_NoteReference( WW8FieldDesc
*, String
& rStr
)
2086 bool bChapterNr
= false;
2087 bool bAboveBelow
= false;
2090 _ReadFieldParams
aReadParam( rStr
);
2091 while( -1 != ( nRet
= aReadParam
.SkipToNextToken() ))
2096 if( !aBkmName
.Len() ) // get name of foot/endnote
2097 aBkmName
= aReadParam
.GetResult();
2100 bChapterNr
= true; // activate flag 'Chapter Number'
2108 // unimplemented switch: just do 'nix nought nothing' :-)
2113 // set Sequence No of corresponding Foot-/Endnote to Zero
2114 // (will be corrected in
2115 SwGetRefField
aFld( (SwGetRefFieldType
*)
2116 rDoc
.GetSysFldType( RES_GETREFFLD
), aBkmName
, REF_FOOTNOTE
, 0,
2118 pReffingStck
->NewAttr(*pPaM
->GetPoint(), SwFmtFld(aFld
));
2119 pReffingStck
->SetAttr(*pPaM
->GetPoint(), RES_TXTATR_FIELD
);
2122 SwGetRefField
aFld2( (SwGetRefFieldType
*)
2123 rDoc
.GetSysFldType( RES_GETREFFLD
),aBkmName
, REF_FOOTNOTE
, 0,
2125 pReffingStck
->NewAttr(*pPaM
->GetPoint(), SwFmtFld(aFld2
));
2126 pReffingStck
->SetAttr(*pPaM
->GetPoint(), RES_TXTATR_FIELD
);
2132 eF_ResT
SwWW8ImplReader::Read_F_PgRef( WW8FieldDesc
*, String
& rStr
)
2136 _ReadFieldParams
aReadParam( rStr
);
2137 while( -1 != ( nRet
= aReadParam
.SkipToNextToken() ))
2142 if( !sOrigName
.Len() )
2143 sOrigName
= aReadParam
.GetResult();
2148 String
sName(GetMappedBookmark(sOrigName
));
2150 #if defined(WW_NATIVE_TOC)
2152 ::rtl::OUString aBookmarkName
=::rtl::OUString::createFromAscii("_REF");
2153 maFieldStack
.back().SetBookmarkName(aBookmarkName
);
2154 maFieldStack
.back().SetBookmarkType(::rtl::OUString::createFromAscii(ECMA_PAGEREF
));
2155 maFieldStack
.back().AddParam(rtl::OUString(), sName
);
2162 (SwGetRefFieldType
*)rDoc
.GetSysFldType( RES_GETREFFLD
), sName
,
2163 REF_BOOKMARK
, 0, REF_PAGE
);
2165 rDoc
.InsertPoolItem( *pPaM
, SwFmtFld( aFld
), 0 );
2169 // "MACROSCHALTFL"ACHE"
2170 eF_ResT
SwWW8ImplReader::Read_F_Macro( WW8FieldDesc
*, String
& rStr
)
2175 bool bNewVText
= true;
2176 bool bBracket
= false;
2177 _ReadFieldParams
aReadParam( rStr
);
2179 xub_StrLen nOffset
= 0;
2181 while( -1 != ( nRet
= aReadParam
.SkipToNextToken() ))
2187 aName
= aReadParam
.GetResult();
2188 else if( !aVText
.Len() || bBracket
)
2190 nOffset
= aReadParam
.GetTokenSttPtr() + 1;
2194 aVText
+= aReadParam
.GetResult();
2197 bBracket
= aVText
.EqualsIgnoreCaseAscii('[', 1, 0)
2201 else if( aVText
.GetChar( aVText
.Len()-1 ) == ']' )
2208 return FLD_TAGIGN
; // makes no sense without Makro-Name
2210 aName
.InsertAscii( "StarOffice.Standard.Modul1.", 0 );
2212 SwMacroField
aFld( (SwMacroFieldType
*)
2213 rDoc
.GetSysFldType( RES_MACROFLD
), aName
, aVText
);
2214 rDoc
.InsertPoolItem( *pPaM
, SwFmtFld( aFld
), 0 );
2217 WW8_CP nOldCp
= pPlcxMan
->Where();
2218 WW8_CP nCp
= nOldCp
+ nOffset
;
2222 aPaM
.Move(fnMoveBackward
);
2225 mpPostProcessAttrsInfo
= new WW8PostProcessAttrsInfo(nCp
, nCp
, aPaM
);
2230 WW8PostProcessAttrsInfo::WW8PostProcessAttrsInfo(WW8_CP nCpStart
, WW8_CP nCpEnd
,
2233 mnCpStart(nCpStart
),
2235 mPaM(*rPaM
.GetPoint(), *rPaM
.GetMark()),
2236 mItemSet(rPaM
.GetDoc()->GetAttrPool(), RES_CHRATR_BEGIN
, RES_PARATR_END
- 1)
2240 bool CanUseRemoteLink(const String
&rGrfName
)
2242 bool bUseRemote
= false;
2245 ::ucbhelper::Content
aCnt(rGrfName
,
2247 ucb::XCommandEnvironment
>() );
2248 rtl::OUString aTitle
;
2250 aCnt
.getPropertyValue(rtl::OUString::createFromAscii("Title" ))
2252 bUseRemote
= (aTitle
.getLength() > 0);
2256 // this file did not exist, so we will not set this as graphiclink
2262 // "EINF"UGENGRAFIK"
2263 eF_ResT
SwWW8ImplReader::Read_F_IncludePicture( WW8FieldDesc
*, String
& rStr
)
2266 bool bEmbedded
= true;
2269 _ReadFieldParams
aReadParam( rStr
);
2270 while( -1 != ( nRet
= aReadParam
.SkipToNextToken() ))
2275 if (!aGrfName
.Len())
2276 ConvertFFileName(aGrfName
, aReadParam
.GetResult());
2280 bEmbedded
= false; // Embedded-Flag deaktivieren
2283 case 'c':// den Converter-Namen ueberlesen
2284 aReadParam
.FindNextStringPiece();
2290 bEmbedded
= !CanUseRemoteLink(aGrfName
);
2297 Wir setzen jetzt den Link ins Doc und merken uns den SwFlyFrmFmt.
2298 Da wir ja unten auf jjeden Fall mit Return-Wert FLD_READ_FSPA enden,
2299 wird der Skip-Wert so bemessen, dass das folgende Char-1 eingelesen
2301 Wenn wir dann in SwWW8ImplReader::ImportGraf() reinlaufen, wird
2302 erkannt, dass wir soeben einen Grafik-Link inserted haben und
2303 das passende SwAttrSet wird ins Frame-Format eingesetzt.
2305 SfxItemSet
aFlySet( rDoc
.GetAttrPool(), RES_FRMATR_BEGIN
,
2307 aFlySet
.Put( SwFmtAnchor( FLY_IN_CNTNT
) );
2308 aFlySet
.Put( SwFmtVertOrient( 0, text::VertOrientation::TOP
, text::RelOrientation::FRAME
));
2309 pFlyFmtOfJustInsertedGraphic
= rDoc
.Insert( *pPaM
,
2315 maGrfNameGenerator
.SetUniqueGraphName(pFlyFmtOfJustInsertedGraphic
,
2316 INetURLObject(aGrfName
).GetBase());
2318 return FLD_READ_FSPA
;
2322 String
wwSectionNamer::UniqueName()
2324 String
aName(msFileLinkSeed
);
2325 aName
+= String::CreateFromInt32(++mnFileSectionNo
);
2326 return mrDoc
.GetUniqueSectionName(&aName
);
2330 eF_ResT
SwWW8ImplReader::Read_F_IncludeText( WW8FieldDesc
* /*pF*/, String
& rStr
)
2335 _ReadFieldParams
aReadParam( rStr
);
2336 while( -1 != ( nRet
= aReadParam
.SkipToNextToken() ))
2342 aPara
= aReadParam
.GetResult();
2343 else if( !aBook
.Len() )
2344 aBook
= aReadParam
.GetResult();
2347 //Skip over MERGEFORMAT
2348 aReadParam
.SkipToNextToken();
2352 ConvertFFileName(aPara
, aPara
);
2354 if (aBook
.Len() && aBook
.GetChar( 0 ) != '\\')
2356 // Bereich aus Quelle ( kein Switch ) ?
2357 ConvertUFName(aBook
);
2358 aPara
+= sfx2::cTokenSeperator
;
2359 aPara
+= sfx2::cTokenSeperator
;
2365 What we will do is insert a section to be linked to a file, but just in
2366 case the file is not available we will fill in the section with the stored
2367 content of this winword field as a fallback.
2369 SwPosition
aTmpPos(*pPaM
->GetPoint());
2371 SwSection
aSection(FILE_LINK_SECTION
, maSectionNameGenerator
.UniqueName());
2372 aSection
.SetLinkFileName( aPara
);
2373 aSection
.SetProtect(true);
2375 SwSection
*const pSection
= rDoc
.InsertSwSection(*pPaM
, aSection
, 0, false);
2376 ASSERT(pSection
, "no section inserted");
2379 const SwSectionNode
* pSectionNode
= pSection
->GetFmt()->GetSectionNode();
2380 ASSERT(pSectionNode
, "no section node!");
2384 pPaM
->GetPoint()->nNode
= pSectionNode
->GetIndex()+1;
2385 pPaM
->GetPoint()->nContent
.Assign(pPaM
->GetCntntNode(), 0 );
2387 //we have inserted a section before this point, so adjust pos
2388 //for future page/section segment insertion
2389 maSectionManager
.PrependedInlineNode(aTmpPos
, *pPaM
->GetNode());
2394 // "SERIENDRUCKFELD"
2395 eF_ResT
SwWW8ImplReader::Read_F_DBField( WW8FieldDesc
* pF
, String
& rStr
)
2399 _ReadFieldParams
aReadParam( rStr
);
2400 while( -1 != ( nRet
= aReadParam
.SkipToNextToken() ))
2406 aName
= aReadParam
.GetResult();
2410 SwDBFieldType
aD( &rDoc
, aName
, SwDBData() ); // Datenbank: Nichts
2412 SwFieldType
* pFT
= rDoc
.InsertFldType( aD
);
2413 SwDBField
aFld( (SwDBFieldType
*)pFT
);
2414 aFld
.SetFieldCode( rStr
);
2417 pSBase
->WW8ReadString( *pStrm
, aResult
, pPlcxMan
->GetCpOfs()+
2418 pF
->nSRes
, pF
->nLRes
, eTextCharSet
);
2420 aFld
.InitContent(aResult
);
2422 rDoc
.InsertPoolItem(*pPaM
, SwFmtFld( aFld
), 0);
2428 eF_ResT
SwWW8ImplReader::Read_F_DBNext( WW8FieldDesc
*, String
& )
2430 SwDBNextSetFieldType aN
;
2431 SwFieldType
* pFT
= rDoc
.InsertFldType( aN
);
2432 SwDBNextSetField
aFld( (SwDBNextSetFieldType
*)pFT
, aEmptyStr
, aEmptyStr
,
2433 SwDBData() ); // Datenbank: Nichts
2434 rDoc
.InsertPoolItem( *pPaM
, SwFmtFld( aFld
), 0 );
2439 eF_ResT
SwWW8ImplReader::Read_F_DBNum( WW8FieldDesc
*, String
& )
2441 SwDBSetNumberFieldType aN
;
2442 SwFieldType
* pFT
= rDoc
.InsertFldType( aN
);
2443 SwDBSetNumberField
aFld( (SwDBSetNumberFieldType
*)pFT
,
2444 SwDBData() ); // Datenbank: Nichts
2445 rDoc
.InsertPoolItem( *pPaM
, SwFmtFld( aFld
), 0 );
2450 EQ , only the usage for
2451 a. Combined Characters supported, must be exactly in the form that word
2452 only accepts as combined charactersm, i.e.
2453 eq \o(\s\up Y(XXX),\s\do Y(XXX))
2454 b. Ruby Text supported, must be in the form that word recognizes as being
2458 eF_ResT
SwWW8ImplReader::Read_F_Equation( WW8FieldDesc
*, String
& rStr
)
2460 _ReadFieldParams
aReadParam( rStr
);
2461 long cChar
= aReadParam
.SkipToNextToken();
2463 Read_SubF_Combined(aReadParam
);
2464 else if ('*' == cChar
)
2465 Read_SubF_Ruby(aReadParam
);
2469 void SwWW8ImplReader::Read_SubF_Combined( _ReadFieldParams
& rReadParam
)
2471 String sCombinedCharacters
;
2472 if ((-2 == rReadParam
.SkipToNextToken()) &&
2473 rReadParam
.GetResult().EqualsIgnoreCaseAscii('(', 1, 0))
2475 for (int i
=0;i
<2;i
++)
2477 if ('s' == rReadParam
.SkipToNextToken())
2479 long cChar
= rReadParam
.SkipToNextToken();
2480 if (-2 != rReadParam
.SkipToNextToken())
2482 String sF
= rReadParam
.GetResult();
2483 if ((('u' == cChar
) && sF
.EqualsIgnoreCaseAscii('p', 1, 0))
2484 || (('d' == cChar
) && sF
.EqualsIgnoreCaseAscii('o', 1, 0)))
2486 if (-2 == rReadParam
.SkipToNextToken())
2488 String sPart
= rReadParam
.GetResult();
2489 xub_StrLen nBegin
= sPart
.Search('(');
2491 //Word disallows brackets in this field, which
2492 //aids figuring out the case of an end of )) vs )
2493 xub_StrLen nEnd
= sPart
.Search(')');
2495 if ((nBegin
!= STRING_NOTFOUND
) &&
2496 (nEnd
!= STRING_NOTFOUND
))
2498 sCombinedCharacters
+=
2499 sPart
.Copy(nBegin
+1,nEnd
-nBegin
-1);
2506 if (sCombinedCharacters
.Len())
2508 SwCombinedCharField
aFld((SwCombinedCharFieldType
*)
2509 rDoc
.GetSysFldType(RES_COMBINED_CHARS
),sCombinedCharacters
);
2510 rDoc
.InsertPoolItem(*pPaM
, SwFmtFld(aFld
), 0);
2514 void SwWW8ImplReader::Read_SubF_Ruby( _ReadFieldParams
& rReadParam
)
2516 USHORT nJustificationCode
=0;
2522 while( -1 != ( nRet
= rReadParam
.SkipToNextToken() ))
2528 String sTemp
= rReadParam
.GetResult();
2529 if( sTemp
.EqualsIgnoreCaseAscii( "jc", 0, 2 ) )
2532 nJustificationCode
= static_cast<USHORT
>(sTemp
.ToInt32());
2534 else if( sTemp
.EqualsIgnoreCaseAscii( "hps", 0, 3 ) )
2537 nFontSize
= static_cast<UINT32
>(sTemp
.ToInt32());
2539 else if( sTemp
.EqualsIgnoreCaseAscii( "Font:", 0, 5 ) )
2549 while( -1 != ( nRet
= rReadParam
.SkipToNextToken() ))
2553 if (-2 == rReadParam
.SkipToNextToken() &&
2554 (rReadParam
.GetResult().EqualsIgnoreCaseAscii('p', 1, 0)))
2556 if (-2 == rReadParam
.SkipToNextToken())
2558 String sPart
= rReadParam
.GetResult();
2559 xub_StrLen nBegin
= sPart
.Search('(');
2561 //Word disallows brackets in this field,
2562 xub_StrLen nEnd
= sPart
.Search(')');
2564 if ((nBegin
!= STRING_NOTFOUND
) &&
2565 (nEnd
!= STRING_NOTFOUND
))
2567 sRuby
= sPart
.Copy(nBegin
+1,nEnd
-nBegin
-1);
2569 if (STRING_NOTFOUND
==
2570 (nBegin
= sPart
.Search(',',nEnd
)))
2572 nBegin
= sPart
.Search(';',nEnd
);
2574 nEnd
= sPart
.SearchBackward(')');
2575 if ((nBegin
!= STRING_NOTFOUND
) &&
2576 (nEnd
!= STRING_NOTFOUND
))
2578 sText
= sPart
.Copy(nBegin
+1,nEnd
-nBegin
-1);
2589 //Translate and apply
2590 if (sRuby
.Len() && sText
.Len() && sFontName
.Len() && nFontSize
)
2592 switch (nJustificationCode
)
2595 nJustificationCode
=1;
2598 nJustificationCode
=3;
2601 nJustificationCode
=4;
2605 nJustificationCode
=0;
2608 nJustificationCode
=2;
2612 SwFmtRuby
aRuby(sRuby
);
2613 const SwCharFmt
*pCharFmt
=0;
2614 //Make a guess at which of asian of western we should be setting
2616 if (pBreakIt
->GetBreakIter().is())
2617 nScript
= pBreakIt
->GetBreakIter()->getScriptType(sRuby
, 0);
2619 nScript
= i18n::ScriptType::ASIAN
;
2621 //Check to see if we already have a ruby charstyle that this fits
2622 std::vector
<const SwCharFmt
*>::const_iterator aEnd
=
2623 aRubyCharFmts
.end();
2624 for(std::vector
<const SwCharFmt
*>::const_iterator aIter
2625 = aRubyCharFmts
.begin(); aIter
!= aEnd
; ++aIter
)
2627 const SvxFontHeightItem
&rFH
=
2628 ItemGet
<SvxFontHeightItem
>(*(*aIter
),
2629 GetWhichOfScript(RES_CHRATR_FONTSIZE
,nScript
));
2630 if (rFH
.GetHeight() == nFontSize
*10)
2632 const SvxFontItem
&rF
= ItemGet
<SvxFontItem
>(*(*aIter
),
2633 GetWhichOfScript(RES_CHRATR_FONT
,nScript
));
2634 if (rF
.GetFamilyName().Equals(sFontName
))
2642 //Create a new char style if necessary
2647 //Take this as the base name
2648 SwStyleNameMapper::FillUIName(RES_POOLCHR_RUBYTEXT
,aNm
);
2649 aNm
+=String::CreateFromInt32(aRubyCharFmts
.size()+1);
2650 pFmt
= rDoc
.MakeCharFmt(aNm
,(SwCharFmt
*)rDoc
.GetDfltCharFmt());
2651 SvxFontHeightItem
aHeightItem(nFontSize
*10, 100, RES_CHRATR_FONTSIZE
);
2652 SvxFontItem
aFontItem(FAMILY_DONTKNOW
,sFontName
,
2653 aEmptyStr
,PITCH_DONTKNOW
,RTL_TEXTENCODING_DONTKNOW
, RES_CHRATR_FONT
);
2654 aHeightItem
.SetWhich(GetWhichOfScript(RES_CHRATR_FONTSIZE
,nScript
));
2655 aFontItem
.SetWhich(GetWhichOfScript(RES_CHRATR_FONT
,nScript
));
2656 pFmt
->SetFmtAttr(aHeightItem
);
2657 pFmt
->SetFmtAttr(aFontItem
);
2658 aRubyCharFmts
.push_back(pFmt
);
2662 //Set the charstyle and justification
2663 aRuby
.SetCharFmtName(pCharFmt
->GetName());
2664 aRuby
.SetCharFmtId(pCharFmt
->GetPoolFmtId());
2665 aRuby
.SetAdjustment(nJustificationCode
);
2668 rDoc
.InsertString( *pPaM
, sText
);
2669 pCtrlStck
->SetAttr( *pPaM
->GetPoint(), RES_TXTATR_CJK_RUBY
);
2673 //-----------------------------------------
2674 // Verzeichnis-Felder
2675 //-----------------------------------------
2677 void lcl_toxMatchACSwitch( SwWW8ImplReader
& /*rReader*/,
2680 _ReadFieldParams
& rParam
,
2681 SwCaptionDisplay eCaptionType
)
2683 xub_StrLen n
= rParam
.GoToTokenParam();
2684 if( STRING_NOTFOUND
!= n
)
2686 SwTOXType
* pType
= (SwTOXType
*)rDoc
.GetTOXType( TOX_ILLUSTRATIONS
, 0);
2687 pType
->Add( &rBase
);
2688 rBase
.SetCaptionDisplay( eCaptionType
);
2689 // Read Sequence Name and store in TOXBase
2690 String
sSeqName( rParam
.GetResult() );
2691 lcl_ConvertSequenceName( sSeqName
);
2692 rBase
.SetSequenceName( sSeqName
);
2696 //For all outline styles that are not in the outline numbering add them here as
2697 //custom extra styles
2698 bool SwWW8ImplReader::AddExtraOutlinesAsExtraStyles(SwTOXBase
& rBase
)
2700 bool bExtras
= false;
2701 //This is the case if the winword outline numbering is set while the
2703 for (USHORT nI
= 0; nI
< nColls
; ++nI
)
2705 SwWW8StyInf
& rSI
= pCollA
[nI
];
2706 if (rSI
.IsOutline())
2708 const SwTxtFmtColl
*pFmt
= (const SwTxtFmtColl
*)(rSI
.pFmt
);
2709 sal_uInt16 nStyleLevel
= rSI
.nOutlineLevel
;
2710 sal_uInt16 nMaxLevel
= rBase
.GetLevel();
2712 //nStyleLevel != pFmt->GetOutlineLevel() && //#outline level,zhaojianwei
2713 nStyleLevel
!= (pFmt
->GetAttrOutlineLevel()-1) && //<-end,zhaojianwei
2714 nStyleLevel
< nMaxLevel
2717 String
sStyles(rBase
.GetStyleNames(rSI
.nOutlineLevel
));
2719 sStyles
+= TOX_STYLE_DELIMITER
;
2720 sStyles
+= pFmt
->GetName();
2721 rBase
.SetStyleNames(sStyles
, rSI
.nOutlineLevel
);
2729 static void EnsureMaxLevelForTemplates(SwTOXBase
& rBase
)
2731 //If the TOC contains Template entries at levels > the evaluation level
2732 //that was initially taken from the max normal outline level of the word TOC
2733 //then we cannot use that for the evaluation level because writer cuts off
2734 //all styles above that level, while word just cuts off the "standard"
2735 //outline styles, we have no option but to expand to the highest level
2737 if ((rBase
.GetLevel() != MAXLEVEL
) && (nsSwTOXElement::TOX_TEMPLATE
& rBase
.GetCreateType()))
2739 for (USHORT nI
= MAXLEVEL
; nI
> 0; --nI
)
2741 String
sStyles(rBase
.GetStyleNames(nI
-1));
2742 if (rBase
.GetStyleNames(nI
-1).Len())
2751 void lcl_toxMatchTSwitch(SwWW8ImplReader
& rReader
, SwTOXBase
& rBase
,
2752 _ReadFieldParams
& rParam
)
2754 xub_StrLen n
= rParam
.GoToTokenParam();
2755 if( STRING_NOTFOUND
!= n
)
2757 String
sParams( rParam
.GetResult() );
2760 xub_StrLen nIndex
= 0;
2762 //#92940# Delimiters between styles and style levels appears to
2763 //allow both ; and ,
2765 String
sTemplate( sParams
.GetToken(0, ';', nIndex
) );
2766 if( STRING_NOTFOUND
== nIndex
)
2769 sTemplate
= sParams
.GetToken(0, ',', nIndex
);
2771 if( STRING_NOTFOUND
== nIndex
)
2773 const SwFmt
* pStyle
= rReader
.GetStyleWithOrgWWName(sTemplate
);
2775 sTemplate
= pStyle
->GetName();
2776 // Store Style for Level 0 into TOXBase
2777 rBase
.SetStyleNames( sTemplate
, 0 );
2779 else while( STRING_NOTFOUND
!= nIndex
)
2781 xub_StrLen nOldIndex
=nIndex
;
2782 USHORT nLevel
= static_cast<USHORT
>(
2783 sParams
.GetToken(0, ';', nIndex
).ToInt32());
2784 if( STRING_NOTFOUND
== nIndex
)
2787 nLevel
= static_cast<USHORT
>(
2788 sParams
.GetToken(0, ',', nIndex
).ToInt32());
2791 if( (0 < nLevel
) && (MAXLEVEL
>= nLevel
) )
2794 // Store Style and Level into TOXBase
2796 = rReader
.GetStyleWithOrgWWName( sTemplate
);
2799 sTemplate
= pStyle
->GetName();
2801 String
sStyles( rBase
.GetStyleNames( nLevel
) );
2803 sStyles
+= TOX_STYLE_DELIMITER
;
2804 sStyles
+= sTemplate
;
2805 rBase
.SetStyleNames( sStyles
, nLevel
);
2807 // read next style name...
2809 sTemplate
= sParams
.GetToken(0, ';', nIndex
);
2810 if( STRING_NOTFOUND
== nIndex
)
2813 sTemplate
= sParams
.GetToken(0, ',', nIndex
);
2820 USHORT
wwSectionManager::CurrentSectionColCount() const
2822 USHORT nIndexCols
= 1;
2823 if (!maSegments
.empty())
2824 nIndexCols
= maSegments
.back().maSep
.ccolM1
+ 1;
2828 //Will there be a new pagebreak at this position (don't know what type
2830 bool wwSectionManager::WillHavePageDescHere(SwNodeIndex aIdx
) const
2833 if (!maSegments
.empty())
2835 if (!maSegments
.back().IsContinous() &&
2836 maSegments
.back().maStart
== aIdx
)
2844 USHORT
lcl_GetMaxValidWordTOCLevel(const SwForm
&rForm
)
2846 // GetFormMax() returns level + 1, hence the -1
2847 USHORT nRet
= rForm
.GetFormMax()-1;
2849 // If the max of this type of TOC is greater than the max of a word
2850 // possible toc, then clip to the word max
2851 if (nRet
> WW8ListManager::nMaxLevel
)
2852 nRet
= WW8ListManager::nMaxLevel
;
2857 eF_ResT
SwWW8ImplReader::Read_F_Tox( WW8FieldDesc
* pF
, String
& rStr
)
2859 #if defined(WW_NATIVE_TOC)
2861 ::rtl::OUString aBookmarkName
=::rtl::OUString::createFromAscii("_TOC");
2862 maFieldStack
.back().SetBookmarkName(aBookmarkName
);
2863 maFieldStack
.back().SetBookmarkType(::rtl::OUString::createFromAscii(ECMA_TOC
));
2864 // maFieldStack.back().AddParam(::rtl::OUString::createFromAscii("Description"), aFormula.sToolTip);
2870 return FLD_TEXT
; // ignore (#i25440#)
2872 TOXTypes eTox
; // Baue ToxBase zusammen
2886 USHORT nCreateOf
= (eTox
== TOX_CONTENT
) ? nsSwTOXElement::TOX_OUTLINELEVEL
: nsSwTOXElement::TOX_MARK
;
2888 USHORT nIndexCols
= 1;
2890 const SwTOXType
* pType
= rDoc
.GetTOXType( eTox
, 0 );
2891 SwForm
aOrigForm(eTox
);
2892 SwTOXBase
* pBase
= new SwTOXBase( pType
, aOrigForm
, nCreateOf
, aEmptyStr
);
2893 pBase
->SetProtected(maSectionManager
.CurrentSectionIsProtected());
2897 USHORT eOptions
= nsSwTOIOptions::TOI_SAME_ENTRY
| nsSwTOIOptions::TOI_CASE_SENSITIVE
;
2899 // TOX_OUTLINELEVEL setzen wir genau dann, wenn
2900 // die Parameter \o in 1 bis 9 liegen
2901 // oder der Parameter \f existiert
2902 // oder GARKEINE Switches Parameter angegeben sind.
2904 _ReadFieldParams
aReadParam( rStr
);
2905 while( -1 != ( nRet
= aReadParam
.SkipToNextToken() ))
2911 xub_StrLen n
= aReadParam
.GoToTokenParam();
2912 if( STRING_NOTFOUND
!= n
)
2914 String
sParams( aReadParam
.GetResult() );
2915 // if NO String just ignore the \c
2919 static_cast<USHORT
>(sParams
.ToInt32());
2926 xub_StrLen n
= aReadParam
.GoToTokenParam();
2927 if( STRING_NOTFOUND
!= n
) // if NO String just ignore the \e
2929 String
sDelimiter( aReadParam
.GetResult() );
2930 SwForm
aForm( pBase
->GetTOXForm() );
2932 // Attention: if TOX_CONTENT brave
2933 // GetFormMax() returns MAXLEVEL + 1 !!
2934 USHORT nEnd
= aForm
.GetFormMax()-1;
2936 for(USHORT nLevel
= 1;
2940 // Levels count from 1
2941 // Level 0 is reserved for CAPTION
2943 // Delimiter statt Tabstop vor der Seitenzahl einsetzen,
2944 // falls es eine Seitenzahl gibt:
2945 FormTokenType ePrevType
= TOKEN_END
;
2946 FormTokenType eType
;
2948 SwFormTokens aPattern
=
2949 aForm
.GetPattern(nLevel
);
2950 SwFormTokens::iterator aIt
= aPattern
.begin();
2953 eType
= ++aIt
== aPattern
.end() ? TOKEN_END
: aIt
->eTokenType
;
2955 if (eType
== TOKEN_PAGE_NUMS
)
2957 if (TOKEN_TAB_STOP
== ePrevType
)
2961 if(0x09 == sDelimiter
.GetChar(0))
2962 aIt
->eTabAlign
= SVX_TAB_ADJUST_END
;
2965 SwFormToken
aToken(TOKEN_TEXT
);
2966 aToken
.sText
= sDelimiter
;
2969 aForm
.SetPattern(nLevel
, aPattern
);
2977 while (TOKEN_END
!= eType
);
2980 pBase
->SetTOXForm( aForm
);
2986 eOptions
|= nsSwTOIOptions::TOI_ALPHA_DELIMITTER
;
2991 pBase
->SetOptions( eOptions
);
2997 bool bIsHyperlink
= false;
2998 // TOX_OUTLINELEVEL setzen wir genau dann, wenn
2999 // die Parameter \o in 1 bis 9 liegen
3000 // oder der Parameter \f existiert
3001 // oder GARKEINE Switches Parameter angegeben sind.
3002 USHORT eCreateFrom
= 0;
3003 USHORT nMaxLevel
= 0;
3005 _ReadFieldParams
aReadParam( rStr
);
3006 while( -1 != ( nRet
= aReadParam
.SkipToNextToken() ))
3011 bIsHyperlink
= true;
3015 lcl_toxMatchACSwitch(*this, rDoc
, *pBase
, aReadParam
,
3023 if( !aReadParam
.GetTokenSttFromTo(0, &nVal
, WW8ListManager::nMaxLevel
) )
3024 nVal
= lcl_GetMaxValidWordTOCLevel(aOrigForm
);
3025 if( nMaxLevel
< nVal
)
3027 eCreateFrom
|= nsSwTOXElement::TOX_OUTLINELEVEL
;
3031 eCreateFrom
|= nsSwTOXElement::TOX_MARK
;
3036 if( aReadParam
.GetTokenSttFromTo(0, &nVal
, WW8ListManager::nMaxLevel
) )
3038 if( nMaxLevel
< nVal
)
3040 eCreateFrom
|= nsSwTOXElement::TOX_MARK
;
3044 case 't': // paragraphs using special styles shall
3045 // provide the TOX's content
3046 lcl_toxMatchTSwitch(*this, *pBase
, aReadParam
);
3047 eCreateFrom
|= nsSwTOXElement::TOX_TEMPLATE
;
3051 xub_StrLen n
= aReadParam
.GoToTokenParam();
3052 if( STRING_NOTFOUND
!= n
) // if NO String just ignore the \p
3054 String
sDelimiter( aReadParam
.GetResult() );
3055 SwForm
aForm( pBase
->GetTOXForm() );
3057 // Attention: if TOX_CONTENT brave
3058 // GetFormMax() returns MAXLEVEL + 1 !!
3059 USHORT nEnd
= aForm
.GetFormMax()-1;
3061 for(USHORT nLevel
= 1;
3065 // Levels count from 1
3066 // Level 0 is reserved for CAPTION
3068 // Delimiter statt Tabstop vor der Seitenzahl einsetzen,
3069 // falls es eine Seitenzahl gibt:
3070 FormTokenType ePrevType
= TOKEN_END
;
3071 FormTokenType eType
;
3074 SwFormTokens aPattern
= aForm
.GetPattern(nLevel
);
3075 SwFormTokens::iterator aIt
= aPattern
.begin();
3078 eType
= ++aIt
== aPattern
.end() ? TOKEN_END
: aIt
->eTokenType
;
3080 if (eType
== TOKEN_PAGE_NUMS
)
3082 if (TOKEN_TAB_STOP
== ePrevType
)
3086 SwFormToken
aToken(TOKEN_TEXT
);
3087 aToken
.sText
= sDelimiter
;
3090 aForm
.SetPattern(nLevel
,
3097 while( TOKEN_END
!= eType
);
3100 pBase
->SetTOXForm( aForm
);
3104 case 'n': // don't print page numbers
3106 // read START and END param
3107 USHORT nStart
, nEnd
;
3108 if( !aReadParam
.GetTokenSttFromTo( &nStart
, &nEnd
,
3109 WW8ListManager::nMaxLevel
) )
3112 nEnd
= aOrigForm
.GetFormMax()-1;
3114 // remove page numbers from this levels
3115 SwForm
aForm( pBase
->GetTOXForm() );
3116 if (aForm
.GetFormMax() <= nEnd
)
3117 nEnd
= aForm
.GetFormMax()-1;
3119 USHORT nLevel
= nStart
; nLevel
<= nEnd
;
3123 // Levels count from 1
3124 // Level 0 is reserved for CAPTION
3126 // Seitenzahl und ggfs. davorstehenden Tabstop
3128 FormTokenType eType
;
3130 SwFormTokens aPattern
= aForm
.GetPattern(nLevel
);
3131 SwFormTokens::iterator aIt
= aPattern
.begin();
3134 eType
= ++aIt
== aPattern
.end() ? TOKEN_END
: aIt
->eTokenType
;
3136 if (eType
== TOKEN_PAGE_NUMS
)
3138 aIt
= aPattern
.erase(aIt
);
3145 aPattern
.erase(aIt
);
3146 aForm
.SetPattern(nLevel
, aPattern
);
3151 while (TOKEN_END
!= eType
);
3154 pBase
->SetTOXForm( aForm
);
3159 // the following switches are not (yet) supported
3160 // by good old StarWriter:
3171 SwForm
aForm(pBase
->GetTOXForm());
3172 USHORT nEnd
= aForm
.GetFormMax()-1;
3173 SwFormToken
aLinkStart(TOKEN_LINK_START
);
3174 SwFormToken
aLinkEnd(TOKEN_LINK_END
);
3177 for(USHORT nLevel
= 1; nLevel
<= nEnd
; ++nLevel
)
3179 SwFormTokens aPattern
= aForm
.GetPattern(nLevel
);
3181 aPattern
.insert(aPattern
.begin(), aLinkStart
);
3182 aPattern
.push_back(aLinkEnd
);
3184 aForm
.SetPattern(nLevel
, aPattern
);
3188 pBase
->SetTOXForm(aForm
);
3192 nMaxLevel
= WW8ListManager::nMaxLevel
;
3193 pBase
->SetLevel(nMaxLevel
);
3195 const TOXTypes eType
= pBase
->GetTOXType()->GetType();
3200 //If we would be created from outlines, either explictly or by default
3201 //then see if we need extra styles added to the outlines
3202 USHORT eEffectivelyFrom
= eCreateFrom
? eCreateFrom
: nsSwTOXElement::TOX_OUTLINELEVEL
;
3203 if (eEffectivelyFrom
& nsSwTOXElement::TOX_OUTLINELEVEL
)
3205 if (AddExtraOutlinesAsExtraStyles(*pBase
))
3206 eCreateFrom
|= (nsSwTOXElement::TOX_TEMPLATE
| nsSwTOXElement::TOX_OUTLINELEVEL
);
3208 // --> FME 2004-12-16 #i19683# Insert a text token " " between the
3209 // number and entry token. In an ideal world we could handle the
3210 // tab stop between the number and the entry correctly, but I
3211 // currently have no clue how to obtain the tab stop position.
3212 // It is _not_ set at the paragraph style.
3214 for (USHORT nI
= 0; nI
< nColls
; ++nI
)
3216 const SwWW8StyInf
& rSI
= pCollA
[nI
];
3217 if (rSI
.IsOutlineNumbered())
3219 sal_uInt16 nStyleLevel
= rSI
.nOutlineLevel
;
3220 const SwNumFmt
& rFmt
= rSI
.GetOutlineNumrule()->Get( nStyleLevel
);
3221 if ( SVX_NUM_NUMBER_NONE
!= rFmt
.GetNumberingType() )
3226 pForm
= new SwForm( pBase
->GetTOXForm() );
3228 SwFormTokens aPattern
= pForm
->GetPattern(nStyleLevel
);
3229 SwFormTokens::iterator aIt
=
3230 find_if(aPattern
.begin(), aPattern
.end(),
3231 SwFormTokenEqualToFormTokenType(TOKEN_ENTRY_NO
));
3233 if ( aIt
!= aPattern
.end() )
3235 SwFormToken
aNumberEntrySeparator( TOKEN_TEXT
);
3236 aNumberEntrySeparator
.sText
= String::CreateFromAscii(" ");
3237 aPattern
.insert( ++aIt
, aNumberEntrySeparator
);
3238 pForm
->SetPattern( nStyleLevel
, aPattern
);
3244 pBase
->SetTOXForm( *pForm
);
3249 pBase
->SetCreate(eCreateFrom
);
3250 EnsureMaxLevelForTemplates(*pBase
);
3253 case TOX_ILLUSTRATIONS
:
3256 eCreateFrom
= nsSwTOXElement::TOX_SEQUENCE
;
3257 pBase
->SetCreate( eCreateFrom
);
3261 We don't know until here if we are an illustration
3262 or not, and so have being used a TOX_CONTENT so far
3263 which has 10 levels, while TOX has only two, this
3264 level is set only in the constructor of SwForm, so
3265 create a new one and copy over anything that could
3266 be set in the old one, and remove entries from the
3267 pattern which do not apply to illustration indices
3269 SwForm
aOldForm( pBase
->GetTOXForm() );
3270 SwForm
aForm( eType
);
3271 USHORT nEnd
= aForm
.GetFormMax()-1;
3274 for(USHORT nLevel
= 1; nLevel
<= nEnd
; ++nLevel
)
3276 SwFormTokens aPattern
= aOldForm
.GetPattern(nLevel
);
3278 SwFormTokens::iterator new_end
=remove_if(aPattern
.begin(), aPattern
.end(),
3279 SwFormTokenEqualToFormTokenType(TOKEN_ENTRY_NO
));
3281 aPattern
.erase (new_end
, aPattern
.end() ); // #124710#: table index imported with wrong page number format
3283 aForm
.SetPattern(nLevel
, aPattern
);
3285 aForm
.SetTemplate( nLevel
,
3286 aOldForm
.GetTemplate(nLevel
));
3290 pBase
->SetTOXForm( aForm
);
3294 ASSERT(!this, "Unhandled toc options!");
3302 ASSERT(!this, "Unhandled toc options!");
3306 // Update fuer TOX anstossen
3307 rDoc
.SetUpdateTOX(true);
3310 // propagate tab stops from paragraph styles used in TOX to
3311 // patterns of the TOX
3312 pBase
->AdjustTabStops(rDoc
, TRUE
);
3314 //#i10028# inserting a toc implicltly acts like a parabreak
3315 //in word and writer
3316 if (pPaM
->GetPoint()->nContent
.GetIndex())
3317 AppendTxtNode(*pPaM
->GetPoint());
3319 const SwPosition
* pPos
= pPaM
->GetPoint();
3321 SwFltTOX
aFltTOX( pBase
, nIndexCols
);
3323 // test if there is already a break item on this node
3324 if(SwCntntNode
* pNd
= pPos
->nNode
.GetNode().GetCntntNode())
3326 const SfxItemSet
* pSet
= pNd
->GetpSwAttrSet();
3329 if (SFX_ITEM_SET
== pSet
->GetItemState(RES_BREAK
, false))
3330 aFltTOX
.SetHadBreakItem(true);
3331 if (SFX_ITEM_SET
== pSet
->GetItemState(RES_PAGEDESC
, false))
3332 aFltTOX
.SetHadPageDescItem(true);
3336 //Will there be a new pagebreak at this position (don't know what type
3338 if (maSectionManager
.WillHavePageDescHere(pPos
->nNode
))
3339 aFltTOX
.SetHadPageDescItem(true);
3341 // Setze Anfang in Stack
3342 pReffedStck
->NewAttr( *pPos
, aFltTOX
);
3344 rDoc
.InsertTableOf(*pPaM
->GetPoint(), *aFltTOX
.GetBase());
3346 //inserting a toc inserts a section before this point, so adjust pos
3347 //for future page/section segment insertion
3348 SwPaM
aRegion(*pPaM
);
3349 aRegion
.Move(fnMoveBackward
);
3350 ASSERT(rDoc
.GetCurTOX(*aRegion
.GetPoint()), "Misunderstood how toc works");
3351 if (SwTOXBase
* pBase2
= (SwTOXBase
*)rDoc
.GetCurTOX(*aRegion
.GetPoint()))
3355 // Set the column number for index
3356 SfxItemSet
aSet( rDoc
.GetAttrPool(), RES_COL
, RES_COL
);
3358 aCol
.Init( nIndexCols
, 708, USHRT_MAX
);
3360 pBase2
->SetAttrSet( aSet
);
3363 maSectionManager
.PrependedInlineNode(*pPaM
->GetPoint(),
3364 *aRegion
.GetNode());
3367 // Setze Ende in Stack
3368 pReffedStck
->SetAttr( *pPos
, RES_FLTR_TOX
);
3370 if (!maApos
.back()) //a para end in apo doesn't count
3375 eF_ResT
SwWW8ImplReader::Read_F_Shape(WW8FieldDesc
* /*pF*/, String
& /*rStr*/)
3378 #i3958# 0x8 followed by 0x1 where the shape is the 0x8 and its anchoring
3379 to be ignored followed by a 0x1 with an empty drawing. Detect in inserting
3380 the drawing that we are in the Shape field and respond accordingly
3385 eF_ResT
SwWW8ImplReader::Read_F_Hyperlink( WW8FieldDesc
* /*pF*/, String
& rStr
)
3387 #if defined(WW_NATIVE_TOC)
3389 ::rtl::OUString aBookmarkName
=::rtl::OUString::createFromAscii("_HYPERLINK");
3390 maFieldStack
.back().SetBookmarkName(aBookmarkName
);
3391 maFieldStack
.back().SetBookmarkType(::rtl::OUString::createFromAscii(ECMA_HYPERLINK
));
3392 // maFieldStack.back().AddParam(::rtl::OUString::createFromAscii("Description"), aFormula.sToolTip);
3397 String sURL
, sTarget
, sMark
;
3398 bool bDataImport
= false;
3399 //HYPERLINk "filename" [switches]
3400 bool bOptions
=false;
3402 rStr
.EraseTrailingChars( 1 );
3407 _ReadFieldParams
aReadParam( rStr
);
3408 while( -1 != ( nRet
= aReadParam
.SkipToNextToken() ))
3413 if (!sURL
.Len() & !bOptions
)
3414 ConvertFFileName(sURL
, aReadParam
.GetResult());
3418 sTarget
.ASSIGN_CONST_ASC( "_blank" );
3423 nRet
= aReadParam
.SkipToNextToken();
3427 sMark
= aReadParam
.GetResult();
3428 if( sMark
.Len() && '"' == sMark
.GetChar( sMark
.Len()-1 ))
3429 sMark
.Erase( sMark
.Len() - 1 );
3434 nRet
= aReadParam
.SkipToNextToken();
3437 sTarget
= aReadParam
.GetResult();
3441 ASSERT( !this, "Auswertung fehlt noch - Daten unbekannt" );
3442 case 's': //worthless fake anchor option
3449 // das Resultat uebernehmen
3450 ASSERT((sURL
.Len() || sMark
.Len()), "WW8: Empty URL")
3453 ( sURL
+= INET_MARK_TOKEN
) += sMark
;
3455 SwFmtINetFmt
aURL( sURL
, sTarget
);
3457 //As an attribute this needs to be closed, and that'll happen from
3458 //EndExtSprm in conjunction with the maFieldStack If there are are flyfrms
3459 //between the start and begin, their hyperlinks will be set at that time
3461 pCtrlStck
->NewAttr( *pPaM
->GetPoint(), aURL
);
3465 void lcl_ImportTox(SwDoc
&rDoc
, SwPaM
&rPaM
, const String
&rStr
, bool bIdx
)
3467 TOXTypes eTox
= ( !bIdx
) ? TOX_CONTENT
: TOX_INDEX
; // Default
3474 _ReadFieldParams
aReadParam(rStr
);
3475 while( -1 != ( nRet
= aReadParam
.SkipToNextToken() ))
3479 if( !sFldTxt
.Len() )
3481 // PrimaryKey ohne ":", 2nd dahinter
3482 sFldTxt
= aReadParam
.GetResult();
3487 n
= aReadParam
.GoToTokenParam();
3488 if( STRING_NOTFOUND
!= n
)
3490 String
sParams( aReadParam
.GetResult() );
3491 if( 'C' != sParams
.GetChar(0) && 'c' != sParams
.GetChar(0) )
3497 n
= aReadParam
.GoToTokenParam();
3498 if( STRING_NOTFOUND
!= n
)
3500 String
sParams( aReadParam
.GetResult() );
3501 if( sParams
.Len() // if NO String just ignore the \l
3502 && sParams
.GetChar( 0 ) > '0'
3503 && sParams
.GetChar( 0 ) <= '9' )
3505 nLevel
= (USHORT
)sParams
.ToInt32();
3511 ASSERT( rDoc
.GetTOXTypeCount( eTox
), "Doc.GetTOXTypeCount() == 0 :-(" );
3513 const SwTOXType
* pT
= rDoc
.GetTOXType( eTox
, 0 );
3516 if( eTox
!= TOX_INDEX
)
3517 aM
.SetLevel( nLevel
);
3520 xub_StrLen nFnd
= sFldTxt
.Search( WW8_TOX_LEVEL_DELIM
);
3521 if( STRING_NOTFOUND
!= nFnd
) // it exist levels
3523 aM
.SetPrimaryKey( sFldTxt
.Copy( 0, nFnd
) );
3524 xub_StrLen nScndFnd
=
3525 sFldTxt
.Search( WW8_TOX_LEVEL_DELIM
, nFnd
+1 );
3526 if( STRING_NOTFOUND
!= nScndFnd
)
3528 aM
.SetSecondaryKey( sFldTxt
.Copy( nFnd
+1, nScndFnd
- nFnd
- 1 ));
3531 sFldTxt
.Erase( 0, nFnd
+1 );
3537 aM
.SetAlternativeText( sFldTxt
);
3538 rDoc
.InsertPoolItem( rPaM
, aM
, 0 );
3542 void sw::ms::ImportXE(SwDoc
&rDoc
, SwPaM
&rPaM
, const String
&rStr
)
3544 lcl_ImportTox(rDoc
, rPaM
, rStr
, true);
3547 void SwWW8ImplReader::ImportTox( int nFldId
, String aStr
)
3549 bool bIdx
= (nFldId
!= 9);
3550 lcl_ImportTox(rDoc
, *pPaM
, aStr
, bIdx
);
3553 void SwWW8ImplReader::Read_FldVanish( USHORT
, const BYTE
*, short nLen
)
3555 //Meaningless in a style
3556 if (pAktColl
|| !pPlcxMan
)
3559 const int nChunk
= 64; //number of characters to read at one time
3561 // Vorsicht: Bei Feldnamen mit Umlauten geht das MEMICMP nicht!
3562 const static sal_Char
*aFldNames
[] = { "\x06""INHALT", "\x02""XE", // dt.
3564 const static BYTE aFldId
[] = { 9, 4, 9 };
3568 bIgnoreText
= false;
3572 // our methode was called from
3573 // ''Skip attributes of field contents'' loop within ReadTextAttr()
3578 long nOldPos
= pStrm
->Tell();
3580 WW8_CP nStartCp
= pPlcxMan
->Where() + pPlcxMan
->GetCpOfs();
3583 USHORT nFieldLen
= pSBase
->WW8ReadString( *pStrm
, sFieldName
, nStartCp
,
3584 nChunk
, eStructCharSet
);
3585 nStartCp
+=nFieldLen
;
3588 //If the first chunk did not start with a field start then
3589 //reset the stream position and give up
3590 if( !nFieldLen
|| (0x13 != sFieldName
.GetChar( nC
))) // Field Start Mark
3592 // If Field End Mark found
3593 if( nFieldLen
&& (0x15 == sFieldName
.GetChar( nC
)))
3594 bIgnoreText
= false;
3595 pStrm
->Seek( nOldPos
);
3596 return; // kein Feld zu finden
3600 //If this chunk does not contain a field end, keep reading chunks
3601 //until we find one, or we run out of text,
3602 while (STRING_NOTFOUND
== (nFnd
= sFieldName
.Search(0x15)))
3605 nFieldLen
= pSBase
->WW8ReadString( *pStrm
, sTemp
,
3606 nStartCp
, nChunk
, eStructCharSet
);
3608 nStartCp
+=nFieldLen
;
3613 pStrm
->Seek( nOldPos
);
3615 //if we have no 0x15 give up, otherwise erase everything from the 0x15
3617 if (STRING_NOTFOUND
== nFnd
)
3620 sFieldName
.Erase(nFnd
);
3623 while( ' ' == sFieldName
.GetChar( nC
))
3626 for( int i
= 0; i
< 3; i
++ )
3628 const sal_Char
* pName
= aFldNames
[i
];
3629 USHORT nNameLen
= *pName
++;
3630 if( sFieldName
.EqualsIgnoreCaseAscii( pName
, nC
, nNameLen
) )
3632 ImportTox( aFldId
[i
], sFieldName
.Copy( nC
+ nNameLen
) );
3633 break; // keine Mehrfachnennungen moeglich
3637 pStrm
->Seek( nOldPos
);
3640 /* vi:set tabstop=4 shiftwidth=4 expandtab: */