xref: /trunk/main/sw/source/core/tox/txmsrt.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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