Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <limits.h>
21 : #include <hintids.hxx>
22 : #include <comphelper/string.hxx>
23 : #include <editeng/langitem.hxx>
24 : #include <editeng/formatbreakitem.hxx>
25 : #include <editeng/tstpitem.hxx>
26 : #include <editeng/lrspitem.hxx>
27 : #include <comphelper/classids.hxx>
28 : #include <docsh.hxx>
29 : #include <ndole.hxx>
30 : #include <txttxmrk.hxx>
31 : #include <fmtinfmt.hxx>
32 : #include <fmtpdsc.hxx>
33 : #include <frmfmt.hxx>
34 : #include <fmtfsize.hxx>
35 : #include <frmatr.hxx>
36 : #include <pagedesc.hxx>
37 : #include <doc.hxx>
38 : #include <IDocumentUndoRedo.hxx>
39 : #include <DocumentSettingManager.hxx>
40 : #include <IDocumentRedlineAccess.hxx>
41 : #include <IDocumentFieldsAccess.hxx>
42 : #include <IDocumentState.hxx>
43 : #include <IDocumentLayoutAccess.hxx>
44 : #include <IDocumentStylePoolAccess.hxx>
45 : #include <pagefrm.hxx>
46 : #include <ndtxt.hxx>
47 : #include <swtable.hxx>
48 : #include <doctxm.hxx>
49 : #include <txmsrt.hxx>
50 : #include <rolbck.hxx>
51 : #include <poolfmt.hxx>
52 : #include <txtfrm.hxx>
53 : #include <rootfrm.hxx>
54 : #include <UndoAttribute.hxx>
55 : #include <swundo.hxx>
56 : #include <mdiexp.hxx>
57 : #include <docary.hxx>
58 : #include <charfmt.hxx>
59 : #include <fchrfmt.hxx>
60 : #include <fldbas.hxx>
61 : #include <fmtfld.hxx>
62 : #include <txtfld.hxx>
63 : #include <expfld.hxx>
64 : #include <chpfld.hxx>
65 : #include <mvsave.hxx>
66 : #include <node2lay.hxx>
67 : #include <SwStyleNameMapper.hxx>
68 : #include <breakit.hxx>
69 : #include <editsh.hxx>
70 : #include <scriptinfo.hxx>
71 : #include <switerator.hxx>
72 : #include <ToxTextGenerator.hxx>
73 : #include <ToxTabStopTokenHandler.hxx>
74 :
75 : #include <boost/make_shared.hpp>
76 :
77 : using namespace ::com::sun::star;
78 :
79 23020 : TYPEINIT2( SwTOXBaseSection, SwTOXBase, SwSection ); // for RTTI
80 :
81 0 : sal_uInt16 SwDoc::GetTOIKeys( SwTOIKeyType eTyp, std::vector<OUString>& rArr ) const
82 : {
83 0 : rArr.clear();
84 :
85 : // Look up all Primary and Secondary via the Pool
86 0 : const sal_uInt32 nMaxItems = GetAttrPool().GetItemCount2( RES_TXTATR_TOXMARK );
87 0 : for( sal_uInt32 i = 0; i < nMaxItems; ++i )
88 : {
89 0 : const SwTOXMark* pItem = (SwTOXMark*)GetAttrPool().GetItem2( RES_TXTATR_TOXMARK, i );
90 0 : if( !pItem )
91 0 : continue;
92 0 : const SwTOXType* pTOXType = pItem->GetTOXType();
93 0 : if ( !pTOXType || pTOXType->GetType()!=TOX_INDEX )
94 0 : continue;
95 0 : const SwTxtTOXMark* pMark = pItem->GetTxtTOXMark();
96 0 : if ( pMark && pMark->GetpTxtNd() &&
97 0 : pMark->GetpTxtNd()->GetNodes().IsDocNodes() )
98 : {
99 : const OUString sStr = TOI_PRIMARY == eTyp
100 : ? pItem->GetPrimaryKey()
101 0 : : pItem->GetSecondaryKey();
102 :
103 0 : if( !sStr.isEmpty() )
104 0 : rArr.push_back( sStr );
105 : }
106 : }
107 :
108 0 : return rArr.size();
109 : }
110 :
111 : /// Get current table of contents Mark.
112 32 : sal_uInt16 SwDoc::GetCurTOXMark( const SwPosition& rPos,
113 : SwTOXMarks& rArr ) const
114 : {
115 : // search on Position rPos for all SwTOXMarks
116 32 : SwTxtNode *const pTxtNd = rPos.nNode.GetNode().GetTxtNode();
117 32 : if( !pTxtNd || !pTxtNd->GetpSwpHints() )
118 32 : return 0;
119 :
120 0 : const SwpHints & rHts = *pTxtNd->GetpSwpHints();
121 : sal_Int32 nSttIdx;
122 : const sal_Int32 *pEndIdx;
123 :
124 0 : const sal_Int32 nAktPos = rPos.nContent.GetIndex();
125 :
126 0 : for( size_t n = 0; n < rHts.Count(); ++n )
127 : {
128 0 : const SwTxtAttr* pHt = rHts[n];
129 0 : if( RES_TXTATR_TOXMARK != pHt->Which() )
130 0 : continue;
131 0 : if( ( nSttIdx = pHt->GetStart() ) < nAktPos )
132 : {
133 : // also check the end
134 0 : if( 0 == ( pEndIdx = pHt->End() ) ||
135 0 : *pEndIdx <= nAktPos )
136 0 : continue; // keep searching
137 : }
138 0 : else if( nSttIdx > nAktPos )
139 : // If Hint's Start is greater than rPos, break, because
140 : // the attributes are sorted by Start!
141 0 : break;
142 :
143 0 : SwTOXMark* pTMark = (SwTOXMark*) &pHt->GetTOXMark();
144 0 : rArr.push_back( pTMark );
145 : }
146 0 : return rArr.size();
147 : }
148 :
149 : /// Delete table of contents Mark
150 10 : void SwDoc::DeleteTOXMark( const SwTOXMark* pTOXMark )
151 : {
152 10 : const SwTxtTOXMark* pTxtTOXMark = pTOXMark->GetTxtTOXMark();
153 : OSL_ENSURE( pTxtTOXMark, "No TxtTOXMark, cannot be deleted" );
154 :
155 10 : SwTxtNode& rTxtNd = const_cast<SwTxtNode&>(pTxtTOXMark->GetTxtNode());
156 : OSL_ENSURE( rTxtNd.GetpSwpHints(), "cannot be deleted" );
157 :
158 10 : if (GetIDocumentUndoRedo().DoesUndo())
159 : {
160 : // save attributes for Undo
161 : SwUndoResetAttr* pUndo = new SwUndoResetAttr(
162 10 : SwPosition( rTxtNd, SwIndex( &rTxtNd, pTxtTOXMark->GetStart() ) ),
163 10 : RES_TXTATR_TOXMARK );
164 10 : GetIDocumentUndoRedo().AppendUndo( pUndo );
165 :
166 10 : SwRegHistory aRHst( rTxtNd, &pUndo->GetHistory() );
167 10 : rTxtNd.GetpSwpHints()->Register( &aRHst );
168 : }
169 :
170 10 : rTxtNd.DeleteAttribute( const_cast<SwTxtTOXMark*>(pTxtTOXMark) );
171 :
172 10 : if (GetIDocumentUndoRedo().DoesUndo())
173 : {
174 10 : if( rTxtNd.GetpSwpHints() )
175 2 : rTxtNd.GetpSwpHints()->DeRegister();
176 : }
177 10 : getIDocumentState().SetModified();
178 10 : }
179 :
180 : /// Travel between table of content Marks
181 : class CompareNodeCntnt
182 : {
183 : sal_uLong nNode;
184 : sal_Int32 nCntnt;
185 : public:
186 0 : CompareNodeCntnt( sal_uLong nNd, sal_Int32 nCnt )
187 0 : : nNode( nNd ), nCntnt( nCnt ) {}
188 :
189 0 : bool operator==( const CompareNodeCntnt& rCmp ) const
190 0 : { return nNode == rCmp.nNode && nCntnt == rCmp.nCntnt; }
191 0 : bool operator!=( const CompareNodeCntnt& rCmp ) const
192 0 : { return nNode != rCmp.nNode || nCntnt != rCmp.nCntnt; }
193 0 : bool operator< ( const CompareNodeCntnt& rCmp ) const
194 0 : { return nNode < rCmp.nNode ||
195 0 : ( nNode == rCmp.nNode && nCntnt < rCmp.nCntnt); }
196 0 : bool operator<=( const CompareNodeCntnt& rCmp ) const
197 0 : { return nNode < rCmp.nNode ||
198 0 : ( nNode == rCmp.nNode && nCntnt <= rCmp.nCntnt); }
199 0 : bool operator> ( const CompareNodeCntnt& rCmp ) const
200 0 : { return nNode > rCmp.nNode ||
201 0 : ( nNode == rCmp.nNode && nCntnt > rCmp.nCntnt); }
202 0 : bool operator>=( const CompareNodeCntnt& rCmp ) const
203 0 : { return nNode > rCmp.nNode ||
204 0 : ( nNode == rCmp.nNode && nCntnt >= rCmp.nCntnt); }
205 : };
206 :
207 0 : const SwTOXMark& SwDoc::GotoTOXMark( const SwTOXMark& rCurTOXMark,
208 : SwTOXSearch eDir, bool bInReadOnly )
209 : {
210 0 : const SwTxtTOXMark* pMark = rCurTOXMark.GetTxtTOXMark();
211 : OSL_ENSURE(pMark, "pMark==0 invalid TxtTOXMark");
212 :
213 0 : const SwTxtNode *pTOXSrc = pMark->GetpTxtNd();
214 :
215 0 : CompareNodeCntnt aAbsIdx( pTOXSrc->GetIndex(), pMark->GetStart() );
216 0 : CompareNodeCntnt aPrevPos( 0, 0 );
217 0 : CompareNodeCntnt aNextPos( ULONG_MAX, SAL_MAX_INT32 );
218 0 : CompareNodeCntnt aMax( 0, 0 );
219 0 : CompareNodeCntnt aMin( ULONG_MAX, SAL_MAX_INT32 );
220 :
221 0 : const SwTOXMark* pNew = 0;
222 0 : const SwTOXMark* pMax = &rCurTOXMark;
223 0 : const SwTOXMark* pMin = &rCurTOXMark;
224 :
225 0 : const SwTOXType* pType = rCurTOXMark.GetTOXType();
226 0 : SwTOXMarks aMarks;
227 0 : SwTOXMark::InsertTOXMarks( aMarks, *pType );
228 :
229 0 : for( size_t nMark=0; nMark<aMarks.size(); ++nMark )
230 : {
231 0 : const SwTOXMark* pTOXMark = aMarks[nMark];
232 0 : if ( pTOXMark == &rCurTOXMark )
233 0 : continue;
234 :
235 0 : pMark = pTOXMark->GetTxtTOXMark();
236 0 : if (!pMark)
237 0 : continue;
238 :
239 0 : pTOXSrc = pMark->GetpTxtNd();
240 0 : if (!pTOXSrc)
241 0 : continue;
242 :
243 0 : Point aPt;
244 0 : const SwCntntFrm* pCFrm = pTOXSrc->getLayoutFrm( getIDocumentLayoutAccess().GetCurrentLayout(), &aPt, 0, false );
245 0 : if (!pCFrm)
246 0 : continue;
247 :
248 0 : if ( bInReadOnly || !pCFrm->IsProtected() )
249 : {
250 0 : CompareNodeCntnt aAbsNew( pTOXSrc->GetIndex(), pMark->GetStart() );
251 0 : switch( eDir )
252 : {
253 : // The following (a bit more complicated) statements make it
254 : // possible to also travel across Entries on the same (!)
255 : // position. If someone has time, please feel free to optimize.
256 : case TOX_SAME_PRV:
257 0 : if( pTOXMark->GetText() != rCurTOXMark.GetText() )
258 0 : break;
259 : /* no break here */
260 : case TOX_PRV:
261 0 : if ( (aAbsNew < aAbsIdx && aAbsNew > aPrevPos) ||
262 0 : (aAbsIdx == aAbsNew &&
263 0 : (sal_uLong(&rCurTOXMark) > sal_uLong(pTOXMark) &&
264 0 : (!pNew ||
265 0 : (pNew && (aPrevPos < aAbsIdx ||
266 0 : sal_uLong(pNew) < sal_uLong(pTOXMark)))))) ||
267 0 : (aPrevPos == aAbsNew && aAbsIdx != aAbsNew &&
268 0 : sal_uLong(pTOXMark) > sal_uLong(pNew)) )
269 : {
270 0 : pNew = pTOXMark;
271 0 : aPrevPos = aAbsNew;
272 0 : if ( aAbsNew >= aMax )
273 : {
274 0 : aMax = aAbsNew;
275 0 : pMax = pTOXMark;
276 : }
277 : }
278 0 : break;
279 :
280 : case TOX_SAME_NXT:
281 0 : if( pTOXMark->GetText() != rCurTOXMark.GetText() )
282 0 : break;
283 : /* no break here */
284 : case TOX_NXT:
285 0 : if ( (aAbsNew > aAbsIdx && aAbsNew < aNextPos) ||
286 0 : (aAbsIdx == aAbsNew &&
287 0 : (sal_uLong(&rCurTOXMark) < sal_uLong(pTOXMark) &&
288 0 : (!pNew ||
289 0 : (pNew && (aNextPos > aAbsIdx ||
290 0 : sal_uLong(pNew) > sal_uLong(pTOXMark)))))) ||
291 0 : (aNextPos == aAbsNew && aAbsIdx != aAbsNew &&
292 0 : sal_uLong(pTOXMark) < sal_uLong(pNew)) )
293 : {
294 0 : pNew = pTOXMark;
295 0 : aNextPos = aAbsNew;
296 0 : if ( aAbsNew <= aMin )
297 : {
298 0 : aMin = aAbsNew;
299 0 : pMin = pTOXMark;
300 : }
301 : }
302 0 : break;
303 : }
304 : }
305 : }
306 :
307 : // We couldn't find a successor
308 : // Use minimum or maximum
309 0 : if(!pNew)
310 : {
311 0 : switch(eDir)
312 : {
313 : case TOX_PRV:
314 : case TOX_SAME_PRV:
315 0 : pNew = pMax;
316 0 : break;
317 : case TOX_NXT:
318 : case TOX_SAME_NXT:
319 0 : pNew = pMin;
320 0 : break;
321 : default:
322 0 : pNew = &rCurTOXMark;
323 : }
324 : }
325 0 : return *pNew;
326 : }
327 :
328 226 : const SwTOXBaseSection* SwDoc::InsertTableOf( const SwPosition& rPos,
329 : const SwTOXBase& rTOX,
330 : const SfxItemSet* pSet,
331 : bool bExpand )
332 : {
333 226 : GetIDocumentUndoRedo().StartUndo( UNDO_INSTOX, NULL );
334 :
335 226 : OUString sSectNm = GetUniqueTOXBaseName( *rTOX.GetTOXType(), rTOX.GetTOXName() );
336 452 : SwPaM aPam( rPos );
337 452 : SwSectionData aSectionData( TOX_CONTENT_SECTION, sSectNm );
338 : SwTOXBaseSection *const pNewSection = dynamic_cast<SwTOXBaseSection *>(
339 226 : InsertSwSection( aPam, aSectionData, & rTOX, pSet, false ));
340 226 : if (pNewSection)
341 : {
342 226 : SwSectionNode *const pSectNd = pNewSection->GetFmt()->GetSectionNode();
343 226 : pNewSection->SetTOXName(sSectNm); // rTOX may have had no name...
344 :
345 226 : if( bExpand )
346 : {
347 : // add value for 2nd parameter = true to
348 : // indicate, that a creation of a new table of content has to be performed.
349 : // Value of 1st parameter = default value.
350 0 : pNewSection->Update( 0, true );
351 : }
352 226 : else if( rTOX.GetTitle().getLength()==1 && IsInReading() )
353 : // insert title of TOX
354 : {
355 : // then insert the headline section
356 0 : SwNodeIndex aIdx( *pSectNd, +1 );
357 :
358 0 : SwTxtNode* pHeadNd = GetNodes().MakeTxtNode( aIdx,
359 0 : getIDocumentStylePoolAccess().GetTxtCollFromPool( RES_POOLCOLL_STANDARD ) );
360 :
361 0 : OUString sNm( pNewSection->GetTOXName() );
362 : // ??Resource
363 0 : sNm += "_Head";
364 :
365 0 : SwSectionData headerData( TOX_HEADER_SECTION, sNm );
366 :
367 0 : SwNodeIndex aStt( *pHeadNd ); aIdx--;
368 0 : SwSectionFmt* pSectFmt = MakeSectionFmt( 0 );
369 0 : GetNodes().InsertTextSection(
370 0 : aStt, *pSectFmt, headerData, 0, &aIdx, true, false);
371 : }
372 : }
373 :
374 226 : GetIDocumentUndoRedo().EndUndo( UNDO_INSTOX, NULL );
375 :
376 452 : return pNewSection;
377 : }
378 :
379 0 : const SwTOXBaseSection* SwDoc::InsertTableOf( sal_uLong nSttNd, sal_uLong nEndNd,
380 : const SwTOXBase& rTOX,
381 : const SfxItemSet* pSet )
382 : {
383 : // check for recursiv TOX
384 0 : SwNode* pNd = GetNodes()[ nSttNd ];
385 0 : SwSectionNode* pSectNd = pNd->FindSectionNode();
386 0 : while( pSectNd )
387 : {
388 0 : SectionType eT = pSectNd->GetSection().GetType();
389 0 : if( TOX_HEADER_SECTION == eT || TOX_CONTENT_SECTION == eT )
390 0 : return 0;
391 0 : pSectNd = pSectNd->StartOfSectionNode()->FindSectionNode();
392 : }
393 :
394 0 : OUString sSectNm = GetUniqueTOXBaseName(*rTOX.GetTOXType(), rTOX.GetTOXName());
395 :
396 0 : SwSectionData aSectionData( TOX_CONTENT_SECTION, sSectNm );
397 :
398 0 : SwNodeIndex aStt( GetNodes(), nSttNd ), aEnd( GetNodes(), nEndNd );
399 0 : SwSectionFmt* pFmt = MakeSectionFmt( 0 );
400 0 : if(pSet)
401 0 : pFmt->SetFmtAttr(*pSet);
402 :
403 : SwSectionNode *const pNewSectionNode =
404 0 : GetNodes().InsertTextSection(aStt, *pFmt, aSectionData, &rTOX, &aEnd);
405 0 : if (!pNewSectionNode)
406 : {
407 0 : DelSectionFmt( pFmt );
408 0 : return 0;
409 : }
410 :
411 : SwTOXBaseSection *const pNewSection(
412 0 : dynamic_cast<SwTOXBaseSection*>(& pNewSectionNode->GetSection()));
413 0 : if (pNewSection)
414 0 : pNewSection->SetTOXName(sSectNm); // rTOX may have had no name...
415 0 : return pNewSection;
416 : }
417 :
418 : /// Get current table of contents
419 2290 : const SwTOXBase* SwDoc::GetCurTOX( const SwPosition& rPos ) const
420 : {
421 2290 : const SwNode& rNd = rPos.nNode.GetNode();
422 2290 : const SwSectionNode* pSectNd = rNd.FindSectionNode();
423 4584 : while( pSectNd )
424 : {
425 40 : SectionType eT = pSectNd->GetSection().GetType();
426 40 : if( TOX_CONTENT_SECTION == eT )
427 : {
428 : OSL_ENSURE( pSectNd->GetSection().ISA( SwTOXBaseSection ),
429 : "no TOXBaseSection!" );
430 : SwTOXBaseSection& rTOXSect = (SwTOXBaseSection&)
431 36 : pSectNd->GetSection();
432 36 : return &rTOXSect;
433 : }
434 4 : pSectNd = pSectNd->StartOfSectionNode()->FindSectionNode();
435 : }
436 2254 : return 0;
437 : }
438 :
439 226 : const SwAttrSet& SwDoc::GetTOXBaseAttrSet(const SwTOXBase& rTOXBase) const
440 : {
441 : OSL_ENSURE( rTOXBase.ISA( SwTOXBaseSection ), "no TOXBaseSection!" );
442 226 : const SwTOXBaseSection& rTOXSect = (const SwTOXBaseSection&)rTOXBase;
443 226 : SwSectionFmt* pFmt = rTOXSect.GetFmt();
444 : OSL_ENSURE( pFmt, "invalid TOXBaseSection!" );
445 226 : return pFmt->GetAttrSet();
446 : }
447 :
448 0 : const SwTOXBase* SwDoc::GetDefaultTOXBase( TOXTypes eTyp, bool bCreate )
449 : {
450 0 : SwTOXBase** prBase = 0;
451 0 : switch(eTyp)
452 : {
453 0 : case TOX_CONTENT: prBase = &mpDefTOXBases->pContBase; break;
454 0 : case TOX_INDEX: prBase = &mpDefTOXBases->pIdxBase; break;
455 0 : case TOX_USER: prBase = &mpDefTOXBases->pUserBase; break;
456 0 : case TOX_TABLES: prBase = &mpDefTOXBases->pTblBase; break;
457 0 : case TOX_OBJECTS: prBase = &mpDefTOXBases->pObjBase; break;
458 0 : case TOX_ILLUSTRATIONS: prBase = &mpDefTOXBases->pIllBase; break;
459 0 : case TOX_AUTHORITIES: prBase = &mpDefTOXBases->pAuthBase; break;
460 0 : case TOX_BIBLIOGRAPHY: prBase = &mpDefTOXBases->pBiblioBase; break;
461 0 : case TOX_CITATION: /** TODO */break;
462 : }
463 0 : if (!prBase)
464 0 : return NULL;
465 0 : if(!(*prBase) && bCreate)
466 : {
467 0 : SwForm aForm(eTyp);
468 0 : const SwTOXType* pType = GetTOXType(eTyp, 0);
469 0 : (*prBase) = new SwTOXBase(pType, aForm, 0, pType->GetTypeName());
470 : }
471 0 : return (*prBase);
472 : }
473 :
474 0 : void SwDoc::SetDefaultTOXBase(const SwTOXBase& rBase)
475 : {
476 0 : SwTOXBase** prBase = 0;
477 0 : switch(rBase.GetType())
478 : {
479 0 : case TOX_CONTENT: prBase = &mpDefTOXBases->pContBase; break;
480 0 : case TOX_INDEX: prBase = &mpDefTOXBases->pIdxBase; break;
481 0 : case TOX_USER: prBase = &mpDefTOXBases->pUserBase; break;
482 0 : case TOX_TABLES: prBase = &mpDefTOXBases->pTblBase; break;
483 0 : case TOX_OBJECTS: prBase = &mpDefTOXBases->pObjBase; break;
484 0 : case TOX_ILLUSTRATIONS: prBase = &mpDefTOXBases->pIllBase; break;
485 0 : case TOX_AUTHORITIES: prBase = &mpDefTOXBases->pAuthBase; break;
486 0 : case TOX_BIBLIOGRAPHY: prBase = &mpDefTOXBases->pBiblioBase; break;
487 0 : case TOX_CITATION: /** TODO */break;
488 : }
489 0 : if (!prBase)
490 0 : return;
491 0 : delete (*prBase);
492 0 : (*prBase) = new SwTOXBase(rBase);
493 : }
494 :
495 : /// Delete table of contents
496 4 : bool SwDoc::DeleteTOX( const SwTOXBase& rTOXBase, bool bDelNodes )
497 : {
498 : // We only delete the TOX, not the Nodes
499 4 : bool bRet = false;
500 : OSL_ENSURE( rTOXBase.ISA( SwTOXBaseSection ), "no TOXBaseSection!" );
501 :
502 4 : const SwTOXBaseSection& rTOXSect = (const SwTOXBaseSection&)rTOXBase;
503 4 : SwSectionFmt* pFmt = rTOXSect.GetFmt();
504 4 : if( pFmt )
505 : {
506 4 : GetIDocumentUndoRedo().StartUndo( UNDO_CLEARTOXRANGE, NULL );
507 :
508 : /* Save the start node of the TOX' section. */
509 4 : SwSectionNode * pMyNode = pFmt->GetSectionNode();
510 : /* Save start node of section's surrounding. */
511 4 : SwNode * pStartNd = pMyNode->StartOfSectionNode();
512 :
513 : /* Look for the point where to move the cursors in the area to
514 : delete to. This is done by first searching forward from the
515 : end of the TOX' section. If no content node is found behind
516 : the TOX one is searched before it. If this is not
517 : successful, too, insert new text node behind the end of
518 : the TOX' section. The cursors from the TOX' section will be
519 : moved to the content node found or the new text node. */
520 :
521 : /* Set PaM to end of TOX' section and search following content node.
522 : aSearchPam will contain the point where to move the cursors
523 : to. */
524 4 : SwPaM aSearchPam(*pMyNode->EndOfSectionNode());
525 8 : SwPosition aEndPos(*pStartNd->EndOfSectionNode());
526 8 : if (! aSearchPam.Move() /* no content node found */
527 4 : || *aSearchPam.GetPoint() >= aEndPos /* content node found
528 : outside surrounding */
529 : )
530 : {
531 : /* Set PaM to beginning of TOX' section and search previous
532 : content node */
533 0 : SwPaM aTmpPam(*pMyNode);
534 0 : aSearchPam = aTmpPam;
535 0 : SwPosition aStartPos(*pStartNd);
536 :
537 0 : if ( ! aSearchPam.Move(fnMoveBackward) /* no content node found */
538 0 : || *aSearchPam.GetPoint() <= aStartPos /* content node
539 : found outside
540 : surrounding */
541 : )
542 : {
543 : /* There is no content node in the surrounding of
544 : TOX'. Append text node behind TOX' section. */
545 :
546 0 : SwPosition aInsPos(*pMyNode->EndOfSectionNode());
547 0 : getIDocumentContentOperations().AppendTxtNode(aInsPos);
548 :
549 0 : SwPaM aTmpPam1(aInsPos);
550 0 : aSearchPam = aTmpPam1;
551 0 : }
552 : }
553 :
554 : /* PaM containing the TOX. */
555 8 : SwPaM aPam(*pMyNode->EndOfSectionNode(), *pMyNode);
556 :
557 : /* Move cursors contained in TOX to the above calculated point. */
558 4 : PaMCorrAbs(aPam, *aSearchPam.GetPoint());
559 :
560 4 : if( !bDelNodes )
561 : {
562 0 : SwSections aArr( 0 );
563 0 : sal_uInt16 nCnt = pFmt->GetChildSections( aArr, SORTSECT_NOT, false );
564 0 : for( sal_uInt16 n = 0; n < nCnt; ++n )
565 : {
566 0 : SwSection* pSect = aArr[ n ];
567 0 : if( TOX_HEADER_SECTION == pSect->GetType() )
568 : {
569 0 : DelSectionFmt( pSect->GetFmt(), bDelNodes );
570 : }
571 0 : }
572 : }
573 :
574 4 : DelSectionFmt( pFmt, bDelNodes );
575 :
576 4 : GetIDocumentUndoRedo().EndUndo( UNDO_CLEARTOXRANGE, NULL );
577 8 : bRet = true;
578 : }
579 :
580 4 : return bRet;
581 : }
582 :
583 : /// Manage table of content types
584 0 : sal_uInt16 SwDoc::GetTOXTypeCount(TOXTypes eTyp) const
585 : {
586 0 : sal_uInt16 nCnt = 0;
587 0 : for( sal_uInt16 n = 0; n < mpTOXTypes->size(); ++n )
588 0 : if( eTyp == (*mpTOXTypes)[n]->GetType() )
589 0 : ++nCnt;
590 0 : return nCnt;
591 : }
592 :
593 560 : const SwTOXType* SwDoc::GetTOXType( TOXTypes eTyp, sal_uInt16 nId ) const
594 : {
595 560 : sal_uInt16 nCnt = 0;
596 1244 : for( sal_uInt16 n = 0; n < mpTOXTypes->size(); ++n )
597 1244 : if( eTyp == (*mpTOXTypes)[n]->GetType() && nCnt++ == nId )
598 560 : return (*mpTOXTypes)[n];
599 0 : return 0;
600 : }
601 :
602 0 : const SwTOXType* SwDoc::InsertTOXType( const SwTOXType& rTyp )
603 : {
604 0 : SwTOXType * pNew = new SwTOXType( rTyp );
605 0 : mpTOXTypes->push_back( pNew );
606 0 : return pNew;
607 : }
608 :
609 452 : OUString SwDoc::GetUniqueTOXBaseName( const SwTOXType& rType,
610 : const OUString& sChkStr ) const
611 : {
612 452 : bool bUseChkStr = !sChkStr.isEmpty();
613 452 : const OUString aName( rType.GetTypeName() );
614 452 : const sal_Int32 nNmLen = aName.getLength();
615 :
616 452 : sal_uInt16 nNum = 0;
617 452 : const sal_uInt16 nFlagSize = ( mpSectionFmtTbl->size() / 8 ) +2;
618 452 : sal_uInt8* pSetFlags = new sal_uInt8[ nFlagSize ];
619 452 : memset( pSetFlags, 0, nFlagSize );
620 :
621 1214 : for( sal_uInt16 n = 0; n < mpSectionFmtTbl->size(); ++n )
622 : {
623 762 : const SwSectionNode *pSectNd = (*mpSectionFmtTbl)[ n ]->GetSectionNode( false );
624 762 : if ( !pSectNd )
625 0 : continue;
626 :
627 762 : const SwSection& rSect = pSectNd->GetSection();
628 762 : if (rSect.GetType()==TOX_CONTENT_SECTION)
629 : {
630 434 : const OUString rNm = rSect.GetSectionName();
631 434 : if ( aName.startsWith(rNm) )
632 : {
633 : // Calculate number and set the Flag
634 0 : nNum = (sal_uInt16)rNm.copy( nNmLen ).toInt32();
635 0 : if( nNum-- && nNum < mpSectionFmtTbl->size() )
636 0 : pSetFlags[ nNum / 8 ] |= (0x01 << ( nNum & 0x07 ));
637 : }
638 434 : if ( bUseChkStr && sChkStr==rNm )
639 0 : bUseChkStr = false;
640 : }
641 : }
642 :
643 452 : if( !bUseChkStr )
644 : {
645 : // All Numbers have been flagged accordingly, so get the right Number
646 452 : nNum = mpSectionFmtTbl->size();
647 452 : for( sal_uInt16 n = 0; n < nFlagSize; ++n )
648 : {
649 452 : sal_uInt16 nTmp = pSetFlags[ n ];
650 452 : if( nTmp != 0xff )
651 : {
652 : // so get the Number
653 452 : nNum = n * 8;
654 904 : while( nTmp & 1 )
655 : {
656 0 : ++nNum;
657 0 : nTmp >>= 1;
658 : }
659 452 : break;
660 : }
661 : }
662 : }
663 452 : delete [] pSetFlags;
664 452 : if ( bUseChkStr )
665 0 : return sChkStr;
666 452 : return aName + OUString::number( ++nNum );
667 : }
668 :
669 226 : bool SwDoc::SetTOXBaseName(const SwTOXBase& rTOXBase, const OUString& rName)
670 : {
671 : OSL_ENSURE( rTOXBase.ISA( SwTOXBaseSection ),
672 : "no TOXBaseSection!" );
673 226 : SwTOXBaseSection* pTOX = (SwTOXBaseSection*)&rTOXBase;
674 :
675 226 : OUString sTmp = GetUniqueTOXBaseName(*rTOXBase.GetTOXType(), rName);
676 226 : bool bRet = sTmp == rName;
677 226 : if(bRet)
678 : {
679 0 : pTOX->SetTOXName(rName);
680 0 : pTOX->SetSectionName(rName);
681 0 : getIDocumentState().SetModified();
682 : }
683 226 : return bRet;
684 : }
685 :
686 4 : static const SwTxtNode* lcl_FindChapterNode( const SwNode& rNd, sal_uInt8 nLvl = 0 )
687 : {
688 4 : const SwNode* pNd = &rNd;
689 4 : if( pNd->GetNodes().GetEndOfExtras().GetIndex() > pNd->GetIndex() )
690 : {
691 : // then find the "Anchor" (Body) position
692 0 : Point aPt;
693 0 : SwNode2Layout aNode2Layout( *pNd, pNd->GetIndex() );
694 0 : const SwFrm* pFrm = aNode2Layout.GetFrm( &aPt, 0, false );
695 :
696 0 : if( pFrm )
697 : {
698 0 : SwPosition aPos( *pNd );
699 0 : pNd = GetBodyTxtNode( *pNd->GetDoc(), aPos, *pFrm );
700 0 : OSL_ENSURE( pNd, "Where's the paragraph?" );
701 0 : }
702 : }
703 4 : return pNd ? pNd->FindOutlineNodeOfLevel( nLvl ) : 0;
704 : }
705 :
706 : // Table of contents class
707 226 : SwTOXBaseSection::SwTOXBaseSection(SwTOXBase const& rBase, SwSectionFmt & rFmt)
708 : : SwTOXBase( rBase )
709 226 : , SwSection( TOX_CONTENT_SECTION, OUString(), rFmt )
710 : {
711 226 : SetProtect( rBase.IsProtected() );
712 226 : SetSectionName( GetTOXName() );
713 226 : }
714 :
715 678 : SwTOXBaseSection::~SwTOXBaseSection()
716 : {
717 226 : for (SwTOXSortTabBases::const_iterator it = aSortArr.begin(); it != aSortArr.end(); ++it)
718 0 : delete *it;
719 452 : }
720 :
721 0 : bool SwTOXBaseSection::SetPosAtStartEnd( SwPosition& rPos, bool bAtStart ) const
722 : {
723 0 : bool bRet = false;
724 0 : const SwSectionNode* pSectNd = GetFmt()->GetSectionNode();
725 0 : if( pSectNd )
726 : {
727 : SwCntntNode* pCNd;
728 0 : sal_Int32 nC = 0;
729 0 : if( bAtStart )
730 : {
731 0 : rPos.nNode = *pSectNd;
732 0 : pCNd = pSectNd->GetDoc()->GetNodes().GoNext( &rPos.nNode );
733 : }
734 : else
735 : {
736 0 : rPos.nNode = *pSectNd->EndOfSectionNode();
737 0 : pCNd = pSectNd->GetDoc()->GetNodes().GoPrevious( &rPos.nNode );
738 0 : if( pCNd ) nC = pCNd->Len();
739 : }
740 0 : rPos.nContent.Assign( pCNd, nC );
741 0 : bRet = true;
742 : }
743 0 : return bRet;
744 : }
745 :
746 : /// Collect table of contents content
747 8 : void SwTOXBaseSection::Update(const SfxItemSet* pAttr,
748 : const bool _bNewTOX )
749 : {
750 : const SwSectionNode* pSectNd;
751 24 : if( !SwTOXBase::GetRegisteredIn()->GetDepends() ||
752 24 : !GetFmt() || 0 == (pSectNd = GetFmt()->GetSectionNode() ) ||
753 24 : !pSectNd->GetNodes().IsDocNodes() ||
754 8 : IsHiddenFlag() )
755 : {
756 8 : return;
757 : }
758 :
759 8 : if ( !mbKeepExpression )
760 : {
761 0 : maMSTOCExpression = OUString();
762 : }
763 :
764 8 : SwDoc* pDoc = (SwDoc*)pSectNd->GetDoc();
765 :
766 : assert(pDoc); //Where is the document?
767 :
768 8 : if (pAttr && GetFmt())
769 0 : pDoc->ChgFmt(*GetFmt(), *pAttr);
770 :
771 : // determine default page description, which will be used by the content nodes,
772 : // if no appropriate one is found.
773 : const SwPageDesc* pDefaultPageDesc;
774 : {
775 : pDefaultPageDesc =
776 8 : pSectNd->GetSection().GetFmt()->GetPageDesc().GetPageDesc();
777 8 : if ( !_bNewTOX && !pDefaultPageDesc )
778 : {
779 : // determine page description of table-of-content
780 8 : sal_uInt32 nPgDescNdIdx = pSectNd->GetIndex() + 1;
781 8 : sal_uInt32* pPgDescNdIdx = &nPgDescNdIdx;
782 8 : pDefaultPageDesc = pSectNd->FindPageDesc( false, pPgDescNdIdx );
783 8 : if ( nPgDescNdIdx < pSectNd->GetIndex() )
784 : {
785 0 : pDefaultPageDesc = 0;
786 : }
787 : }
788 : // consider end node of content section in the node array.
789 8 : if ( !pDefaultPageDesc &&
790 0 : ( pSectNd->EndOfSectionNode()->GetIndex() <
791 0 : (pSectNd->GetNodes().GetEndOfContent().GetIndex() - 1) )
792 : )
793 : {
794 : // determine page description of content after table-of-content
795 0 : SwNodeIndex aIdx( *(pSectNd->EndOfSectionNode()) );
796 0 : const SwCntntNode* pNdAfterTOX = pSectNd->GetNodes().GoNext( &aIdx );
797 0 : const SwAttrSet& aNdAttrSet = pNdAfterTOX->GetSwAttrSet();
798 0 : const SvxBreak eBreak = aNdAttrSet.GetBreak().GetBreak();
799 0 : if ( !( eBreak == SVX_BREAK_PAGE_BEFORE ||
800 0 : eBreak == SVX_BREAK_PAGE_BOTH )
801 : )
802 : {
803 0 : pDefaultPageDesc = pNdAfterTOX->FindPageDesc( false );
804 0 : }
805 : }
806 : // consider start node of content section in the node array.
807 8 : if ( !pDefaultPageDesc &&
808 0 : ( pSectNd->GetIndex() >
809 0 : (pSectNd->GetNodes().GetEndOfContent().StartOfSectionIndex() + 1) )
810 : )
811 : {
812 : // determine page description of content before table-of-content
813 0 : SwNodeIndex aIdx( *pSectNd );
814 : pDefaultPageDesc =
815 0 : pSectNd->GetNodes().GoPrevious( &aIdx )->FindPageDesc( false );
816 :
817 : }
818 8 : if ( !pDefaultPageDesc )
819 : {
820 : // determine default page description
821 0 : pDefaultPageDesc = &pDoc->GetPageDesc( 0 );
822 : }
823 : }
824 :
825 8 : pDoc->getIDocumentState().SetModified();
826 :
827 : // get current Language
828 8 : SwTOXInternational aIntl( GetLanguage(),
829 8 : TOX_INDEX == GetTOXType()->GetType() ?
830 2 : GetOptions() : 0,
831 26 : GetSortAlgorithm() );
832 :
833 8 : for (SwTOXSortTabBases::const_iterator it = aSortArr.begin(); it != aSortArr.end(); ++it)
834 0 : delete *it;
835 8 : aSortArr.clear();
836 :
837 : // find the first layout node for this TOX, if it only find the content
838 : // in his own chapter
839 8 : const SwTxtNode* pOwnChapterNode = IsFromChapter()
840 2 : ? ::lcl_FindChapterNode( *pSectNd, 0 )
841 10 : : 0;
842 :
843 16 : SwNode2Layout aN2L( *pSectNd );
844 8 : ((SwSectionNode*)pSectNd)->DelFrms();
845 :
846 : // remove old content an insert one empty textnode (to hold the layout!)
847 : SwTxtNode* pFirstEmptyNd;
848 : {
849 8 : pDoc->getIDocumentRedlineAccess().DeleteRedline( *pSectNd, true, USHRT_MAX );
850 :
851 8 : SwNodeIndex aSttIdx( *pSectNd, +1 );
852 16 : SwNodeIndex aEndIdx( *pSectNd->EndOfSectionNode() );
853 8 : pFirstEmptyNd = pDoc->GetNodes().MakeTxtNode( aEndIdx,
854 16 : pDoc->getIDocumentStylePoolAccess().GetTxtCollFromPool( RES_POOLCOLL_TEXT ) );
855 :
856 : {
857 : // Task 70995 - save and restore PageDesc and Break Attributes
858 8 : SwNodeIndex aNxtIdx( aSttIdx );
859 8 : const SwCntntNode* pCNd = aNxtIdx.GetNode().GetCntntNode();
860 8 : if( !pCNd )
861 4 : pCNd = pDoc->GetNodes().GoNext( &aNxtIdx );
862 8 : if( pCNd->HasSwAttrSet() )
863 : {
864 0 : SfxItemSet aBrkSet( pDoc->GetAttrPool(), aBreakSetRange );
865 0 : aBrkSet.Put( *pCNd->GetpSwAttrSet() );
866 0 : if( aBrkSet.Count() )
867 0 : pFirstEmptyNd->SetAttr( aBrkSet );
868 8 : }
869 : }
870 8 : aEndIdx--;
871 16 : SwPosition aPos( aEndIdx, SwIndex( pFirstEmptyNd, 0 ));
872 8 : pDoc->CorrAbs( aSttIdx, aEndIdx, aPos, true );
873 :
874 : // delete flys in whole range including start node which requires
875 : // giving the node before start node as Mark parameter, hence -1.
876 : // (flys must be deleted because the anchor nodes are removed)
877 8 : DelFlyInRange( SwNodeIndex(aSttIdx, -1), aEndIdx );
878 :
879 16 : pDoc->GetNodes().Delete( aSttIdx, aEndIdx.GetIndex() - aSttIdx.GetIndex() );
880 : }
881 :
882 : // insert title of TOX
883 8 : if ( !GetTitle().isEmpty() )
884 : {
885 : // then insert the headline section
886 8 : SwNodeIndex aIdx( *pSectNd, +1 );
887 :
888 8 : SwTxtNode* pHeadNd = pDoc->GetNodes().MakeTxtNode( aIdx,
889 16 : GetTxtFmtColl( FORM_TITLE ) );
890 8 : pHeadNd->InsertText( GetTitle(), SwIndex( pHeadNd ) );
891 :
892 16 : OUString sNm( GetTOXName() );
893 : // ??Resource
894 8 : sNm += "_Head";
895 :
896 16 : SwSectionData headerData( TOX_HEADER_SECTION, sNm );
897 :
898 16 : SwNodeIndex aStt( *pHeadNd ); aIdx--;
899 8 : SwSectionFmt* pSectFmt = pDoc->MakeSectionFmt( 0 );
900 8 : pDoc->GetNodes().InsertTextSection(
901 16 : aStt, *pSectFmt, headerData, 0, &aIdx, true, false);
902 : }
903 :
904 : // This would be a good time to update the Numbering
905 8 : pDoc->UpdateNumRule();
906 :
907 8 : if( GetCreateType() & nsSwTOXElement::TOX_MARK )
908 8 : UpdateMarks( aIntl, pOwnChapterNode );
909 :
910 8 : if( GetCreateType() & nsSwTOXElement::TOX_OUTLINELEVEL )
911 6 : UpdateOutline( pOwnChapterNode );
912 :
913 8 : if( GetCreateType() & nsSwTOXElement::TOX_TEMPLATE )
914 0 : UpdateTemplate( pOwnChapterNode );
915 :
916 16 : if( GetCreateType() & nsSwTOXElement::TOX_OLE ||
917 8 : TOX_OBJECTS == SwTOXBase::GetType())
918 0 : UpdateCntnt( nsSwTOXElement::TOX_OLE, pOwnChapterNode );
919 :
920 16 : if( GetCreateType() & nsSwTOXElement::TOX_TABLE ||
921 8 : (TOX_TABLES == SwTOXBase::GetType() && IsFromObjectNames()) )
922 0 : UpdateTable( pOwnChapterNode );
923 :
924 16 : if( GetCreateType() & nsSwTOXElement::TOX_GRAPHIC ||
925 8 : (TOX_ILLUSTRATIONS == SwTOXBase::GetType() && IsFromObjectNames()))
926 0 : UpdateCntnt( nsSwTOXElement::TOX_GRAPHIC, pOwnChapterNode );
927 :
928 8 : if( !GetSequenceName().isEmpty() && !IsFromObjectNames() &&
929 0 : (TOX_TABLES == SwTOXBase::GetType() ||
930 0 : TOX_ILLUSTRATIONS == SwTOXBase::GetType() ) )
931 0 : UpdateSequence( pOwnChapterNode );
932 :
933 8 : if( GetCreateType() & nsSwTOXElement::TOX_FRAME )
934 0 : UpdateCntnt( nsSwTOXElement::TOX_FRAME, pOwnChapterNode );
935 :
936 8 : if(TOX_AUTHORITIES == SwTOXBase::GetType())
937 0 : UpdateAuthorities( aIntl );
938 :
939 : // Insert AlphaDelimitters if needed (just for keywords)
940 10 : if( TOX_INDEX == SwTOXBase::GetType() &&
941 2 : ( GetOptions() & nsSwTOIOptions::TOI_ALPHA_DELIMITTER ) )
942 2 : InsertAlphaDelimitter( aIntl );
943 :
944 : // Sort the List of all TOC Marks and TOC Sections
945 16 : std::vector<SwTxtFmtColl*> aCollArr( GetTOXForm().GetFormMax(), 0 );
946 16 : SwNodeIndex aInsPos( *pFirstEmptyNd, 1 );
947 16 : for( sal_uInt16 nCnt = 0; nCnt < aSortArr.size(); ++nCnt )
948 : {
949 8 : ::SetProgressState( 0, pDoc->GetDocShell() );
950 :
951 : // Put the Text into the TOC
952 8 : sal_uInt16 nLvl = aSortArr[ nCnt ]->GetLevel();
953 8 : SwTxtFmtColl* pColl = aCollArr[ nLvl ];
954 8 : if( !pColl )
955 : {
956 6 : pColl = GetTxtFmtColl( nLvl );
957 6 : aCollArr[ nLvl ] = pColl;
958 : }
959 :
960 : // Generate: Set dynamic TabStops
961 8 : SwTxtNode* pTOXNd = pDoc->GetNodes().MakeTxtNode( aInsPos , pColl );
962 8 : aSortArr[ nCnt ]->pTOXNd = pTOXNd;
963 :
964 : // Generate: Evaluate Form and insert the place holder for the
965 : // page number. If it is a TOX_INDEX and the SwForm IsCommaSeparated()
966 : // then a range of entries must be generated into one paragraph
967 8 : size_t nRange = 1;
968 18 : if(TOX_INDEX == SwTOXBase::GetType() &&
969 8 : GetTOXForm().IsCommaSeparated() &&
970 0 : aSortArr[nCnt]->GetType() == TOX_SORT_INDEX)
971 : {
972 0 : const SwTOXMark& rMark = aSortArr[nCnt]->pTxtMark->GetTOXMark();
973 0 : const OUString sPrimKey = rMark.GetPrimaryKey();
974 0 : const OUString sSecKey = rMark.GetSecondaryKey();
975 0 : const SwTOXMark* pNextMark = 0;
976 0 : while(aSortArr.size() > (nCnt + nRange)&&
977 0 : aSortArr[nCnt + nRange]->GetType() == TOX_SORT_INDEX &&
978 0 : 0 != (pNextMark = &(aSortArr[nCnt + nRange]->pTxtMark->GetTOXMark())) &&
979 0 : pNextMark->GetPrimaryKey() == sPrimKey &&
980 0 : pNextMark->GetSecondaryKey() == sSecKey)
981 0 : nRange++;
982 : }
983 : // pass node index of table-of-content section and default page description
984 : // to method <GenerateText(..)>.
985 8 : ::SetProgressState( 0, pDoc->GetDocShell() );
986 :
987 : boost::shared_ptr<sw::ToxTabStopTokenHandler> tabStopTokenHandler =
988 : boost::make_shared<sw::DefaultToxTabStopTokenHandler>(
989 16 : pSectNd->GetIndex(), *pDefaultPageDesc, GetTOXForm().IsRelTabPos(),
990 8 : pDoc->GetDocumentSettingManager().get(IDocumentSettingAccess::TABS_RELATIVE_TO_INDENT) ?
991 : sw::DefaultToxTabStopTokenHandler::TABSTOPS_RELATIVE_TO_INDENT :
992 24 : sw::DefaultToxTabStopTokenHandler::TABSTOPS_RELATIVE_TO_PAGE);
993 16 : sw::ToxTextGenerator ttgn(GetTOXForm(), tabStopTokenHandler);
994 8 : ttgn.GenerateText((SwDoc*) GetFmt()->GetDoc(), aSortArr, nCnt, nRange);
995 8 : nCnt += nRange - 1;
996 8 : }
997 :
998 : // delete the first dummy node and remove all Cursor into the previous node
999 8 : aInsPos = *pFirstEmptyNd;
1000 : {
1001 8 : SwPaM aCorPam( *pFirstEmptyNd );
1002 8 : aCorPam.GetPoint()->nContent.Assign( pFirstEmptyNd, 0 );
1003 8 : if( !aCorPam.Move( fnMoveForward ) )
1004 0 : aCorPam.Move( fnMoveBackward );
1005 16 : SwNodeIndex aEndIdx( aInsPos, 1 );
1006 8 : pDoc->CorrAbs( aInsPos, aEndIdx, *aCorPam.GetPoint(), true );
1007 :
1008 : // Task 70995 - save and restore PageDesc and Break Attributes
1009 8 : if( pFirstEmptyNd->HasSwAttrSet() )
1010 : {
1011 0 : if( !GetTitle().isEmpty() )
1012 0 : aEndIdx = *pSectNd;
1013 : else
1014 0 : aEndIdx = *pFirstEmptyNd;
1015 0 : SwCntntNode* pCNd = pDoc->GetNodes().GoNext( &aEndIdx );
1016 0 : if( pCNd ) // Robust against defect documents, e.g. i60336
1017 0 : pCNd->SetAttr( *pFirstEmptyNd->GetpSwAttrSet() );
1018 8 : }
1019 : }
1020 :
1021 : // now create the new Frames
1022 8 : sal_uLong nIdx = pSectNd->GetIndex();
1023 : // don't delete if index is empty
1024 8 : if(nIdx + 2 < pSectNd->EndOfSectionIndex())
1025 8 : pDoc->GetNodes().Delete( aInsPos, 1 );
1026 :
1027 8 : aN2L.RestoreUpperFrms( pDoc->GetNodes(), nIdx, nIdx + 1 );
1028 16 : std::set<SwRootFrm*> aAllLayouts = pDoc->GetAllLayouts();
1029 16 : for ( std::set<SwRootFrm*>::iterator pLayoutIter = aAllLayouts.begin(); pLayoutIter != aAllLayouts.end(); ++pLayoutIter)
1030 : {
1031 8 : SwFrm::CheckPageDescs( (SwPageFrm*)(*pLayoutIter)->Lower() );
1032 : }
1033 :
1034 16 : SetProtect( SwTOXBase::IsProtected() );
1035 : }
1036 :
1037 2 : void SwTOXBaseSection::InsertAlphaDelimitter( const SwTOXInternational& rIntl )
1038 : {
1039 2 : SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc();
1040 4 : OUString sDeli, sLastDeli;
1041 2 : sal_uInt16 i = 0;
1042 6 : while( i < aSortArr.size() )
1043 : {
1044 2 : ::SetProgressState( 0, pDoc->GetDocShell() );
1045 :
1046 2 : sal_uInt16 nLevel = aSortArr[i]->GetLevel();
1047 :
1048 : // Skip AlphaDelimitter
1049 2 : if( nLevel == FORM_ALPHA_DELIMITTER )
1050 0 : continue;
1051 :
1052 4 : sDeli = rIntl.GetIndexKey( aSortArr[i]->GetTxt(),
1053 4 : aSortArr[i]->GetLocale() );
1054 :
1055 : // Do we already have a Delimitter?
1056 2 : if( !sDeli.isEmpty() && sLastDeli != sDeli )
1057 : {
1058 : // We skip all that are less than a small Blank (these are special characters)
1059 0 : if( ' ' <= sDeli[0] )
1060 : {
1061 : SwTOXCustom* pCst = new SwTOXCustom( TextAndReading(sDeli, OUString()),
1062 : FORM_ALPHA_DELIMITTER,
1063 0 : rIntl, aSortArr[i]->GetLocale() );
1064 0 : aSortArr.insert( aSortArr.begin() + i, pCst);
1065 0 : i++;
1066 : }
1067 0 : sLastDeli = sDeli;
1068 : }
1069 :
1070 : // Skip until we get to the same or a lower Level
1071 2 : do {
1072 2 : i++;
1073 2 : } while (i < aSortArr.size() && aSortArr[i]->GetLevel() > nLevel);
1074 2 : }
1075 2 : }
1076 :
1077 : /// Evaluate Template
1078 14 : SwTxtFmtColl* SwTOXBaseSection::GetTxtFmtColl( sal_uInt16 nLevel )
1079 : {
1080 14 : SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc();
1081 14 : const OUString& rName = GetTOXForm().GetTemplate( nLevel );
1082 14 : SwTxtFmtColl* pColl = !rName.isEmpty() ? pDoc->FindTxtFmtCollByName(rName) :0;
1083 14 : if( !pColl )
1084 : {
1085 8 : sal_uInt16 nPoolFmt = 0;
1086 8 : const TOXTypes eMyType = SwTOXBase::GetType();
1087 8 : switch( eMyType )
1088 : {
1089 4 : case TOX_INDEX: nPoolFmt = RES_POOLCOLL_TOX_IDXH; break;
1090 : case TOX_USER:
1091 0 : if( nLevel < 6 )
1092 0 : nPoolFmt = RES_POOLCOLL_TOX_USERH;
1093 : else
1094 0 : nPoolFmt = RES_POOLCOLL_TOX_USER6 - 6;
1095 0 : break;
1096 0 : case TOX_ILLUSTRATIONS: nPoolFmt = RES_POOLCOLL_TOX_ILLUSH; break;
1097 0 : case TOX_OBJECTS: nPoolFmt = RES_POOLCOLL_TOX_OBJECTH; break;
1098 0 : case TOX_TABLES: nPoolFmt = RES_POOLCOLL_TOX_TABLESH; break;
1099 : case TOX_AUTHORITIES:
1100 : case TOX_BIBLIOGRAPHY:
1101 0 : nPoolFmt = RES_POOLCOLL_TOX_AUTHORITIESH; break;
1102 0 : case TOX_CITATION: /** TODO */break;
1103 : case TOX_CONTENT:
1104 : // There's a jump in the ContentArea!
1105 4 : if( nLevel < 6 )
1106 4 : nPoolFmt = RES_POOLCOLL_TOX_CNTNTH;
1107 : else
1108 0 : nPoolFmt = RES_POOLCOLL_TOX_CNTNT6 - 6;
1109 4 : break;
1110 : }
1111 :
1112 8 : if(eMyType == TOX_AUTHORITIES && nLevel)
1113 0 : nPoolFmt = nPoolFmt + 1;
1114 8 : else if(eMyType == TOX_INDEX && nLevel)
1115 : {
1116 : // pool: Level 1,2,3, Delimiter
1117 : // SwForm: Delimiter, Level 1,2,3
1118 2 : nPoolFmt += 1 == nLevel ? nLevel + 3 : nLevel - 1;
1119 : }
1120 : else
1121 6 : nPoolFmt = nPoolFmt + nLevel;
1122 8 : pColl = pDoc->getIDocumentStylePoolAccess().GetTxtCollFromPool( nPoolFmt );
1123 : }
1124 14 : return pColl;
1125 : }
1126 :
1127 : /// Create from Marks
1128 8 : void SwTOXBaseSection::UpdateMarks( const SwTOXInternational& rIntl,
1129 : const SwTxtNode* pOwnChapterNode )
1130 : {
1131 8 : const SwTOXType* pType = (SwTOXType*) SwTOXBase::GetRegisteredIn();
1132 8 : if( !pType->GetDepends() )
1133 8 : return;
1134 :
1135 8 : SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc();
1136 8 : TOXTypes eTOXTyp = GetTOXType()->GetType();
1137 8 : SwIterator<SwTOXMark,SwTOXType> aIter( *pType );
1138 :
1139 : SwTxtTOXMark* pTxtMark;
1140 : SwTOXMark* pMark;
1141 12 : for( pMark = aIter.First(); pMark; pMark = aIter.Next() )
1142 : {
1143 4 : ::SetProgressState( 0, pDoc->GetDocShell() );
1144 :
1145 4 : if( pMark->GetTOXType()->GetType() == eTOXTyp &&
1146 : 0 != ( pTxtMark = pMark->GetTxtTOXMark() ) )
1147 : {
1148 2 : const SwTxtNode* pTOXSrc = pTxtMark->GetpTxtNd();
1149 : // Only insert TOXMarks from the Doc, not from the
1150 : // UNDO.
1151 :
1152 : // If selected use marks from the same chapter only
1153 6 : if( pTOXSrc->GetNodes().IsDocNodes() &&
1154 6 : pTOXSrc->GetTxt().getLength() && pTOXSrc->GetDepends() &&
1155 4 : pTOXSrc->getLayoutFrm( pDoc->getIDocumentLayoutAccess().GetCurrentLayout() ) &&
1156 6 : (!IsFromChapter() || ::lcl_FindChapterNode( *pTOXSrc, 0 ) == pOwnChapterNode ) &&
1157 6 : !pTOXSrc->HasHiddenParaField() &&
1158 2 : !SwScriptInfo::IsInHiddenRange( *pTOXSrc, pTxtMark->GetStart() ) )
1159 : {
1160 2 : SwTOXSortTabBase* pBase = 0;
1161 2 : if(TOX_INDEX == eTOXTyp)
1162 : {
1163 : // index entry mark
1164 2 : lang::Locale aLocale;
1165 2 : if ( g_pBreakIt->GetBreakIter().is() )
1166 : {
1167 : aLocale = g_pBreakIt->GetLocale(
1168 2 : pTOXSrc->GetLang( pTxtMark->GetStart() ) );
1169 : }
1170 :
1171 : pBase = new SwTOXIndex( *pTOXSrc, pTxtMark,
1172 2 : GetOptions(), FORM_ENTRY, rIntl, aLocale );
1173 2 : InsertSorted(pBase);
1174 8 : if(GetOptions() & nsSwTOIOptions::TOI_KEY_AS_ENTRY &&
1175 8 : !pTxtMark->GetTOXMark().GetPrimaryKey().isEmpty())
1176 : {
1177 : pBase = new SwTOXIndex( *pTOXSrc, pTxtMark,
1178 0 : GetOptions(), FORM_PRIMARY_KEY, rIntl, aLocale );
1179 0 : InsertSorted(pBase);
1180 0 : if (!pTxtMark->GetTOXMark().GetSecondaryKey().isEmpty())
1181 : {
1182 : pBase = new SwTOXIndex( *pTOXSrc, pTxtMark,
1183 0 : GetOptions(), FORM_SECONDARY_KEY, rIntl, aLocale );
1184 0 : InsertSorted(pBase);
1185 : }
1186 2 : }
1187 : }
1188 0 : else if( TOX_USER == eTOXTyp ||
1189 0 : pMark->GetLevel() <= GetLevel())
1190 : { // table of content mark
1191 : // also used for user marks
1192 0 : pBase = new SwTOXContent( *pTOXSrc, pTxtMark, rIntl );
1193 0 : InsertSorted(pBase);
1194 : }
1195 : }
1196 : }
1197 8 : }
1198 : }
1199 :
1200 : /// Generate table of contents from outline
1201 6 : void SwTOXBaseSection::UpdateOutline( const SwTxtNode* pOwnChapterNode )
1202 : {
1203 6 : SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc();
1204 6 : SwNodes& rNds = pDoc->GetNodes();
1205 :
1206 6 : const SwOutlineNodes& rOutlNds = rNds.GetOutLineNds();
1207 12 : for( sal_uInt16 n = 0; n < rOutlNds.size(); ++n )
1208 : {
1209 6 : ::SetProgressState( 0, pDoc->GetDocShell() );
1210 6 : SwTxtNode* pTxtNd = rOutlNds[ n ]->GetTxtNode();
1211 18 : if( pTxtNd && pTxtNd->Len() && pTxtNd->GetDepends() &&
1212 12 : sal_uInt16( pTxtNd->GetAttrOutlineLevel()) <= GetLevel() &&
1213 12 : pTxtNd->getLayoutFrm( pDoc->getIDocumentLayoutAccess().GetCurrentLayout() ) &&
1214 12 : !pTxtNd->HasHiddenParaField() &&
1215 24 : !pTxtNd->HasHiddenCharAttribute( true ) &&
1216 6 : ( !IsFromChapter() ||
1217 0 : ::lcl_FindChapterNode( *pTxtNd, 0 ) == pOwnChapterNode ))
1218 : {
1219 6 : SwTOXPara * pNew = new SwTOXPara( *pTxtNd, nsSwTOXElement::TOX_OUTLINELEVEL );
1220 6 : InsertSorted( pNew );
1221 : }
1222 : }
1223 6 : }
1224 :
1225 : /// Generate table of contents from template areas
1226 0 : void SwTOXBaseSection::UpdateTemplate( const SwTxtNode* pOwnChapterNode )
1227 : {
1228 0 : SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc();
1229 0 : for(sal_uInt16 i = 0; i < MAXLEVEL; i++)
1230 : {
1231 0 : OUString sTmpStyleNames = GetStyleNames(i);
1232 0 : sal_uInt16 nTokenCount = comphelper::string::getTokenCount(sTmpStyleNames, TOX_STYLE_DELIMITER);
1233 0 : for( sal_uInt16 nStyle = 0; nStyle < nTokenCount; ++nStyle )
1234 : {
1235 : SwTxtFmtColl* pColl = pDoc->FindTxtFmtCollByName(
1236 : sTmpStyleNames.getToken( nStyle,
1237 0 : TOX_STYLE_DELIMITER ));
1238 : //TODO: no outline Collections in content indexes if OutlineLevels are already included
1239 0 : if( !pColl ||
1240 0 : ( TOX_CONTENT == SwTOXBase::GetType() &&
1241 0 : GetCreateType() & nsSwTOXElement::TOX_OUTLINELEVEL &&
1242 0 : pColl->IsAssignedToListLevelOfOutlineStyle()) )
1243 0 : continue;
1244 :
1245 0 : SwIterator<SwTxtNode,SwFmtColl> aIter( *pColl );
1246 0 : for( SwTxtNode* pTxtNd = aIter.First(); pTxtNd; pTxtNd = aIter.Next() )
1247 : {
1248 0 : ::SetProgressState( 0, pDoc->GetDocShell() );
1249 :
1250 0 : if (pTxtNd->GetTxt().getLength() &&
1251 0 : pTxtNd->getLayoutFrm(pDoc->getIDocumentLayoutAccess().GetCurrentLayout()) &&
1252 0 : pTxtNd->GetNodes().IsDocNodes() &&
1253 0 : ( !IsFromChapter() || pOwnChapterNode ==
1254 0 : ::lcl_FindChapterNode( *pTxtNd, 0 ) ) )
1255 : {
1256 0 : SwTOXPara * pNew = new SwTOXPara( *pTxtNd, nsSwTOXElement::TOX_TEMPLATE, i + 1 );
1257 0 : InsertSorted(pNew);
1258 : }
1259 : }
1260 0 : }
1261 0 : }
1262 0 : }
1263 :
1264 : /// Generate content from sequence fields
1265 0 : void SwTOXBaseSection::UpdateSequence( const SwTxtNode* pOwnChapterNode )
1266 : {
1267 0 : SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc();
1268 0 : SwFieldType* pSeqFld = pDoc->getIDocumentFieldsAccess().GetFldType(RES_SETEXPFLD, GetSequenceName(), false);
1269 0 : if(!pSeqFld)
1270 0 : return;
1271 :
1272 0 : SwIterator<SwFmtFld,SwFieldType> aIter( *pSeqFld );
1273 0 : for( SwFmtFld* pFmtFld = aIter.First(); pFmtFld; pFmtFld = aIter.Next() )
1274 : {
1275 0 : const SwTxtFld* pTxtFld = pFmtFld->GetTxtFld();
1276 0 : if(!pTxtFld)
1277 0 : continue;
1278 0 : const SwTxtNode& rTxtNode = pTxtFld->GetTxtNode();
1279 0 : ::SetProgressState( 0, pDoc->GetDocShell() );
1280 :
1281 0 : if (rTxtNode.GetTxt().getLength() &&
1282 0 : rTxtNode.getLayoutFrm(pDoc->getIDocumentLayoutAccess().GetCurrentLayout()) &&
1283 0 : rTxtNode.GetNodes().IsDocNodes() &&
1284 0 : ( !IsFromChapter() ||
1285 0 : ::lcl_FindChapterNode( rTxtNode, 0 ) == pOwnChapterNode ) )
1286 : {
1287 0 : const SwSetExpField& rSeqField = dynamic_cast<const SwSetExpField&>(*(pFmtFld->GetField()));
1288 0 : OUString sName = GetSequenceName();
1289 0 : sName += OUString( cSequenceMarkSeparator );
1290 0 : sName += OUString::number( rSeqField.GetSeqNumber() );
1291 0 : SwTOXPara * pNew = new SwTOXPara( rTxtNode, nsSwTOXElement::TOX_SEQUENCE, 1, sName );
1292 : // set indexes if the number or the reference text are to be displayed
1293 0 : if( GetCaptionDisplay() == CAPTION_TEXT )
1294 : {
1295 : pNew->SetStartIndex(
1296 0 : SwGetExpField::GetReferenceTextPos( *pFmtFld, *pDoc ));
1297 : }
1298 0 : else if(GetCaptionDisplay() == CAPTION_NUMBER)
1299 : {
1300 0 : pNew->SetEndIndex(pTxtFld->GetStart() + 1);
1301 : }
1302 0 : InsertSorted(pNew);
1303 : }
1304 0 : }
1305 : }
1306 :
1307 0 : void SwTOXBaseSection::UpdateAuthorities( const SwTOXInternational& rIntl )
1308 : {
1309 0 : SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc();
1310 0 : SwFieldType* pAuthFld = pDoc->getIDocumentFieldsAccess().GetFldType(RES_AUTHORITY, OUString(), false);
1311 0 : if(!pAuthFld)
1312 0 : return;
1313 :
1314 0 : SwIterator<SwFmtFld,SwFieldType> aIter( *pAuthFld );
1315 0 : for( SwFmtFld* pFmtFld = aIter.First(); pFmtFld; pFmtFld = aIter.Next() )
1316 : {
1317 0 : const SwTxtFld* pTxtFld = pFmtFld->GetTxtFld();
1318 : // undo
1319 0 : if(!pTxtFld)
1320 0 : continue;
1321 0 : const SwTxtNode& rTxtNode = pTxtFld->GetTxtNode();
1322 0 : ::SetProgressState( 0, pDoc->GetDocShell() );
1323 :
1324 0 : if (rTxtNode.GetTxt().getLength() &&
1325 0 : rTxtNode.getLayoutFrm(pDoc->getIDocumentLayoutAccess().GetCurrentLayout()) &&
1326 0 : rTxtNode.GetNodes().IsDocNodes() )
1327 : {
1328 : //#106485# the body node has to be used!
1329 0 : SwCntntFrm *pFrm = rTxtNode.getLayoutFrm( pDoc->getIDocumentLayoutAccess().GetCurrentLayout() );
1330 0 : SwPosition aFldPos(rTxtNode);
1331 0 : const SwTxtNode* pTxtNode = 0;
1332 0 : if(pFrm && !pFrm->IsInDocBody())
1333 0 : pTxtNode = GetBodyTxtNode( *pDoc, aFldPos, *pFrm );
1334 0 : if(!pTxtNode)
1335 0 : pTxtNode = &rTxtNode;
1336 0 : SwTOXAuthority* pNew = new SwTOXAuthority( *pTxtNode, *pFmtFld, rIntl );
1337 :
1338 0 : InsertSorted(pNew);
1339 : }
1340 0 : }
1341 : }
1342 :
1343 0 : static long lcl_IsSOObject( const SvGlobalName& rFactoryNm )
1344 : {
1345 : static struct _SoObjType {
1346 : long nFlag;
1347 : // GlobalNameId
1348 : struct _GlobalNameIds {
1349 : sal_uInt32 n1;
1350 : sal_uInt16 n2, n3;
1351 : sal_uInt8 b8, b9, b10, b11, b12, b13, b14, b15;
1352 : } aGlNmIds[4];
1353 : } aArr[] = {
1354 : { nsSwTOOElements::TOO_MATH,
1355 : { {SO3_SM_CLASSID_60},{SO3_SM_CLASSID_50},
1356 : {SO3_SM_CLASSID_40},{SO3_SM_CLASSID_30} } },
1357 : { nsSwTOOElements::TOO_CHART,
1358 : { {SO3_SCH_CLASSID_60},{SO3_SCH_CLASSID_50},
1359 : {SO3_SCH_CLASSID_40},{SO3_SCH_CLASSID_30} } },
1360 : { nsSwTOOElements::TOO_CALC,
1361 : { {SO3_SC_CLASSID_60},{SO3_SC_CLASSID_50},
1362 : {SO3_SC_CLASSID_40},{SO3_SC_CLASSID_30} } },
1363 : { nsSwTOOElements::TOO_DRAW_IMPRESS,
1364 : { {SO3_SIMPRESS_CLASSID_60},{SO3_SIMPRESS_CLASSID_50},
1365 : {SO3_SIMPRESS_CLASSID_40},{SO3_SIMPRESS_CLASSID_30} } },
1366 : { nsSwTOOElements::TOO_DRAW_IMPRESS,
1367 : { {SO3_SDRAW_CLASSID_60},{SO3_SDRAW_CLASSID_50}}},
1368 : { 0,{{0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0},
1369 : {0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0} } }
1370 : };
1371 :
1372 0 : long nRet = 0;
1373 0 : for( const _SoObjType* pArr = aArr; !nRet && pArr->nFlag; ++pArr )
1374 0 : for ( int n = 0; n < 4; ++n )
1375 : {
1376 0 : const _SoObjType::_GlobalNameIds& rId = pArr->aGlNmIds[ n ];
1377 0 : if( !rId.n1 )
1378 0 : break;
1379 : SvGlobalName aGlbNm( rId.n1, rId.n2, rId.n3,
1380 : rId.b8, rId.b9, rId.b10, rId.b11,
1381 0 : rId.b12, rId.b13, rId.b14, rId.b15 );
1382 0 : if( rFactoryNm == aGlbNm )
1383 : {
1384 0 : nRet = pArr->nFlag;
1385 0 : break;
1386 : }
1387 0 : }
1388 :
1389 0 : return nRet;
1390 : }
1391 :
1392 0 : void SwTOXBaseSection::UpdateCntnt( SwTOXElement eMyType,
1393 : const SwTxtNode* pOwnChapterNode )
1394 : {
1395 0 : SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc();
1396 0 : SwNodes& rNds = pDoc->GetNodes();
1397 : // on the 1st Node of the 1st Section
1398 0 : sal_uLong nIdx = rNds.GetEndOfAutotext().StartOfSectionIndex() + 2,
1399 0 : nEndIdx = rNds.GetEndOfAutotext().GetIndex();
1400 :
1401 0 : while( nIdx < nEndIdx )
1402 : {
1403 0 : ::SetProgressState( 0, pDoc->GetDocShell() );
1404 :
1405 0 : SwNode* pNd = rNds[ nIdx ];
1406 0 : SwCntntNode* pCNd = 0;
1407 0 : switch( eMyType )
1408 : {
1409 : case nsSwTOXElement::TOX_FRAME:
1410 0 : if( !pNd->IsNoTxtNode() )
1411 : {
1412 0 : pCNd = pNd->GetCntntNode();
1413 0 : if( !pCNd )
1414 : {
1415 0 : SwNodeIndex aTmp( *pNd );
1416 0 : pCNd = rNds.GoNext( &aTmp );
1417 : }
1418 : }
1419 0 : break;
1420 : case nsSwTOXElement::TOX_GRAPHIC:
1421 0 : if( pNd->IsGrfNode() )
1422 0 : pCNd = (SwCntntNode*)pNd;
1423 0 : break;
1424 : case nsSwTOXElement::TOX_OLE:
1425 0 : if( pNd->IsOLENode() )
1426 : {
1427 0 : bool bInclude = true;
1428 0 : if(TOX_OBJECTS == SwTOXBase::GetType())
1429 : {
1430 0 : SwOLENode* pOLENode = pNd->GetOLENode();
1431 0 : long nMyOLEOptions = GetOLEOptions();
1432 0 : SwOLEObj& rOLEObj = pOLENode->GetOLEObj();
1433 :
1434 0 : if( rOLEObj.IsOleRef() ) // Not yet loaded
1435 : {
1436 0 : SvGlobalName aTmpName = SvGlobalName( rOLEObj.GetOleRef()->getClassID() );
1437 0 : long nObj = ::lcl_IsSOObject( aTmpName );
1438 0 : bInclude = ( (nMyOLEOptions & nsSwTOOElements::TOO_OTHER) && 0 == nObj)
1439 0 : || (0 != (nMyOLEOptions & nObj));
1440 : }
1441 : else
1442 : {
1443 : OSL_FAIL("OLE Object no loaded?");
1444 0 : bInclude = false;
1445 : }
1446 : }
1447 :
1448 0 : if(bInclude)
1449 0 : pCNd = (SwCntntNode*)pNd;
1450 : }
1451 0 : break;
1452 0 : default: break;
1453 : }
1454 :
1455 0 : if( pCNd )
1456 : {
1457 : // find node in body text
1458 0 : int nSetLevel = USHRT_MAX;
1459 :
1460 : //#111105# tables of tables|illustrations|objects don't support hierarchies
1461 0 : if( IsLevelFromChapter() &&
1462 0 : TOX_TABLES != SwTOXBase::GetType() &&
1463 0 : TOX_ILLUSTRATIONS != SwTOXBase::GetType() &&
1464 0 : TOX_OBJECTS != SwTOXBase::GetType() )
1465 : {
1466 : const SwTxtNode* pOutlNd = ::lcl_FindChapterNode( *pCNd,
1467 0 : MAXLEVEL - 1 );
1468 0 : if( pOutlNd )
1469 : {
1470 0 : if( pOutlNd->GetTxtColl()->IsAssignedToListLevelOfOutlineStyle())
1471 : {
1472 0 : nSetLevel = pOutlNd->GetTxtColl()->GetAttrOutlineLevel();
1473 : }
1474 : }
1475 : }
1476 :
1477 0 : if( pCNd->getLayoutFrm( pDoc->getIDocumentLayoutAccess().GetCurrentLayout() ) && ( !IsFromChapter() ||
1478 0 : ::lcl_FindChapterNode( *pCNd, 0 ) == pOwnChapterNode ))
1479 : {
1480 : SwTOXPara * pNew = new SwTOXPara( *pCNd, eMyType,
1481 : ( USHRT_MAX != nSetLevel )
1482 : ? static_cast<sal_uInt16>(nSetLevel)
1483 0 : : FORM_ALPHA_DELIMITTER );
1484 0 : InsertSorted( pNew );
1485 : }
1486 : }
1487 :
1488 0 : nIdx = pNd->StartOfSectionNode()->EndOfSectionIndex() + 2; // 2 == End/Start Node
1489 : }
1490 0 : }
1491 :
1492 : /// Collect table entries
1493 0 : void SwTOXBaseSection::UpdateTable( const SwTxtNode* pOwnChapterNode )
1494 : {
1495 0 : SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc();
1496 0 : SwNodes& rNds = pDoc->GetNodes();
1497 0 : const SwFrmFmts& rArr = *pDoc->GetTblFrmFmts();
1498 :
1499 0 : for( sal_uInt16 n = 0; n < rArr.size(); ++n )
1500 : {
1501 0 : ::SetProgressState( 0, pDoc->GetDocShell() );
1502 :
1503 0 : SwTable* pTmpTbl = SwTable::FindTable( rArr[ n ] );
1504 : SwTableBox* pFBox;
1505 0 : if( pTmpTbl && 0 != (pFBox = pTmpTbl->GetTabSortBoxes()[0] ) &&
1506 0 : pFBox->GetSttNd() && pFBox->GetSttNd()->GetNodes().IsDocNodes() )
1507 : {
1508 0 : const SwTableNode* pTblNd = pFBox->GetSttNd()->FindTableNode();
1509 0 : SwNodeIndex aCntntIdx( *pTblNd, 1 );
1510 :
1511 : SwCntntNode* pCNd;
1512 0 : while( 0 != ( pCNd = rNds.GoNext( &aCntntIdx ) ) &&
1513 0 : aCntntIdx.GetIndex() < pTblNd->EndOfSectionIndex() )
1514 : {
1515 0 : if( pCNd->getLayoutFrm( pDoc->getIDocumentLayoutAccess().GetCurrentLayout() ) && (!IsFromChapter() ||
1516 0 : ::lcl_FindChapterNode( *pCNd, 0 ) == pOwnChapterNode ))
1517 : {
1518 0 : SwTOXTable * pNew = new SwTOXTable( *pCNd );
1519 0 : if( IsLevelFromChapter() && TOX_TABLES != SwTOXBase::GetType())
1520 : {
1521 : const SwTxtNode* pOutlNd =
1522 0 : ::lcl_FindChapterNode( *pCNd, MAXLEVEL - 1 );
1523 0 : if( pOutlNd )
1524 : {
1525 0 : if( pOutlNd->GetTxtColl()->IsAssignedToListLevelOfOutlineStyle())
1526 : {
1527 0 : const int nTmp = pOutlNd->GetTxtColl()->GetAttrOutlineLevel();
1528 0 : pNew->SetLevel(static_cast<sal_uInt16>(nTmp));
1529 : }
1530 : }
1531 : }
1532 0 : InsertSorted(pNew);
1533 0 : break;
1534 : }
1535 0 : }
1536 : }
1537 : }
1538 0 : }
1539 :
1540 : /// Calculate PageNumber and insert after formatting
1541 234 : void SwTOXBaseSection::UpdatePageNum()
1542 : {
1543 234 : if( aSortArr.empty() )
1544 462 : return ;
1545 :
1546 : // Insert the current PageNumber into the TOC
1547 6 : SwPageFrm* pAktPage = 0;
1548 6 : sal_uInt16 nPage = 0;
1549 6 : SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc();
1550 :
1551 6 : SwTOXInternational aIntl( GetLanguage(),
1552 6 : TOX_INDEX == GetTOXType()->GetType() ?
1553 2 : GetOptions() : 0,
1554 20 : GetSortAlgorithm() );
1555 :
1556 14 : for( size_t nCnt = 0; nCnt < aSortArr.size(); ++nCnt )
1557 : {
1558 : // Loop over all SourceNodes
1559 8 : std::vector<sal_uInt16> aNums; // the PageNumber
1560 16 : std::vector<SwPageDesc*> aDescs; // The PageDescriptors matching the PageNumbers
1561 8 : std::vector<sal_uInt16> *pMainNums = 0; // contains page numbers of main entries
1562 :
1563 : // process run in lines
1564 8 : sal_uInt16 nRange = 0;
1565 8 : if(GetTOXForm().IsCommaSeparated() &&
1566 0 : aSortArr[nCnt]->GetType() == TOX_SORT_INDEX)
1567 : {
1568 0 : const SwTOXMark& rMark = aSortArr[nCnt]->pTxtMark->GetTOXMark();
1569 0 : const OUString sPrimKey = rMark.GetPrimaryKey();
1570 0 : const OUString sSecKey = rMark.GetSecondaryKey();
1571 0 : const SwTOXMark* pNextMark = 0;
1572 0 : while(aSortArr.size() > (nCnt + nRange)&&
1573 0 : aSortArr[nCnt + nRange]->GetType() == TOX_SORT_INDEX &&
1574 0 : 0 != (pNextMark = &(aSortArr[nCnt + nRange]->pTxtMark->GetTOXMark())) &&
1575 0 : pNextMark->GetPrimaryKey() == sPrimKey &&
1576 0 : pNextMark->GetSecondaryKey() == sSecKey)
1577 0 : nRange++;
1578 : }
1579 : else
1580 8 : nRange = 1;
1581 :
1582 16 : for(sal_uInt16 nRunInEntry = nCnt; nRunInEntry < nCnt + nRange; nRunInEntry++)
1583 : {
1584 8 : SwTOXSortTabBase* pSortBase = aSortArr[nRunInEntry];
1585 8 : size_t nSize = pSortBase->aTOXSources.size();
1586 16 : for (size_t j = 0; j < nSize; ++j)
1587 : {
1588 8 : ::SetProgressState( 0, pDoc->GetDocShell() );
1589 :
1590 8 : SwTOXSource& rTOXSource = pSortBase->aTOXSources[j];
1591 8 : if( rTOXSource.pNd )
1592 : {
1593 8 : SwCntntFrm* pFrm = rTOXSource.pNd->getLayoutFrm( pDoc->getIDocumentLayoutAccess().GetCurrentLayout() );
1594 : OSL_ENSURE( pFrm || pDoc->IsUpdateTOX(), "TOX, no Frame found");
1595 8 : if( !pFrm )
1596 0 : continue;
1597 8 : if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->HasFollow() )
1598 : {
1599 : // find the right one
1600 0 : SwTxtFrm* pNext = (SwTxtFrm*)pFrm;
1601 0 : while( 0 != ( pNext = (SwTxtFrm*)pFrm->GetFollow() )
1602 0 : && rTOXSource.nPos >= pNext->GetOfst() )
1603 0 : pFrm = pNext;
1604 : }
1605 :
1606 8 : SwPageFrm* pTmpPage = pFrm->FindPageFrm();
1607 8 : if( pTmpPage != pAktPage )
1608 : {
1609 6 : nPage = pTmpPage->GetVirtPageNum();
1610 6 : pAktPage = pTmpPage;
1611 : }
1612 :
1613 : // Insert as sorted
1614 : sal_uInt16 i;
1615 8 : for( i = 0; i < aNums.size() && aNums[i] < nPage; ++i )
1616 : ;
1617 :
1618 8 : if( i >= aNums.size() || aNums[ i ] != nPage )
1619 : {
1620 8 : aNums.insert(aNums.begin() + i, nPage);
1621 8 : aDescs.insert(aDescs.begin() + i, pAktPage->GetPageDesc() );
1622 : }
1623 : // is it a main entry?
1624 8 : if(TOX_SORT_INDEX == pSortBase->GetType() &&
1625 : rTOXSource.bMainEntry)
1626 : {
1627 0 : if(!pMainNums)
1628 0 : pMainNums = new std::vector<sal_uInt16>;
1629 0 : pMainNums->push_back(nPage);
1630 : }
1631 : }
1632 : }
1633 : // Insert the PageNumber into the TOC TextNode
1634 8 : const SwTOXSortTabBase* pBase = aSortArr[ nCnt ];
1635 8 : if(pBase->pTOXNd)
1636 : {
1637 8 : const SwTxtNode* pTxtNd = pBase->pTOXNd->GetTxtNode();
1638 : OSL_ENSURE( pTxtNd, "no TextNode, wrong TOC" );
1639 :
1640 : _UpdatePageNum( (SwTxtNode*)pTxtNd, aNums, aDescs, pMainNums,
1641 8 : aIntl );
1642 : }
1643 8 : DELETEZ(pMainNums);
1644 8 : aNums.clear();
1645 : }
1646 8 : }
1647 : // Delete the mapping array after setting the right PageNumber
1648 14 : for (SwTOXSortTabBases::const_iterator it = aSortArr.begin(); it != aSortArr.end(); ++it)
1649 8 : delete *it;
1650 6 : aSortArr.clear();
1651 : }
1652 :
1653 : /// Replace the PageNumber place holders. Search for the page no. in the array
1654 : /// of main entry page numbers.
1655 0 : static bool lcl_HasMainEntry( const std::vector<sal_uInt16>* pMainEntryNums, sal_uInt16 nToFind )
1656 : {
1657 0 : for(sal_uInt16 i = 0; pMainEntryNums && i < pMainEntryNums->size(); ++i)
1658 0 : if(nToFind == (*pMainEntryNums)[i])
1659 0 : return true;
1660 0 : return false;
1661 : }
1662 :
1663 8 : void SwTOXBaseSection::_UpdatePageNum( SwTxtNode* pNd,
1664 : const std::vector<sal_uInt16>& rNums,
1665 : const std::vector<SwPageDesc*>& rDescs,
1666 : const std::vector<sal_uInt16>* pMainEntryNums,
1667 : const SwTOXInternational& rIntl )
1668 : {
1669 : // collect starts end ends of main entry character style
1670 8 : boost::scoped_ptr< std::vector<sal_uInt16> > xCharStyleIdx(pMainEntryNums ? new std::vector<sal_uInt16> : 0);
1671 :
1672 16 : OUString sSrchStr = OUStringBuffer().append(C_NUM_REPL).
1673 24 : append(S_PAGE_DELI).append(C_NUM_REPL).makeStringAndClear();
1674 8 : sal_Int32 nStartPos = pNd->GetTxt().indexOf(sSrchStr);
1675 24 : sSrchStr = OUStringBuffer().append(C_NUM_REPL).
1676 24 : append(C_END_PAGE_NUM).makeStringAndClear();
1677 8 : sal_Int32 nEndPos = pNd->GetTxt().indexOf(sSrchStr);
1678 : sal_uInt16 i;
1679 :
1680 8 : if (-1 == nEndPos || rNums.empty())
1681 8 : return;
1682 :
1683 8 : if (-1 == nStartPos || nStartPos > nEndPos)
1684 8 : nStartPos = nEndPos;
1685 :
1686 8 : sal_uInt16 nOld = rNums[0],
1687 8 : nBeg = nOld,
1688 8 : nCount = 0;
1689 8 : OUString aNumStr( SvxNumberType( rDescs[0]->GetNumType() ).
1690 24 : GetNumStr( nBeg ) );
1691 8 : if( xCharStyleIdx && lcl_HasMainEntry( pMainEntryNums, nBeg ))
1692 : {
1693 0 : sal_uInt16 nTemp = 0;
1694 0 : xCharStyleIdx->push_back( nTemp );
1695 : }
1696 :
1697 : // Delete place holder
1698 16 : SwIndex aPos(pNd, nStartPos);
1699 8 : SwCharFmt* pPageNoCharFmt = 0;
1700 8 : SwpHints* pHints = pNd->GetpSwpHints();
1701 8 : if(pHints)
1702 16 : for(size_t nHintIdx = 0; nHintIdx < pHints->GetStartCount(); ++nHintIdx)
1703 : {
1704 10 : SwTxtAttr* pAttr = pHints->GetStart(nHintIdx);
1705 10 : const sal_Int32 nTmpEnd = pAttr->End() ? *pAttr->End() : 0;
1706 30 : if( nStartPos >= pAttr->GetStart() &&
1707 16 : (nStartPos + 2) <= nTmpEnd &&
1708 6 : pAttr->Which() == RES_TXTATR_CHARFMT)
1709 : {
1710 0 : pPageNoCharFmt = pAttr->GetCharFmt().GetCharFmt();
1711 0 : break;
1712 : }
1713 : }
1714 8 : pNd->EraseText(aPos, nEndPos - nStartPos + 2);
1715 :
1716 8 : for( i = 1; i < rNums.size(); ++i)
1717 : {
1718 0 : SvxNumberType aType( rDescs[i]->GetNumType() );
1719 0 : if( TOX_INDEX == SwTOXBase::GetType() )
1720 : { // Summarize for the following
1721 : // Add up all following
1722 : // break up if main entry starts or ends and
1723 : // insert a char style index
1724 0 : bool bMainEntryChanges = lcl_HasMainEntry(pMainEntryNums, nOld)
1725 0 : != lcl_HasMainEntry(pMainEntryNums, rNums[i]);
1726 :
1727 0 : if(nOld == rNums[i]-1 && !bMainEntryChanges &&
1728 0 : 0 != (GetOptions() & (nsSwTOIOptions::TOI_FF|nsSwTOIOptions::TOI_DASH)))
1729 0 : nCount++;
1730 : else
1731 : {
1732 : // Flush for the following old values
1733 0 : if(GetOptions() & nsSwTOIOptions::TOI_FF)
1734 : {
1735 0 : if ( nCount >= 1 )
1736 0 : aNumStr += rIntl.GetFollowingText( nCount > 1 );
1737 : }
1738 : else
1739 : {
1740 0 : if(nCount >= 2 )
1741 0 : aNumStr += "-";
1742 0 : else if(nCount == 1 )
1743 0 : aNumStr += S_PAGE_DELI;
1744 : //#58127# If nCount == 0, then the only PageNumber is already in aNumStr!
1745 0 : if(nCount)
1746 0 : aNumStr += aType.GetNumStr( nBeg + nCount );
1747 : }
1748 :
1749 : // Create new String
1750 0 : nBeg = rNums[i];
1751 0 : aNumStr += S_PAGE_DELI;
1752 : //the change of the character style must apply after sPageDeli is appended
1753 0 : if (xCharStyleIdx && bMainEntryChanges)
1754 : {
1755 0 : xCharStyleIdx->push_back(aNumStr.getLength());
1756 : }
1757 0 : aNumStr += aType.GetNumStr( nBeg );
1758 0 : nCount = 0;
1759 : }
1760 0 : nOld = rNums[i];
1761 : }
1762 : else
1763 : { // Insert all Numbers
1764 0 : aNumStr += aType.GetNumStr( sal_uInt16(rNums[i]) );
1765 0 : if(i != (rNums.size()-1))
1766 0 : aNumStr += S_PAGE_DELI;
1767 : }
1768 0 : }
1769 : // Flush when ending and the following old values
1770 8 : if( TOX_INDEX == SwTOXBase::GetType() )
1771 : {
1772 2 : if(GetOptions() & nsSwTOIOptions::TOI_FF)
1773 : {
1774 2 : if( nCount >= 1 )
1775 0 : aNumStr += rIntl.GetFollowingText( nCount > 1 );
1776 : }
1777 : else
1778 : {
1779 0 : if(nCount >= 2)
1780 0 : aNumStr += "-";
1781 0 : else if(nCount == 1)
1782 0 : aNumStr += S_PAGE_DELI;
1783 : //#58127# If nCount == 0, then the only PageNumber is already in aNumStr!
1784 0 : if(nCount)
1785 0 : aNumStr += SvxNumberType( rDescs[i-1]->GetNumType() ).GetNumStr( nBeg+nCount );
1786 : }
1787 : }
1788 : pNd->InsertText( aNumStr, aPos,
1789 : static_cast<IDocumentContentOperations::InsertFlags>(
1790 : IDocumentContentOperations::INS_EMPTYEXPAND |
1791 8 : IDocumentContentOperations::INS_FORCEHINTEXPAND) );
1792 8 : if(pPageNoCharFmt)
1793 : {
1794 0 : SwFmtCharFmt aCharFmt( pPageNoCharFmt );
1795 0 : pNd->InsertItem(aCharFmt, nStartPos, nStartPos + aNumStr.getLength(), nsSetAttrMode::SETATTR_DONTEXPAND);
1796 : }
1797 :
1798 : // The main entries should get their character style
1799 8 : if (xCharStyleIdx && !xCharStyleIdx->empty() && !GetMainEntryCharStyle().isEmpty())
1800 : {
1801 : // eventually the last index must me appended
1802 0 : if (xCharStyleIdx->size()&0x01)
1803 0 : xCharStyleIdx->push_back(aNumStr.getLength());
1804 :
1805 : // search by name
1806 0 : SwDoc* pDoc = pNd->GetDoc();
1807 0 : sal_uInt16 nPoolId = SwStyleNameMapper::GetPoolIdFromUIName( GetMainEntryCharStyle(), nsSwGetPoolIdFromName::GET_POOLID_CHRFMT );
1808 0 : SwCharFmt* pCharFmt = 0;
1809 0 : if(USHRT_MAX != nPoolId)
1810 0 : pCharFmt = pDoc->getIDocumentStylePoolAccess().GetCharFmtFromPool(nPoolId);
1811 : else
1812 0 : pCharFmt = pDoc->FindCharFmtByName( GetMainEntryCharStyle() );
1813 0 : if(!pCharFmt)
1814 0 : pCharFmt = pDoc->MakeCharFmt(GetMainEntryCharStyle(), 0);
1815 :
1816 : // find the page numbers in aNumStr and set the character style
1817 0 : sal_Int32 nOffset = pNd->GetTxt().getLength() - aNumStr.getLength();
1818 0 : SwFmtCharFmt aCharFmt(pCharFmt);
1819 0 : for (sal_uInt16 j = 0; j < xCharStyleIdx->size(); j += 2)
1820 : {
1821 0 : sal_Int32 nStartIdx = (*xCharStyleIdx)[j] + nOffset;
1822 0 : sal_Int32 nEndIdx = (*xCharStyleIdx)[j + 1] + nOffset;
1823 0 : pNd->InsertItem(aCharFmt, nStartIdx, nEndIdx, nsSetAttrMode::SETATTR_DONTEXPAND);
1824 0 : }
1825 :
1826 8 : }
1827 : }
1828 :
1829 8 : void SwTOXBaseSection::InsertSorted(SwTOXSortTabBase* pNew)
1830 : {
1831 8 : Range aRange(0, aSortArr.size());
1832 8 : if( TOX_INDEX == SwTOXBase::GetType() && pNew->pTxtMark )
1833 : {
1834 2 : const SwTOXMark& rMark = pNew->pTxtMark->GetTOXMark();
1835 : // Evaluate Key
1836 : // Calculate the range where to insert
1837 6 : if( 0 == (GetOptions() & nsSwTOIOptions::TOI_KEY_AS_ENTRY) &&
1838 2 : !rMark.GetPrimaryKey().isEmpty() )
1839 : {
1840 : aRange = GetKeyRange( rMark.GetPrimaryKey(),
1841 : rMark.GetPrimaryKeyReading(),
1842 0 : *pNew, FORM_PRIMARY_KEY, aRange );
1843 :
1844 0 : if( !rMark.GetSecondaryKey().isEmpty() )
1845 : aRange = GetKeyRange( rMark.GetSecondaryKey(),
1846 : rMark.GetSecondaryKeyReading(),
1847 0 : *pNew, FORM_SECONDARY_KEY, aRange );
1848 : }
1849 : }
1850 : // Search for identical entries and remove the trailing one
1851 8 : if(TOX_AUTHORITIES == SwTOXBase::GetType())
1852 : {
1853 0 : for(short i = (short)aRange.Min(); i < (short)aRange.Max(); ++i)
1854 : {
1855 0 : SwTOXSortTabBase* pOld = aSortArr[i];
1856 0 : if(*pOld == *pNew)
1857 : {
1858 0 : if(*pOld < *pNew)
1859 : {
1860 0 : delete pNew;
1861 0 : return;
1862 : }
1863 : else
1864 : {
1865 : // remove the old content
1866 0 : delete aSortArr[i];
1867 0 : aSortArr.erase( aSortArr.begin() + i );
1868 0 : aRange.Max()--;
1869 0 : break;
1870 : }
1871 : }
1872 : }
1873 : }
1874 :
1875 : // find position and insert
1876 : short i;
1877 :
1878 10 : for( i = (short)aRange.Min(); i < (short)aRange.Max(); ++i)
1879 : { // Only check for same level
1880 2 : SwTOXSortTabBase* pOld = aSortArr[i];
1881 2 : if(*pOld == *pNew)
1882 : {
1883 0 : if(TOX_AUTHORITIES != SwTOXBase::GetType())
1884 : {
1885 : // Own entry for for double entries or keywords
1886 0 : if( pOld->GetType() == TOX_SORT_CUSTOM &&
1887 0 : pNew->GetOptions() & nsSwTOIOptions::TOI_KEY_AS_ENTRY)
1888 0 : continue;
1889 :
1890 0 : if(!(pNew->GetOptions() & nsSwTOIOptions::TOI_SAME_ENTRY))
1891 : { // Own entry
1892 0 : aSortArr.insert(aSortArr.begin() + i, pNew);
1893 0 : return;
1894 : }
1895 : // If the own entry is already present, add it to the references list
1896 0 : pOld->aTOXSources.push_back(pNew->aTOXSources[0]);
1897 :
1898 0 : delete pNew;
1899 0 : return;
1900 : }
1901 : #if OSL_DEBUG_LEVEL > 0
1902 : else
1903 : OSL_FAIL("Bibliography entries cannot be found here");
1904 : #endif
1905 : }
1906 2 : if(*pNew < *pOld)
1907 0 : break;
1908 : }
1909 : // Skip SubLevel
1910 16 : while( TOX_INDEX == SwTOXBase::GetType() && i < aRange.Max() &&
1911 0 : aSortArr[i]->GetLevel() > pNew->GetLevel() )
1912 0 : i++;
1913 :
1914 : // Insert at position i
1915 8 : aSortArr.insert(aSortArr.begin()+i, pNew);
1916 : }
1917 :
1918 : /// Find Key Range and insert if possible
1919 0 : Range SwTOXBaseSection::GetKeyRange(const OUString& rStr, const OUString& rStrReading,
1920 : const SwTOXSortTabBase& rNew,
1921 : sal_uInt16 nLevel, const Range& rRange )
1922 : {
1923 0 : const SwTOXInternational& rIntl = *rNew.pTOXIntl;
1924 0 : TextAndReading aToCompare(rStr, rStrReading);
1925 :
1926 0 : if( 0 != (nsSwTOIOptions::TOI_INITIAL_CAPS & GetOptions()) )
1927 : {
1928 0 : aToCompare.sText = rIntl.ToUpper( aToCompare.sText, 0 )
1929 0 : + aToCompare.sText.copy(1);
1930 : }
1931 :
1932 : OSL_ENSURE(rRange.Min() >= 0 && rRange.Max() >= 0, "Min Max < 0");
1933 :
1934 0 : const sal_uInt16 nMin = (sal_uInt16)rRange.Min();
1935 0 : const sal_uInt16 nMax = (sal_uInt16)rRange.Max();
1936 :
1937 : sal_uInt16 i;
1938 :
1939 0 : for( i = nMin; i < nMax; ++i)
1940 : {
1941 0 : SwTOXSortTabBase* pBase = aSortArr[i];
1942 :
1943 0 : if( rIntl.IsEqual( pBase->GetTxt(), pBase->GetLocale(),
1944 0 : aToCompare, rNew.GetLocale() ) &&
1945 0 : pBase->GetLevel() == nLevel )
1946 0 : break;
1947 : }
1948 0 : if(i == nMax)
1949 : { // If not already present, create and insert
1950 : SwTOXCustom* pKey = new SwTOXCustom( aToCompare, nLevel, rIntl,
1951 0 : rNew.GetLocale() );
1952 0 : for(i = nMin; i < nMax; ++i)
1953 : {
1954 0 : if(nLevel == aSortArr[i]->GetLevel() && *pKey < *(aSortArr[i]))
1955 0 : break;
1956 : }
1957 0 : aSortArr.insert(aSortArr.begin() + i, pKey);
1958 : }
1959 0 : sal_uInt16 nStart = i+1;
1960 0 : sal_uInt16 nEnd = aSortArr.size();
1961 :
1962 : // Find end of range
1963 0 : for(i = nStart; i < aSortArr.size(); ++i)
1964 : {
1965 0 : if(aSortArr[i]->GetLevel() <= nLevel)
1966 0 : { nEnd = i;
1967 0 : break;
1968 : }
1969 : }
1970 0 : return Range(nStart, nEnd);
1971 : }
1972 :
1973 0 : bool SwTOXBase::IsTOXBaseInReadonly() const
1974 : {
1975 0 : const SwTOXBaseSection *pSect = dynamic_cast<const SwTOXBaseSection*>(this);
1976 0 : if (!pSect || !pSect->GetFmt())
1977 0 : return false;
1978 :
1979 0 : const SwSectionNode* pSectNode = pSect->GetFmt()->GetSectionNode();
1980 0 : if (!pSectNode)
1981 0 : return false;
1982 :
1983 0 : const SwDocShell* pDocSh = pSectNode->GetDoc()->GetDocShell();
1984 0 : if (!pDocSh)
1985 0 : return false;
1986 :
1987 0 : if (pDocSh->IsReadOnly())
1988 0 : return true;
1989 :
1990 0 : pSectNode = pSectNode->StartOfSectionNode()->FindSectionNode();
1991 0 : if (!pSectNode)
1992 0 : return false;
1993 :
1994 0 : return pSectNode->GetSection().IsProtectFlag();
1995 : }
1996 :
1997 0 : const SfxItemSet* SwTOXBase::GetAttrSet() const
1998 : {
1999 0 : const SwTOXBaseSection *pSect = dynamic_cast<const SwTOXBaseSection*>(this);
2000 0 : if(pSect && pSect->GetFmt())
2001 0 : return &pSect->GetFmt()->GetAttrSet();
2002 0 : return 0;
2003 : }
2004 :
2005 0 : void SwTOXBase::SetAttrSet( const SfxItemSet& rSet )
2006 : {
2007 0 : const SwTOXBaseSection *pSect = dynamic_cast<const SwTOXBaseSection*>(this);
2008 0 : if( pSect && pSect->GetFmt() )
2009 0 : pSect->GetFmt()->SetFmtAttr( rSet );
2010 0 : }
2011 :
2012 0 : bool SwTOXBase::GetInfo( SfxPoolItem& rInfo ) const
2013 : {
2014 0 : switch( rInfo.Which() )
2015 : {
2016 : case RES_CONTENT_VISIBLE:
2017 : {
2018 0 : const SwTOXBaseSection *pSect = dynamic_cast<const SwTOXBaseSection*>(this);
2019 0 : if( pSect && pSect->GetFmt() )
2020 0 : pSect->GetFmt()->GetInfo( rInfo );
2021 : }
2022 0 : return false;
2023 : }
2024 0 : return true;
2025 270 : }
2026 :
2027 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|