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