xref: /trunk/main/sw/source/core/tox/txmsrt.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sw.hxx"
30 
31 
32 #include <tools/resid.hxx>
33 #include <unotools/charclass.hxx>
34 #include <com/sun/star/i18n/CollatorOptions.hpp>
35 #include <editeng/unolingu.hxx>
36 #include <txtfld.hxx>
37 #include <doc.hxx>
38 #include <docary.hxx>
39 #include <cntfrm.hxx>
40 #include <node.hxx>
41 #include <frmatr.hxx>
42 #include <pam.hxx>
43 #include <txttxmrk.hxx>
44 #include <frmfmt.hxx>
45 #include <fmtfld.hxx>
46 #include <txmsrt.hxx>
47 #include <ndtxt.hxx>
48 #include <txtatr.hxx>
49 #include <swtable.hxx>
50 #include <expfld.hxx>
51 #include <authfld.hxx>
52 #include <toxwrap.hxx>
53 
54 #include <comcore.hrc>
55 #include <numrule.hxx>
56 
57 extern sal_Bool IsFrameBehind( const SwTxtNode& rMyNd, xub_StrLen nMySttPos,
58 						   const SwTxtNode& rBehindNd, xub_StrLen nSttPos );
59 
60 using namespace ::com::sun::star;
61 using namespace ::com::sun::star::uno;
62 using ::rtl::OUString;
63 /*--------------------------------------------------------------------
64 	Beschreibung: Strings initialisieren
65  --------------------------------------------------------------------*/
66 
67 sal_uInt16 SwTOXSortTabBase::nOpt = 0;
68 
69 SV_IMPL_VARARR( SwTOXSources, SwTOXSource )
70 
71 
72 SwTOXInternational::SwTOXInternational( LanguageType nLang, sal_uInt16 nOpt,
73                                         const String& rSortAlgorithm ) :
74     eLang( nLang ),
75     sSortAlgorithm(rSortAlgorithm),
76     nOptions( nOpt )
77 {
78 	Init();
79 }
80 
81 SwTOXInternational::SwTOXInternational( const SwTOXInternational& rIntl ) :
82     eLang( rIntl.eLang ),
83     sSortAlgorithm(rIntl.sSortAlgorithm),
84     nOptions( rIntl.nOptions )
85 {
86   Init();
87 }
88 
89 void SwTOXInternational::Init()
90 {
91 	pIndexWrapper = new IndexEntrySupplierWrapper();
92 
93     const lang::Locale aLcl( SvxCreateLocale( eLang ) );
94     pIndexWrapper->SetLocale( aLcl );
95 
96     if(!sSortAlgorithm.Len())
97     {
98         Sequence < OUString > aSeq( pIndexWrapper->GetAlgorithmList( aLcl ));
99         if(aSeq.getLength())
100             sSortAlgorithm = aSeq.getConstArray()[0];
101     }
102 
103     if ( nOptions & nsSwTOIOptions::TOI_CASE_SENSITIVE )
104         pIndexWrapper->LoadAlgorithm( aLcl, sSortAlgorithm, 0 );
105     else
106         pIndexWrapper->LoadAlgorithm( aLcl, sSortAlgorithm, SW_COLLATOR_IGNORES );
107 
108 	pCharClass = new CharClass( aLcl );
109 
110 }
111 
112 SwTOXInternational::~SwTOXInternational()
113 {
114 	delete pCharClass;
115 	delete pIndexWrapper;
116 }
117 
118 String SwTOXInternational::ToUpper( const String& rStr, xub_StrLen nPos ) const
119 {
120 	return pCharClass->toUpper( rStr, nPos, 1 );
121 }
122 inline sal_Bool SwTOXInternational::IsNumeric( const String& rStr ) const
123 {
124 	return pCharClass->isNumeric( rStr );
125 }
126 
127 sal_Int32 SwTOXInternational::Compare( const String& rTxt1, const String& rTxtReading1,
128                                        const lang::Locale& rLocale1,
129                                        const String& rTxt2, const String& rTxtReading2,
130                                        const lang::Locale& rLocale2 ) const
131 {
132     return pIndexWrapper->CompareIndexEntry( rTxt1, rTxtReading1, rLocale1,
133                                              rTxt2, rTxtReading2, rLocale2 );
134 }
135 
136 String SwTOXInternational::GetIndexKey( const String& rTxt, const String& rTxtReading,
137                                         const lang::Locale& rLocale ) const
138 {
139     return pIndexWrapper->GetIndexKey( rTxt, rTxtReading, rLocale );
140 }
141 
142 String SwTOXInternational::GetFollowingText( sal_Bool bMorePages ) const
143 {
144 	return pIndexWrapper->GetFollowingText( bMorePages );
145 }
146 
147 /*--------------------------------------------------------------------
148 	 Beschreibung:	SortierElement fuer Verzeichniseintraege
149  --------------------------------------------------------------------*/
150 
151 
152 SwTOXSortTabBase::SwTOXSortTabBase( TOXSortType nTyp, const SwCntntNode* pNd,
153 									const SwTxtTOXMark* pMark,
154                                     const SwTOXInternational* pInter,
155                                     const lang::Locale* pLocale )
156     : pTOXNd( 0 ), pTxtMark( pMark ), pTOXIntl( pInter ),
157     nPos( 0 ), nCntPos( 0 ), nType( static_cast<sal_uInt16>(nTyp) ), bValidTxt( sal_False )
158 {
159     if ( pLocale )
160         aLocale = *pLocale;
161 
162     if( pNd )
163 	{
164 		xub_StrLen n = 0;
165 		if( pTxtMark )
166 			n = *pTxtMark->GetStart();
167 		SwTOXSource aTmp( pNd, n,
168 					pTxtMark ? pTxtMark->GetTOXMark().IsMainEntry() : sal_False );
169 		aTOXSources.Insert( aTmp, aTOXSources.Count() );
170 
171 		nPos = pNd->GetIndex();
172 
173 		switch( nTyp )
174 		{
175 		case TOX_SORT_CONTENT:
176 		case TOX_SORT_PARA:
177 		case TOX_SORT_TABLE:
178 			// falls sie in Sonderbereichen stehen, sollte man die
179 			// Position im Body besorgen
180 			if( nPos < pNd->GetNodes().GetEndOfExtras().GetIndex() )
181 			{
182 				// dann die "Anker" (Body) Position holen.
183 				Point aPt;
184 				const SwCntntFrm* pFrm = pNd->getLayoutFrm( pNd->GetDoc()->GetCurrentLayout(), &aPt, 0, sal_False );
185 				if( pFrm )
186 				{
187 					SwPosition aPos( *pNd );
188 					const SwDoc& rDoc = *pNd->GetDoc();
189 #ifdef DBG_UTIL
190 					ASSERT( GetBodyTxtNode( rDoc, aPos, *pFrm ),
191 							"wo steht der Absatz" );
192 #else
193 					GetBodyTxtNode( rDoc, aPos, *pFrm );
194 #endif
195 					nPos = aPos.nNode.GetIndex();
196 					nCntPos = aPos.nContent.GetIndex();
197 				}
198 			}
199 			else
200 				nCntPos = n;
201 			break;
202         default: break;
203 		}
204 	}
205 }
206 
207 
208 String SwTOXSortTabBase::GetURL() const
209 {
210 	return aEmptyStr;
211 }
212 
213 void SwTOXSortTabBase::FillText( SwTxtNode& rNd, const SwIndex& rInsPos,
214 									sal_uInt16 ) const
215 {
216     String sMyTxt;
217     String sMyTxtReading;
218 
219     GetTxt( sMyTxt, sMyTxtReading );
220 
221     rNd.InsertText( sMyTxt, rInsPos );
222 }
223 
224 sal_Bool SwTOXSortTabBase::operator==( const SwTOXSortTabBase& rCmp )
225 {
226 	sal_Bool bRet = nPos == rCmp.nPos && nCntPos == rCmp.nCntPos &&
227 			(!aTOXSources[0].pNd || !rCmp.aTOXSources[0].pNd ||
228 			aTOXSources[0].pNd == rCmp.aTOXSources[0].pNd );
229 
230 	if( TOX_SORT_CONTENT == nType )
231 	{
232 		bRet = bRet && pTxtMark && rCmp.pTxtMark &&
233 				*pTxtMark->GetStart() == *rCmp.pTxtMark->GetStart();
234 
235 		if( bRet )
236 		{
237 			// beide Pointer vorhanden -> vergleiche Text
238 			// beide Pointer nicht vorhanden -> vergleiche AlternativText
239 			const xub_StrLen *pEnd	= pTxtMark->GetEnd(),
240 					   		 *pEndCmp = rCmp.pTxtMark->GetEnd();
241 
242             String sMyTxt;
243             String sMyTxtReading;
244             GetTxt( sMyTxt, sMyTxtReading );
245 
246             String sOtherTxt;
247             String sOtherTxtReading;
248             rCmp.GetTxt( sOtherTxt, sOtherTxtReading );
249 
250 			bRet = ( ( pEnd && pEndCmp ) || ( !pEnd && !pEndCmp ) ) &&
251                     pTOXIntl->IsEqual( sMyTxt, sMyTxtReading, GetLocale(),
252                                        sOtherTxt, sOtherTxtReading, rCmp.GetLocale() );
253 		}
254 	}
255 	return bRet;
256 }
257 
258 sal_Bool SwTOXSortTabBase::operator<( const SwTOXSortTabBase& rCmp )
259 {
260 	if( nPos < rCmp.nPos )
261 		return sal_True;
262 
263 	if( nPos == rCmp.nPos )
264 	{
265 		if( nCntPos < rCmp.nCntPos )
266 			return sal_True;
267 
268 		if( nCntPos == rCmp.nCntPos )
269 		{
270 			const SwNode* pFirst = aTOXSources[0].pNd;
271 			const SwNode* pNext = rCmp.aTOXSources[0].pNd;
272 
273 			if( pFirst && pFirst == pNext )
274 			{
275 				if( TOX_SORT_CONTENT == nType && pTxtMark && rCmp.pTxtMark )
276 				{
277 					if( *pTxtMark->GetStart() < *rCmp.pTxtMark->GetStart() )
278 						return sal_True;
279 
280 					if( *pTxtMark->GetStart() == *rCmp.pTxtMark->GetStart() )
281 					{
282 						const xub_StrLen *pEnd = pTxtMark->GetEnd(),
283 								   		 *pEndCmp = rCmp.pTxtMark->GetEnd();
284 
285                         String sMyTxt;
286                         String sMyTxtReading;
287                         GetTxt( sMyTxt, sMyTxtReading );
288 
289                         String sOtherTxt;
290                         String sOtherTxtReading;
291                         rCmp.GetTxt( sOtherTxt, sOtherTxtReading );
292 
293                         // beide Pointer vorhanden -> vergleiche Text
294 						// beide Pointer nicht vorhanden -> vergleiche AlternativText
295 						if( ( pEnd && pEndCmp ) || ( !pEnd && !pEndCmp ) )
296                             pTOXIntl->IsEqual( sMyTxt, sMyTxtReading, GetLocale(),
297                                                sOtherTxt, sOtherTxtReading, rCmp.GetLocale() );
298 
299 						if( pEnd && !pEndCmp )
300 							return sal_True;
301 					}
302 				}
303 			}
304 			else if( pFirst && pFirst->IsTxtNode() &&
305 					 pNext && pNext->IsTxtNode() )
306 					return ::IsFrameBehind( *(SwTxtNode*)pNext, nCntPos,
307 											*(SwTxtNode*)pFirst, nCntPos );
308 		}
309 	}
310 	return sal_False;
311 }
312 
313 /*--------------------------------------------------------------------
314 	 Beschreibung: sortierter Stichworteintrag
315  --------------------------------------------------------------------*/
316 
317 
318 SwTOXIndex::SwTOXIndex( const SwTxtNode& rNd,
319                         const SwTxtTOXMark* pMark, sal_uInt16 nOptions,
320                         sal_uInt8 nKyLevel,
321                         const SwTOXInternational& rIntl,
322                         const lang::Locale& rLocale )
323     : SwTOXSortTabBase( TOX_SORT_INDEX, &rNd, pMark, &rIntl, &rLocale ),
324 	nKeyLevel(nKyLevel)
325 {
326 	nPos = rNd.GetIndex();
327 	nOpt = nOptions;
328 }
329 
330 //
331 // Stichworte vergleichen. Bezieht sich nur auf den Text
332 //
333 
334 
335 sal_Bool SwTOXIndex::operator==( const SwTOXSortTabBase& rCmpBase )
336 {
337 	SwTOXIndex& rCmp = (SwTOXIndex&)rCmpBase;
338 
339 	// In Abhaengigkeit von den Optionen Grosskleinschreibung beachten
340 	if(GetLevel() != rCmp.GetLevel() || nKeyLevel != rCmp.nKeyLevel)
341 		return sal_False;
342 
343 	ASSERT(pTxtMark, "pTxtMark == 0, Kein Stichwort");
344 
345     String sMyTxt;
346     String sMyTxtReading;
347     GetTxt( sMyTxt, sMyTxtReading );
348 
349     String sOtherTxt;
350     String sOtherTxtReading;
351     rCmp.GetTxt( sOtherTxt, sOtherTxtReading );
352 
353     sal_Bool bRet = pTOXIntl->IsEqual( sMyTxt, sMyTxtReading, GetLocale(),
354                                    sOtherTxt, sOtherTxtReading, rCmp.GetLocale() );
355 
356 	// Wenn nicht zusammengefasst wird muss die Pos aus gewertet werden
357     if(bRet && !(GetOptions() & nsSwTOIOptions::TOI_SAME_ENTRY))
358 		bRet = nPos == rCmp.nPos;
359 
360 	return bRet;
361 }
362 
363 //
364 // kleiner haengt nur vom Text ab
365 
366 
367 //
368 
369 sal_Bool SwTOXIndex::operator<( const SwTOXSortTabBase& rCmpBase )
370 {
371 	SwTOXIndex& rCmp = (SwTOXIndex&)rCmpBase;
372 
373 	ASSERT(pTxtMark, "pTxtMark == 0, Kein Stichwort");
374 
375     String sMyTxt;
376     String sMyTxtReading;
377     GetTxt( sMyTxt, sMyTxtReading );
378 
379     String sOtherTxt;
380     String sOtherTxtReading;
381     rCmp.GetTxt( sOtherTxt, sOtherTxtReading );
382 
383     sal_Bool bRet = GetLevel() == rCmp.GetLevel() &&
384                 pTOXIntl->IsLess( sMyTxt, sMyTxtReading, GetLocale(),
385                                   sOtherTxt, sOtherTxtReading, rCmp.GetLocale() );
386 
387 	// Wenn nicht zusammengefasst wird muss die Pos aus gewertet werden
388     if( !bRet && !(GetOptions() & nsSwTOIOptions::TOI_SAME_ENTRY) )
389     {
390         bRet = pTOXIntl->IsEqual( sMyTxt, sMyTxtReading, GetLocale(),
391                                    sOtherTxt, sOtherTxtReading, rCmp.GetLocale() ) &&
392                nPos < rCmp.nPos;
393     }
394 
395 	return bRet;
396 }
397 
398 //
399 // Das Stichwort selbst
400 
401 
402 //
403 
404 void SwTOXIndex::GetText_Impl( String& rTxt, String& rTxtReading ) const
405 {
406 	ASSERT(pTxtMark, "pTxtMark == 0, Kein Stichwort");
407 	const SwTOXMark& rTOXMark = pTxtMark->GetTOXMark();
408 	switch(nKeyLevel)
409 	{
410 		case FORM_PRIMARY_KEY	 :
411         {
412 			rTxt = rTOXMark.GetPrimaryKey();
413             rTxtReading = rTOXMark.GetPrimaryKeyReading();
414         }
415 		break;
416 		case FORM_SECONDARY_KEY  :
417         {
418 			rTxt = rTOXMark.GetSecondaryKey();
419             rTxtReading = rTOXMark.GetSecondaryKeyReading();
420         }
421 		break;
422 		case FORM_ENTRY			 :
423         {
424 			rTxt = rTOXMark.GetText();
425             rTxtReading = rTOXMark.GetTextReading();
426         }
427 		break;
428 	}
429 	// if TOI_INITIAL_CAPS is set, first character is to be capitalized
430     if( nsSwTOIOptions::TOI_INITIAL_CAPS & nOpt && pTOXIntl )
431 	{
432 		String sUpper( pTOXIntl->ToUpper( rTxt, 0 ));
433 		rTxt.Erase( 0, 1 ).Insert( sUpper, 0 );
434 	}
435 }
436 
437 void SwTOXIndex::FillText( SwTxtNode& rNd, const SwIndex& rInsPos, sal_uInt16 ) const
438 {
439 	const xub_StrLen* pEnd = pTxtMark->GetEnd();
440 	String sTmp;
441     String sTmpReading;
442 	if( pEnd && !pTxtMark->GetTOXMark().IsAlternativeText() &&
443             0 == (GetOptions() & nsSwTOIOptions::TOI_KEY_AS_ENTRY))
444 	{
445 		sTmp = ((SwTxtNode*)aTOXSources[0].pNd)->GetExpandTxt(
446 							*pTxtMark->GetStart(),
447 							*pEnd - *pTxtMark->GetStart());
448         if(nsSwTOIOptions::TOI_INITIAL_CAPS&nOpt && pTOXIntl)
449 		{
450 			String sUpper( pTOXIntl->ToUpper( sTmp, 0 ));
451 			sTmp.Erase( 0, 1 ).Insert( sUpper, 0 );
452 		}
453 	}
454 	else
455         GetTxt( sTmp, sTmpReading );
456 
457     rNd.InsertText( sTmp, rInsPos );
458 }
459 
460 
461 
462 sal_uInt16 SwTOXIndex::GetLevel() const
463 {
464 	ASSERT(pTxtMark, "pTxtMark == 0, Kein Stichwort");
465 
466 	sal_uInt16 nForm = FORM_PRIMARY_KEY;
467 
468     if( 0 == (GetOptions() & nsSwTOIOptions::TOI_KEY_AS_ENTRY)&&
469 		pTxtMark->GetTOXMark().GetPrimaryKey().Len() )
470 	{
471 		nForm = FORM_SECONDARY_KEY;
472 		if( pTxtMark->GetTOXMark().GetSecondaryKey().Len() )
473 			nForm = FORM_ENTRY;
474 	}
475 	return nForm;
476 }
477 
478 /*--------------------------------------------------------------------
479 	 Beschreibung: Schluessel und Trennzeichen
480  --------------------------------------------------------------------*/
481 
482 
483 SwTOXCustom::SwTOXCustom(const String& rStr, const String& rReading,
484                          sal_uInt16 nLevel,
485                          const SwTOXInternational& rIntl,
486                          const lang::Locale& rLocale )
487     : SwTOXSortTabBase( TOX_SORT_CUSTOM, 0, 0, &rIntl, &rLocale ),
488     aKey(rStr), sReading(rReading), nLev(nLevel)
489 {
490 }
491 
492 
493 sal_Bool SwTOXCustom::operator==(const SwTOXSortTabBase& rCmpBase)
494 {
495     String sMyTxt;
496     String sMyTxtReading;
497     GetTxt( sMyTxt, sMyTxtReading );
498 
499     String sOtherTxt;
500     String sOtherTxtReading;
501     rCmpBase.GetTxt( sOtherTxt, sOtherTxtReading );
502 
503     return GetLevel() == rCmpBase.GetLevel() &&
504            pTOXIntl->IsEqual( sMyTxt, sMyTxtReading, GetLocale(),
505                               sOtherTxt, sOtherTxtReading, rCmpBase.GetLocale() );
506 }
507 
508 
509 sal_Bool SwTOXCustom::operator < (const SwTOXSortTabBase& rCmpBase)
510 {
511     String sMyTxt;
512     String sMyTxtReading;
513     GetTxt( sMyTxt, sMyTxtReading );
514 
515     String sOtherTxt;
516     String sOtherTxtReading;
517     rCmpBase.GetTxt( sOtherTxt, sOtherTxtReading );
518 
519     return  GetLevel() <= rCmpBase.GetLevel() &&
520             pTOXIntl->IsLess( sMyTxt, sMyTxtReading, GetLocale(),
521                               sOtherTxt, sOtherTxtReading, rCmpBase.GetLocale() );
522 }
523 
524 
525 sal_uInt16 SwTOXCustom::GetLevel() const
526 {
527 	return nLev;
528 }
529 
530 
531 void SwTOXCustom::GetText_Impl( String& rTxt, String &rTxtReading ) const
532 {
533 	rTxt = aKey;
534     rTxtReading = sReading;
535     /// !!!!!!!!!!!!!!
536 }
537 
538 
539 /*--------------------------------------------------------------------
540 	 Beschreibung: sortierter Inhaltsverz. Eintrag
541  --------------------------------------------------------------------*/
542 
543 
544 SwTOXContent::SwTOXContent( const SwTxtNode& rNd, const SwTxtTOXMark* pMark,
545 						const SwTOXInternational& rIntl)
546     : SwTOXSortTabBase( TOX_SORT_CONTENT, &rNd, pMark, &rIntl )
547 {
548 }
549 
550 
551 //	Der Text des Inhalts
552 //
553 
554 void SwTOXContent::GetText_Impl( String& rTxt, String& rTxtReading ) const
555 {
556 	const xub_StrLen* pEnd = pTxtMark->GetEnd();
557 	if( pEnd && !pTxtMark->GetTOXMark().IsAlternativeText() )
558     {
559 		rTxt = ((SwTxtNode*)aTOXSources[0].pNd)->GetExpandTxt(
560 									 *pTxtMark->GetStart(),
561 									 *pEnd - *pTxtMark->GetStart() );
562 
563         rTxtReading = pTxtMark->GetTOXMark().GetTextReading();
564     }
565 	else
566 		rTxt = pTxtMark->GetTOXMark().GetAlternativeText();
567 }
568 
569 void SwTOXContent::FillText( SwTxtNode& rNd, const SwIndex& rInsPos, sal_uInt16 ) const
570 {
571 	const xub_StrLen* pEnd = pTxtMark->GetEnd();
572 	if( pEnd && !pTxtMark->GetTOXMark().IsAlternativeText() )
573 		((SwTxtNode*)aTOXSources[0].pNd)->GetExpandTxt( rNd, &rInsPos,
574 									*pTxtMark->GetStart(),
575 									*pEnd - *pTxtMark->GetStart() );
576 	else
577     {
578         String sTmp, sTmpReading;
579         GetTxt( sTmp, sTmpReading );
580         rNd.InsertText( sTmp, rInsPos );
581     }
582 }
583 
584 //
585 // Die Ebene fuer Anzeige
586 //
587 
588 
589 sal_uInt16 SwTOXContent::GetLevel() const
590 {
591 	return pTxtMark->GetTOXMark().GetLevel();
592 }
593 
594 /*--------------------------------------------------------------------
595 	 Beschreibung: Verzeichnis aus Absaetzen zusammengesammelt
596  --------------------------------------------------------------------*/
597 
598 // bei Sortierung von OLE/Grafiken aufpassen !!!
599 // Die Position darf nicht die im Dokument,
600 // sondern muss die vom "Henkel" sein  !!
601 
602 
603 SwTOXPara::SwTOXPara( const SwCntntNode& rNd, SwTOXElement eT, sal_uInt16 nLevel )
604 	: SwTOXSortTabBase( TOX_SORT_PARA, &rNd, 0, 0 ),
605 	eType( eT ),
606 	m_nLevel(nLevel),
607 	nStartIndex(0),
608 	nEndIndex(STRING_LEN)
609 {
610 }
611 
612 
613 void SwTOXPara::GetText_Impl( String& rTxt, String& ) const
614 {
615 	const SwCntntNode* pNd = aTOXSources[0].pNd;
616 	switch( eType )
617 	{
618     case nsSwTOXElement::TOX_SEQUENCE:
619     case nsSwTOXElement::TOX_TEMPLATE:
620     case nsSwTOXElement::TOX_OUTLINELEVEL:
621 		{
622 			xub_StrLen nStt = nStartIndex;
623 /* JP 22.01.98:
624 	Tabs ueberspringen - macht aber keinen Sinn, solange in der TOX-Form
625 	nicht die KapitelNummer eingestellt werden kann
626 			const String& rTmp = ((SwTxtNode*)pNd)->GetTxt();
627 			while( '\t' == rTmp.GetChar( nStt ) && nStt < rTmp.Len() )
628 				++nStt;
629 */
630 			rTxt = ((SwTxtNode*)pNd)->GetExpandTxt(
631 					nStt,
632 					STRING_NOTFOUND == nEndIndex ? STRING_LEN : nEndIndex - nStt);
633 		}
634 		break;
635 
636     case nsSwTOXElement::TOX_OLE:
637     case nsSwTOXElement::TOX_GRAPHIC:
638     case nsSwTOXElement::TOX_FRAME:
639 		{
640 			// suche das FlyFormat, dort steht der Object/Grafik-Name
641 			SwFrmFmt* pFly = pNd->GetFlyFmt();
642 			if( pFly )
643 				rTxt = pFly->GetName();
644 			else
645 			{
646 				ASSERT( !this, "Grafik/Object ohne Namen" )
647                 sal_uInt16 nId = nsSwTOXElement::TOX_OLE == eType
648 								? STR_OBJECT_DEFNAME
649                                 : nsSwTOXElement::TOX_GRAPHIC == eType
650 									? STR_GRAPHIC_DEFNAME
651 									: STR_FRAME_DEFNAME;
652 				rTxt = SW_RESSTR( nId );
653 			}
654 		}
655 		break;
656     default: break;
657 	}
658 }
659 
660 void SwTOXPara::FillText( SwTxtNode& rNd, const SwIndex& rInsPos, sal_uInt16 ) const
661 {
662     if( nsSwTOXElement::TOX_TEMPLATE == eType || nsSwTOXElement::TOX_SEQUENCE == eType  || nsSwTOXElement::TOX_OUTLINELEVEL == eType)
663 	{
664 		SwTxtNode* pSrc = (SwTxtNode*)aTOXSources[0].pNd;
665 		xub_StrLen nStt = nStartIndex;
666 /* JP 22.01.98:
667 	Tabs ueberspringen - macht aber keinen Sinn, solange in der TOX-Form
668 	nicht die KapitelNummer eingestellt werden kann
669 		const String& rTxt = pSrc->GetTxt();
670 		while( '\t' == rTxt.GetChar( nStt ) && nStt < rTxt.Len() )
671 			++nStt;
672 */
673 		pSrc->GetExpandTxt( rNd, &rInsPos, nStt,
674 				nEndIndex == STRING_LEN ? STRING_LEN : nEndIndex - nStt,
675                 sal_False, sal_False, sal_True );
676 	}
677 	else
678     {
679         String sTmp, sTmpReading;
680         GetTxt( sTmp, sTmpReading );
681 		sTmp.SearchAndReplaceAll('\t', ' ');
682         rNd.InsertText( sTmp, rInsPos );
683     }
684 }
685 
686 
687 sal_uInt16 SwTOXPara::GetLevel() const
688 {
689 	sal_uInt16 nRet = m_nLevel;
690 	const SwCntntNode*	pNd = aTOXSources[0].pNd;
691 
692     if( nsSwTOXElement::TOX_OUTLINELEVEL == eType && pNd->GetTxtNode() )
693 	{
694 		//sal_uInt16 nTmp = ((SwTxtNode*)pNd)->GetTxtColl()->GetOutlineLevel();//#outline level,zhaojianwei
695 		//if(nTmp < NO_NUMBERING)
696 		//	nRet = nTmp + 1;
697         const int nTmp = ((SwTxtNode*)pNd)->GetAttrOutlineLevel();//#outline level,zhaojianwei????
698 		if(nTmp != 0 )
699             nRet = static_cast<sal_uInt16>(nTmp);
700 	}
701 	return nRet;
702 }
703 
704 
705 String SwTOXPara::GetURL() const
706 {
707 	String aTxt;
708 	const SwCntntNode* pNd = aTOXSources[0].pNd;
709 	switch( eType )
710 	{
711     case nsSwTOXElement::TOX_TEMPLATE:
712     case nsSwTOXElement::TOX_OUTLINELEVEL:
713 		{
714             const SwTxtNode * pTxtNd = static_cast<const SwTxtNode *>(pNd);
715 
716             // --> OD 2009-08-05 #i103265#
717 //            //if( MAXLEVEL >= pTxtNd->GetTxtColl()->GetOutlineLevel())  //#outline level,zhaojianwei
718 //            if ( pTxtNd->GetAttrOutlineLevel() > 0)  //<-end,zhaojianwei
719 //            {
720 //                aTxt = '#';
721 //                const SwNumRule * pRule = pTxtNd->GetNumRule();
722 //                if( pRule )
723 //                {
724 //                    // dann noch die rel. Nummer davor setzen
725 //                    const sal_uInt16 nCurrLevel = static_cast<sal_uInt16>(pTxtNd->GetActualListLevel());
726 //                    if(nCurrLevel <= MAXLEVEL)
727 //                    {
728 //                        // --> OD 2005-11-02 #i51089 - TUNING#
729 //                        if ( pTxtNd->GetNum() )
730 //                        {
731 //                            SwNumberTree::tNumberVector aNumVector =
732 //                                pTxtNd->GetNumberVector();
733 
734 //                            for( sal_uInt16 n = 0; n <= nCurrLevel; ++n )
735 //                            {
736 //                                int nNum = aNumVector[ n ];
737 //                                nNum -= ( pRule->Get( n ).GetStart() - 1 );
738 //                                ( aTxt += String::CreateFromInt32( nNum )) += '.';
739 //                            }
740 //                        }
741 //                        else
742 //                        {
743 //                            ASSERT( false,
744 //                                    "<SwTOXPara::GetURL()> - text node with numbering rule, but without number. This is a serious defect -> inform OD" );
745 //                        }
746 //                    }
747 //                }
748 //                aTxt += pTxtNd->GetExpandTxt();
749 //                ( aTxt += cMarkSeperator ).AppendAscii( pMarkToOutline );
750 //            }
751             SwDoc* pDoc = const_cast<SwDoc*>( pTxtNd->GetDoc() );
752             ::sw::mark::IMark const * const pMark = pDoc->getIDocumentMarkAccess()->getMarkForTxtNode(
753                                 *(pTxtNd),
754                                 IDocumentMarkAccess::CROSSREF_HEADING_BOOKMARK);
755             aTxt = '#';
756             const String aMarkName( pMark->GetName() );
757             aTxt += aMarkName;
758             // <--
759 		}
760 		break;
761 
762     case nsSwTOXElement::TOX_OLE:
763     case nsSwTOXElement::TOX_GRAPHIC:
764     case nsSwTOXElement::TOX_FRAME:
765 		{
766 			// suche das FlyFormat, dort steht der Object/Grafik-Name
767 			SwFrmFmt* pFly = pNd->GetFlyFmt();
768 			if( pFly )
769 			{
770 				(( aTxt = '#' ) += pFly->GetName() ) += cMarkSeperator;
771 				const sal_Char* pStr;
772 				switch( eType )
773 				{
774                 case nsSwTOXElement::TOX_OLE:       pStr = pMarkToOLE; break;
775                 case nsSwTOXElement::TOX_GRAPHIC:   pStr = pMarkToGraphic; break;
776                 case nsSwTOXElement::TOX_FRAME:     pStr = pMarkToFrame; break;
777 				default:			pStr = 0;
778 				}
779 				if( pStr )
780 					aTxt.AppendAscii( pStr );
781 			}
782 		}
783 		break;
784     default: break;
785 	}
786 	return aTxt;
787 }
788 
789 
790 /*--------------------------------------------------------------------
791 	Beschreibung: Tabelle
792  --------------------------------------------------------------------*/
793 
794 
795 SwTOXTable::SwTOXTable( const SwCntntNode& rNd )
796 	: SwTOXSortTabBase( TOX_SORT_TABLE, &rNd, 0, 0 ),
797 	nLevel(FORM_ALPHA_DELIMITTER)
798 {
799 }
800 
801 
802 void SwTOXTable::GetText_Impl( String& rTxt, String& ) const
803 {
804 	const SwNode* pNd = aTOXSources[0].pNd;
805 	if( pNd && 0 != ( pNd = pNd->FindTableNode() ) )
806 	{
807 		rTxt = ((SwTableNode*)pNd)->GetTable().GetFrmFmt()->GetName();
808 	}
809 	else
810 	{
811 		ASSERT( !this, "Wo ist meine Tabelle geblieben?" )
812 		rTxt = SW_RESSTR( STR_TABLE_DEFNAME );
813 	}
814 }
815 
816 sal_uInt16 SwTOXTable::GetLevel() const
817 {
818 	return nLevel;
819 }
820 
821 
822 String SwTOXTable::GetURL() const
823 {
824 	String aTxt;
825 	const SwNode* pNd = aTOXSources[0].pNd;
826 	if( pNd && 0 != ( pNd = pNd->FindTableNode() ) )
827 	{
828 		aTxt = ((SwTableNode*)pNd)->GetTable().GetFrmFmt()->GetName();
829 		if( aTxt.Len() )
830 		{
831 			( aTxt.Insert( '#', 0 ) += cMarkSeperator ).
832 											AppendAscii( pMarkToTable );
833 		}
834 	}
835 	return aTxt;
836 }
837 /*-- 15.09.99 14:28:08---------------------------------------------------
838 
839   -----------------------------------------------------------------------*/
840 
841 SwTOXAuthority::SwTOXAuthority( const SwCntntNode& rNd,
842 				SwFmtFld& rField, const SwTOXInternational& rIntl ) :
843 	SwTOXSortTabBase( TOX_SORT_AUTHORITY, &rNd, 0, &rIntl ),
844 	m_rField(rField)
845 {
846 	if(rField.GetTxtFld())
847 		nCntPos = *rField.GetTxtFld()->GetStart();
848 }
849 
850 sal_uInt16 SwTOXAuthority::GetLevel() const
851 {
852 	String sText(((SwAuthorityField*)m_rField.GetFld())->
853 						GetFieldText(AUTH_FIELD_AUTHORITY_TYPE));
854     //#i18655# the level '0' is the heading level therefor the values are incremented here
855     sal_uInt16 nRet = 1;
856 	if( pTOXIntl->IsNumeric( sText ) )
857 	{
858 		nRet = (sal_uInt16)sText.ToInt32();
859 		nRet++;
860 	}
861     //illegal values are also set to 'ARTICLE' as non-numeric values are
862     if(nRet > AUTH_TYPE_END)
863         nRet = 1;
864 	return nRet;
865 }
866 /*-- 15.09.99 14:28:08---------------------------------------------------
867 
868   -----------------------------------------------------------------------*/
869 static String lcl_GetText(SwFmtFld const& rField)
870 {
871     return rField.GetFld()->ExpandField(true);
872 }
873 
874 void SwTOXAuthority::GetText_Impl( String& rTxt, String& ) const
875 {
876     rTxt = lcl_GetText(m_rField);
877 }
878 
879 /* -----------------21.09.99 12:50-------------------
880 
881  --------------------------------------------------*/
882 void 	SwTOXAuthority::FillText( SwTxtNode& rNd,
883 						const SwIndex& rInsPos, sal_uInt16 nAuthField ) const
884 {
885 	SwAuthorityField* pField = (SwAuthorityField*)m_rField.GetFld();
886 	String sText;
887 	if(AUTH_FIELD_IDENTIFIER == nAuthField)
888 	{
889         sText = lcl_GetText(m_rField);
890         const SwAuthorityFieldType* pType = (const SwAuthorityFieldType*)pField->GetTyp();
891         sal_Unicode cChar = pType->GetPrefix();
892         if(cChar && cChar != ' ')
893             sText.Erase(0, 1);
894         cChar = pType->GetSuffix();
895         if(cChar && cChar != ' ')
896             sText.Erase(sText.Len() - 1, 1);
897 	}
898 	else if(AUTH_FIELD_AUTHORITY_TYPE == nAuthField)
899 	{
900 		sal_uInt16 nLevel = GetLevel();
901 		if(nLevel)
902 			sText = SwAuthorityFieldType::GetAuthTypeName((ToxAuthorityType) --nLevel);
903 	}
904 	else
905 		sText = (pField->GetFieldText((ToxAuthorityField) nAuthField));
906     rNd.InsertText( sText, rInsPos );
907 }
908 /* -----------------14.10.99 09:35-------------------
909 
910  --------------------------------------------------*/
911 sal_Bool 	SwTOXAuthority::operator==( const SwTOXSortTabBase& rCmp)
912 {
913 	return nType == rCmp.nType &&
914 			((SwAuthorityField*)m_rField.GetFld())->GetHandle() ==
915 				((SwAuthorityField*)((SwTOXAuthority&)rCmp).m_rField.GetFld())->GetHandle();
916 }
917 /* -----------------21.10.99 09:52-------------------
918 
919  --------------------------------------------------*/
920 sal_Bool 	SwTOXAuthority::operator<( const SwTOXSortTabBase& rBase)
921 {
922 	sal_Bool bRet = sal_False;
923 	SwAuthorityField* pField = (SwAuthorityField*)m_rField.GetFld();
924 	SwAuthorityFieldType* pType = (SwAuthorityFieldType*)
925 												pField->GetTyp();
926 	if(pType->IsSortByDocument())
927 		bRet = SwTOXSortTabBase::operator<(rBase);
928 	else
929 	{
930 		SwAuthorityField* pCmpField = (SwAuthorityField*)
931 						((SwTOXAuthority&)rBase).m_rField.GetFld();
932 
933 
934 		for(sal_uInt16 i = 0; i < pType->GetSortKeyCount(); i++)
935 		{
936 			const SwTOXSortKey*	pKey = pType->GetSortKey(i);
937             String sMyTxt = pField->GetFieldText(pKey->eField);
938             String sMyTxtReading;
939             String sOtherTxt = pCmpField->GetFieldText(pKey->eField);
940             String sOtherTxtReading;
941 
942             sal_Int32 nComp = pTOXIntl->Compare( sMyTxt, sMyTxtReading, GetLocale(),
943                                                  sOtherTxt, sOtherTxtReading, rBase.GetLocale() );
944 
945             if( nComp )
946 			{
947 				bRet = (-1 == nComp) == pKey->bSortAscending;
948 				break;
949 			}
950 		}
951 	}
952 	return bRet;
953 }
954