xref: /trunk/main/sw/source/core/doc/docnum.cxx (revision cf6516809c57e1bb0a940545cca99cdad54d4ce2)
1efeef26fSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3efeef26fSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4efeef26fSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5efeef26fSAndrew Rist  * distributed with this work for additional information
6efeef26fSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7efeef26fSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8efeef26fSAndrew Rist  * "License"); you may not use this file except in compliance
9efeef26fSAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11efeef26fSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13efeef26fSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14efeef26fSAndrew Rist  * software distributed under the License is distributed on an
15efeef26fSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16efeef26fSAndrew Rist  * KIND, either express or implied.  See the License for the
17efeef26fSAndrew Rist  * specific language governing permissions and limitations
18efeef26fSAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20efeef26fSAndrew Rist  *************************************************************/
21efeef26fSAndrew Rist 
22efeef26fSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sw.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <hintids.hxx>
283d14cea3SMichael Stahl #include <rtl/random.h>
29cdf0e10cSrcweir #include <tools/resid.hxx>
30cdf0e10cSrcweir #include <editeng/lrspitem.hxx>
31cdf0e10cSrcweir #include <ftninfo.hxx>
32cdf0e10cSrcweir #include <ftnidx.hxx>
33cdf0e10cSrcweir #include <doc.hxx>
34cdf0e10cSrcweir #include <IDocumentUndoRedo.hxx>
35cdf0e10cSrcweir #include <pam.hxx>
36cdf0e10cSrcweir #include <ndtxt.hxx>
37cdf0e10cSrcweir #include <doctxm.hxx>       // pTOXBaseRing
38cdf0e10cSrcweir #include <poolfmt.hxx>
39cdf0e10cSrcweir #include <UndoCore.hxx>
40cdf0e10cSrcweir #include <UndoRedline.hxx>
41cdf0e10cSrcweir #include <UndoNumbering.hxx>
42cdf0e10cSrcweir #include <swundo.hxx>
43cdf0e10cSrcweir #include <SwUndoFmt.hxx>
44cdf0e10cSrcweir #include <rolbck.hxx>
45cdf0e10cSrcweir #include <paratr.hxx>
46cdf0e10cSrcweir #include <docary.hxx>
47cdf0e10cSrcweir #include <mvsave.hxx>
48cdf0e10cSrcweir #include <txtfrm.hxx>
49cdf0e10cSrcweir #include <pamtyp.hxx>
50cdf0e10cSrcweir #include <redline.hxx>
51cdf0e10cSrcweir #include <comcore.hrc>
52cdf0e10cSrcweir #include <editeng/adjitem.hxx>
53cdf0e10cSrcweir #include <editeng/frmdiritem.hxx>
54cdf0e10cSrcweir #include <frmatr.hxx>
55cdf0e10cSrcweir #include <SwStyleNameMapper.hxx>
56cdf0e10cSrcweir #include <SwNodeNum.hxx>
57cdf0e10cSrcweir #include <list.hxx>
58cdf0e10cSrcweir #include <listfunc.hxx>
59cdf0e10cSrcweir #include <switerator.hxx>
60cdf0e10cSrcweir 
61cdf0e10cSrcweir #include <map>
62cdf0e10cSrcweir 
63b264d727SArmin Le Grand #include <stdlib.h>
64b264d727SArmin Le Grand 
65b264d727SArmin Le Grand 
GetUpperLvlChg(sal_uInt8 nCurLvl,sal_uInt8 nLevel,sal_uInt16 nMask)66cdf0e10cSrcweir inline sal_uInt8 GetUpperLvlChg( sal_uInt8 nCurLvl, sal_uInt8 nLevel, sal_uInt16 nMask )
67cdf0e10cSrcweir {
68cdf0e10cSrcweir     if( 1 < nLevel )
69cdf0e10cSrcweir     {
70cdf0e10cSrcweir         if( nCurLvl + 1 >= nLevel )
71cdf0e10cSrcweir             nCurLvl -= nLevel - 1;
72cdf0e10cSrcweir         else
73cdf0e10cSrcweir             nCurLvl = 0;
74cdf0e10cSrcweir     }
75cdf0e10cSrcweir     return static_cast<sal_uInt8>((nMask - 1) & ~(( 1 << nCurLvl ) - 1));
76cdf0e10cSrcweir }
77cdf0e10cSrcweir 
SetOutlineNumRule(const SwNumRule & rRule)78cdf0e10cSrcweir void SwDoc::SetOutlineNumRule( const SwNumRule& rRule )
79cdf0e10cSrcweir {
80cdf0e10cSrcweir     if( pOutlineRule )
81cdf0e10cSrcweir         (*pOutlineRule) = rRule;
82cdf0e10cSrcweir     else
83cdf0e10cSrcweir     {
84cdf0e10cSrcweir         pOutlineRule = new SwNumRule( rRule );
85cdf0e10cSrcweir 
86cdf0e10cSrcweir         AddNumRule(pOutlineRule); // #i36749#
87cdf0e10cSrcweir     }
88cdf0e10cSrcweir 
89cdf0e10cSrcweir     pOutlineRule->SetRuleType( OUTLINE_RULE );
90cdf0e10cSrcweir     // --> OD 2008-07-08 #i91400#
91cdf0e10cSrcweir     pOutlineRule->SetName( String::CreateFromAscii(
92cdf0e10cSrcweir                                         SwNumRule::GetOutlineRuleName() ),
93cdf0e10cSrcweir                            *this);
94cdf0e10cSrcweir     // <--
95cdf0e10cSrcweir     // --> OD 2006-09-21 #i69522#
96cdf0e10cSrcweir     // assure that the outline numbering rule is an automatic rule
97cdf0e10cSrcweir     pOutlineRule->SetAutoRule( sal_True );
98cdf0e10cSrcweir     // <--
99cdf0e10cSrcweir 
100cdf0e10cSrcweir     // teste ob die evt. gesetzen CharFormate in diesem Document
101cdf0e10cSrcweir     // definiert sind
102cdf0e10cSrcweir     pOutlineRule->CheckCharFmts( this );
103cdf0e10cSrcweir 
104cdf0e10cSrcweir     // --> OD 2008-05-13 #refactorlists#
105cdf0e10cSrcweir     // notify text nodes, which are registered at the outline style, about the
106cdf0e10cSrcweir     // changed outline style
107cdf0e10cSrcweir     SwNumRule::tTxtNodeList aTxtNodeList;
108cdf0e10cSrcweir     pOutlineRule->GetTxtNodeList( aTxtNodeList );
109cdf0e10cSrcweir     for ( SwNumRule::tTxtNodeList::iterator aIter = aTxtNodeList.begin();
110cdf0e10cSrcweir           aIter != aTxtNodeList.end(); ++aIter )
111cdf0e10cSrcweir     {
112cdf0e10cSrcweir         SwTxtNode* pTxtNd = *aIter;
113cdf0e10cSrcweir         pTxtNd->NumRuleChgd();
114cdf0e10cSrcweir         // --> OD 2009-01-20 #i94152#
115cdf0e10cSrcweir         // assure that list level corresponds to outline level
116cdf0e10cSrcweir         if ( pTxtNd->GetTxtColl()->IsAssignedToListLevelOfOutlineStyle() &&
117cdf0e10cSrcweir              pTxtNd->GetAttrListLevel() != pTxtNd->GetTxtColl()->GetAssignedOutlineStyleLevel() )
118cdf0e10cSrcweir         {
119cdf0e10cSrcweir             pTxtNd->SetAttrListLevel( pTxtNd->GetTxtColl()->GetAssignedOutlineStyleLevel() );
120cdf0e10cSrcweir         }
121cdf0e10cSrcweir         // <--
122cdf0e10cSrcweir     }
123cdf0e10cSrcweir     // <--
124cdf0e10cSrcweir 
125cdf0e10cSrcweir     PropagateOutlineRule();
126cdf0e10cSrcweir     pOutlineRule->SetInvalidRule(sal_True);
127cdf0e10cSrcweir     UpdateNumRule();
128cdf0e10cSrcweir 
129cdf0e10cSrcweir     // gibt es Fussnoten && gilt Kapitelweises Nummerieren, dann updaten
130cdf0e10cSrcweir     if( GetFtnIdxs().Count() && FTNNUM_CHAPTER == GetFtnInfo().eNum )
131cdf0e10cSrcweir         GetFtnIdxs().UpdateAllFtn();
132cdf0e10cSrcweir 
133cdf0e10cSrcweir     UpdateExpFlds(NULL, true);
134cdf0e10cSrcweir 
135cdf0e10cSrcweir     SetModified();
136cdf0e10cSrcweir }
137cdf0e10cSrcweir 
PropagateOutlineRule()138cdf0e10cSrcweir void SwDoc::PropagateOutlineRule()
139cdf0e10cSrcweir {
140cdf0e10cSrcweir     for (sal_uInt16 n = 0; n < pTxtFmtCollTbl->Count(); n++)
141cdf0e10cSrcweir     {
142cdf0e10cSrcweir         SwTxtFmtColl *pColl = (*pTxtFmtCollTbl)[n];
143cdf0e10cSrcweir 
144cdf0e10cSrcweir        // if (NO_NUMBERING != pColl->GetOutlineLevel())//#outline level,zhaojianwei
145cdf0e10cSrcweir         if(pColl->IsAssignedToListLevelOfOutlineStyle())//<-end,zhaojianwei
146cdf0e10cSrcweir         {
147cdf0e10cSrcweir             // --> OD 2006-11-20 #i71764#
148cdf0e10cSrcweir             // Check only the list style, which is set at the paragraph style
149cdf0e10cSrcweir             const SwNumRuleItem & rCollRuleItem = pColl->GetNumRule( sal_False );
150cdf0e10cSrcweir             // <--
151cdf0e10cSrcweir 
152cdf0e10cSrcweir             // --> OD 2006-11-20 #i71764#
153cdf0e10cSrcweir             // Check on document setting OUTLINE_LEVEL_YIELDS_OUTLINE_RULE no longer needed.
154cdf0e10cSrcweir             if ( rCollRuleItem.GetValue().Len() == 0 )
155cdf0e10cSrcweir             // <--
156cdf0e10cSrcweir             {
157cdf0e10cSrcweir                 SwNumRule * pMyOutlineRule = GetOutlineNumRule();
158cdf0e10cSrcweir 
159cdf0e10cSrcweir                 if (pMyOutlineRule)
160cdf0e10cSrcweir                 {
161cdf0e10cSrcweir                     SwNumRuleItem aNumItem( pMyOutlineRule->GetName() );
162cdf0e10cSrcweir 
163cdf0e10cSrcweir                     pColl->SetFmtAttr(aNumItem);
164cdf0e10cSrcweir                 }
165cdf0e10cSrcweir             }
166cdf0e10cSrcweir         }
167cdf0e10cSrcweir     }
168cdf0e10cSrcweir }
169cdf0e10cSrcweir 
170cdf0e10cSrcweir     // Hoch-/Runterstufen
OutlineUpDown(const SwPaM & rPam,short nOffset)171cdf0e10cSrcweir sal_Bool SwDoc::OutlineUpDown( const SwPaM& rPam, short nOffset )
172cdf0e10cSrcweir {
173cdf0e10cSrcweir     if( !GetNodes().GetOutLineNds().Count() || !nOffset )
174cdf0e10cSrcweir         return sal_False;
175cdf0e10cSrcweir 
176cdf0e10cSrcweir     // den Bereich feststellen
177cdf0e10cSrcweir     const SwOutlineNodes& rOutlNds = GetNodes().GetOutLineNds();
178cdf0e10cSrcweir     const SwNodePtr pSttNd = (SwNodePtr)&rPam.Start()->nNode.GetNode();
179cdf0e10cSrcweir     const SwNodePtr pEndNd = (SwNodePtr)&rPam.End()->nNode.GetNode();
180cdf0e10cSrcweir     sal_uInt16 nSttPos, nEndPos;
181cdf0e10cSrcweir 
182cdf0e10cSrcweir     if( !rOutlNds.Seek_Entry( pSttNd, &nSttPos ) &&
183cdf0e10cSrcweir         !nSttPos-- )
184cdf0e10cSrcweir         // wir stehen in keiner "Outline-Section"
185cdf0e10cSrcweir         return sal_False;
186cdf0e10cSrcweir 
187cdf0e10cSrcweir     if( rOutlNds.Seek_Entry( pEndNd, &nEndPos ) )
188cdf0e10cSrcweir         ++nEndPos;
189cdf0e10cSrcweir 
190cdf0e10cSrcweir     // jetzt haben wir unseren Bereich im OutlineNodes-Array
191cdf0e10cSrcweir     // dann prufe ersmal, ob nicht unterebenen aufgehoben werden
192cdf0e10cSrcweir     // (Stufung ueber die Grenzen)
193cdf0e10cSrcweir     sal_uInt16 n;
194cdf0e10cSrcweir 
195cdf0e10cSrcweir     // so, dann koennen wir:
196cdf0e10cSrcweir     // 1. Vorlagen-Array anlegen
197cdf0e10cSrcweir     SwTxtFmtColl* aCollArr[ MAXLEVEL ];
198cdf0e10cSrcweir     memset( aCollArr, 0, sizeof( SwTxtFmtColl* ) * MAXLEVEL );
199cdf0e10cSrcweir 
200cdf0e10cSrcweir     for( n = 0; n < pTxtFmtCollTbl->Count(); ++n )
201cdf0e10cSrcweir     {
202cdf0e10cSrcweir         //sal_uInt8 nLevel = (*pTxtFmtCollTbl)[ n ]->GetOutlineLevel();//#outline level,zhaojianwei
203cdf0e10cSrcweir         //if( nLevel < MAXLEVEL )
204cdf0e10cSrcweir         //  aCollArr[ nLevel ] = (*pTxtFmtCollTbl)[ n ];
205cdf0e10cSrcweir         if((*pTxtFmtCollTbl)[ n ]->IsAssignedToListLevelOfOutlineStyle())
206cdf0e10cSrcweir         {
207cdf0e10cSrcweir             const int nLevel = (*pTxtFmtCollTbl)[ n ]->GetAssignedOutlineStyleLevel();
208cdf0e10cSrcweir             aCollArr[ nLevel ] = (*pTxtFmtCollTbl)[ n ];
209cdf0e10cSrcweir         }//<-end,zhaojianwei
210cdf0e10cSrcweir     }
211cdf0e10cSrcweir 
212cdf0e10cSrcweir     /* --> #111107# */
213cdf0e10cSrcweir     /* Find the last occupied level (backward). */
214cdf0e10cSrcweir     for (n = MAXLEVEL - 1; n > 0; n--)
215cdf0e10cSrcweir     {
216cdf0e10cSrcweir         if (aCollArr[n] != 0)
217cdf0e10cSrcweir             break;
218cdf0e10cSrcweir     }
219cdf0e10cSrcweir 
220cdf0e10cSrcweir     /* If an occupied level is found, choose next level (which IS
221cdf0e10cSrcweir        unoccupied) until a valid level is found. If no occupied level
222cdf0e10cSrcweir        was found n is 0 and aCollArr[0] is 0. In this case no demoting
223cdf0e10cSrcweir        is possible. */
224cdf0e10cSrcweir     if (aCollArr[n] != 0)
225cdf0e10cSrcweir     {
226cdf0e10cSrcweir         while (n < MAXLEVEL - 1)
227cdf0e10cSrcweir         {
228cdf0e10cSrcweir             n++;
229cdf0e10cSrcweir 
230cdf0e10cSrcweir             SwTxtFmtColl *aTmpColl =
231cdf0e10cSrcweir                 GetTxtCollFromPool(static_cast<sal_uInt16>(RES_POOLCOLL_HEADLINE1 + n));
232cdf0e10cSrcweir 
233cdf0e10cSrcweir             //if (aTmpColl->GetOutlineLevel() == n)//#outline level,zhaojianwei
234cdf0e10cSrcweir             if( aTmpColl->IsAssignedToListLevelOfOutlineStyle() &&
235cdf0e10cSrcweir                 aTmpColl->GetAssignedOutlineStyleLevel() == n )//<-end,zhaojianwei
236cdf0e10cSrcweir             {
237cdf0e10cSrcweir                 aCollArr[n] = aTmpColl;
238cdf0e10cSrcweir                 break;
239cdf0e10cSrcweir             }
240cdf0e10cSrcweir         }
241cdf0e10cSrcweir     }
242cdf0e10cSrcweir 
243cdf0e10cSrcweir     /* Find the first occupied level (forward). */
244cdf0e10cSrcweir     for (n = 0; n < MAXLEVEL - 1; n++)
245cdf0e10cSrcweir     {
246cdf0e10cSrcweir         if (aCollArr[n] != 0)
247cdf0e10cSrcweir             break;
248cdf0e10cSrcweir     }
249cdf0e10cSrcweir 
250cdf0e10cSrcweir     /* If an occupied level is found, choose previous level (which IS
251cdf0e10cSrcweir        unoccupied) until a valid level is found. If no occupied level
252cdf0e10cSrcweir        was found n is MAXLEVEL - 1 and aCollArr[MAXLEVEL - 1] is 0. In
253cdf0e10cSrcweir        this case no demoting is possible. */
254cdf0e10cSrcweir     if (aCollArr[n] != 0)
255cdf0e10cSrcweir     {
256cdf0e10cSrcweir         while (n > 0)
257cdf0e10cSrcweir         {
258cdf0e10cSrcweir             n--;
259cdf0e10cSrcweir 
260cdf0e10cSrcweir             SwTxtFmtColl *aTmpColl =
261cdf0e10cSrcweir                 GetTxtCollFromPool(static_cast<sal_uInt16>(RES_POOLCOLL_HEADLINE1 + n));
262cdf0e10cSrcweir 
263cdf0e10cSrcweir             //if (aTmpColl->GetOutlineLevel() == n)//#outline level,zhaojianwei
264cdf0e10cSrcweir             if( aTmpColl->IsAssignedToListLevelOfOutlineStyle() &&
265cdf0e10cSrcweir                 aTmpColl->GetAssignedOutlineStyleLevel() == n )//<-end,zhaojianwei
266cdf0e10cSrcweir             {
267cdf0e10cSrcweir                 aCollArr[n] = aTmpColl;
268cdf0e10cSrcweir                 break;
269cdf0e10cSrcweir             }
270cdf0e10cSrcweir         }
271cdf0e10cSrcweir     }
272cdf0e10cSrcweir     /* <-- #111107# */
273cdf0e10cSrcweir 
274cdf0e10cSrcweir     /* --> #i13747#
275cdf0e10cSrcweir 
276cdf0e10cSrcweir        Build a move table that states from which level an outline will
277cdf0e10cSrcweir 
278cdf0e10cSrcweir   be moved to which other level. */
279cdf0e10cSrcweir 
280cdf0e10cSrcweir     /* the move table
281cdf0e10cSrcweir 
282cdf0e10cSrcweir        aMoveArr[n] = m: replace aCollArr[n] with aCollArr[m]
283cdf0e10cSrcweir     */
284cdf0e10cSrcweir     int aMoveArr[MAXLEVEL];
285cdf0e10cSrcweir     int nStep; // step size for searching in aCollArr: -1 or 1
286cdf0e10cSrcweir     int nNum; // amount of steps for stepping in aCollArr
287cdf0e10cSrcweir 
288cdf0e10cSrcweir     if (nOffset < 0)
289cdf0e10cSrcweir     {
290cdf0e10cSrcweir         nStep = -1;
291cdf0e10cSrcweir         nNum = -nOffset;
292cdf0e10cSrcweir     }
293cdf0e10cSrcweir     else
294cdf0e10cSrcweir     {
295cdf0e10cSrcweir         nStep = 1;
296cdf0e10cSrcweir         nNum = nOffset;
297cdf0e10cSrcweir     }
298cdf0e10cSrcweir 
299cdf0e10cSrcweir     /* traverse aCollArr */
300cdf0e10cSrcweir     for (n = 0; n < MAXLEVEL; n++)
301cdf0e10cSrcweir     {
302cdf0e10cSrcweir         /* If outline level n has an assigned paragraph style step
303cdf0e10cSrcweir            nNum steps forwards (nStep == 1) or backwards (nStep ==
304cdf0e10cSrcweir            -1).  One step is to go to the next non-null entry in
305cdf0e10cSrcweir            aCollArr in the selected direction. If nNum steps were
306cdf0e10cSrcweir            possible write the index of the entry found to aCollArr[n],
307cdf0e10cSrcweir            i.e. outline level n will be replaced by outline level
308cdf0e10cSrcweir            aCollArr[n].
309cdf0e10cSrcweir 
310cdf0e10cSrcweir            If outline level n has no assigned paragraph style
311cdf0e10cSrcweir            aMoveArr[n] is set to -1.
312cdf0e10cSrcweir         */
313cdf0e10cSrcweir         if (aCollArr[n] != NULL)
314cdf0e10cSrcweir         {
315cdf0e10cSrcweir             sal_uInt16 m = n;
316cdf0e10cSrcweir             int nCount = nNum;
317cdf0e10cSrcweir 
318cdf0e10cSrcweir             while (nCount > 0 && m + nStep >= 0 && m + nStep < MAXLEVEL)
319cdf0e10cSrcweir             {
320cdf0e10cSrcweir                 m = static_cast<sal_uInt16>(m + nStep);
321cdf0e10cSrcweir 
322cdf0e10cSrcweir                 if (aCollArr[m] != NULL)
323cdf0e10cSrcweir                     nCount--;
324cdf0e10cSrcweir             }
325cdf0e10cSrcweir 
326cdf0e10cSrcweir             if (nCount == 0)
327cdf0e10cSrcweir                 aMoveArr[n] = m;
328cdf0e10cSrcweir             else
329cdf0e10cSrcweir                 aMoveArr[n] = -1;
330cdf0e10cSrcweir 
331cdf0e10cSrcweir         }
332cdf0e10cSrcweir         else
333cdf0e10cSrcweir             aMoveArr[n] = -1;
334cdf0e10cSrcweir     }
335cdf0e10cSrcweir 
336cdf0e10cSrcweir     /* If moving of the outline levels is applicable, i.e. for all
33786e1cf34SPedro Giffuni        outline levels occurring in the document there has to be a valid
338cdf0e10cSrcweir        target outline level implied by aMoveArr. */
339cdf0e10cSrcweir     bool bMoveApplicable = true;
340cdf0e10cSrcweir     for (n = nSttPos; n < nEndPos; n++)
341cdf0e10cSrcweir     {
342cdf0e10cSrcweir         SwTxtNode* pTxtNd = rOutlNds[ n ]->GetTxtNode();
343cdf0e10cSrcweir         SwTxtFmtColl* pColl = pTxtNd->GetTxtColl();
344cdf0e10cSrcweir //        int nLevel = pColl->GetOutlineLevel();//#outline level,zhaojianwei
345cdf0e10cSrcweir //        if (aMoveArr[nLevel] == -1)
346cdf0e10cSrcweir //          bMoveApplicable = false;
347cdf0e10cSrcweir         if( pColl->IsAssignedToListLevelOfOutlineStyle() )
348cdf0e10cSrcweir         {
349cdf0e10cSrcweir             const int nLevel = pColl->GetAssignedOutlineStyleLevel();
350cdf0e10cSrcweir             if (aMoveArr[nLevel] == -1)
351cdf0e10cSrcweir                 bMoveApplicable = false;
352cdf0e10cSrcweir         }//<-end,zhaojianwei
353cdf0e10cSrcweir         // --> OD 2008-12-16 #i70748#
354cdf0e10cSrcweir         // Check on outline level attribute of text node, if text node is
355cdf0e10cSrcweir         // not an outline via a to outline style assigned paragraph style.
356cdf0e10cSrcweir         else
357cdf0e10cSrcweir         {
358cdf0e10cSrcweir             const int nNewOutlineLevel = pTxtNd->GetAttrOutlineLevel() + nOffset;
359cdf0e10cSrcweir             if ( nNewOutlineLevel < 1 || nNewOutlineLevel > MAXLEVEL )
360cdf0e10cSrcweir             {
361cdf0e10cSrcweir                 bMoveApplicable = false;
362cdf0e10cSrcweir             }
363cdf0e10cSrcweir         }
364cdf0e10cSrcweir         // <--
365cdf0e10cSrcweir     }
366cdf0e10cSrcweir 
367cdf0e10cSrcweir     if (! bMoveApplicable )
368cdf0e10cSrcweir         return sal_False;
369cdf0e10cSrcweir 
370cdf0e10cSrcweir     /* <-- #i13747 # */
371cdf0e10cSrcweir     if (GetIDocumentUndoRedo().DoesUndo())
372cdf0e10cSrcweir     {
373cdf0e10cSrcweir         GetIDocumentUndoRedo().StartUndo(UNDO_OUTLINE_LR, NULL);
374cdf0e10cSrcweir         SwUndo *const pUndoOLR( new SwUndoOutlineLeftRight( rPam, nOffset ) );
375cdf0e10cSrcweir         GetIDocumentUndoRedo().AppendUndo(pUndoOLR);
376cdf0e10cSrcweir     }
377cdf0e10cSrcweir 
378cdf0e10cSrcweir     // 2. allen Nodes die neue Vorlage zuweisen
379cdf0e10cSrcweir 
380cdf0e10cSrcweir     n = nSttPos;
381cdf0e10cSrcweir     while( n < nEndPos)
382cdf0e10cSrcweir     {
383cdf0e10cSrcweir         SwTxtNode* pTxtNd = rOutlNds[ n ]->GetTxtNode();
384cdf0e10cSrcweir         SwTxtFmtColl* pColl = pTxtNd->GetTxtColl();
385cdf0e10cSrcweir 
386cdf0e10cSrcweir         if( pColl->IsAssignedToListLevelOfOutlineStyle() )
387cdf0e10cSrcweir         {
388cdf0e10cSrcweir         // ASSERT(pColl->GetOutlineLevel() < MAXLEVEL,  //#outline level,removed by zhaojianwei
389cdf0e10cSrcweir         //         "non outline node in outline nodes?");
390cdf0e10cSrcweir         //int nLevel = pColl->GetOutlineLevel();
391cdf0e10cSrcweir             const int nLevel = pColl->GetAssignedOutlineStyleLevel();//#outline level,add by zhaojianwei
392cdf0e10cSrcweir 
393cdf0e10cSrcweir             ASSERT(aMoveArr[nLevel] >= 0,
394cdf0e10cSrcweir                 "move table: current TxtColl not found when building table!");
395cdf0e10cSrcweir 
396cdf0e10cSrcweir 
397cdf0e10cSrcweir             if (nLevel < MAXLEVEL && aMoveArr[nLevel] >= 0)
398cdf0e10cSrcweir             {
399cdf0e10cSrcweir                 pColl = aCollArr[ aMoveArr[nLevel] ];
400cdf0e10cSrcweir 
401cdf0e10cSrcweir                 if (pColl != NULL)
402cdf0e10cSrcweir                     pColl = (SwTxtFmtColl*)pTxtNd->ChgFmtColl( pColl );
403cdf0e10cSrcweir             }
404cdf0e10cSrcweir 
405cdf0e10cSrcweir         }
406cdf0e10cSrcweir         else if( pTxtNd->GetAttrOutlineLevel() > 0) //#outline level,add by zhaojianwei
407cdf0e10cSrcweir         {
408cdf0e10cSrcweir             int nLevel = pTxtNd->GetAttrOutlineLevel() + nOffset;
409cdf0e10cSrcweir             if( 0 <= nLevel && nLevel <= MAXLEVEL)
410cdf0e10cSrcweir                 pTxtNd->SetAttrOutlineLevel( nLevel );
411cdf0e10cSrcweir 
412cdf0e10cSrcweir         }//<-end,zhaojianwei
413cdf0e10cSrcweir 
414cdf0e10cSrcweir         n++;
415cdf0e10cSrcweir         // Undo ???
416cdf0e10cSrcweir     }
417cdf0e10cSrcweir     if (GetIDocumentUndoRedo().DoesUndo())
418cdf0e10cSrcweir     {
419cdf0e10cSrcweir         GetIDocumentUndoRedo().EndUndo(UNDO_OUTLINE_LR, NULL);
420cdf0e10cSrcweir     }
421cdf0e10cSrcweir 
422cdf0e10cSrcweir     ChkCondColls();
423cdf0e10cSrcweir     SetModified();
424cdf0e10cSrcweir 
425cdf0e10cSrcweir     return sal_True;
426cdf0e10cSrcweir }
427cdf0e10cSrcweir 
428cdf0e10cSrcweir 
429cdf0e10cSrcweir 
430cdf0e10cSrcweir     // Hoch-/Runter - Verschieben !
MoveOutlinePara(const SwPaM & rPam,short nOffset)431cdf0e10cSrcweir sal_Bool SwDoc::MoveOutlinePara( const SwPaM& rPam, short nOffset )
432cdf0e10cSrcweir {
433cdf0e10cSrcweir     // kein Verschiebung in den Sonderbereichen
434cdf0e10cSrcweir     const SwPosition& rStt = *rPam.Start(),
435cdf0e10cSrcweir                     & rEnd = &rStt == rPam.GetPoint() ? *rPam.GetMark()
436cdf0e10cSrcweir                                                       : *rPam.GetPoint();
437cdf0e10cSrcweir     if( !GetNodes().GetOutLineNds().Count() || !nOffset ||
438cdf0e10cSrcweir         (rStt.nNode.GetIndex() < GetNodes().GetEndOfExtras().GetIndex()) ||
439cdf0e10cSrcweir         (rEnd.nNode.GetIndex() < GetNodes().GetEndOfExtras().GetIndex()))
440cdf0e10cSrcweir     {
441cdf0e10cSrcweir         return sal_False;
442cdf0e10cSrcweir     }
443cdf0e10cSrcweir 
444cdf0e10cSrcweir     sal_uInt16 nAktPos = 0;
445cdf0e10cSrcweir     SwNodeIndex aSttRg( rStt.nNode ), aEndRg( rEnd.nNode );
446cdf0e10cSrcweir 
447cdf0e10cSrcweir     //sal_uInt8 nOutLineLevel = NO_NUMBERING;   //#outline level,zhaojianwei
448cdf0e10cSrcweir     int nOutLineLevel = MAXLEVEL;           //<-end,zhaojianwei
449cdf0e10cSrcweir     SwNode* pSrch = &aSttRg.GetNode();
450cdf0e10cSrcweir     //if( pSrch->IsTxtNode() )              //#outline level,zhaojianwei
451cdf0e10cSrcweir     //     nOutLineLevel = static_cast<sal_uInt8>(((SwTxtNode*)pSrch)->GetOutlineLevel());
452cdf0e10cSrcweir    if( pSrch->IsTxtNode())
453cdf0e10cSrcweir         nOutLineLevel = static_cast<sal_uInt8>(((SwTxtNode*)pSrch)->GetAttrOutlineLevel()-1);//<-end,zhaojianwei
454cdf0e10cSrcweir     SwNode* pEndSrch = &aEndRg.GetNode();
455cdf0e10cSrcweir     if( !GetNodes().GetOutLineNds().Seek_Entry( pSrch, &nAktPos ) )
456cdf0e10cSrcweir     {
457cdf0e10cSrcweir         if( !nAktPos )
458cdf0e10cSrcweir             return sal_False; // Promoting or demoting before the first outline => no.
459cdf0e10cSrcweir         if( --nAktPos )
460cdf0e10cSrcweir             aSttRg = *GetNodes().GetOutLineNds()[ nAktPos ];
461cdf0e10cSrcweir         else if( 0 > nOffset )
462cdf0e10cSrcweir             return sal_False; // Promoting at the top of document?!
463cdf0e10cSrcweir         else
464cdf0e10cSrcweir             aSttRg = *GetNodes().GetEndOfContent().StartOfSectionNode();
465cdf0e10cSrcweir     }
466cdf0e10cSrcweir     sal_uInt16 nTmpPos = 0;
467cdf0e10cSrcweir     // If the given range ends at an outlined text node we have to decide if it has to be a part of
468cdf0e10cSrcweir     // the moving range or not. Normally it will be a sub outline of our chapter
469cdf0e10cSrcweir     // and has to be moved, too. But if the chapter ends with a table(or a section end),
47086e1cf34SPedro Giffuni     // the next text node will be chosen and this could be the next outline of the same level.
471cdf0e10cSrcweir     // The criteria has to be the outline level: sub level => incorporate, same/higher level => no.
472cdf0e10cSrcweir     if( GetNodes().GetOutLineNds().Seek_Entry( pEndSrch, &nTmpPos ) )
473cdf0e10cSrcweir     {
474cdf0e10cSrcweir         if( !pEndSrch->IsTxtNode() || pEndSrch == pSrch ||
475cdf0e10cSrcweir             //nOutLineLevel < ((SwTxtNode*)pEndSrch)->GetOutlineLevel() )//#outline level,zhaojianwei
476cdf0e10cSrcweir             nOutLineLevel < ((SwTxtNode*)pEndSrch)->GetAttrOutlineLevel()-1 )//<-end,zhaojianwei
477cdf0e10cSrcweir             ++nTmpPos; // For sub outlines only!
478cdf0e10cSrcweir     }
479cdf0e10cSrcweir 
480cdf0e10cSrcweir     aEndRg = nTmpPos < GetNodes().GetOutLineNds().Count()
481cdf0e10cSrcweir                     ? *GetNodes().GetOutLineNds()[ nTmpPos ]
482cdf0e10cSrcweir                     : GetNodes().GetEndOfContent();
483cdf0e10cSrcweir     if( nOffset >= 0 )
484cdf0e10cSrcweir         nAktPos = nTmpPos;
485cdf0e10cSrcweir     if( aEndRg == aSttRg )
486cdf0e10cSrcweir     {
487cdf0e10cSrcweir         ASSERT( false, "Moving outlines: Surprising selection" );
488cdf0e10cSrcweir         aEndRg++;
489cdf0e10cSrcweir     }
490cdf0e10cSrcweir 
491cdf0e10cSrcweir     const SwNode* pNd;
492cdf0e10cSrcweir     // The following code corrects the range to handle sections (start/end nodes)
493cdf0e10cSrcweir     // The range will be extended if the least node before the range is a start node
494cdf0e10cSrcweir     // which ends inside the range => The complete section will be moved.
49586e1cf34SPedro Giffuni     // The range will be shrunk if the last position is a start node.
49686e1cf34SPedro Giffuni     // The range will be shrunk if the last node is an end node which starts before the range.
497cdf0e10cSrcweir     aSttRg--;
498cdf0e10cSrcweir     while( aSttRg.GetNode().IsStartNode() )
499cdf0e10cSrcweir     {
500cdf0e10cSrcweir         pNd = aSttRg.GetNode().EndOfSectionNode();
501cdf0e10cSrcweir         if( pNd->GetIndex() >= aEndRg.GetIndex() )
502cdf0e10cSrcweir             break;
503cdf0e10cSrcweir         aSttRg--;
504cdf0e10cSrcweir     }
505cdf0e10cSrcweir     aSttRg++;
506cdf0e10cSrcweir 
507cdf0e10cSrcweir     aEndRg--;
508cdf0e10cSrcweir     while( aEndRg.GetNode().IsStartNode() )
509cdf0e10cSrcweir         aEndRg--;
510cdf0e10cSrcweir     while( aEndRg.GetNode().IsEndNode() )
511cdf0e10cSrcweir     {
512cdf0e10cSrcweir         pNd = aEndRg.GetNode().StartOfSectionNode();
513cdf0e10cSrcweir         if( pNd->GetIndex() >= aSttRg.GetIndex() )
514cdf0e10cSrcweir             break;
515cdf0e10cSrcweir         aEndRg--;
516cdf0e10cSrcweir     }
517cdf0e10cSrcweir     aEndRg++;
518cdf0e10cSrcweir 
519cdf0e10cSrcweir     // calculation of the new position
520cdf0e10cSrcweir     if( nOffset < 0 && nAktPos < sal_uInt16(-nOffset) )
521cdf0e10cSrcweir         pNd = GetNodes().GetEndOfContent().StartOfSectionNode();
522cdf0e10cSrcweir     else if( nAktPos + nOffset >= GetNodes().GetOutLineNds().Count() )
523cdf0e10cSrcweir         pNd = &GetNodes().GetEndOfContent();
524cdf0e10cSrcweir     else
525cdf0e10cSrcweir         pNd = GetNodes().GetOutLineNds()[ nAktPos + nOffset ];
526cdf0e10cSrcweir 
527cdf0e10cSrcweir     sal_uLong nNewPos = pNd->GetIndex();
528cdf0e10cSrcweir 
529cdf0e10cSrcweir     // And now a correction of the insert position if necessary...
530cdf0e10cSrcweir     SwNodeIndex aInsertPos( *pNd, -1 );
531cdf0e10cSrcweir     while( aInsertPos.GetNode().IsStartNode() )
532cdf0e10cSrcweir     {
533cdf0e10cSrcweir         // Just before the insert position starts a section:
534cdf0e10cSrcweir         // when I'm moving forward I do not want to enter the section,
535cdf0e10cSrcweir         // when I'm moving backward I want to stay in the section if I'm already a part of,
536cdf0e10cSrcweir         // I want to stay outside if I was outside before.
537cdf0e10cSrcweir         if( nOffset < 0 )
538cdf0e10cSrcweir         {
539cdf0e10cSrcweir             pNd = aInsertPos.GetNode().EndOfSectionNode();
540cdf0e10cSrcweir             if( pNd->GetIndex() >= aEndRg.GetIndex() )
541cdf0e10cSrcweir                 break;
542cdf0e10cSrcweir         }
543cdf0e10cSrcweir         aInsertPos--;
544cdf0e10cSrcweir         --nNewPos;
545cdf0e10cSrcweir     }
546cdf0e10cSrcweir     if( nOffset >= 0 )
547cdf0e10cSrcweir     {
548cdf0e10cSrcweir         // When just before the insert position a section ends, it is okay when I'm moving backward
549cdf0e10cSrcweir         // because I want to stay outside the section.
550cdf0e10cSrcweir         // When moving forward I've to check if I started inside or outside the section
551cdf0e10cSrcweir         // because I don't want to enter of leave such a section
552cdf0e10cSrcweir         while( aInsertPos.GetNode().IsEndNode() )
553cdf0e10cSrcweir         {
554cdf0e10cSrcweir             pNd = aInsertPos.GetNode().StartOfSectionNode();
555cdf0e10cSrcweir             if( pNd->GetIndex() >= aSttRg.GetIndex() )
556cdf0e10cSrcweir                 break;
557cdf0e10cSrcweir             aInsertPos--;
558cdf0e10cSrcweir             --nNewPos;
559cdf0e10cSrcweir         }
560cdf0e10cSrcweir     }
561cdf0e10cSrcweir     // We do not want to move into tables (at the moment)
562cdf0e10cSrcweir     aInsertPos++;
563cdf0e10cSrcweir     pNd = &aInsertPos.GetNode();
564cdf0e10cSrcweir     if( pNd->IsTableNode() )
565cdf0e10cSrcweir         pNd = pNd->StartOfSectionNode();
566cdf0e10cSrcweir     if( pNd->FindTableNode() )
567cdf0e10cSrcweir         return sal_False;
568cdf0e10cSrcweir 
569cdf0e10cSrcweir     ASSERT( aSttRg.GetIndex() > nNewPos || nNewPos >= aEndRg.GetIndex(),
570cdf0e10cSrcweir                 "Position liegt im MoveBereich" );
571cdf0e10cSrcweir 
572cdf0e10cSrcweir     // wurde ein Position in den Sonderbereichen errechnet, dann
573cdf0e10cSrcweir     // setze die Position auf den Dokumentanfang.
574cdf0e10cSrcweir     // Sollten da Bereiche oder Tabellen stehen, so werden sie nach
575cdf0e10cSrcweir     // hinten verschoben.
576cdf0e10cSrcweir     nNewPos = Max( nNewPos, GetNodes().GetEndOfExtras().GetIndex() + 2 );
577cdf0e10cSrcweir 
578cdf0e10cSrcweir     long nOffs = nNewPos - ( 0 < nOffset ? aEndRg.GetIndex() : aSttRg.GetIndex());
579cdf0e10cSrcweir     SwPaM aPam( aSttRg, aEndRg, 0, -1 );
580cdf0e10cSrcweir     return MoveParagraph( aPam, nOffs, sal_True );
581cdf0e10cSrcweir }
582cdf0e10cSrcweir 
583cdf0e10cSrcweir 
lcl_FindOutlineName(const SwNodes & rNds,const String & rName,sal_Bool bExact)584cdf0e10cSrcweir sal_uInt16 lcl_FindOutlineName( const SwNodes& rNds, const String& rName,
585cdf0e10cSrcweir                             sal_Bool bExact )
586cdf0e10cSrcweir {
587cdf0e10cSrcweir     sal_uInt16 nSavePos = USHRT_MAX;
588cdf0e10cSrcweir     const SwOutlineNodes& rOutlNds = rNds.GetOutLineNds();
589cdf0e10cSrcweir     for( sal_uInt16 n = 0; n < rOutlNds.Count(); ++n )
590cdf0e10cSrcweir     {
591cdf0e10cSrcweir         SwTxtNode* pTxtNd = rOutlNds[ n ]->GetTxtNode();
592cdf0e10cSrcweir         String sTxt( pTxtNd->GetExpandTxt() );
593cdf0e10cSrcweir         if( sTxt.Equals( rName ) )
594cdf0e10cSrcweir         {
595cdf0e10cSrcweir             // "exact" gefunden, setze Pos auf den Node
596cdf0e10cSrcweir             nSavePos = n;
597cdf0e10cSrcweir             break;
598cdf0e10cSrcweir         }
599cdf0e10cSrcweir         else if( !bExact && USHRT_MAX == nSavePos &&
600cdf0e10cSrcweir                     COMPARE_EQUAL == sTxt.CompareTo( rName, rName.Len()) )
601cdf0e10cSrcweir         {
602cdf0e10cSrcweir             // dann vielleicht nur den den 1.Teil vom Text gefunden
603cdf0e10cSrcweir             nSavePos = n;
604cdf0e10cSrcweir         }
605cdf0e10cSrcweir     }
606cdf0e10cSrcweir 
607cdf0e10cSrcweir     return nSavePos;
608cdf0e10cSrcweir }
609cdf0e10cSrcweir 
610cdf0e10cSrcweir 
611cdf0e10cSrcweir 
lcl_FindOutlineNum(const SwNodes & rNds,String & rName)612cdf0e10cSrcweir sal_uInt16 lcl_FindOutlineNum( const SwNodes& rNds, String& rName )
613cdf0e10cSrcweir {
614cdf0e10cSrcweir     // Gueltig Nummern sind (immer nur Offsets!!!):
615cdf0e10cSrcweir     //  ([Nummer]+\.)+  (als regulaerer Ausdruck!)
616cdf0e10cSrcweir     //  (Nummer gefolgt von Punkt, zum 5 Wiederholungen)
617cdf0e10cSrcweir     //  also: "1.1.", "1.", "1.1.1."
618cdf0e10cSrcweir     xub_StrLen nPos = 0;
619cdf0e10cSrcweir     String sNum = rName.GetToken( 0, '.', nPos );
620cdf0e10cSrcweir     if( STRING_NOTFOUND == nPos )
621cdf0e10cSrcweir         return USHRT_MAX;           // ungueltige Nummer!!!
622cdf0e10cSrcweir 
623cdf0e10cSrcweir     sal_uInt16 nLevelVal[ MAXLEVEL ];       // Nummern aller Levels
624cdf0e10cSrcweir     memset( nLevelVal, 0, MAXLEVEL * sizeof( nLevelVal[0] ));
625cdf0e10cSrcweir     sal_uInt8 nLevel = 0;
626cdf0e10cSrcweir     String sName( rName );
627cdf0e10cSrcweir 
628cdf0e10cSrcweir     while( STRING_NOTFOUND != nPos )
629cdf0e10cSrcweir     {
630cdf0e10cSrcweir         sal_uInt16 nVal = 0;
631cdf0e10cSrcweir         sal_Unicode c;
632cdf0e10cSrcweir         for( sal_uInt16 n = 0; n < sNum.Len(); ++n )
633cdf0e10cSrcweir             if( '0' <= ( c = sNum.GetChar( n )) && c <= '9' )
634cdf0e10cSrcweir             {
635cdf0e10cSrcweir                 nVal *= 10;  nVal += c - '0';
636cdf0e10cSrcweir             }
637cdf0e10cSrcweir             else if( nLevel )
638cdf0e10cSrcweir                 break;                      // "fast" gueltige Nummer
639cdf0e10cSrcweir             else
640cdf0e10cSrcweir                 return USHRT_MAX;           // ungueltige Nummer!!!
641cdf0e10cSrcweir 
642cdf0e10cSrcweir         if( MAXLEVEL > nLevel )
643cdf0e10cSrcweir             nLevelVal[ nLevel++ ] = nVal;
644cdf0e10cSrcweir 
645cdf0e10cSrcweir         sName.Erase( 0, nPos );
646cdf0e10cSrcweir         nPos = 0;
647cdf0e10cSrcweir         sNum = sName.GetToken( 0, '.', nPos );
648cdf0e10cSrcweir         // #i4533# without this check all parts delimited by a dot are treated as outline numbers
649cdf0e10cSrcweir         if(!ByteString(sNum, gsl_getSystemTextEncoding()).IsNumericAscii())
650cdf0e10cSrcweir             nPos = STRING_NOTFOUND;
651cdf0e10cSrcweir     }
652cdf0e10cSrcweir     rName = sName;      // das ist der nachfolgende Text.
653cdf0e10cSrcweir 
654cdf0e10cSrcweir     // alle Levels gelesen, dann suche mal im Document nach dieser
655cdf0e10cSrcweir     // Gliederung:
656cdf0e10cSrcweir     const SwOutlineNodes& rOutlNds = rNds.GetOutLineNds();
657cdf0e10cSrcweir     // OS: ohne OutlineNodes lohnt die Suche nicht
658cdf0e10cSrcweir     // und man spart sich einen Absturz #42958#
659cdf0e10cSrcweir     if(!rOutlNds.Count())
660cdf0e10cSrcweir         return USHRT_MAX;
661cdf0e10cSrcweir     SwTxtNode* pNd;
662cdf0e10cSrcweir     nPos = 0;
663cdf0e10cSrcweir     //search in the existing outline nodes for the required outline num array
664cdf0e10cSrcweir     for( ; nPos < rOutlNds.Count(); ++nPos )
665cdf0e10cSrcweir     {
666cdf0e10cSrcweir         pNd = rOutlNds[ nPos ]->GetTxtNode();
667cdf0e10cSrcweir         //sal_uInt8 nLvl = pNd->GetTxtColl()->GetOutlineLevel();    //#outline level,zhaojianwei
668cdf0e10cSrcweir         const int nLvl = pNd->GetAttrOutlineLevel()-1;   //<-end,zhaojianwei
669cdf0e10cSrcweir         if( nLvl == nLevel - 1)
670cdf0e10cSrcweir         {
671cdf0e10cSrcweir             // check for the outline num
672cdf0e10cSrcweir             // --> OD 2005-11-02 #i51089 - TUNING#
673cdf0e10cSrcweir             // --> OD 2006-09-22 #i68289#
674cdf0e10cSrcweir             // Assure, that text node has the correct numbering level. Otherwise,
675cdf0e10cSrcweir             // its number vector will not fit to the searched level.
676cdf0e10cSrcweir //            if ( pNd->GetNum() )
677cdf0e10cSrcweir             if ( pNd->GetNum() &&
678cdf0e10cSrcweir                  pNd->GetActualListLevel() == ( nLevel - 1 ) )
679cdf0e10cSrcweir             // <--
680cdf0e10cSrcweir             {
681cdf0e10cSrcweir                 const SwNodeNum & rNdNum = *(pNd->GetNum());
682cdf0e10cSrcweir                 SwNumberTree::tNumberVector aLevelVal = rNdNum.GetNumberVector();
683cdf0e10cSrcweir                 //now compare with the one searched for
684cdf0e10cSrcweir                 bool bEqual = true;
685cdf0e10cSrcweir                 for( sal_uInt8 n = 0; (n < nLevel) && bEqual; ++n )
686cdf0e10cSrcweir                 {
687cdf0e10cSrcweir                     bEqual = aLevelVal[n] == nLevelVal[n];
688cdf0e10cSrcweir                 }
689cdf0e10cSrcweir                 if(bEqual)
690cdf0e10cSrcweir                 {
691cdf0e10cSrcweir                     break;
692cdf0e10cSrcweir                 }
693cdf0e10cSrcweir             }
694cdf0e10cSrcweir             else
695cdf0e10cSrcweir             {
696cdf0e10cSrcweir                 // --> OD 2006-01-12 #126588#
697cdf0e10cSrcweir                 // A text node, which has an outline paragraph style applied and
698cdf0e10cSrcweir                 // has as hard attribute 'no numbering' set, has an outline level,
699cdf0e10cSrcweir                 // but no numbering tree node. Thus, consider this situation in
700cdf0e10cSrcweir                 // the assertion condition.
701cdf0e10cSrcweir                 ASSERT( !pNd->GetNumRule(),
702cdf0e10cSrcweir                         "<lcl_FindOutlineNum(..)> - text node with outline level and numbering rule, but without numbering tree node. This is a serious defect -> inform OD" );
703cdf0e10cSrcweir             }
704cdf0e10cSrcweir         }
705cdf0e10cSrcweir     }
706cdf0e10cSrcweir     if( nPos >= rOutlNds.Count() )
707cdf0e10cSrcweir         nPos = USHRT_MAX;
708cdf0e10cSrcweir     return nPos;
709cdf0e10cSrcweir }
710cdf0e10cSrcweir 
711cdf0e10cSrcweir     // zu diesem Gliederungspunkt
712cdf0e10cSrcweir 
713cdf0e10cSrcweir 
714cdf0e10cSrcweir     // JP 13.06.96:
715cdf0e10cSrcweir     // im Namen kann eine Nummer oder/und der Text stehen.
716cdf0e10cSrcweir     // zuerst wird ueber die Nummer versucht den richtigen Eintrag zu finden.
717cdf0e10cSrcweir     // Gibt es diesen, dann wird ueber den Text verglichen, od es der
718cdf0e10cSrcweir     // gewuenschte ist. Ist das nicht der Fall, wird noch mal nur ueber den
719cdf0e10cSrcweir     // Text gesucht. Wird dieser gefunden ist es der Eintrag. Ansonsten der,
720cdf0e10cSrcweir     // der ueber die Nummer gefunden wurde.
721cdf0e10cSrcweir     // Ist keine Nummer angegeben, dann nur den Text suchen.
722cdf0e10cSrcweir 
GotoOutline(SwPosition & rPos,const String & rName) const723cdf0e10cSrcweir sal_Bool SwDoc::GotoOutline( SwPosition& rPos, const String& rName ) const
724cdf0e10cSrcweir {
725cdf0e10cSrcweir     if( rName.Len() )
726cdf0e10cSrcweir     {
727cdf0e10cSrcweir         const SwOutlineNodes& rOutlNds = GetNodes().GetOutLineNds();
728cdf0e10cSrcweir 
729cdf0e10cSrcweir         // 1. Schritt: ueber die Nummer:
730cdf0e10cSrcweir         String sName( rName );
731cdf0e10cSrcweir         sal_uInt16 nFndPos = ::lcl_FindOutlineNum( GetNodes(), sName );
732cdf0e10cSrcweir         if( USHRT_MAX != nFndPos )
733cdf0e10cSrcweir         {
734cdf0e10cSrcweir             SwTxtNode* pNd = rOutlNds[ nFndPos ]->GetTxtNode();
735cdf0e10cSrcweir             String sExpandedText = pNd->GetExpandTxt();
736cdf0e10cSrcweir             //#i4533# leading numbers followed by a dot have been remove while
737cdf0e10cSrcweir             //searching for the outline position
738cdf0e10cSrcweir             //to compensate this they must be removed from the paragraphs text content, too
739cdf0e10cSrcweir             sal_uInt16 nPos = 0;
740cdf0e10cSrcweir             String sTempNum;
741cdf0e10cSrcweir             while(sExpandedText.Len() && (sTempNum = sExpandedText.GetToken(0, '.', nPos)).Len() &&
742cdf0e10cSrcweir                     STRING_NOTFOUND != nPos &&
743cdf0e10cSrcweir                     ByteString(sTempNum, gsl_getSystemTextEncoding()).IsNumericAscii())
744cdf0e10cSrcweir             {
745cdf0e10cSrcweir                 sExpandedText.Erase(0, nPos);
746cdf0e10cSrcweir                 nPos = 0;
747cdf0e10cSrcweir             }
748cdf0e10cSrcweir 
749cdf0e10cSrcweir             if( !sExpandedText.Equals( sName ) )
750cdf0e10cSrcweir             {
751cdf0e10cSrcweir                 sal_uInt16 nTmp = ::lcl_FindOutlineName( GetNodes(), sName, sal_True );
752cdf0e10cSrcweir                 if( USHRT_MAX != nTmp )             // ueber den Namen gefunden
753cdf0e10cSrcweir                 {
754cdf0e10cSrcweir                     nFndPos = nTmp;
755cdf0e10cSrcweir                     pNd = rOutlNds[ nFndPos ]->GetTxtNode();
756cdf0e10cSrcweir                 }
757cdf0e10cSrcweir             }
758cdf0e10cSrcweir             rPos.nNode = *pNd;
759cdf0e10cSrcweir             rPos.nContent.Assign( pNd, 0 );
760cdf0e10cSrcweir             return sal_True;
761cdf0e10cSrcweir         }
762cdf0e10cSrcweir 
763cdf0e10cSrcweir         nFndPos = ::lcl_FindOutlineName( GetNodes(), rName, sal_False );
764cdf0e10cSrcweir         if( USHRT_MAX != nFndPos )
765cdf0e10cSrcweir         {
766cdf0e10cSrcweir             SwTxtNode* pNd = rOutlNds[ nFndPos ]->GetTxtNode();
767cdf0e10cSrcweir             rPos.nNode = *pNd;
768cdf0e10cSrcweir             rPos.nContent.Assign( pNd, 0 );
769cdf0e10cSrcweir             return sal_True;
770cdf0e10cSrcweir         }
771cdf0e10cSrcweir 
772cdf0e10cSrcweir         // --> OD 2006-09-22 #i68289#
773cdf0e10cSrcweir         // additional search on hyperlink URL without its outline numbering part
774cdf0e10cSrcweir         if ( !sName.Equals( rName ) )
775cdf0e10cSrcweir         {
776cdf0e10cSrcweir             nFndPos = ::lcl_FindOutlineName( GetNodes(), sName, sal_False );
777cdf0e10cSrcweir             if( USHRT_MAX != nFndPos )
778cdf0e10cSrcweir             {
779cdf0e10cSrcweir                 SwTxtNode* pNd = rOutlNds[ nFndPos ]->GetTxtNode();
780cdf0e10cSrcweir                 rPos.nNode = *pNd;
781cdf0e10cSrcweir                 rPos.nContent.Assign( pNd, 0 );
782cdf0e10cSrcweir                 return sal_True;
783cdf0e10cSrcweir             }
784cdf0e10cSrcweir         }
785cdf0e10cSrcweir         // <--
786cdf0e10cSrcweir     }
787cdf0e10cSrcweir     return sal_False;
788cdf0e10cSrcweir }
789cdf0e10cSrcweir 
790*1dda6fa0Smseidel /* */
791cdf0e10cSrcweir 
792cdf0e10cSrcweir // --- Nummerierung -----------------------------------------
793cdf0e10cSrcweir 
794cdf0e10cSrcweir // --> OD 2008-02-19 #refactorlists#
795cdf0e10cSrcweir //void SwNumRuleInfo::MakeList( SwDoc& rDoc, sal_Bool )
796cdf0e10cSrcweir //{
797cdf0e10cSrcweir //    SwNumRule* pRule = rDoc.FindNumRulePtr(rName);
798cdf0e10cSrcweir 
799cdf0e10cSrcweir //    // no rule, no fun.
800cdf0e10cSrcweir //    if ( !pRule )
801cdf0e10cSrcweir //        return;
802cdf0e10cSrcweir 
803cdf0e10cSrcweir //    //
804cdf0e10cSrcweir //    // 1. Case: Information already available at pRule:
805cdf0e10cSrcweir //    //
806cdf0e10cSrcweir //    if (pRule->GetTxtNodeList())
807cdf0e10cSrcweir //    {
808cdf0e10cSrcweir //        // copy list to own pList pointer:
809cdf0e10cSrcweir //        aList = *pRule->GetTxtNodeList();
810cdf0e10cSrcweir //        return;
811cdf0e10cSrcweir //    }
812cdf0e10cSrcweir 
813cdf0e10cSrcweir //    //
814cdf0e10cSrcweir //    // 2. Case: Information has to be generated from scratch:
815cdf0e10cSrcweir //    //
816cdf0e10cSrcweir 
817cdf0e10cSrcweir //    if (pRule->IsOutlineRule())
818cdf0e10cSrcweir //    {
819cdf0e10cSrcweir //        const SwOutlineNodes & rOutlineNodes = rDoc.GetNodes().GetOutLineNds();
820cdf0e10cSrcweir 
821cdf0e10cSrcweir //        for (sal_uInt16 i = 0; i < rOutlineNodes.Count(); ++i)
822cdf0e10cSrcweir //        {
823cdf0e10cSrcweir //            SwTxtNode & aNode = *((SwTxtNode *) rOutlineNodes[i]);
824cdf0e10cSrcweir 
825cdf0e10cSrcweir //            if (pRule == aNode.GetNumRule())
826cdf0e10cSrcweir //                AddNode(aNode);
827cdf0e10cSrcweir //        }
828cdf0e10cSrcweir //    }
829cdf0e10cSrcweir //    {
830cdf0e10cSrcweir //        SwModify* pMod;
831cdf0e10cSrcweir //        const SfxPoolItem* pItem;
832cdf0e10cSrcweir //        sal_uInt16 i, nMaxItems = rDoc.GetAttrPool().GetItemCount
833cdf0e10cSrcweir //            ( RES_PARATR_NUMRULE);
834cdf0e10cSrcweir //        for( i = 0; i < nMaxItems; ++i )
835cdf0e10cSrcweir //        {
836cdf0e10cSrcweir //            pItem = rDoc.GetAttrPool().GetItem( RES_PARATR_NUMRULE, i );
837cdf0e10cSrcweir //            if( 0 != pItem)
838cdf0e10cSrcweir //            {
839cdf0e10cSrcweir //                pMod = (SwModify*)((SwNumRuleItem*)pItem)->GetDefinedIn();
840cdf0e10cSrcweir //                if (0 != pMod &&
841cdf0e10cSrcweir //                    ((SwNumRuleItem*)pItem)->GetValue().Len() &&
842cdf0e10cSrcweir //                    ((SwNumRuleItem*)pItem)->GetValue() == rName )
843cdf0e10cSrcweir //                {
844cdf0e10cSrcweir //                    if( pMod->IsA( TYPE( SwFmt )) )
845cdf0e10cSrcweir //                        pMod->GetInfo( *this );
846cdf0e10cSrcweir //                    else
847cdf0e10cSrcweir //                    {
848cdf0e10cSrcweir //                        SwTxtNode* pModTxtNode = (SwTxtNode*)pMod;
849cdf0e10cSrcweir 
850cdf0e10cSrcweir //                        // #115901#
851cdf0e10cSrcweir //                        if( pModTxtNode->GetNodes().IsDocNodes())
852cdf0e10cSrcweir //                        {
853cdf0e10cSrcweir //                            AddNode( *pModTxtNode );
854cdf0e10cSrcweir //                        }
855cdf0e10cSrcweir //                    }
856cdf0e10cSrcweir //                }
857cdf0e10cSrcweir //            }
858cdf0e10cSrcweir //        }
859cdf0e10cSrcweir //    }
860cdf0e10cSrcweir 
861cdf0e10cSrcweir //    // --> FME 2004-11-03 #i36571# The numrule and this info structure should
862cdf0e10cSrcweir //    // have different instances of the list:
863cdf0e10cSrcweir //    // --> OD 2006-09-12 #i69145#
864cdf0e10cSrcweir //    // method <SwNumRule::SetList(..)> copies content of list provided by the parameter
865cdf0e10cSrcweir //    pRule->SetTxtNodeList( aList );
866cdf0e10cSrcweir //    // <--
867cdf0e10cSrcweir //}
868cdf0e10cSrcweir // <--
869cdf0e10cSrcweir 
870cdf0e10cSrcweir 
lcl_ChgNumRule(SwDoc & rDoc,const SwNumRule & rRule)87134760e49SOliver-Rainer Wittmann void lcl_ChgNumRule(
87234760e49SOliver-Rainer Wittmann     SwDoc& rDoc,
87334760e49SOliver-Rainer Wittmann     const SwNumRule& rRule )
874cdf0e10cSrcweir {
875cdf0e10cSrcweir     SwNumRule* pOld = rDoc.FindNumRulePtr( rRule.GetName() );
876cdf0e10cSrcweir     ASSERT( pOld, "ohne die alte NumRule geht gar nichts" );
877cdf0e10cSrcweir 
87834760e49SOliver-Rainer Wittmann     sal_uInt16 nChgFmtLevel = 0;
87934760e49SOliver-Rainer Wittmann     sal_uInt16 nMask = 1;
880cdf0e10cSrcweir 
88134760e49SOliver-Rainer Wittmann     for ( sal_uInt8 n = 0; n < MAXLEVEL; ++n, nMask <<= 1 )
882cdf0e10cSrcweir     {
88334760e49SOliver-Rainer Wittmann         const SwNumFmt& rOldFmt = pOld->Get( n ), &rNewFmt = rRule.Get( n );
884cdf0e10cSrcweir 
885cdf0e10cSrcweir         if ( rOldFmt != rNewFmt )
886cdf0e10cSrcweir         {
887cdf0e10cSrcweir             nChgFmtLevel |= nMask;
888cdf0e10cSrcweir         }
88934760e49SOliver-Rainer Wittmann         else if ( SVX_NUM_NUMBER_NONE > rNewFmt.GetNumberingType()
89034760e49SOliver-Rainer Wittmann                   && 1 < rNewFmt.GetIncludeUpperLevels()
89134760e49SOliver-Rainer Wittmann                   && 0 != ( nChgFmtLevel & GetUpperLvlChg( n, rNewFmt.GetIncludeUpperLevels(), nMask ) ) )
89234760e49SOliver-Rainer Wittmann         {
893cdf0e10cSrcweir             nChgFmtLevel |= nMask;
894cdf0e10cSrcweir         }
89534760e49SOliver-Rainer Wittmann     }
896cdf0e10cSrcweir 
897cdf0e10cSrcweir     if( !nChgFmtLevel )         // es wurde nichts veraendert?
898cdf0e10cSrcweir     {
899cdf0e10cSrcweir         const bool bInvalidateNumRule( pOld->IsContinusNum() != rRule.IsContinusNum() );
900cdf0e10cSrcweir         pOld->CheckCharFmts( &rDoc );
901cdf0e10cSrcweir         pOld->SetContinusNum( rRule.IsContinusNum() );
902cdf0e10cSrcweir         if ( bInvalidateNumRule )
903cdf0e10cSrcweir         {
904cdf0e10cSrcweir             pOld->SetInvalidRule(sal_True);
905cdf0e10cSrcweir         }
906cdf0e10cSrcweir         return ;
907cdf0e10cSrcweir     }
908cdf0e10cSrcweir 
909cdf0e10cSrcweir     SwNumRule::tTxtNodeList aTxtNodeList;
910cdf0e10cSrcweir     pOld->GetTxtNodeList( aTxtNodeList );
911cdf0e10cSrcweir     sal_uInt8 nLvl( 0 );
912cdf0e10cSrcweir     for ( SwNumRule::tTxtNodeList::iterator aIter = aTxtNodeList.begin();
913cdf0e10cSrcweir           aIter != aTxtNodeList.end(); ++aIter )
914cdf0e10cSrcweir     {
915cdf0e10cSrcweir         SwTxtNode* pTxtNd = *aIter;
916cdf0e10cSrcweir         nLvl = static_cast<sal_uInt8>(pTxtNd->GetActualListLevel());
917cdf0e10cSrcweir 
918cdf0e10cSrcweir         if( nLvl < MAXLEVEL )
919cdf0e10cSrcweir         {
920cdf0e10cSrcweir             if( nChgFmtLevel & ( 1 << nLvl ))
921cdf0e10cSrcweir             {
922cdf0e10cSrcweir                 pTxtNd->NumRuleChgd();
923cdf0e10cSrcweir             }
924cdf0e10cSrcweir         }
925cdf0e10cSrcweir     }
926cdf0e10cSrcweir 
92734760e49SOliver-Rainer Wittmann     for ( sal_uInt8 n = 0; n < MAXLEVEL; ++n )
928cdf0e10cSrcweir         if ( nChgFmtLevel & ( 1 << n ) )
929cdf0e10cSrcweir             pOld->Set( n, rRule.GetNumFmt( n ) );
930cdf0e10cSrcweir 
931cdf0e10cSrcweir     pOld->CheckCharFmts( &rDoc );
932cdf0e10cSrcweir     pOld->SetInvalidRule( sal_True );
933cdf0e10cSrcweir     pOld->SetContinusNum( rRule.IsContinusNum() );
934cdf0e10cSrcweir 
935cdf0e10cSrcweir     rDoc.UpdateNumRule();
936cdf0e10cSrcweir }
937cdf0e10cSrcweir 
93834760e49SOliver-Rainer Wittmann 
SetNumRule(const SwPaM & rPam,const SwNumRule & rRule,const bool bCreateNewList,const String sContinuedListId,bool bSetItem,const bool bResetIndentAttrs)939cdf0e10cSrcweir void SwDoc::SetNumRule( const SwPaM& rPam,
940cdf0e10cSrcweir                         const SwNumRule& rRule,
941cdf0e10cSrcweir                         const bool bCreateNewList,
942cdf0e10cSrcweir                         const String sContinuedListId,
94334760e49SOliver-Rainer Wittmann                         bool bSetItem,
944cdf0e10cSrcweir                         const bool bResetIndentAttrs )
945cdf0e10cSrcweir {
946cdf0e10cSrcweir     SwUndoInsNum * pUndo = NULL;
947cdf0e10cSrcweir     if (GetIDocumentUndoRedo().DoesUndo())
948cdf0e10cSrcweir     {
949cdf0e10cSrcweir         // Start/End for attributes!
950cdf0e10cSrcweir         GetIDocumentUndoRedo().StartUndo( UNDO_INSNUM, NULL );
951cdf0e10cSrcweir         pUndo = new SwUndoInsNum( rPam, rRule );
952cdf0e10cSrcweir         GetIDocumentUndoRedo().AppendUndo(pUndo);
953cdf0e10cSrcweir     }
954cdf0e10cSrcweir 
95534760e49SOliver-Rainer Wittmann     SwNumRule* pNewOrChangedNumRule = FindNumRulePtr( rRule.GetName() );
95634760e49SOliver-Rainer Wittmann     bool bNewNumRuleCreated = false;
95734760e49SOliver-Rainer Wittmann     if ( pNewOrChangedNumRule == NULL )
958cdf0e10cSrcweir     {
95934760e49SOliver-Rainer Wittmann         // create new numbering rule based on given one
96034760e49SOliver-Rainer Wittmann         pNewOrChangedNumRule = ( *pNumRuleTbl )[MakeNumRule( rRule.GetName(), &rRule )];
96134760e49SOliver-Rainer Wittmann         bNewNumRuleCreated = true;
962cdf0e10cSrcweir     }
96334760e49SOliver-Rainer Wittmann     else if ( rRule != *pNewOrChangedNumRule )
964cdf0e10cSrcweir     {
96534760e49SOliver-Rainer Wittmann         // change existing numbering rule
96634760e49SOliver-Rainer Wittmann         if( pUndo != NULL )
96734760e49SOliver-Rainer Wittmann         {
96834760e49SOliver-Rainer Wittmann             pUndo->SaveOldNumRule( *pNewOrChangedNumRule );
969cdf0e10cSrcweir         }
970cdf0e10cSrcweir         ::lcl_ChgNumRule( *this, rRule );
97134760e49SOliver-Rainer Wittmann         if( pUndo != NULL )
97234760e49SOliver-Rainer Wittmann         {
973cdf0e10cSrcweir             pUndo->SetLRSpaceEndPos();
974cdf0e10cSrcweir         }
975cdf0e10cSrcweir     }
976cdf0e10cSrcweir 
977cdf0e10cSrcweir     if ( bSetItem )
978cdf0e10cSrcweir     {
97934760e49SOliver-Rainer Wittmann         String sListId;
980cdf0e10cSrcweir         if ( bCreateNewList )
981cdf0e10cSrcweir         {
98234760e49SOliver-Rainer Wittmann             if ( bNewNumRuleCreated )
983cdf0e10cSrcweir             {
984cdf0e10cSrcweir                 // apply list id of list, which has been created for the new list style
98534760e49SOliver-Rainer Wittmann                 sListId = pNewOrChangedNumRule->GetDefaultListId();
986cdf0e10cSrcweir             }
987cdf0e10cSrcweir             else
988cdf0e10cSrcweir             {
989cdf0e10cSrcweir                 // create new list and apply its list id
99034760e49SOliver-Rainer Wittmann                 const SwList* pNewList = createList( String(), pNewOrChangedNumRule->GetName() );
991cdf0e10cSrcweir                 ASSERT( pNewList,
992cdf0e10cSrcweir                         "<SwDoc::SetNumRule(..)> - could not create new list. Serious defect -> please inform OD." );
993cdf0e10cSrcweir                 sListId = pNewList->GetListId();
994cdf0e10cSrcweir             }
995cdf0e10cSrcweir         }
996cdf0e10cSrcweir         else if ( sContinuedListId.Len() > 0 )
997cdf0e10cSrcweir         {
998cdf0e10cSrcweir             // apply given list id
99934760e49SOliver-Rainer Wittmann             sListId = sContinuedListId;
100034760e49SOliver-Rainer Wittmann         }
100134760e49SOliver-Rainer Wittmann         if ( sListId.Len() > 0 )
100234760e49SOliver-Rainer Wittmann         {
100334760e49SOliver-Rainer Wittmann             InsertPoolItem( rPam, SfxStringItem( RES_PARATR_LIST_ID, sListId ), 0 );
1004cdf0e10cSrcweir         }
1005cdf0e10cSrcweir     }
1006cdf0e10cSrcweir 
1007cdf0e10cSrcweir     if ( !rPam.HasMark() )
1008cdf0e10cSrcweir     {
1009cdf0e10cSrcweir         SwTxtNode * pTxtNd = rPam.GetPoint()->nNode.GetNode().GetTxtNode();
101034760e49SOliver-Rainer Wittmann         // robust code: consider case that the PaM doesn't denote a text node - e.g. it denotes a graphic node
101134760e49SOliver-Rainer Wittmann         if ( pTxtNd != NULL )
1012cdf0e10cSrcweir         {
1013cdf0e10cSrcweir             SwNumRule * pRule = pTxtNd->GetNumRule();
1014cdf0e10cSrcweir 
101534760e49SOliver-Rainer Wittmann             if (pRule && pRule->GetName() == pNewOrChangedNumRule->GetName())
1016cdf0e10cSrcweir             {
101734760e49SOliver-Rainer Wittmann                 bSetItem = false;
1018cdf0e10cSrcweir                 if ( !pTxtNd->IsInList() )
1019cdf0e10cSrcweir                 {
1020cdf0e10cSrcweir                     pTxtNd->AddToList();
1021cdf0e10cSrcweir                 }
1022cdf0e10cSrcweir             }
102369a74367SOliver-Rainer Wittmann             // only clear numbering attribute at text node,
102469a74367SOliver-Rainer Wittmann             // if at paragraph style the new numbering rule is found.
1025cdf0e10cSrcweir             else if ( !pRule )
1026cdf0e10cSrcweir             {
1027cdf0e10cSrcweir                 SwTxtFmtColl* pColl = pTxtNd->GetTxtColl();
1028cdf0e10cSrcweir                 if ( pColl )
1029cdf0e10cSrcweir                 {
1030cdf0e10cSrcweir                     SwNumRule* pCollRule = FindNumRulePtr(pColl->GetNumRule().GetValue());
103134760e49SOliver-Rainer Wittmann                     if ( pCollRule && pCollRule->GetName() == pNewOrChangedNumRule->GetName() )
1032cdf0e10cSrcweir                     {
1033cdf0e10cSrcweir                         pTxtNd->ResetAttr( RES_PARATR_NUMRULE );
103434760e49SOliver-Rainer Wittmann                         bSetItem = false;
1035cdf0e10cSrcweir                     }
1036cdf0e10cSrcweir                 }
1037cdf0e10cSrcweir             }
1038cdf0e10cSrcweir         }
1039cdf0e10cSrcweir     }
1040cdf0e10cSrcweir 
1041cdf0e10cSrcweir     if ( bSetItem )
1042cdf0e10cSrcweir     {
104334760e49SOliver-Rainer Wittmann         InsertPoolItem( rPam, SwNumRuleItem( pNewOrChangedNumRule->GetName() ), 0 );
1044cdf0e10cSrcweir     }
1045cdf0e10cSrcweir 
104634760e49SOliver-Rainer Wittmann     if ( bResetIndentAttrs
104734760e49SOliver-Rainer Wittmann          && pNewOrChangedNumRule->Get( 0 ).GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
1048cdf0e10cSrcweir     {
1049cdf0e10cSrcweir         SvUShortsSort aResetAttrsArray;
1050cdf0e10cSrcweir         aResetAttrsArray.Insert( RES_LR_SPACE );
1051cdf0e10cSrcweir         // On a selection setup a corresponding Point-and-Mark in order to get
1052cdf0e10cSrcweir         // the indentation attribute reset on all paragraphs touched by the selection
1053cdf0e10cSrcweir         if ( rPam.HasMark() &&
1054cdf0e10cSrcweir              rPam.End()->nNode.GetNode().GetTxtNode() )
1055cdf0e10cSrcweir         {
1056cdf0e10cSrcweir             SwPaM aPam( rPam.Start()->nNode,
1057cdf0e10cSrcweir                         rPam.End()->nNode );
1058cdf0e10cSrcweir             aPam.Start()->nContent = 0;
1059cdf0e10cSrcweir             aPam.End()->nContent = rPam.End()->nNode.GetNode().GetTxtNode()->Len();
1060cdf0e10cSrcweir             ResetAttrs( aPam, sal_False, &aResetAttrsArray );
1061cdf0e10cSrcweir         }
1062cdf0e10cSrcweir         else
1063cdf0e10cSrcweir         {
1064cdf0e10cSrcweir             ResetAttrs( rPam, sal_False, &aResetAttrsArray );
1065cdf0e10cSrcweir         }
1066cdf0e10cSrcweir     }
1067cdf0e10cSrcweir 
1068cdf0e10cSrcweir     if (GetIDocumentUndoRedo().DoesUndo())
1069cdf0e10cSrcweir     {
1070cdf0e10cSrcweir         GetIDocumentUndoRedo().EndUndo( UNDO_INSNUM, NULL );
1071cdf0e10cSrcweir     }
1072cdf0e10cSrcweir 
1073cdf0e10cSrcweir     SetModified();
1074cdf0e10cSrcweir }
1075cdf0e10cSrcweir 
107634760e49SOliver-Rainer Wittmann 
SetCounted(const SwPaM & rPam,bool bCounted)1077cdf0e10cSrcweir void SwDoc::SetCounted(const SwPaM & rPam, bool bCounted)
1078cdf0e10cSrcweir {
1079cdf0e10cSrcweir     if ( bCounted )
1080cdf0e10cSrcweir     {
1081cdf0e10cSrcweir         SvUShortsSort aResetAttrsArray;
1082cdf0e10cSrcweir         aResetAttrsArray.Insert( RES_PARATR_LIST_ISCOUNTED );
1083cdf0e10cSrcweir         // On a selection setup a corresponding Point-and-Mark in order to get
1084cdf0e10cSrcweir         // the list-is-counted attribute reset on all paragraphs touched by the selection
1085cdf0e10cSrcweir         if ( rPam.HasMark() &&
1086cdf0e10cSrcweir              rPam.End()->nNode.GetNode().GetTxtNode() )
1087cdf0e10cSrcweir         {
1088cdf0e10cSrcweir             SwPaM aPam( rPam.Start()->nNode,
1089cdf0e10cSrcweir                         rPam.End()->nNode );
1090cdf0e10cSrcweir             aPam.Start()->nContent = 0;
1091cdf0e10cSrcweir             aPam.End()->nContent = rPam.End()->nNode.GetNode().GetTxtNode()->Len();
1092cdf0e10cSrcweir             ResetAttrs( aPam, sal_False, &aResetAttrsArray );
1093cdf0e10cSrcweir         }
1094cdf0e10cSrcweir         else
1095cdf0e10cSrcweir         {
1096cdf0e10cSrcweir             ResetAttrs( rPam, sal_False, &aResetAttrsArray );
1097cdf0e10cSrcweir         }
1098cdf0e10cSrcweir     }
1099cdf0e10cSrcweir     else
1100cdf0e10cSrcweir     {
110169a74367SOliver-Rainer Wittmann         InsertPoolItem( rPam, SfxBoolItem( RES_PARATR_LIST_ISCOUNTED, sal_False ), 0 );
1102cdf0e10cSrcweir     }
1103cdf0e10cSrcweir }
1104cdf0e10cSrcweir 
SetNumRuleStart(const SwPosition & rPos,sal_Bool bFlag)1105cdf0e10cSrcweir void SwDoc::SetNumRuleStart( const SwPosition& rPos, sal_Bool bFlag )
1106cdf0e10cSrcweir {
1107cdf0e10cSrcweir     SwTxtNode* pTxtNd = rPos.nNode.GetNode().GetTxtNode();
1108cdf0e10cSrcweir 
1109cdf0e10cSrcweir     if (pTxtNd)
1110cdf0e10cSrcweir     {
1111cdf0e10cSrcweir         const SwNumRule* pRule = pTxtNd->GetNumRule();
1112cdf0e10cSrcweir         if( pRule && !bFlag != !pTxtNd->IsListRestart())
1113cdf0e10cSrcweir         {
1114cdf0e10cSrcweir             if (GetIDocumentUndoRedo().DoesUndo())
1115cdf0e10cSrcweir             {
1116cdf0e10cSrcweir                 SwUndo *const pUndo( new SwUndoNumRuleStart(rPos, bFlag) );
1117cdf0e10cSrcweir                 GetIDocumentUndoRedo().AppendUndo(pUndo);
1118cdf0e10cSrcweir             }
1119cdf0e10cSrcweir 
1120cdf0e10cSrcweir             pTxtNd->SetListRestart(bFlag ? true : false);
1121cdf0e10cSrcweir 
1122cdf0e10cSrcweir             SetModified();
1123cdf0e10cSrcweir         }
1124cdf0e10cSrcweir     }
1125cdf0e10cSrcweir }
1126cdf0e10cSrcweir 
SetNodeNumStart(const SwPosition & rPos,sal_uInt16 nStt)1127cdf0e10cSrcweir void SwDoc::SetNodeNumStart( const SwPosition& rPos, sal_uInt16 nStt )
1128cdf0e10cSrcweir {
1129cdf0e10cSrcweir     SwTxtNode* pTxtNd = rPos.nNode.GetNode().GetTxtNode();
1130cdf0e10cSrcweir 
1131cdf0e10cSrcweir     if (pTxtNd)
1132cdf0e10cSrcweir     {
1133cdf0e10cSrcweir         // --> OD 2008-02-27 #refactorlists#
1134cdf0e10cSrcweir //        const SwNumRule* pRule = pTxtNd->GetNumRule();
1135cdf0e10cSrcweir //        if( pRule && nStt != pTxtNd->GetListRestartValue() )
1136cdf0e10cSrcweir //        {
1137cdf0e10cSrcweir //            if( DoesUndo() )
1138cdf0e10cSrcweir //            {
1139cdf0e10cSrcweir //                ClearRedo();
1140cdf0e10cSrcweir //                AppendUndo( new SwUndoNumRuleStart( rPos, nStt ));
1141cdf0e10cSrcweir //            }
1142cdf0e10cSrcweir //        }
1143cdf0e10cSrcweir //        pTxtNd->SetListRestartValue(nStt);
1144cdf0e10cSrcweir 
1145cdf0e10cSrcweir //        SetModified();
1146cdf0e10cSrcweir         if ( !pTxtNd->HasAttrListRestartValue() ||
1147cdf0e10cSrcweir              pTxtNd->GetAttrListRestartValue() != nStt )
1148cdf0e10cSrcweir         {
1149cdf0e10cSrcweir             if (GetIDocumentUndoRedo().DoesUndo())
1150cdf0e10cSrcweir             {
1151cdf0e10cSrcweir                 SwUndo *const pUndo( new SwUndoNumRuleStart(rPos, nStt) );
1152cdf0e10cSrcweir                 GetIDocumentUndoRedo().AppendUndo(pUndo);
1153cdf0e10cSrcweir             }
1154cdf0e10cSrcweir             pTxtNd->SetAttrListRestartValue( nStt );
1155cdf0e10cSrcweir 
1156cdf0e10cSrcweir             SetModified();
1157cdf0e10cSrcweir         }
1158cdf0e10cSrcweir         // <--
1159cdf0e10cSrcweir     }
1160cdf0e10cSrcweir }
1161cdf0e10cSrcweir 
1162cdf0e10cSrcweir     // loeschen geht nur, wenn die Rule niemand benutzt!
DelNumRule(const String & rName,sal_Bool bBroadcast)1163cdf0e10cSrcweir sal_Bool SwDoc::DelNumRule( const String& rName, sal_Bool bBroadcast )
1164cdf0e10cSrcweir {
1165cdf0e10cSrcweir     sal_uInt16 nPos = FindNumRule( rName );
1166cdf0e10cSrcweir 
1167cdf0e10cSrcweir     // --> OD 2007-12-17 #151213#
1168cdf0e10cSrcweir     if ( (*pNumRuleTbl)[ nPos ] == GetOutlineNumRule() )
1169cdf0e10cSrcweir     {
1170cdf0e10cSrcweir         ASSERT( false,
1171cdf0e10cSrcweir                 "<SwDoc::DelNumRule(..)> - No deletion of outline list style. This is serious defect - please inform OD" );
1172cdf0e10cSrcweir         return sal_False;
1173cdf0e10cSrcweir     }
1174cdf0e10cSrcweir     // <--
1175cdf0e10cSrcweir 
1176cdf0e10cSrcweir     if( USHRT_MAX != nPos && !IsUsed( *(*pNumRuleTbl)[ nPos ] ))
1177cdf0e10cSrcweir     {
1178cdf0e10cSrcweir         if (GetIDocumentUndoRedo().DoesUndo())
1179cdf0e10cSrcweir         {
1180cdf0e10cSrcweir             SwUndo * pUndo =
1181cdf0e10cSrcweir                 new SwUndoNumruleDelete(*(*pNumRuleTbl)[nPos], this);
1182cdf0e10cSrcweir             GetIDocumentUndoRedo().AppendUndo(pUndo);
1183cdf0e10cSrcweir         }
1184cdf0e10cSrcweir 
1185cdf0e10cSrcweir         if (bBroadcast)
1186cdf0e10cSrcweir             BroadcastStyleOperation(rName, SFX_STYLE_FAMILY_PSEUDO,
1187cdf0e10cSrcweir                                     SFX_STYLESHEET_ERASED);
1188cdf0e10cSrcweir 
1189cdf0e10cSrcweir         // --> OD 2008-04-02 #refactorlists#
1190cdf0e10cSrcweir         deleteListForListStyle( rName );
1191cdf0e10cSrcweir         {
1192cdf0e10cSrcweir             // delete further list, which have the deleted list style as default list style
1193cdf0e10cSrcweir             std::vector< SwList* > aListsForDeletion;
1194cdf0e10cSrcweir             tHashMapForLists::iterator aListIter = maLists.begin();
1195cdf0e10cSrcweir             while ( aListIter != maLists.end() )
1196cdf0e10cSrcweir             {
1197cdf0e10cSrcweir                 SwList* pList = (*aListIter).second;
1198cdf0e10cSrcweir                 if ( pList->GetDefaultListStyleName() == rName )
1199cdf0e10cSrcweir                 {
1200cdf0e10cSrcweir                     aListsForDeletion.push_back( pList );
1201cdf0e10cSrcweir                 }
1202cdf0e10cSrcweir 
1203cdf0e10cSrcweir                 ++aListIter;
1204cdf0e10cSrcweir             }
1205cdf0e10cSrcweir             while ( aListsForDeletion.size() > 0 )
1206cdf0e10cSrcweir             {
1207cdf0e10cSrcweir                 SwList* pList = aListsForDeletion.back();
1208cdf0e10cSrcweir                 aListsForDeletion.pop_back();
1209cdf0e10cSrcweir                 deleteList( pList->GetListId() );
1210cdf0e10cSrcweir             }
1211cdf0e10cSrcweir         }
1212cdf0e10cSrcweir         // <--
1213cdf0e10cSrcweir         // --> FME 2004-11-02 #i34097# DeleteAndDestroy deletes rName if
1214cdf0e10cSrcweir         // rName is directly taken from the numrule.
1215cdf0e10cSrcweir         const String aTmpName( rName );
1216cdf0e10cSrcweir         // <--
1217cdf0e10cSrcweir         pNumRuleTbl->DeleteAndDestroy( nPos );
1218cdf0e10cSrcweir         maNumRuleMap.erase(aTmpName);
1219cdf0e10cSrcweir 
1220cdf0e10cSrcweir         SetModified();
1221cdf0e10cSrcweir         return sal_True;
1222cdf0e10cSrcweir     }
1223cdf0e10cSrcweir     return sal_False;
1224cdf0e10cSrcweir }
1225cdf0e10cSrcweir 
1226cdf0e10cSrcweir // #106897#
ChgNumRuleFmts(const SwNumRule & rRule,const String * pName)1227cdf0e10cSrcweir void SwDoc::ChgNumRuleFmts( const SwNumRule& rRule, const String * pName )
1228cdf0e10cSrcweir {
1229cdf0e10cSrcweir     // #106897#
1230cdf0e10cSrcweir     SwNumRule* pRule = FindNumRulePtr( pName ? *pName : rRule.GetName() );
1231cdf0e10cSrcweir     if( pRule )
1232cdf0e10cSrcweir     {
1233cdf0e10cSrcweir         SwUndoInsNum* pUndo = 0;
1234cdf0e10cSrcweir         if (GetIDocumentUndoRedo().DoesUndo())
1235cdf0e10cSrcweir         {
1236cdf0e10cSrcweir             pUndo = new SwUndoInsNum( *pRule, rRule );
1237cdf0e10cSrcweir             pUndo->GetHistory();
1238cdf0e10cSrcweir             GetIDocumentUndoRedo().AppendUndo( pUndo );
1239cdf0e10cSrcweir         }
1240cdf0e10cSrcweir         ::lcl_ChgNumRule( *this, rRule );
1241cdf0e10cSrcweir 
1242cdf0e10cSrcweir         if( pUndo )
1243cdf0e10cSrcweir             pUndo->SetLRSpaceEndPos();
1244cdf0e10cSrcweir 
1245cdf0e10cSrcweir         SetModified();
1246cdf0e10cSrcweir     }
1247cdf0e10cSrcweir }
1248cdf0e10cSrcweir 
RenameNumRule(const String & rOldName,const String & rNewName,sal_Bool bBroadcast)1249cdf0e10cSrcweir sal_Bool SwDoc::RenameNumRule(const String & rOldName, const String & rNewName,
1250cdf0e10cSrcweir                               sal_Bool bBroadcast)
1251cdf0e10cSrcweir {
1252cdf0e10cSrcweir     sal_Bool bResult = sal_False;
1253cdf0e10cSrcweir     SwNumRule * pNumRule = FindNumRulePtr(rOldName);
1254cdf0e10cSrcweir 
1255cdf0e10cSrcweir     if (pNumRule)
1256cdf0e10cSrcweir     {
1257cdf0e10cSrcweir         if (GetIDocumentUndoRedo().DoesUndo())
1258cdf0e10cSrcweir         {
1259cdf0e10cSrcweir             SwUndo * pUndo = new SwUndoNumruleRename(rOldName, rNewName, this);
1260cdf0e10cSrcweir             GetIDocumentUndoRedo().AppendUndo(pUndo);
1261cdf0e10cSrcweir         }
1262cdf0e10cSrcweir 
1263cdf0e10cSrcweir         // --> OD 2008-02-19 #refactorlists#
1264cdf0e10cSrcweir //        SwNumRuleInfo aInfo(rOldName);
1265cdf0e10cSrcweir //        aInfo.MakeList(*this);
1266cdf0e10cSrcweir         SwNumRule::tTxtNodeList aTxtNodeList;
1267cdf0e10cSrcweir         pNumRule->GetTxtNodeList( aTxtNodeList );
1268cdf0e10cSrcweir         // <--
1269cdf0e10cSrcweir 
1270cdf0e10cSrcweir         // --> OD 2008-07-08 #i91400#
1271cdf0e10cSrcweir         pNumRule->SetName( rNewName, *this );
1272cdf0e10cSrcweir         // <--
1273cdf0e10cSrcweir 
1274cdf0e10cSrcweir         SwNumRuleItem aItem(rNewName);
1275cdf0e10cSrcweir         // --> OD 2008-02-19 #refactorlists#
1276cdf0e10cSrcweir //        for (sal_uLong nI = 0; nI < aInfo.GetList().Count(); ++nI)
1277cdf0e10cSrcweir //        {
1278cdf0e10cSrcweir //            SwTxtNode * pTxtNd = aInfo.GetList().GetObject(nI);
1279cdf0e10cSrcweir //            pTxtNd->SwCntntNode::SetAttr(aItem);
1280cdf0e10cSrcweir //        }
1281cdf0e10cSrcweir         for ( SwNumRule::tTxtNodeList::iterator aIter = aTxtNodeList.begin();
1282cdf0e10cSrcweir               aIter != aTxtNodeList.end(); ++aIter )
1283cdf0e10cSrcweir         {
1284cdf0e10cSrcweir             SwTxtNode * pTxtNd = *aIter;
1285cdf0e10cSrcweir             pTxtNd->SetAttr(aItem);
1286cdf0e10cSrcweir         }
1287cdf0e10cSrcweir         // <--
1288cdf0e10cSrcweir 
1289cdf0e10cSrcweir         bResult = sal_True;
1290cdf0e10cSrcweir 
1291cdf0e10cSrcweir         if (bBroadcast)
1292cdf0e10cSrcweir             BroadcastStyleOperation(rOldName, SFX_STYLE_FAMILY_PSEUDO,
1293cdf0e10cSrcweir                                     SFX_STYLESHEET_MODIFIED);
1294cdf0e10cSrcweir     }
1295cdf0e10cSrcweir 
1296cdf0e10cSrcweir     return bResult;
1297cdf0e10cSrcweir }
1298cdf0e10cSrcweir 
StopNumRuleAnimations(OutputDevice * pOut)1299cdf0e10cSrcweir void SwDoc::StopNumRuleAnimations( OutputDevice* pOut )
1300cdf0e10cSrcweir {
1301cdf0e10cSrcweir     for( sal_uInt16 n = GetNumRuleTbl().Count(); n; )
1302cdf0e10cSrcweir     {
1303cdf0e10cSrcweir         SwNumRule::tTxtNodeList aTxtNodeList;
1304cdf0e10cSrcweir         GetNumRuleTbl()[ --n ]->GetTxtNodeList( aTxtNodeList );
1305cdf0e10cSrcweir         for ( SwNumRule::tTxtNodeList::iterator aTxtNodeIter = aTxtNodeList.begin();
1306cdf0e10cSrcweir               aTxtNodeIter != aTxtNodeList.end(); ++aTxtNodeIter )
1307cdf0e10cSrcweir         {
1308cdf0e10cSrcweir             SwTxtNode* pTNd = *aTxtNodeIter;
1309cdf0e10cSrcweir             SwIterator<SwTxtFrm,SwTxtNode> aIter(*pTNd);
1310cdf0e10cSrcweir             for(SwTxtFrm* pFrm = aIter.First(); pFrm; pFrm = aIter.Next() )
1311cdf0e10cSrcweir                 if( pFrm->HasAnimation() )
1312cdf0e10cSrcweir                     pFrm->StopAnimation( pOut );
1313cdf0e10cSrcweir         }
1314cdf0e10cSrcweir     }
1315cdf0e10cSrcweir }
1316cdf0e10cSrcweir 
ReplaceNumRule(const SwPosition & rPos,const String & rOldRule,const String & rNewRule)131734760e49SOliver-Rainer Wittmann sal_Bool SwDoc::ReplaceNumRule(
131834760e49SOliver-Rainer Wittmann     const SwPosition& rPos,
131934760e49SOliver-Rainer Wittmann     const String& rOldRule,
132034760e49SOliver-Rainer Wittmann     const String& rNewRule )
1321cdf0e10cSrcweir {
1322cdf0e10cSrcweir     sal_Bool bRet = sal_False;
132334760e49SOliver-Rainer Wittmann     SwNumRule* pOldRule = FindNumRulePtr( rOldRule );
132434760e49SOliver-Rainer Wittmann     SwNumRule* pNewRule = FindNumRulePtr( rNewRule );
132534760e49SOliver-Rainer Wittmann     if ( pOldRule != NULL
132634760e49SOliver-Rainer Wittmann          && pNewRule != NULL
132734760e49SOliver-Rainer Wittmann          && pOldRule != pNewRule )
1328cdf0e10cSrcweir     {
1329cdf0e10cSrcweir         SwUndoInsNum* pUndo = 0;
1330cdf0e10cSrcweir         if (GetIDocumentUndoRedo().DoesUndo())
1331cdf0e10cSrcweir         {
1332cdf0e10cSrcweir             // Start/End for attributes!
1333cdf0e10cSrcweir             GetIDocumentUndoRedo().StartUndo( UNDO_START, NULL );
1334cdf0e10cSrcweir             pUndo = new SwUndoInsNum( rPos, *pNewRule, rOldRule );
1335cdf0e10cSrcweir             GetIDocumentUndoRedo().AppendUndo(pUndo);
1336cdf0e10cSrcweir         }
1337cdf0e10cSrcweir 
1338cdf0e10cSrcweir         SwNumRule::tTxtNodeList aTxtNodeList;
1339cdf0e10cSrcweir         pOldRule->GetTxtNodeList( aTxtNodeList );
1340cdf0e10cSrcweir         if ( aTxtNodeList.size() > 0 )
1341cdf0e10cSrcweir         {
1342cdf0e10cSrcweir             SwRegHistory aRegH( pUndo ? pUndo->GetHistory() : 0 );
1343cdf0e10cSrcweir             sal_uInt16 nChgFmtLevel = 0;
1344cdf0e10cSrcweir             for( sal_uInt8 n = 0; n < MAXLEVEL; ++n )
1345cdf0e10cSrcweir             {
1346cdf0e10cSrcweir                 const SwNumFmt& rOldFmt = pOldRule->Get( n ),
1347cdf0e10cSrcweir                     & rNewFmt = pNewRule->Get( n );
1348cdf0e10cSrcweir 
1349cdf0e10cSrcweir                 if( rOldFmt.GetAbsLSpace() != rNewFmt.GetAbsLSpace() ||
1350cdf0e10cSrcweir                     rOldFmt.GetFirstLineOffset() != rNewFmt.GetFirstLineOffset() )
1351cdf0e10cSrcweir                     nChgFmtLevel |= ( 1 << n );
1352cdf0e10cSrcweir             }
1353cdf0e10cSrcweir 
1354cdf0e10cSrcweir             const SwTxtNode* pGivenTxtNode = rPos.nNode.GetNode().GetTxtNode();
1355cdf0e10cSrcweir             SwNumRuleItem aRule( rNewRule );
1356cdf0e10cSrcweir             for ( SwNumRule::tTxtNodeList::iterator aIter = aTxtNodeList.begin();
1357cdf0e10cSrcweir                   aIter != aTxtNodeList.end(); ++aIter )
1358cdf0e10cSrcweir             {
1359cdf0e10cSrcweir                 SwTxtNode* pTxtNd = *aIter;
1360cdf0e10cSrcweir 
1361cdf0e10cSrcweir                 if ( pGivenTxtNode &&
1362cdf0e10cSrcweir                      pGivenTxtNode->GetListId() == pTxtNd->GetListId() )
1363cdf0e10cSrcweir                 {
1364cdf0e10cSrcweir                     aRegH.RegisterInModify( pTxtNd, *pTxtNd );
1365cdf0e10cSrcweir 
1366cdf0e10cSrcweir                     pTxtNd->SetAttr( aRule );
1367cdf0e10cSrcweir                     pTxtNd->NumRuleChgd();
1368cdf0e10cSrcweir                 }
1369cdf0e10cSrcweir             }
1370cdf0e10cSrcweir             GetIDocumentUndoRedo().EndUndo( UNDO_END, NULL );
1371cdf0e10cSrcweir             SetModified();
1372cdf0e10cSrcweir 
1373cdf0e10cSrcweir             bRet = sal_True;     // #106897#
1374cdf0e10cSrcweir         }
1375cdf0e10cSrcweir     }
1376cdf0e10cSrcweir 
1377cdf0e10cSrcweir     return bRet;
1378cdf0e10cSrcweir }
1379cdf0e10cSrcweir 
138034760e49SOliver-Rainer Wittmann 
1381cdf0e10cSrcweir namespace
1382cdf0e10cSrcweir {
1383cdf0e10cSrcweir     struct ListStyleData
1384cdf0e10cSrcweir     {
1385cdf0e10cSrcweir         SwNumRule* pReplaceNumRule;
1386cdf0e10cSrcweir         bool bCreateNewList;
1387cdf0e10cSrcweir         String sListId;
1388cdf0e10cSrcweir 
ListStyleData__anonbc585d730111::ListStyleData1389cdf0e10cSrcweir         ListStyleData()
1390cdf0e10cSrcweir             : pReplaceNumRule( 0 ),
1391cdf0e10cSrcweir               bCreateNewList( false ),
1392cdf0e10cSrcweir               sListId()
1393cdf0e10cSrcweir         {}
1394cdf0e10cSrcweir     };
1395cdf0e10cSrcweir }
1396cdf0e10cSrcweir 
MakeUniqueNumRules(const SwPaM & rPaM)1397cdf0e10cSrcweir void SwDoc::MakeUniqueNumRules(const SwPaM & rPaM)
1398cdf0e10cSrcweir {
1399cdf0e10cSrcweir     ASSERT( rPaM.GetDoc() == this, "need same doc" );
1400cdf0e10cSrcweir 
1401cdf0e10cSrcweir     ::std::map<SwNumRule *, ListStyleData> aMyNumRuleMap;
1402cdf0e10cSrcweir 
1403cdf0e10cSrcweir     bool bFirst = true;
1404cdf0e10cSrcweir 
140534760e49SOliver-Rainer Wittmann     const sal_uLong nStt = rPaM.Start()->nNode.GetIndex();
140634760e49SOliver-Rainer Wittmann     const sal_uLong nEnd = rPaM.End()->nNode.GetIndex();
1407cdf0e10cSrcweir     for (sal_uLong n = nStt; n <= nEnd; n++)
1408cdf0e10cSrcweir     {
1409cdf0e10cSrcweir         SwTxtNode * pCNd = GetNodes()[n]->GetTxtNode();
1410cdf0e10cSrcweir 
1411cdf0e10cSrcweir         if (pCNd)
1412cdf0e10cSrcweir         {
1413cdf0e10cSrcweir             SwNumRule * pRule = pCNd->GetNumRule();
1414cdf0e10cSrcweir 
1415cdf0e10cSrcweir             if (pRule && pRule->IsAutoRule() && ! pRule->IsOutlineRule())
1416cdf0e10cSrcweir             {
1417cdf0e10cSrcweir                 ListStyleData aListStyleData = aMyNumRuleMap[pRule];
1418cdf0e10cSrcweir 
1419cdf0e10cSrcweir                 if ( aListStyleData.pReplaceNumRule == 0 )
1420cdf0e10cSrcweir                 {
1421cdf0e10cSrcweir                     if (bFirst)
1422cdf0e10cSrcweir                     {
1423cdf0e10cSrcweir                         SwPosition aPos(*pCNd);
1424cdf0e10cSrcweir                         aListStyleData.pReplaceNumRule =
1425cdf0e10cSrcweir                             const_cast<SwNumRule *>
1426cdf0e10cSrcweir                             (SearchNumRule( aPos, false, pCNd->HasNumber(),
1427cdf0e10cSrcweir                                             false, 0,
1428cdf0e10cSrcweir                                             aListStyleData.sListId, true ));
1429cdf0e10cSrcweir                     }
1430cdf0e10cSrcweir 
1431cdf0e10cSrcweir                     if ( aListStyleData.pReplaceNumRule == 0 )
1432cdf0e10cSrcweir                     {
1433cdf0e10cSrcweir                         aListStyleData.pReplaceNumRule = new SwNumRule(*pRule);
143434760e49SOliver-Rainer Wittmann                         aListStyleData.pReplaceNumRule->SetName( GetUniqueNumRuleName(), *this );
1435cdf0e10cSrcweir                         aListStyleData.bCreateNewList = true;
1436cdf0e10cSrcweir                     }
1437cdf0e10cSrcweir 
1438cdf0e10cSrcweir                     aMyNumRuleMap[pRule] = aListStyleData;
1439cdf0e10cSrcweir                 }
1440cdf0e10cSrcweir 
1441cdf0e10cSrcweir                 SwPaM aPam(*pCNd);
1442cdf0e10cSrcweir 
144334760e49SOliver-Rainer Wittmann                 SetNumRule( aPam,
144434760e49SOliver-Rainer Wittmann                             *aListStyleData.pReplaceNumRule,
1445cdf0e10cSrcweir                             aListStyleData.bCreateNewList,
1446cdf0e10cSrcweir                             aListStyleData.sListId );
1447cdf0e10cSrcweir                 if ( aListStyleData.bCreateNewList )
1448cdf0e10cSrcweir                 {
1449cdf0e10cSrcweir                     aListStyleData.bCreateNewList = false;
1450cdf0e10cSrcweir                     aListStyleData.sListId = pCNd->GetListId();
1451cdf0e10cSrcweir                     aMyNumRuleMap[pRule] = aListStyleData;
1452cdf0e10cSrcweir                 }
1453cdf0e10cSrcweir                 // <--
1454cdf0e10cSrcweir 
1455cdf0e10cSrcweir                 bFirst = false;
1456cdf0e10cSrcweir             }
1457cdf0e10cSrcweir         }
1458cdf0e10cSrcweir     }
1459cdf0e10cSrcweir }
1460cdf0e10cSrcweir 
NoNum(const SwPaM & rPam)1461cdf0e10cSrcweir sal_Bool SwDoc::NoNum( const SwPaM& rPam )
1462cdf0e10cSrcweir {
1463cdf0e10cSrcweir 
1464cdf0e10cSrcweir     sal_Bool bRet = SplitNode( *rPam.GetPoint(), false );
1465cdf0e10cSrcweir     // ist ueberhaupt Nummerierung im Spiel ?
1466cdf0e10cSrcweir     if( bRet )
1467cdf0e10cSrcweir     {
1468cdf0e10cSrcweir         // NoNum setzen und Upaten
1469cdf0e10cSrcweir         const SwNodeIndex& rIdx = rPam.GetPoint()->nNode;
1470cdf0e10cSrcweir         SwTxtNode* pNd = rIdx.GetNode().GetTxtNode();
1471cdf0e10cSrcweir         const SwNumRule* pRule = pNd->GetNumRule();
1472cdf0e10cSrcweir         if( pRule )
1473cdf0e10cSrcweir         {
1474cdf0e10cSrcweir             pNd->SetCountedInList(false);
1475cdf0e10cSrcweir 
1476cdf0e10cSrcweir             SetModified();
1477cdf0e10cSrcweir         }
1478cdf0e10cSrcweir         else
1479cdf0e10cSrcweir             bRet = sal_False;   // keine Nummerierung , ?? oder immer sal_True ??
1480cdf0e10cSrcweir     }
1481cdf0e10cSrcweir     return bRet;
1482cdf0e10cSrcweir }
1483cdf0e10cSrcweir 
DelNumRules(const SwPaM & rPam)1484cdf0e10cSrcweir void SwDoc::DelNumRules( const SwPaM& rPam )
1485cdf0e10cSrcweir {
1486cdf0e10cSrcweir     sal_uLong nStt = rPam.GetPoint()->nNode.GetIndex(),
1487cdf0e10cSrcweir             nEnd = rPam.GetMark()->nNode.GetIndex();
1488cdf0e10cSrcweir     if( nStt > nEnd )
1489cdf0e10cSrcweir     {
1490cdf0e10cSrcweir         sal_uLong nTmp = nStt; nStt = nEnd; nEnd = nTmp;
1491cdf0e10cSrcweir     }
1492cdf0e10cSrcweir 
1493cdf0e10cSrcweir     SwUndoDelNum* pUndo;
1494cdf0e10cSrcweir     if (GetIDocumentUndoRedo().DoesUndo())
1495cdf0e10cSrcweir     {
1496cdf0e10cSrcweir         pUndo = new SwUndoDelNum( rPam );
1497cdf0e10cSrcweir         GetIDocumentUndoRedo().AppendUndo(pUndo);
1498cdf0e10cSrcweir     }
1499cdf0e10cSrcweir     else
1500cdf0e10cSrcweir         pUndo = 0;
1501cdf0e10cSrcweir 
1502cdf0e10cSrcweir     SwRegHistory aRegH( pUndo ? pUndo->GetHistory() : 0 );
1503cdf0e10cSrcweir 
1504cdf0e10cSrcweir     SwNumRuleItem aEmptyRule( aEmptyStr );
1505cdf0e10cSrcweir     const SwNode* pOutlNd = 0;
1506cdf0e10cSrcweir     for( ; nStt <= nEnd; ++nStt )
1507cdf0e10cSrcweir     {
1508cdf0e10cSrcweir         SwTxtNode* pTNd = GetNodes()[ nStt ]->GetTxtNode();
1509cdf0e10cSrcweir         // --> OD 2008-03-13 #refactorlists#
1510cdf0e10cSrcweir //        if( pTNd && 0 != ( pItem = pTNd->GetNoCondAttr(
1511cdf0e10cSrcweir //            RES_PARATR_NUMRULE, sal_True ) ) &&
1512cdf0e10cSrcweir //            ( pName = &((SwNumRuleItem*)pItem)->GetValue())->Len() )
1513cdf0e10cSrcweir         SwNumRule* pNumRuleOfTxtNode = pTNd ? pTNd->GetNumRule() : 0;
1514cdf0e10cSrcweir         if ( pTNd && pNumRuleOfTxtNode )
1515cdf0e10cSrcweir         // <--
1516cdf0e10cSrcweir         {
1517cdf0e10cSrcweir             // recognize changes of attribute for undo
1518cdf0e10cSrcweir             aRegH.RegisterInModify( pTNd, *pTNd );
1519cdf0e10cSrcweir 
1520cdf0e10cSrcweir             if( pUndo )
1521cdf0e10cSrcweir                 pUndo->AddNode( *pTNd, sal_False );
1522cdf0e10cSrcweir 
1523cdf0e10cSrcweir             // directly set list style attribute is reset, otherwise empty
1524cdf0e10cSrcweir             // list style is applied
1525cdf0e10cSrcweir             const SfxItemSet* pAttrSet = pTNd->GetpSwAttrSet();
1526cdf0e10cSrcweir             if ( pAttrSet &&
1527cdf0e10cSrcweir                  pAttrSet->GetItemState( RES_PARATR_NUMRULE, sal_False ) == SFX_ITEM_SET )
1528cdf0e10cSrcweir                 pTNd->ResetAttr( RES_PARATR_NUMRULE );
1529cdf0e10cSrcweir             else
1530cdf0e10cSrcweir                 pTNd->SetAttr( aEmptyRule );
1531cdf0e10cSrcweir 
1532cdf0e10cSrcweir             // --> OD 2008-03-26 #refactorlists#
1533cdf0e10cSrcweir             pTNd->ResetAttr( RES_PARATR_LIST_ID );
1534cdf0e10cSrcweir             pTNd->ResetAttr( RES_PARATR_LIST_LEVEL );
1535cdf0e10cSrcweir             pTNd->ResetAttr( RES_PARATR_LIST_ISRESTART );
1536cdf0e10cSrcweir             pTNd->ResetAttr( RES_PARATR_LIST_RESTARTVALUE );
1537cdf0e10cSrcweir             pTNd->ResetAttr( RES_PARATR_LIST_ISCOUNTED );
1538cdf0e10cSrcweir             // <--
1539cdf0e10cSrcweir 
1540cdf0e10cSrcweir             if( RES_CONDTXTFMTCOLL == pTNd->GetFmtColl()->Which() )
1541cdf0e10cSrcweir                 pTNd->ChkCondColl();
1542cdf0e10cSrcweir             //else if( !pOutlNd && NO_NUMBERING != //#outline level,zhaojianwei
1543cdf0e10cSrcweir             //  ((SwTxtFmtColl*)pTNd->GetFmtColl())->GetOutlineLevel() )
1544cdf0e10cSrcweir             else if( !pOutlNd &&
1545cdf0e10cSrcweir                 ((SwTxtFmtColl*)pTNd->GetFmtColl())->IsAssignedToListLevelOfOutlineStyle() )//<-end,zhaojianwei
1546cdf0e10cSrcweir                 pOutlNd = pTNd;
1547cdf0e10cSrcweir         }
1548cdf0e10cSrcweir     }
1549cdf0e10cSrcweir 
1550cdf0e10cSrcweir     // dann noch alle Updaten
1551cdf0e10cSrcweir     UpdateNumRule();
1552cdf0e10cSrcweir 
1553cdf0e10cSrcweir     if( pOutlNd )
1554cdf0e10cSrcweir         GetNodes().UpdtOutlineIdx( *pOutlNd );
1555cdf0e10cSrcweir }
1556cdf0e10cSrcweir 
InvalidateNumRules()1557cdf0e10cSrcweir void SwDoc::InvalidateNumRules()
1558cdf0e10cSrcweir {
1559cdf0e10cSrcweir     for (sal_uInt16 n = 0; n < pNumRuleTbl->Count(); ++n)
1560cdf0e10cSrcweir         (*pNumRuleTbl)[n]->SetInvalidRule(sal_True);
1561cdf0e10cSrcweir }
1562cdf0e10cSrcweir 
1563cdf0e10cSrcweir     // zum naechsten/vorhergehenden Punkt auf gleicher Ebene
1564cdf0e10cSrcweir 
lcl_IsNumOk(sal_uInt8 nSrchNum,sal_uInt8 & rLower,sal_uInt8 & rUpper,sal_Bool bOverUpper,sal_uInt8 nNumber)1565cdf0e10cSrcweir sal_Bool lcl_IsNumOk( sal_uInt8 nSrchNum, sal_uInt8& rLower, sal_uInt8& rUpper,
1566cdf0e10cSrcweir                     sal_Bool bOverUpper, sal_uInt8 nNumber )
1567cdf0e10cSrcweir {
1568cdf0e10cSrcweir     // --> OD 2008-04-02 #refactorlists#
1569cdf0e10cSrcweir     ASSERT( nNumber < MAXLEVEL,
1570cdf0e10cSrcweir             "<lcl_IsNumOk(..)> - misusage of method" );
1571cdf0e10cSrcweir     // <--
1572cdf0e10cSrcweir 
1573cdf0e10cSrcweir     sal_Bool bRet = sal_False;
1574cdf0e10cSrcweir     {
1575cdf0e10cSrcweir         if( bOverUpper ? nSrchNum == nNumber : nSrchNum >= nNumber )
1576cdf0e10cSrcweir             bRet = sal_True;
1577cdf0e10cSrcweir         else if( nNumber > rLower )
1578cdf0e10cSrcweir             rLower = nNumber;
1579cdf0e10cSrcweir         else if( nNumber < rUpper )
1580cdf0e10cSrcweir             rUpper = nNumber;
1581cdf0e10cSrcweir     }
1582cdf0e10cSrcweir     return bRet;
1583cdf0e10cSrcweir }
1584cdf0e10cSrcweir 
lcl_IsValidPrevNextNumNode(const SwNodeIndex & rIdx)1585cdf0e10cSrcweir sal_Bool lcl_IsValidPrevNextNumNode( const SwNodeIndex& rIdx )
1586cdf0e10cSrcweir {
1587cdf0e10cSrcweir     sal_Bool bRet = sal_False;
1588cdf0e10cSrcweir     const SwNode& rNd = rIdx.GetNode();
1589cdf0e10cSrcweir     switch( rNd.GetNodeType() )
1590cdf0e10cSrcweir     {
1591cdf0e10cSrcweir     case ND_ENDNODE:
1592cdf0e10cSrcweir         bRet = SwTableBoxStartNode == rNd.StartOfSectionNode()->GetStartNodeType() ||
1593cdf0e10cSrcweir                 rNd.StartOfSectionNode()->IsSectionNode();
1594cdf0e10cSrcweir         break;
1595cdf0e10cSrcweir 
1596cdf0e10cSrcweir     case ND_STARTNODE:
1597cdf0e10cSrcweir         bRet = SwTableBoxStartNode == ((SwStartNode&)rNd).GetStartNodeType();
1598cdf0e10cSrcweir         break;
1599cdf0e10cSrcweir 
1600cdf0e10cSrcweir     case ND_SECTIONNODE:            // der ist erlaubt, also weiter
1601cdf0e10cSrcweir         bRet = sal_True;
1602cdf0e10cSrcweir         break;
1603cdf0e10cSrcweir     }
1604cdf0e10cSrcweir     return bRet;
1605cdf0e10cSrcweir }
1606cdf0e10cSrcweir 
lcl_GotoNextPrevNum(SwPosition & rPos,sal_Bool bNext,sal_Bool bOverUpper,sal_uInt8 * pUpper,sal_uInt8 * pLower)1607cdf0e10cSrcweir sal_Bool lcl_GotoNextPrevNum( SwPosition& rPos, sal_Bool bNext,
1608cdf0e10cSrcweir                             sal_Bool bOverUpper, sal_uInt8* pUpper, sal_uInt8* pLower )
1609cdf0e10cSrcweir {
1610cdf0e10cSrcweir     const SwTxtNode* pNd = rPos.nNode.GetNode().GetTxtNode();
1611cdf0e10cSrcweir     const SwNumRule* pRule;
1612cdf0e10cSrcweir     if( !pNd || 0 == ( pRule = pNd->GetNumRule()))
1613cdf0e10cSrcweir         return sal_False;
1614cdf0e10cSrcweir 
1615cdf0e10cSrcweir     sal_uInt8 nSrchNum = static_cast<sal_uInt8>(pNd->GetActualListLevel());
1616cdf0e10cSrcweir 
1617cdf0e10cSrcweir     SwNodeIndex aIdx( rPos.nNode );
1618cdf0e10cSrcweir     if( ! pNd->IsCountedInList() )
1619cdf0e10cSrcweir     {
1620cdf0e10cSrcweir         // falls gerade mal NO_NUMLEVEL an ist, so such den vorherigen Node
1621cdf0e10cSrcweir         // mit Nummerierung
1622cdf0e10cSrcweir         sal_Bool bError = sal_False;
1623cdf0e10cSrcweir         do {
1624cdf0e10cSrcweir             aIdx--;
1625cdf0e10cSrcweir             if( aIdx.GetNode().IsTxtNode() )
1626cdf0e10cSrcweir             {
1627cdf0e10cSrcweir                 pNd = aIdx.GetNode().GetTxtNode();
1628cdf0e10cSrcweir                 pRule = pNd->GetNumRule();
1629cdf0e10cSrcweir 
1630cdf0e10cSrcweir                 sal_uInt8 nTmpNum;
1631cdf0e10cSrcweir 
1632cdf0e10cSrcweir                 if( pRule  )
1633cdf0e10cSrcweir                 {
1634cdf0e10cSrcweir                     nTmpNum = static_cast<sal_uInt8>(pNd->GetActualListLevel());
1635cdf0e10cSrcweir                     if( !( ! pNd->IsCountedInList() &&
1636cdf0e10cSrcweir                          (nTmpNum >= nSrchNum )) )
1637cdf0e10cSrcweir                         break;      // gefunden
1638cdf0e10cSrcweir                 }
1639cdf0e10cSrcweir                 else
1640cdf0e10cSrcweir                     bError = sal_True;
1641cdf0e10cSrcweir             }
1642cdf0e10cSrcweir             else
1643cdf0e10cSrcweir                 bError = !lcl_IsValidPrevNextNumNode( aIdx );
1644cdf0e10cSrcweir 
1645cdf0e10cSrcweir         } while( !bError );
1646cdf0e10cSrcweir         if( bError )
1647cdf0e10cSrcweir             return sal_False;
1648cdf0e10cSrcweir     }
1649cdf0e10cSrcweir 
1650cdf0e10cSrcweir     sal_uInt8 nLower = nSrchNum, nUpper = nSrchNum;
1651cdf0e10cSrcweir     sal_Bool bRet = sal_False;
1652cdf0e10cSrcweir 
1653cdf0e10cSrcweir     const SwTxtNode* pLast;
1654cdf0e10cSrcweir     if( bNext )
1655cdf0e10cSrcweir         aIdx++, pLast = pNd;
1656cdf0e10cSrcweir     else
1657cdf0e10cSrcweir         aIdx--, pLast = 0;
1658cdf0e10cSrcweir 
1659cdf0e10cSrcweir     while( bNext ? ( aIdx.GetIndex() < aIdx.GetNodes().Count() - 1 )
1660cdf0e10cSrcweir                  : aIdx.GetIndex() )
1661cdf0e10cSrcweir     {
1662cdf0e10cSrcweir         if( aIdx.GetNode().IsTxtNode() )
1663cdf0e10cSrcweir         {
1664cdf0e10cSrcweir             pNd = aIdx.GetNode().GetTxtNode();
1665cdf0e10cSrcweir             pRule = pNd->GetNumRule();
1666cdf0e10cSrcweir             if( pRule )
1667cdf0e10cSrcweir             {
1668cdf0e10cSrcweir                 if( ::lcl_IsNumOk( nSrchNum, nLower, nUpper, bOverUpper,
1669cdf0e10cSrcweir                                     static_cast<sal_uInt8>(pNd->GetActualListLevel()) ))
1670cdf0e10cSrcweir                 {
1671cdf0e10cSrcweir                     rPos.nNode = aIdx;
1672cdf0e10cSrcweir                     rPos.nContent.Assign( (SwTxtNode*)pNd, 0 );
1673cdf0e10cSrcweir                     bRet = sal_True;
1674cdf0e10cSrcweir                     break;
1675cdf0e10cSrcweir                 }
1676cdf0e10cSrcweir                 else
1677cdf0e10cSrcweir                     pLast = pNd;
1678cdf0e10cSrcweir             }
1679cdf0e10cSrcweir             else
1680cdf0e10cSrcweir                 break;
1681cdf0e10cSrcweir         }
1682cdf0e10cSrcweir         else if( !lcl_IsValidPrevNextNumNode( aIdx ))
1683cdf0e10cSrcweir             break;
1684cdf0e10cSrcweir 
1685cdf0e10cSrcweir         if( bNext )
1686cdf0e10cSrcweir             aIdx++;
1687cdf0e10cSrcweir         else
1688cdf0e10cSrcweir             aIdx--;
1689cdf0e10cSrcweir     }
1690cdf0e10cSrcweir 
1691cdf0e10cSrcweir     if( !bRet && !bOverUpper && pLast )     // nicht ueber hoehere Nummmern, aber bis Ende
1692cdf0e10cSrcweir     {
1693cdf0e10cSrcweir         if( bNext )
1694cdf0e10cSrcweir         {
1695cdf0e10cSrcweir             rPos.nNode = aIdx;
1696cdf0e10cSrcweir             if( aIdx.GetNode().IsCntntNode() )
1697cdf0e10cSrcweir                 rPos.nContent.Assign( aIdx.GetNode().GetCntntNode(), 0 );
1698cdf0e10cSrcweir         }
1699cdf0e10cSrcweir         else
1700cdf0e10cSrcweir         {
1701cdf0e10cSrcweir             rPos.nNode.Assign( *pLast );
1702cdf0e10cSrcweir             rPos.nContent.Assign( (SwTxtNode*)pLast, 0 );
1703cdf0e10cSrcweir         }
1704cdf0e10cSrcweir         bRet = sal_True;
1705cdf0e10cSrcweir     }
1706cdf0e10cSrcweir 
1707cdf0e10cSrcweir     if( bRet )
1708cdf0e10cSrcweir     {
1709cdf0e10cSrcweir         if( pUpper )
1710cdf0e10cSrcweir             *pUpper = nUpper;
1711cdf0e10cSrcweir         if( pLower )
1712cdf0e10cSrcweir             *pLower = nLower;
1713cdf0e10cSrcweir     }
1714cdf0e10cSrcweir     return bRet;
1715cdf0e10cSrcweir }
1716cdf0e10cSrcweir 
GotoNextNum(SwPosition & rPos,sal_Bool bOverUpper,sal_uInt8 * pUpper,sal_uInt8 * pLower)1717cdf0e10cSrcweir sal_Bool SwDoc::GotoNextNum( SwPosition& rPos, sal_Bool bOverUpper,
1718cdf0e10cSrcweir                             sal_uInt8* pUpper, sal_uInt8* pLower  )
1719cdf0e10cSrcweir {
1720cdf0e10cSrcweir    return ::lcl_GotoNextPrevNum( rPos, sal_True, bOverUpper, pUpper, pLower );
1721cdf0e10cSrcweir }
1722cdf0e10cSrcweir 
1723cdf0e10cSrcweir // -> #i23731#
1724cdf0e10cSrcweir // --> OD 2008-03-18 #refactorlists# - add output parameter <sListId>
SearchNumRule(const SwPosition & rPos,const bool bForward,const bool bNum,const bool bOutline,int nNonEmptyAllowed,String & sListId,const bool bInvestigateStartNode)1725cdf0e10cSrcweir const SwNumRule *  SwDoc::SearchNumRule(const SwPosition & rPos,
1726cdf0e10cSrcweir                                         const bool bForward,
1727cdf0e10cSrcweir                                         const bool bNum,
1728cdf0e10cSrcweir                                         const bool bOutline,
1729cdf0e10cSrcweir                                         int nNonEmptyAllowed,
1730cdf0e10cSrcweir                                         String& sListId,
1731cdf0e10cSrcweir                                         const bool bInvestigateStartNode)
1732cdf0e10cSrcweir {
1733cdf0e10cSrcweir     const SwNumRule * pResult = NULL;
1734cdf0e10cSrcweir     SwTxtNode * pTxtNd = rPos.nNode.GetNode().GetTxtNode();
1735cdf0e10cSrcweir     SwNode * pStartFromNode = pTxtNd;
1736cdf0e10cSrcweir 
1737cdf0e10cSrcweir     if (pTxtNd)
1738cdf0e10cSrcweir     {
1739cdf0e10cSrcweir         SwNodeIndex aIdx(rPos.nNode);
1740cdf0e10cSrcweir 
1741cdf0e10cSrcweir         // --> OD 2005-10-20 #i55391#
1742cdf0e10cSrcweir         // - the start node has also been investigated, if requested.
1743cdf0e10cSrcweir         const SwNode * pNode = NULL;
1744cdf0e10cSrcweir         do
1745cdf0e10cSrcweir         {
1746cdf0e10cSrcweir             // --> OD 2005-10-20 #i55391#
1747cdf0e10cSrcweir             if ( !bInvestigateStartNode )
1748cdf0e10cSrcweir             {
1749cdf0e10cSrcweir                 if (bForward)
1750cdf0e10cSrcweir                     aIdx++;
1751cdf0e10cSrcweir                 else
1752cdf0e10cSrcweir                     aIdx--;
1753cdf0e10cSrcweir             }
1754cdf0e10cSrcweir             // <--
1755cdf0e10cSrcweir             if (aIdx.GetNode().IsTxtNode())
1756cdf0e10cSrcweir             {
1757cdf0e10cSrcweir                 pTxtNd = aIdx.GetNode().GetTxtNode();
1758cdf0e10cSrcweir 
1759cdf0e10cSrcweir                 const SwNumRule * pNumRule = pTxtNd->GetNumRule();
1760cdf0e10cSrcweir                 if (pNumRule)
1761cdf0e10cSrcweir                 {
1762cdf0e10cSrcweir                     if ( ( pNumRule->IsOutlineRule() == ( bOutline ? sal_True : sal_False ) ) && // #115901#
1763cdf0e10cSrcweir                          ( ( bNum && pNumRule->Get(0).IsEnumeration()) ||
1764cdf0e10cSrcweir                            ( !bNum && pNumRule->Get(0).IsItemize() ) ) ) // #i22362#, #i29560#
1765cdf0e10cSrcweir                     {
1766cdf0e10cSrcweir                         pResult = pTxtNd->GetNumRule();
1767cdf0e10cSrcweir                         // --> OD 2008-03-18 #refactorlists#
1768cdf0e10cSrcweir                         // provide also the list id, to which the text node belongs.
1769cdf0e10cSrcweir                         sListId = pTxtNd->GetListId();
1770cdf0e10cSrcweir                     }
1771cdf0e10cSrcweir 
1772cdf0e10cSrcweir                     break;
1773cdf0e10cSrcweir                 }
1774cdf0e10cSrcweir                 else if (pTxtNd->Len() > 0 || NULL != pTxtNd->GetNumRule())
1775cdf0e10cSrcweir                 {
1776cdf0e10cSrcweir                     if (nNonEmptyAllowed == 0)
1777cdf0e10cSrcweir                         break;
1778cdf0e10cSrcweir 
1779cdf0e10cSrcweir                     nNonEmptyAllowed--;
1780cdf0e10cSrcweir 
1781cdf0e10cSrcweir                     if (nNonEmptyAllowed < 0)
1782cdf0e10cSrcweir                         nNonEmptyAllowed = -1;
1783cdf0e10cSrcweir                 }
1784cdf0e10cSrcweir             }
1785cdf0e10cSrcweir 
1786cdf0e10cSrcweir             // --> OD 2005-10-20 #i55391#
1787cdf0e10cSrcweir             if ( bInvestigateStartNode )
1788cdf0e10cSrcweir             {
1789cdf0e10cSrcweir                 if (bForward)
1790cdf0e10cSrcweir                     aIdx++;
1791cdf0e10cSrcweir                 else
1792cdf0e10cSrcweir                     aIdx--;
1793cdf0e10cSrcweir             }
1794cdf0e10cSrcweir             // <--
1795cdf0e10cSrcweir 
1796cdf0e10cSrcweir             pNode = &aIdx.GetNode();
1797cdf0e10cSrcweir         }
1798cdf0e10cSrcweir         while (!(pNode == GetNodes().DocumentSectionStartNode(pStartFromNode) ||
1799cdf0e10cSrcweir                  pNode == GetNodes().DocumentSectionEndNode(pStartFromNode)));
1800cdf0e10cSrcweir         // <--
1801cdf0e10cSrcweir     }
1802cdf0e10cSrcweir 
1803cdf0e10cSrcweir     return pResult;
1804cdf0e10cSrcweir }
1805cdf0e10cSrcweir // <- #i23731#
1806cdf0e10cSrcweir 
GotoPrevNum(SwPosition & rPos,sal_Bool bOverUpper,sal_uInt8 * pUpper,sal_uInt8 * pLower)1807cdf0e10cSrcweir sal_Bool SwDoc::GotoPrevNum( SwPosition& rPos, sal_Bool bOverUpper,
1808cdf0e10cSrcweir                             sal_uInt8* pUpper, sal_uInt8* pLower  )
1809cdf0e10cSrcweir {
1810cdf0e10cSrcweir    return ::lcl_GotoNextPrevNum( rPos, sal_False, bOverUpper, pUpper, pLower );
1811cdf0e10cSrcweir }
1812cdf0e10cSrcweir 
NumUpDown(const SwPaM & rPam,sal_Bool bDown)1813cdf0e10cSrcweir sal_Bool SwDoc::NumUpDown( const SwPaM& rPam, sal_Bool bDown )
1814cdf0e10cSrcweir {
1815cdf0e10cSrcweir     sal_uLong nStt = rPam.GetPoint()->nNode.GetIndex(),
1816cdf0e10cSrcweir             nEnd = rPam.GetMark()->nNode.GetIndex();
1817cdf0e10cSrcweir     if( nStt > nEnd )
1818cdf0e10cSrcweir     {
1819cdf0e10cSrcweir         sal_uLong nTmp = nStt; nStt = nEnd; nEnd = nTmp;
1820cdf0e10cSrcweir     }
1821cdf0e10cSrcweir 
1822cdf0e10cSrcweir     // -> #115901# outline nodes are promoted or demoted differently
1823cdf0e10cSrcweir     bool bOnlyOutline = true;
1824cdf0e10cSrcweir     bool bOnlyNonOutline = true;
1825cdf0e10cSrcweir     for (sal_uLong n = nStt; n <= nEnd; n++)
1826cdf0e10cSrcweir     {
1827cdf0e10cSrcweir         SwTxtNode * pTxtNd = GetNodes()[n]->GetTxtNode();
1828cdf0e10cSrcweir 
1829cdf0e10cSrcweir         if (pTxtNd)
1830cdf0e10cSrcweir         {
1831cdf0e10cSrcweir             SwNumRule * pRule = pTxtNd->GetNumRule();
1832cdf0e10cSrcweir 
1833cdf0e10cSrcweir             if (pRule)
1834cdf0e10cSrcweir             {
1835cdf0e10cSrcweir                 if (pRule->IsOutlineRule())
1836cdf0e10cSrcweir                     bOnlyNonOutline = false;
1837cdf0e10cSrcweir                 else
1838cdf0e10cSrcweir                     bOnlyOutline = false;
1839cdf0e10cSrcweir             }
1840cdf0e10cSrcweir         }
1841cdf0e10cSrcweir     }
1842cdf0e10cSrcweir     // <- #115901#
1843cdf0e10cSrcweir 
1844cdf0e10cSrcweir     sal_Bool bRet = sal_True;
1845cdf0e10cSrcweir     char nDiff = bDown ? 1 : -1;
1846cdf0e10cSrcweir 
1847cdf0e10cSrcweir     // ->#115901#
1848cdf0e10cSrcweir     if (bOnlyOutline)
1849cdf0e10cSrcweir         bRet = OutlineUpDown(rPam, nDiff);
1850cdf0e10cSrcweir     else if (bOnlyNonOutline)
1851cdf0e10cSrcweir     {
1852cdf0e10cSrcweir         /* --> #i24560#
1853cdf0e10cSrcweir 
1854cdf0e10cSrcweir         Only promote or demote if all selected paragraphs are
1855cdf0e10cSrcweir         promotable resp. demotable.
1856cdf0e10cSrcweir 
1857cdf0e10cSrcweir         */
1858cdf0e10cSrcweir         for (sal_uLong nTmp = nStt; nTmp <= nEnd; ++nTmp)
1859cdf0e10cSrcweir         {
1860cdf0e10cSrcweir             SwTxtNode* pTNd = GetNodes()[ nTmp ]->GetTxtNode();
1861cdf0e10cSrcweir 
1862cdf0e10cSrcweir             // --> OD 2006-10-19 #134160# - make code robust:
1863cdf0e10cSrcweir             // consider case that the node doesn't denote a text node.
1864cdf0e10cSrcweir             if ( pTNd )
1865cdf0e10cSrcweir             {
1866cdf0e10cSrcweir                 SwNumRule * pRule = pTNd->GetNumRule();
1867cdf0e10cSrcweir 
1868cdf0e10cSrcweir                 if (pRule)
1869cdf0e10cSrcweir                 {
1870cdf0e10cSrcweir                     sal_uInt8 nLevel = static_cast<sal_uInt8>(pTNd->GetActualListLevel());
1871cdf0e10cSrcweir                     if( (-1 == nDiff && 0 >= nLevel) ||
1872cdf0e10cSrcweir                         (1 == nDiff && MAXLEVEL - 1 <= nLevel))
1873cdf0e10cSrcweir                         bRet = sal_False;
1874cdf0e10cSrcweir                 }
1875cdf0e10cSrcweir             }
1876cdf0e10cSrcweir             // <--
1877cdf0e10cSrcweir         }
1878cdf0e10cSrcweir 
1879cdf0e10cSrcweir         if( bRet )
1880cdf0e10cSrcweir         {
1881cdf0e10cSrcweir             /* <-- #i24560# */
1882cdf0e10cSrcweir             if (GetIDocumentUndoRedo().DoesUndo())
1883cdf0e10cSrcweir             {
1884cdf0e10cSrcweir                 SwUndo *const pUndo( new SwUndoNumUpDown(rPam, nDiff) );
1885cdf0e10cSrcweir                 GetIDocumentUndoRedo().AppendUndo(pUndo);
1886cdf0e10cSrcweir             }
1887cdf0e10cSrcweir 
1888cdf0e10cSrcweir             String sNumRule;
1889cdf0e10cSrcweir 
1890cdf0e10cSrcweir             for(sal_uLong nTmp = nStt; nTmp <= nEnd; ++nTmp )
1891cdf0e10cSrcweir             {
1892cdf0e10cSrcweir                 SwTxtNode* pTNd = GetNodes()[ nTmp ]->GetTxtNode();
1893cdf0e10cSrcweir 
1894cdf0e10cSrcweir                 if( pTNd)
1895cdf0e10cSrcweir                 {
1896cdf0e10cSrcweir                     SwNumRule * pRule = pTNd->GetNumRule();
1897cdf0e10cSrcweir 
1898cdf0e10cSrcweir                     if (pRule)
1899cdf0e10cSrcweir                     {
1900cdf0e10cSrcweir                         sal_uInt8 nLevel = static_cast<sal_uInt8>(pTNd->GetActualListLevel());
1901cdf0e10cSrcweir                         nLevel = nLevel + nDiff;
1902cdf0e10cSrcweir 
1903cdf0e10cSrcweir                         pTNd->SetAttrListLevel(nLevel);
1904cdf0e10cSrcweir                     }
1905cdf0e10cSrcweir                 }
1906cdf0e10cSrcweir             }
1907cdf0e10cSrcweir 
1908cdf0e10cSrcweir             ChkCondColls();
1909cdf0e10cSrcweir             SetModified();
1910cdf0e10cSrcweir         }
1911cdf0e10cSrcweir     }
1912cdf0e10cSrcweir 
1913cdf0e10cSrcweir     return bRet;
1914cdf0e10cSrcweir }
1915cdf0e10cSrcweir 
MoveParagraph(const SwPaM & rPam,long nOffset,sal_Bool bIsOutlMv)1916cdf0e10cSrcweir sal_Bool SwDoc::MoveParagraph( const SwPaM& rPam, long nOffset, sal_Bool bIsOutlMv )
1917cdf0e10cSrcweir {
1918cdf0e10cSrcweir     const SwPosition *pStt = rPam.Start(), *pEnd = rPam.End();
1919cdf0e10cSrcweir 
1920cdf0e10cSrcweir     sal_uLong nStIdx = pStt->nNode.GetIndex();
1921cdf0e10cSrcweir     sal_uLong nEndIdx = pEnd->nNode.GetIndex();
1922cdf0e10cSrcweir 
1923cdf0e10cSrcweir     // Here are some sophisticated checks whether the wished PaM will be moved or not.
1924cdf0e10cSrcweir     // For moving outlines (bIsOutlMv) I've already done some checks, so here are two different
1925cdf0e10cSrcweir     // checks...
1926cdf0e10cSrcweir     SwNode *pTmp1;
1927cdf0e10cSrcweir     SwNode *pTmp2;
1928cdf0e10cSrcweir     if( bIsOutlMv )
1929cdf0e10cSrcweir     {
1930cdf0e10cSrcweir         // For moving chapters (outline) the following reason will deny the move:
1931cdf0e10cSrcweir         // if a start node is inside the moved area and its end node outside or vice versa.
1932cdf0e10cSrcweir         // If a start node is the first moved paragraph, its end node has to be within the moved
1933cdf0e10cSrcweir         // area, too (e.g. as last node).
1934cdf0e10cSrcweir         // If an end node is the last node of the moved area, its start node has to be a part of
1935cdf0e10cSrcweir         // the moved section, too.
1936cdf0e10cSrcweir         pTmp1 = GetNodes()[ nStIdx ];
1937cdf0e10cSrcweir         if( pTmp1->IsStartNode() )
1938cdf0e10cSrcweir         {   // First is a start node
1939cdf0e10cSrcweir             pTmp2 = pTmp1->EndOfSectionNode();
1940cdf0e10cSrcweir             if( pTmp2->GetIndex() > nEndIdx )
1941cdf0e10cSrcweir                 return sal_False; // Its end node is behind the moved range
1942cdf0e10cSrcweir         }
1943cdf0e10cSrcweir         pTmp1 = pTmp1->StartOfSectionNode()->EndOfSectionNode();
1944cdf0e10cSrcweir         if( pTmp1->GetIndex() <= nEndIdx )
1945cdf0e10cSrcweir             return sal_False; // End node inside but start node before moved range => no.
1946cdf0e10cSrcweir         pTmp1 = GetNodes()[ nEndIdx ];
1947cdf0e10cSrcweir         if( pTmp1->IsEndNode() )
1948cdf0e10cSrcweir         {   // The last one is an end node
1949cdf0e10cSrcweir             pTmp1 = pTmp1->StartOfSectionNode();
1950cdf0e10cSrcweir             if( pTmp1->GetIndex() < nStIdx )
1951cdf0e10cSrcweir                 return sal_False; // Its start node is before the moved range.
1952cdf0e10cSrcweir         }
1953cdf0e10cSrcweir         pTmp1 = pTmp1->StartOfSectionNode();
1954cdf0e10cSrcweir         if( pTmp1->GetIndex() >= nStIdx )
1955cdf0e10cSrcweir             return sal_False; // A start node which ends behind the moved area => no.
1956cdf0e10cSrcweir     }
1957cdf0e10cSrcweir 
1958cdf0e10cSrcweir     sal_uLong nInStIdx, nInEndIdx;
1959cdf0e10cSrcweir     long nOffs = nOffset;
1960cdf0e10cSrcweir     if( nOffset > 0 )
1961cdf0e10cSrcweir     {
1962cdf0e10cSrcweir         nInEndIdx = nEndIdx;
1963cdf0e10cSrcweir         nEndIdx += nOffset;
1964cdf0e10cSrcweir         ++nOffs;
1965cdf0e10cSrcweir     }
1966cdf0e10cSrcweir     else
1967cdf0e10cSrcweir     {
1968cdf0e10cSrcweir         //Impossible to move to negative index
1969cdf0e10cSrcweir         if( sal_uLong(abs( nOffset )) > nStIdx)
1970cdf0e10cSrcweir             return sal_False;
1971cdf0e10cSrcweir 
1972cdf0e10cSrcweir         nInEndIdx = nStIdx - 1;
1973cdf0e10cSrcweir         nStIdx += nOffset;
1974cdf0e10cSrcweir     }
1975cdf0e10cSrcweir     nInStIdx = nInEndIdx + 1;
1976cdf0e10cSrcweir     // Folgende Absatzbloecke sollen vertauscht werden:
1977cdf0e10cSrcweir     // [ nStIdx, nInEndIdx ] mit [ nInStIdx, nEndIdx ]
1978cdf0e10cSrcweir 
1979cdf0e10cSrcweir     if( nEndIdx >= GetNodes().GetEndOfContent().GetIndex() )
1980cdf0e10cSrcweir         return sal_False;
1981cdf0e10cSrcweir 
1982cdf0e10cSrcweir     if( !bIsOutlMv )
1983cdf0e10cSrcweir     {   // And here the restrictions for moving paragraphs other than chapters (outlines)
1984cdf0e10cSrcweir         // The plan is to exchange [nStIdx,nInEndIdx] and [nStartIdx,nEndIdx]
1985cdf0e10cSrcweir         // It will checked if the both "start" nodes as well as the both "end" notes belongs to
1986cdf0e10cSrcweir         // the same start-end-section. This is more restrictive than the conditions checked above.
1987cdf0e10cSrcweir         // E.g. a paragraph will not escape from a section or be inserted to another section.
1988cdf0e10cSrcweir         pTmp1 = GetNodes()[ nStIdx ]->StartOfSectionNode();
1989cdf0e10cSrcweir         pTmp2 = GetNodes()[ nInStIdx ]->StartOfSectionNode();
1990cdf0e10cSrcweir         if( pTmp1 != pTmp2 )
1991cdf0e10cSrcweir             return sal_False; // "start" nodes in different sections
1992cdf0e10cSrcweir         pTmp1 = GetNodes()[ nEndIdx ];
1993cdf0e10cSrcweir         bool bIsEndNode = pTmp1->IsEndNode();
1994cdf0e10cSrcweir         if( !pTmp1->IsStartNode() )
1995cdf0e10cSrcweir         {
1996cdf0e10cSrcweir             pTmp1 = pTmp1->StartOfSectionNode();
1997cdf0e10cSrcweir             if( bIsEndNode ) // For end nodes the first start node is of course inside the range,
1998cdf0e10cSrcweir                 pTmp1 = pTmp1->StartOfSectionNode(); // I've to check the start node of the start node.
1999cdf0e10cSrcweir         }
2000cdf0e10cSrcweir         pTmp1 = pTmp1->EndOfSectionNode();
2001cdf0e10cSrcweir         pTmp2 = GetNodes()[ nInEndIdx ];
2002cdf0e10cSrcweir         if( !pTmp2->IsStartNode() )
2003cdf0e10cSrcweir         {
2004cdf0e10cSrcweir             bIsEndNode = pTmp2->IsEndNode();
2005cdf0e10cSrcweir             pTmp2 = pTmp2->StartOfSectionNode();
2006cdf0e10cSrcweir             if( bIsEndNode )
2007cdf0e10cSrcweir                 pTmp2 = pTmp2->StartOfSectionNode();
2008cdf0e10cSrcweir         }
2009cdf0e10cSrcweir         pTmp2 = pTmp2->EndOfSectionNode();
2010cdf0e10cSrcweir         if( pTmp1 != pTmp2 )
2011cdf0e10cSrcweir             return sal_False; // The "end" notes are in different sections
2012cdf0e10cSrcweir     }
2013cdf0e10cSrcweir 
2014cdf0e10cSrcweir     // auf Redlining testen - darf die Selektion ueberhaupt verschoben
2015cdf0e10cSrcweir     // werden?
2016cdf0e10cSrcweir     if( !IsIgnoreRedline() )
2017cdf0e10cSrcweir     {
2018cdf0e10cSrcweir         sal_uInt16 nRedlPos = GetRedlinePos( pStt->nNode.GetNode(), nsRedlineType_t::REDLINE_DELETE );
2019cdf0e10cSrcweir         if( USHRT_MAX != nRedlPos )
2020cdf0e10cSrcweir         {
2021cdf0e10cSrcweir             SwPosition aStPos( *pStt ), aEndPos( *pEnd );
2022cdf0e10cSrcweir             aStPos.nContent = 0;
2023cdf0e10cSrcweir             SwCntntNode* pCNd = pEnd->nNode.GetNode().GetCntntNode();
2024cdf0e10cSrcweir             aEndPos.nContent = pCNd ? pCNd->Len() : 1;
2025cdf0e10cSrcweir             sal_Bool bCheckDel = sal_True;
2026cdf0e10cSrcweir 
2027cdf0e10cSrcweir             // es existiert fuer den Bereich irgendein Redline-Delete-Object
2028cdf0e10cSrcweir             for( ; nRedlPos < GetRedlineTbl().Count(); ++nRedlPos )
2029cdf0e10cSrcweir             {
2030cdf0e10cSrcweir                 const SwRedline* pTmp = GetRedlineTbl()[ nRedlPos ];
2031cdf0e10cSrcweir                 if( !bCheckDel || nsRedlineType_t::REDLINE_DELETE == pTmp->GetType() )
2032cdf0e10cSrcweir                 {
2033cdf0e10cSrcweir                     const SwPosition *pRStt = pTmp->Start(), *pREnd = pTmp->End();
2034cdf0e10cSrcweir                     switch( ComparePosition( *pRStt, *pREnd, aStPos, aEndPos ))
2035cdf0e10cSrcweir                     {
2036cdf0e10cSrcweir                     case POS_COLLIDE_START:
2037cdf0e10cSrcweir                     case POS_BEHIND:            // Pos1 liegt hinter Pos2
2038cdf0e10cSrcweir                         nRedlPos = GetRedlineTbl().Count();
2039cdf0e10cSrcweir                         break;
2040cdf0e10cSrcweir 
2041cdf0e10cSrcweir                     case POS_COLLIDE_END:
2042cdf0e10cSrcweir                     case POS_BEFORE:            // Pos1 liegt vor Pos2
2043cdf0e10cSrcweir                         break;
2044cdf0e10cSrcweir                     case POS_INSIDE:            // Pos1 liegt vollstaendig in Pos2
2045cdf0e10cSrcweir                         // ist erlaubt, aber checke dann alle nachfolgenden
2046cdf0e10cSrcweir                         // auf Ueberlappungen
2047cdf0e10cSrcweir                         bCheckDel = sal_False;
2048cdf0e10cSrcweir                         break;
2049cdf0e10cSrcweir 
2050cdf0e10cSrcweir                     case POS_OUTSIDE:           // Pos2 liegt vollstaendig in Pos1
2051cdf0e10cSrcweir                     case POS_EQUAL:             // Pos1 ist genauso gross wie Pos2
2052cdf0e10cSrcweir                     case POS_OVERLAP_BEFORE:    // Pos1 ueberlappt Pos2 am Anfang
2053cdf0e10cSrcweir                     case POS_OVERLAP_BEHIND:    // Pos1 ueberlappt Pos2 am Ende
2054cdf0e10cSrcweir                         return sal_False;
2055cdf0e10cSrcweir                     }
2056cdf0e10cSrcweir                 }
2057cdf0e10cSrcweir             }
2058cdf0e10cSrcweir         }
2059cdf0e10cSrcweir     }
2060cdf0e10cSrcweir 
2061cdf0e10cSrcweir     {
2062cdf0e10cSrcweir         // DataChanged vorm verschieben verschicken, dann bekommt
2063cdf0e10cSrcweir         // man noch mit, welche Objecte sich im Bereich befinden.
2064cdf0e10cSrcweir         // Danach koennen sie vor/hinter der Position befinden.
2065cdf0e10cSrcweir         SwDataChanged aTmp( rPam, 0 );
2066cdf0e10cSrcweir     }
2067cdf0e10cSrcweir 
2068cdf0e10cSrcweir     SwNodeIndex aIdx( nOffset > 0 ? pEnd->nNode : pStt->nNode, nOffs );
2069cdf0e10cSrcweir     SwNodeRange aMvRg( pStt->nNode, 0, pEnd->nNode, +1 );
2070cdf0e10cSrcweir 
2071cdf0e10cSrcweir     SwRedline* pOwnRedl = 0;
2072cdf0e10cSrcweir     if( IsRedlineOn() )
2073cdf0e10cSrcweir     {
2074cdf0e10cSrcweir         // wenn der Bereich komplett im eigenen Redline liegt, kann es
2075cdf0e10cSrcweir         // verschoben werden!
2076cdf0e10cSrcweir         sal_uInt16 nRedlPos = GetRedlinePos( pStt->nNode.GetNode(), nsRedlineType_t::REDLINE_INSERT );
2077cdf0e10cSrcweir         if( USHRT_MAX != nRedlPos )
2078cdf0e10cSrcweir         {
2079cdf0e10cSrcweir             SwRedline* pTmp = GetRedlineTbl()[ nRedlPos ];
2080cdf0e10cSrcweir             const SwPosition *pRStt = pTmp->Start(), *pREnd = pTmp->End();
2081cdf0e10cSrcweir             SwRedline aTmpRedl( nsRedlineType_t::REDLINE_INSERT, rPam );
2082cdf0e10cSrcweir             const SwCntntNode* pCEndNd = pEnd->nNode.GetNode().GetCntntNode();
2083cdf0e10cSrcweir             // liegt komplett im Bereich, und ist auch der eigene Redline?
2084cdf0e10cSrcweir             if( aTmpRedl.IsOwnRedline( *pTmp ) &&
2085cdf0e10cSrcweir                 (pRStt->nNode < pStt->nNode ||
2086cdf0e10cSrcweir                 (pRStt->nNode == pStt->nNode && !pRStt->nContent.GetIndex()) ) &&
2087cdf0e10cSrcweir                 (pEnd->nNode < pREnd->nNode ||
2088cdf0e10cSrcweir                 (pEnd->nNode == pREnd->nNode &&
2089cdf0e10cSrcweir                  pCEndNd ? pREnd->nContent.GetIndex() == pCEndNd->Len()
2090cdf0e10cSrcweir                          : !pREnd->nContent.GetIndex() )) )
2091cdf0e10cSrcweir             {
2092cdf0e10cSrcweir                 pOwnRedl = pTmp;
2093cdf0e10cSrcweir                 if( nRedlPos + 1 < GetRedlineTbl().Count() )
2094cdf0e10cSrcweir                 {
2095cdf0e10cSrcweir                     pTmp = GetRedlineTbl()[ nRedlPos+1 ];
2096cdf0e10cSrcweir                     if( *pTmp->Start() == *pREnd )
2097cdf0e10cSrcweir                         // dann doch nicht!
2098cdf0e10cSrcweir                         pOwnRedl = 0;
2099cdf0e10cSrcweir                 }
2100cdf0e10cSrcweir 
2101cdf0e10cSrcweir                 if( pOwnRedl &&
2102cdf0e10cSrcweir                     !( pRStt->nNode <= aIdx && aIdx <= pREnd->nNode ))
2103cdf0e10cSrcweir                 {
2104cdf0e10cSrcweir                     // nicht in sich selbst, dann auch nicht moven
2105cdf0e10cSrcweir                     pOwnRedl = 0;
2106cdf0e10cSrcweir                 }
2107cdf0e10cSrcweir             }
2108cdf0e10cSrcweir         }
2109cdf0e10cSrcweir 
2110cdf0e10cSrcweir         if( !pOwnRedl )
2111cdf0e10cSrcweir         {
2112cdf0e10cSrcweir             GetIDocumentUndoRedo().StartUndo( UNDO_START, NULL );
2113cdf0e10cSrcweir 
2114cdf0e10cSrcweir             // zuerst das Insert, dann das Loeschen
2115cdf0e10cSrcweir             SwPosition aInsPos( aIdx );
2116cdf0e10cSrcweir             aInsPos.nContent.Assign( aIdx.GetNode().GetCntntNode(), 0 );
2117cdf0e10cSrcweir 
2118cdf0e10cSrcweir             SwPaM aPam( pStt->nNode, aMvRg.aEnd );
2119cdf0e10cSrcweir 
2120cdf0e10cSrcweir             SwPaM& rOrigPam = (SwPaM&)rPam;
2121cdf0e10cSrcweir             rOrigPam.DeleteMark();
2122cdf0e10cSrcweir             rOrigPam.GetPoint()->nNode = aIdx.GetIndex() - 1;
2123cdf0e10cSrcweir 
2124cdf0e10cSrcweir             sal_Bool bDelLastPara = !aInsPos.nNode.GetNode().IsCntntNode();
2125cdf0e10cSrcweir 
2126cdf0e10cSrcweir             /* #101076# When copying to a non-content node Copy will
2127cdf0e10cSrcweir                insert a paragraph before that node and insert before
2128cdf0e10cSrcweir                that inserted node. Copy creates an SwUndoInserts that
2129cdf0e10cSrcweir                does not cover the extra paragraph. Thus we insert the
2130cdf0e10cSrcweir                extra paragraph ourselves, _with_ correct undo
2131cdf0e10cSrcweir                information. */
2132cdf0e10cSrcweir             if (bDelLastPara)
2133cdf0e10cSrcweir             {
2134cdf0e10cSrcweir                 /* aInsPos points to the non-content node. Move it to
2135cdf0e10cSrcweir                    the previous content node. */
2136cdf0e10cSrcweir                 SwPaM aInsPam(aInsPos);
2137cdf0e10cSrcweir                 sal_Bool bMoved = aInsPam.Move(fnMoveBackward);
2138cdf0e10cSrcweir                 ASSERT(bMoved, "No content node found!");
2139cdf0e10cSrcweir 
2140cdf0e10cSrcweir                 if (bMoved)
2141cdf0e10cSrcweir                 {
2142cdf0e10cSrcweir                     /* Append the new node after the content node
2143cdf0e10cSrcweir                        found. The new position to insert the moved
2144cdf0e10cSrcweir                        paragraph at is before the inserted
2145cdf0e10cSrcweir                        paragraph. */
2146cdf0e10cSrcweir                     AppendTxtNode(*aInsPam.GetPoint());
2147cdf0e10cSrcweir                     aInsPos = *aInsPam.GetPoint();
2148cdf0e10cSrcweir                 }
2149cdf0e10cSrcweir             }
2150cdf0e10cSrcweir 
2151cdf0e10cSrcweir             CopyRange( aPam, aInsPos, false );
2152cdf0e10cSrcweir             if( bDelLastPara )
2153cdf0e10cSrcweir             {
2154cdf0e10cSrcweir                 // dann muss der letzte leere Node wieder entfernt werden
2155cdf0e10cSrcweir                 aIdx = aInsPos.nNode;
2156cdf0e10cSrcweir                 SwCntntNode* pCNd = GetNodes().GoPrevious( &aInsPos.nNode );
2157cdf0e10cSrcweir                 xub_StrLen nCLen = 0; if( pCNd ) nCLen = pCNd->Len();
2158cdf0e10cSrcweir                 aInsPos.nContent.Assign( pCNd, nCLen );
2159cdf0e10cSrcweir 
2160cdf0e10cSrcweir                 // alle die im zu loeschenden Node stehen, mussen auf den
2161cdf0e10cSrcweir                 // naechsten umgestezt werden
2162cdf0e10cSrcweir                 SwPosition* pPos;
2163cdf0e10cSrcweir                 for( sal_uInt16 n = 0; n < GetRedlineTbl().Count(); ++n )
2164cdf0e10cSrcweir                 {
2165cdf0e10cSrcweir                     SwRedline* pTmp = GetRedlineTbl()[ n ];
2166cdf0e10cSrcweir                     if( ( pPos = &pTmp->GetBound(sal_True))->nNode == aIdx )
2167cdf0e10cSrcweir                     {
2168cdf0e10cSrcweir                         pPos->nNode++;
2169cdf0e10cSrcweir                         pPos->nContent.Assign( pPos->nNode.GetNode().GetCntntNode(),0);
2170cdf0e10cSrcweir                     }
2171cdf0e10cSrcweir                     if( ( pPos = &pTmp->GetBound(sal_False))->nNode == aIdx )
2172cdf0e10cSrcweir                     {
2173cdf0e10cSrcweir                         pPos->nNode++;
2174cdf0e10cSrcweir                         pPos->nContent.Assign( pPos->nNode.GetNode().GetCntntNode(),0);
2175cdf0e10cSrcweir                     }
2176cdf0e10cSrcweir                 }
2177cdf0e10cSrcweir                 CorrRel( aIdx, aInsPos, 0, sal_False );
2178cdf0e10cSrcweir 
2179cdf0e10cSrcweir                 pCNd->JoinNext();
2180cdf0e10cSrcweir             }
2181cdf0e10cSrcweir 
2182cdf0e10cSrcweir             rOrigPam.GetPoint()->nNode++;
2183cdf0e10cSrcweir             rOrigPam.GetPoint()->nContent.Assign( rOrigPam.GetCntntNode(), 0 );
2184cdf0e10cSrcweir 
2185cdf0e10cSrcweir             RedlineMode_t eOld = GetRedlineMode();
2186cdf0e10cSrcweir             checkRedlining(eOld);
2187cdf0e10cSrcweir             if (GetIDocumentUndoRedo().DoesUndo())
2188cdf0e10cSrcweir             {
2189cdf0e10cSrcweir                 //JP 06.01.98: MUSS noch optimiert werden!!!
2190cdf0e10cSrcweir                 SetRedlineMode(
2191cdf0e10cSrcweir                    (RedlineMode_t)(nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_SHOW_INSERT | nsRedlineMode_t::REDLINE_SHOW_DELETE));
2192cdf0e10cSrcweir                 SwUndo *const pUndo(new SwUndoRedlineDelete(aPam, UNDO_DELETE));
2193cdf0e10cSrcweir                 GetIDocumentUndoRedo().AppendUndo(pUndo);
2194cdf0e10cSrcweir             }
2195cdf0e10cSrcweir 
2196cdf0e10cSrcweir             SwRedline* pNewRedline = new SwRedline( nsRedlineType_t::REDLINE_DELETE, aPam );
2197cdf0e10cSrcweir 
2198cdf0e10cSrcweir             // #101654# prevent assertion from aPam's target being deleted
2199cdf0e10cSrcweir             // (Alternatively, one could just let aPam go out of scope, but
2200cdf0e10cSrcweir             //  that requires touching a lot of code.)
2201cdf0e10cSrcweir             aPam.GetBound(sal_True).nContent.Assign( NULL, 0 );
2202cdf0e10cSrcweir             aPam.GetBound(sal_False).nContent.Assign( NULL, 0 );
2203cdf0e10cSrcweir 
2204cdf0e10cSrcweir             AppendRedline( pNewRedline, true );
2205cdf0e10cSrcweir 
2206cdf0e10cSrcweir //JP 06.01.98: MUSS noch optimiert werden!!!
2207cdf0e10cSrcweir SetRedlineMode( eOld );
2208cdf0e10cSrcweir             GetIDocumentUndoRedo().EndUndo( UNDO_END, NULL );
2209cdf0e10cSrcweir             SetModified();
2210cdf0e10cSrcweir 
2211cdf0e10cSrcweir             return sal_True;
2212cdf0e10cSrcweir         }
2213cdf0e10cSrcweir     }
2214cdf0e10cSrcweir 
2215cdf0e10cSrcweir     if( !pOwnRedl && !IsIgnoreRedline() && GetRedlineTbl().Count() )
2216cdf0e10cSrcweir     {
2217cdf0e10cSrcweir         SwPaM aTemp(aIdx);
2218cdf0e10cSrcweir         SplitRedline(aTemp);
2219cdf0e10cSrcweir     }
2220cdf0e10cSrcweir 
2221cdf0e10cSrcweir     sal_uLong nRedlSttNd(0), nRedlEndNd(0);
2222cdf0e10cSrcweir     if( pOwnRedl )
2223cdf0e10cSrcweir     {
2224cdf0e10cSrcweir         const SwPosition *pRStt = pOwnRedl->Start(), *pREnd = pOwnRedl->End();
2225cdf0e10cSrcweir         nRedlSttNd = pRStt->nNode.GetIndex();
2226cdf0e10cSrcweir         nRedlEndNd = pREnd->nNode.GetIndex();
2227cdf0e10cSrcweir     }
2228cdf0e10cSrcweir 
2229cdf0e10cSrcweir     SwUndoMoveNum* pUndo = 0;
2230cdf0e10cSrcweir     sal_uLong nMoved = 0;
2231cdf0e10cSrcweir     if (GetIDocumentUndoRedo().DoesUndo())
2232cdf0e10cSrcweir     {
2233cdf0e10cSrcweir         pUndo = new SwUndoMoveNum( rPam, nOffset, bIsOutlMv );
2234cdf0e10cSrcweir         nMoved = rPam.End()->nNode.GetIndex() - rPam.Start()->nNode.GetIndex() + 1;
2235cdf0e10cSrcweir     }
2236cdf0e10cSrcweir 
2237cdf0e10cSrcweir 
2238cdf0e10cSrcweir     MoveNodeRange( aMvRg, aIdx, DOC_MOVEREDLINES );
2239cdf0e10cSrcweir 
2240cdf0e10cSrcweir     if( pUndo )
2241cdf0e10cSrcweir     {
2242cdf0e10cSrcweir         // i57907: Under circumstances (sections at the end of a chapter)
2243cdf0e10cSrcweir         // the rPam.Start() is not moved to the new position.
2244cdf0e10cSrcweir         // But aIdx should be at the new end position and as long as the number of moved paragraphs
2245cdf0e10cSrcweir         // is nMoved, I know, where the new position is.
2246cdf0e10cSrcweir         pUndo->SetStartNode( aIdx.GetIndex() - nMoved );
2247cdf0e10cSrcweir         GetIDocumentUndoRedo().AppendUndo(pUndo);
2248cdf0e10cSrcweir     }
2249cdf0e10cSrcweir 
2250cdf0e10cSrcweir     if( pOwnRedl )
2251cdf0e10cSrcweir     {
2252cdf0e10cSrcweir         SwPosition *pRStt = pOwnRedl->Start(), *pREnd = pOwnRedl->End();
2253cdf0e10cSrcweir         if( pRStt->nNode.GetIndex() != nRedlSttNd )
2254cdf0e10cSrcweir         {
2255cdf0e10cSrcweir             pRStt->nNode = nRedlSttNd;
2256cdf0e10cSrcweir             pRStt->nContent.Assign( pRStt->nNode.GetNode().GetCntntNode(),0);
2257cdf0e10cSrcweir         }
2258cdf0e10cSrcweir         if( pREnd->nNode.GetIndex() != nRedlEndNd )
2259cdf0e10cSrcweir         {
2260cdf0e10cSrcweir             pREnd->nNode = nRedlEndNd;
2261cdf0e10cSrcweir             SwCntntNode* pCNd = pREnd->nNode.GetNode().GetCntntNode();
2262cdf0e10cSrcweir             xub_StrLen nL = 0; if( pCNd ) nL = pCNd->Len();
2263cdf0e10cSrcweir             pREnd->nContent.Assign( pCNd, nL );
2264cdf0e10cSrcweir         }
2265cdf0e10cSrcweir     }
2266cdf0e10cSrcweir 
2267cdf0e10cSrcweir     SetModified();
2268cdf0e10cSrcweir     return sal_True;
2269cdf0e10cSrcweir }
2270cdf0e10cSrcweir 
NumOrNoNum(const SwNodeIndex & rIdx,sal_Bool bDel)2271cdf0e10cSrcweir sal_Bool SwDoc::NumOrNoNum( const SwNodeIndex& rIdx, sal_Bool bDel )
2272cdf0e10cSrcweir {
2273cdf0e10cSrcweir     sal_Bool bResult = sal_False;
2274cdf0e10cSrcweir     SwTxtNode * pTxtNd = rIdx.GetNode().GetTxtNode();
2275cdf0e10cSrcweir 
2276cdf0e10cSrcweir     if (pTxtNd && pTxtNd->GetNumRule() != NULL &&
2277cdf0e10cSrcweir         (pTxtNd->HasNumber() || pTxtNd->HasBullet()))
2278cdf0e10cSrcweir     {
2279cdf0e10cSrcweir         if ( !pTxtNd->IsCountedInList() == !bDel)
2280cdf0e10cSrcweir         {
2281cdf0e10cSrcweir             sal_Bool bOldNum = bDel; // == pTxtNd->IsCounted();
2282cdf0e10cSrcweir             sal_Bool bNewNum = bDel ? sal_False : sal_True;
2283cdf0e10cSrcweir             pTxtNd->SetCountedInList(bNewNum ? true : false);
2284cdf0e10cSrcweir 
2285cdf0e10cSrcweir             SetModified();
2286cdf0e10cSrcweir 
2287cdf0e10cSrcweir             bResult = sal_True;
2288cdf0e10cSrcweir 
2289cdf0e10cSrcweir             if (GetIDocumentUndoRedo().DoesUndo())
2290cdf0e10cSrcweir             {
2291cdf0e10cSrcweir                 SwUndoNumOrNoNum * pUndo =
2292cdf0e10cSrcweir                     new SwUndoNumOrNoNum(rIdx, bOldNum, bNewNum);
2293cdf0e10cSrcweir 
2294cdf0e10cSrcweir                 GetIDocumentUndoRedo().AppendUndo(pUndo);
2295cdf0e10cSrcweir             }
2296cdf0e10cSrcweir         }
2297cdf0e10cSrcweir         else if (bDel && pTxtNd->GetNumRule(sal_False) &&
2298cdf0e10cSrcweir                  pTxtNd->GetActualListLevel() >= 0 &&
2299cdf0e10cSrcweir                  pTxtNd->GetActualListLevel() < MAXLEVEL)
2300cdf0e10cSrcweir         {
2301cdf0e10cSrcweir             SwPaM aPam(*pTxtNd);
2302cdf0e10cSrcweir 
2303cdf0e10cSrcweir             DelNumRules(aPam);
2304cdf0e10cSrcweir 
2305cdf0e10cSrcweir             bResult = sal_True;
2306cdf0e10cSrcweir         }
2307cdf0e10cSrcweir     }
2308cdf0e10cSrcweir 
2309cdf0e10cSrcweir     return bResult;
2310cdf0e10cSrcweir }
2311cdf0e10cSrcweir 
GetNumRuleAtPos(const SwPosition & rPos) const231234760e49SOliver-Rainer Wittmann SwNumRule* SwDoc::GetNumRuleAtPos( const SwPosition& rPos ) const
2313cdf0e10cSrcweir {
231434760e49SOliver-Rainer Wittmann     SwNumRule* pRet = NULL;
2315cdf0e10cSrcweir     SwTxtNode* pTNd = rPos.nNode.GetNode().GetTxtNode();
2316cdf0e10cSrcweir 
231734760e49SOliver-Rainer Wittmann     if ( pTNd != NULL )
2318cdf0e10cSrcweir     {
2319cdf0e10cSrcweir         pRet = pTNd->GetNumRule();
2320cdf0e10cSrcweir     }
2321cdf0e10cSrcweir 
2322cdf0e10cSrcweir     return pRet;
2323cdf0e10cSrcweir }
2324cdf0e10cSrcweir 
FindNumRule(const String & rName) const2325cdf0e10cSrcweir sal_uInt16 SwDoc::FindNumRule( const String& rName ) const
2326cdf0e10cSrcweir {
2327cdf0e10cSrcweir     for( sal_uInt16 n = pNumRuleTbl->Count(); n; )
2328cdf0e10cSrcweir         if( (*pNumRuleTbl)[ --n ]->GetName() == rName )
2329cdf0e10cSrcweir             return n;
2330cdf0e10cSrcweir 
2331cdf0e10cSrcweir     return USHRT_MAX;
2332cdf0e10cSrcweir }
2333cdf0e10cSrcweir 
FindNumRulePtr(const String & rName) const2334cdf0e10cSrcweir SwNumRule* SwDoc::FindNumRulePtr( const String& rName ) const
2335cdf0e10cSrcweir {
2336cdf0e10cSrcweir     SwNumRule * pResult = 0;
2337cdf0e10cSrcweir 
2338cdf0e10cSrcweir     pResult = maNumRuleMap[rName];
2339cdf0e10cSrcweir 
2340cdf0e10cSrcweir     if ( !pResult )
2341cdf0e10cSrcweir     {
2342cdf0e10cSrcweir         for (sal_uInt16 n = 0; n < pNumRuleTbl->Count(); ++n)
2343cdf0e10cSrcweir         {
2344cdf0e10cSrcweir             if ((*pNumRuleTbl)[n]->GetName() == rName)
2345cdf0e10cSrcweir             {
2346cdf0e10cSrcweir                 pResult = (*pNumRuleTbl)[n];
2347cdf0e10cSrcweir 
2348cdf0e10cSrcweir                 break;
2349cdf0e10cSrcweir             }
2350cdf0e10cSrcweir         }
2351cdf0e10cSrcweir     }
2352cdf0e10cSrcweir 
2353cdf0e10cSrcweir     return pResult;
2354cdf0e10cSrcweir }
2355cdf0e10cSrcweir 
2356cdf0e10cSrcweir // #i36749#
AddNumRule(SwNumRule * pRule)2357cdf0e10cSrcweir void SwDoc::AddNumRule(SwNumRule * pRule)
2358cdf0e10cSrcweir {
2359b264d727SArmin Le Grand     if ((SAL_MAX_UINT16 - 1) <= pNumRuleTbl->Count())
2360b264d727SArmin Le Grand     {
2361b264d727SArmin Le Grand         OSL_ENSURE(false, "SwDoc::AddNumRule: table full.");
2362b264d727SArmin Le Grand         abort(); // this should never happen on real documents
2363b264d727SArmin Le Grand     }
2364cdf0e10cSrcweir     pNumRuleTbl->Insert(pRule, pNumRuleTbl->Count());
2365cdf0e10cSrcweir     maNumRuleMap[pRule->GetName()] = pRule;
2366cdf0e10cSrcweir     pRule->SetNumRuleMap(&maNumRuleMap);
2367cdf0e10cSrcweir 
2368cdf0e10cSrcweir     // --> OD 2008-03-26 #refactorlists#
2369cdf0e10cSrcweir     createListForListStyle( pRule->GetName() );
2370cdf0e10cSrcweir     // <--
2371cdf0e10cSrcweir }
2372cdf0e10cSrcweir 
2373cdf0e10cSrcweir // --> OD 2008-02-11 #newlistlevelattrs#
MakeNumRule(const String & rName,const SwNumRule * pCpy,sal_Bool bBroadcast,const SvxNumberFormat::SvxNumPositionAndSpaceMode eDefaultNumberFormatPositionAndSpaceMode)2374cdf0e10cSrcweir sal_uInt16 SwDoc::MakeNumRule( const String &rName,
2375cdf0e10cSrcweir             const SwNumRule* pCpy,
2376cdf0e10cSrcweir             sal_Bool bBroadcast,
2377cdf0e10cSrcweir             const SvxNumberFormat::SvxNumPositionAndSpaceMode eDefaultNumberFormatPositionAndSpaceMode )
2378cdf0e10cSrcweir {
2379cdf0e10cSrcweir     SwNumRule* pNew;
2380cdf0e10cSrcweir     if( pCpy )
2381cdf0e10cSrcweir     {
2382cdf0e10cSrcweir         pNew = new SwNumRule( *pCpy );
2383cdf0e10cSrcweir 
2384cdf0e10cSrcweir         // --> OD 2008-07-08 #i91400#
2385cdf0e10cSrcweir         pNew->SetName( GetUniqueNumRuleName( &rName ), *this );
2386cdf0e10cSrcweir         // <--
2387cdf0e10cSrcweir         if( pNew->GetName() != rName )
2388cdf0e10cSrcweir         {
2389cdf0e10cSrcweir             pNew->SetPoolFmtId( USHRT_MAX );
2390cdf0e10cSrcweir             pNew->SetPoolHelpId( USHRT_MAX );
2391cdf0e10cSrcweir             pNew->SetPoolHlpFileId( UCHAR_MAX );
2392cdf0e10cSrcweir             // --> OD 2008-04-03 #refactorlists#
2393cdf0e10cSrcweir             pNew->SetDefaultListId( String() );
2394cdf0e10cSrcweir             // <--
2395cdf0e10cSrcweir         }
2396cdf0e10cSrcweir         pNew->CheckCharFmts( this );
2397cdf0e10cSrcweir     }
2398cdf0e10cSrcweir     else
2399cdf0e10cSrcweir     {
2400cdf0e10cSrcweir         // --> OD 2008-02-11 #newlistlevelattrs#
2401cdf0e10cSrcweir         pNew = new SwNumRule( GetUniqueNumRuleName( &rName ),
2402cdf0e10cSrcweir                               eDefaultNumberFormatPositionAndSpaceMode );
2403cdf0e10cSrcweir         // <--
2404cdf0e10cSrcweir     }
2405cdf0e10cSrcweir 
2406cdf0e10cSrcweir     sal_uInt16 nRet = pNumRuleTbl->Count();
2407cdf0e10cSrcweir 
2408cdf0e10cSrcweir     AddNumRule(pNew); // #i36749#
2409cdf0e10cSrcweir 
2410cdf0e10cSrcweir     if (GetIDocumentUndoRedo().DoesUndo())
2411cdf0e10cSrcweir     {
2412cdf0e10cSrcweir         SwUndo * pUndo = new SwUndoNumruleCreate(pNew, this);
2413cdf0e10cSrcweir         GetIDocumentUndoRedo().AppendUndo(pUndo);
2414cdf0e10cSrcweir     }
2415cdf0e10cSrcweir 
2416cdf0e10cSrcweir     if (bBroadcast)
2417cdf0e10cSrcweir         BroadcastStyleOperation(pNew->GetName(), SFX_STYLE_FAMILY_PSEUDO,
2418cdf0e10cSrcweir                                 SFX_STYLESHEET_CREATED);
2419cdf0e10cSrcweir 
2420cdf0e10cSrcweir     return nRet;
2421cdf0e10cSrcweir }
2422cdf0e10cSrcweir 
GetUniqueNumRuleName(const String * pChkStr,sal_Bool bAutoNum) const2423cdf0e10cSrcweir String SwDoc::GetUniqueNumRuleName( const String* pChkStr, sal_Bool bAutoNum ) const
2424cdf0e10cSrcweir {
2425cdf0e10cSrcweir     String aName;
2426cdf0e10cSrcweir     if( bAutoNum )
2427cdf0e10cSrcweir     {
24283d14cea3SMichael Stahl         // --> OD #o12311627#
24293d14cea3SMichael Stahl         static rtlRandomPool s_RandomPool( rtl_random_createPool() );
24303d14cea3SMichael Stahl         sal_Int64 n;
24313d14cea3SMichael Stahl         rtl_random_getBytes( s_RandomPool, &n, sizeof(n) );
24323d14cea3SMichael Stahl         aName = String::CreateFromInt64( (n < 0 ? -n : n) );
24333d14cea3SMichael Stahl         // <--
2434cdf0e10cSrcweir         if( pChkStr && !pChkStr->Len() )
2435cdf0e10cSrcweir             pChkStr = 0;
2436cdf0e10cSrcweir     }
2437cdf0e10cSrcweir     else if( pChkStr && pChkStr->Len() )
2438cdf0e10cSrcweir         aName = *pChkStr;
2439cdf0e10cSrcweir     else
2440cdf0e10cSrcweir     {
2441cdf0e10cSrcweir         pChkStr = 0;
2442cdf0e10cSrcweir         aName = SW_RESSTR( STR_NUMRULE_DEFNAME );
2443cdf0e10cSrcweir     }
2444cdf0e10cSrcweir 
2445cdf0e10cSrcweir     sal_uInt16 nNum(0), nTmp, nFlagSize = ( pNumRuleTbl->Count() / 8 ) +2;
2446cdf0e10cSrcweir     sal_uInt8* pSetFlags = new sal_uInt8[ nFlagSize ];
2447cdf0e10cSrcweir     memset( pSetFlags, 0, nFlagSize );
2448cdf0e10cSrcweir 
2449cdf0e10cSrcweir     xub_StrLen nNmLen = aName.Len();
2450cdf0e10cSrcweir     if( !bAutoNum && pChkStr )
2451cdf0e10cSrcweir     {
2452cdf0e10cSrcweir         while( nNmLen-- && '0' <= aName.GetChar( nNmLen ) &&
2453cdf0e10cSrcweir                            '9' >= aName.GetChar( nNmLen ) )
2454cdf0e10cSrcweir             ; //nop
2455cdf0e10cSrcweir 
2456cdf0e10cSrcweir         if( ++nNmLen < aName.Len() )
2457cdf0e10cSrcweir         {
2458cdf0e10cSrcweir             aName.Erase( nNmLen );
2459cdf0e10cSrcweir             pChkStr = 0;
2460cdf0e10cSrcweir         }
2461cdf0e10cSrcweir     }
2462cdf0e10cSrcweir 
2463cdf0e10cSrcweir     const SwNumRule* pNumRule;
2464cdf0e10cSrcweir     sal_uInt16 n;
2465cdf0e10cSrcweir 
2466cdf0e10cSrcweir     for( n = 0; n < pNumRuleTbl->Count(); ++n )
2467cdf0e10cSrcweir         if( 0 != ( pNumRule = (*pNumRuleTbl)[ n ] ) )
2468cdf0e10cSrcweir         {
2469cdf0e10cSrcweir             const String& rNm = pNumRule->GetName();
2470cdf0e10cSrcweir             if( rNm.Match( aName ) == nNmLen )
2471cdf0e10cSrcweir             {
2472cdf0e10cSrcweir                 // Nummer bestimmen und das Flag setzen
2473cdf0e10cSrcweir                 nNum = (sal_uInt16)rNm.Copy( nNmLen ).ToInt32();
2474cdf0e10cSrcweir                 if( nNum-- && nNum < pNumRuleTbl->Count() )
2475cdf0e10cSrcweir                     pSetFlags[ nNum / 8 ] |= (0x01 << ( nNum & 0x07 ));
2476cdf0e10cSrcweir             }
2477cdf0e10cSrcweir             if( pChkStr && pChkStr->Equals( rNm ) )
2478cdf0e10cSrcweir                 pChkStr = 0;
2479cdf0e10cSrcweir         }
2480cdf0e10cSrcweir 
2481cdf0e10cSrcweir     if( !pChkStr )
2482cdf0e10cSrcweir     {
2483cdf0e10cSrcweir         // alle Nummern entsprechend geflag, also bestimme die richtige Nummer
2484cdf0e10cSrcweir         nNum = pNumRuleTbl->Count();
2485cdf0e10cSrcweir         for( n = 0; n < nFlagSize; ++n )
2486cdf0e10cSrcweir             if( 0xff != ( nTmp = pSetFlags[ n ] ))
2487cdf0e10cSrcweir             {
2488cdf0e10cSrcweir                 // also die Nummer bestimmen
2489cdf0e10cSrcweir                 nNum = n * 8;
2490cdf0e10cSrcweir                 while( nTmp & 1 )
2491cdf0e10cSrcweir                     ++nNum, nTmp >>= 1;
2492cdf0e10cSrcweir                 break;
2493cdf0e10cSrcweir             }
2494cdf0e10cSrcweir 
2495cdf0e10cSrcweir     }
2496cdf0e10cSrcweir     delete [] pSetFlags;
2497cdf0e10cSrcweir     if( pChkStr && pChkStr->Len() )
2498cdf0e10cSrcweir         return *pChkStr;
2499cdf0e10cSrcweir     return aName += String::CreateFromInt32( ++nNum );
2500cdf0e10cSrcweir }
2501cdf0e10cSrcweir 
UpdateNumRule()2502cdf0e10cSrcweir void SwDoc::UpdateNumRule()
2503cdf0e10cSrcweir {
2504cdf0e10cSrcweir     const SwNumRuleTbl& rNmTbl = GetNumRuleTbl();
2505cdf0e10cSrcweir     for( sal_uInt16 n = 0; n < rNmTbl.Count(); ++n )
2506cdf0e10cSrcweir         if( rNmTbl[ n ]->IsInvalidRule() )
2507cdf0e10cSrcweir             rNmTbl[ n ]->Validate();
2508cdf0e10cSrcweir }
2509cdf0e10cSrcweir 
251034760e49SOliver-Rainer Wittmann 
MarkListLevel(const String & sListId,const int nListLevel,const sal_Bool bValue)2511cdf0e10cSrcweir void SwDoc::MarkListLevel( const String& sListId,
2512cdf0e10cSrcweir                            const int nListLevel,
2513cdf0e10cSrcweir                            const sal_Bool bValue )
2514cdf0e10cSrcweir {
2515cdf0e10cSrcweir     SwList* pList = getListByName( sListId );
2516cdf0e10cSrcweir 
2517cdf0e10cSrcweir     if ( pList )
2518cdf0e10cSrcweir     {
2519cdf0e10cSrcweir         MarkListLevel( *pList, nListLevel, bValue );
2520cdf0e10cSrcweir     }
2521cdf0e10cSrcweir }
2522cdf0e10cSrcweir 
MarkListLevel(SwList & rList,const int nListLevel,const sal_Bool bValue)2523cdf0e10cSrcweir void SwDoc::MarkListLevel( SwList& rList,
2524cdf0e10cSrcweir                            const int nListLevel,
2525cdf0e10cSrcweir                            const sal_Bool bValue )
2526cdf0e10cSrcweir {
2527cdf0e10cSrcweir     // Set new marked list level and notify all affected nodes of the changed mark.
2528cdf0e10cSrcweir     rList.MarkListLevel( nListLevel, bValue );
2529cdf0e10cSrcweir }
2530cdf0e10cSrcweir 
253134760e49SOliver-Rainer Wittmann 
IsFirstOfNumRuleAtPos(const SwPosition & rPos)253234760e49SOliver-Rainer Wittmann bool SwDoc::IsFirstOfNumRuleAtPos( const SwPosition & rPos )
2533cdf0e10cSrcweir {
253434760e49SOliver-Rainer Wittmann     bool bResult = false;
2535cdf0e10cSrcweir 
253634760e49SOliver-Rainer Wittmann     const SwTxtNode* pTxtNode = rPos.nNode.GetNode().GetTxtNode();
253734760e49SOliver-Rainer Wittmann     if ( pTxtNode != NULL )
2538cdf0e10cSrcweir     {
2539cdf0e10cSrcweir         bResult = pTxtNode->IsFirstOfNumRule();
2540cdf0e10cSrcweir     }
2541cdf0e10cSrcweir 
2542cdf0e10cSrcweir     return bResult;
2543cdf0e10cSrcweir }
2544cdf0e10cSrcweir 
254534760e49SOliver-Rainer Wittmann 
2546cdf0e10cSrcweir // implementation for interface <IDocumentListItems>
operator ()(const SwNodeNum * pNodeNumOne,const SwNodeNum * pNodeNumTwo) const2547cdf0e10cSrcweir bool SwDoc::lessThanNodeNum::operator()( const SwNodeNum* pNodeNumOne,
2548cdf0e10cSrcweir                                          const SwNodeNum* pNodeNumTwo ) const
2549cdf0e10cSrcweir {
2550cdf0e10cSrcweir     return pNodeNumOne->LessThan( *pNodeNumTwo );
2551cdf0e10cSrcweir }
2552cdf0e10cSrcweir 
addListItem(const SwNodeNum & rNodeNum)2553cdf0e10cSrcweir void SwDoc::addListItem( const SwNodeNum& rNodeNum )
2554cdf0e10cSrcweir {
2555cdf0e10cSrcweir     if ( mpListItemsList == 0 )
2556cdf0e10cSrcweir     {
2557cdf0e10cSrcweir         return;
2558cdf0e10cSrcweir     }
2559cdf0e10cSrcweir 
2560cdf0e10cSrcweir     const bool bAlreadyInserted(
2561cdf0e10cSrcweir             mpListItemsList->find( &rNodeNum ) != mpListItemsList->end() );
2562cdf0e10cSrcweir     ASSERT( !bAlreadyInserted,
2563cdf0e10cSrcweir             "<SwDoc::InsertListItem(..)> - <SwNodeNum> instance already registered as numbered item!" );
2564cdf0e10cSrcweir     if ( !bAlreadyInserted )
2565cdf0e10cSrcweir     {
2566cdf0e10cSrcweir         mpListItemsList->insert( &rNodeNum );
2567cdf0e10cSrcweir     }
2568cdf0e10cSrcweir }
2569cdf0e10cSrcweir 
removeListItem(const SwNodeNum & rNodeNum)2570cdf0e10cSrcweir void SwDoc::removeListItem( const SwNodeNum& rNodeNum )
2571cdf0e10cSrcweir {
2572cdf0e10cSrcweir     if ( mpListItemsList == 0 )
2573cdf0e10cSrcweir     {
2574cdf0e10cSrcweir         return;
2575cdf0e10cSrcweir     }
2576cdf0e10cSrcweir 
2577cdf0e10cSrcweir     const tImplSortedNodeNumList::size_type nDeleted = mpListItemsList->erase( &rNodeNum );
2578cdf0e10cSrcweir     if ( nDeleted > 1 )
2579cdf0e10cSrcweir     {
2580cdf0e10cSrcweir         ASSERT( false,
2581cdf0e10cSrcweir                 "<SwDoc::RemoveListItem(..)> - <SwNodeNum> was registered more than once as numbered item!" );
2582cdf0e10cSrcweir     }
2583cdf0e10cSrcweir }
2584cdf0e10cSrcweir 
getListItemText(const SwNodeNum & rNodeNum,const bool bWithNumber,const bool bWithSpacesForLevel) const2585cdf0e10cSrcweir String SwDoc::getListItemText( const SwNodeNum& rNodeNum,
2586cdf0e10cSrcweir                                const bool bWithNumber,
2587cdf0e10cSrcweir                                const bool bWithSpacesForLevel ) const
2588cdf0e10cSrcweir {
2589cdf0e10cSrcweir     return rNodeNum.GetTxtNode()
2590cdf0e10cSrcweir            ? rNodeNum.GetTxtNode()->GetExpandTxt( 0, STRING_LEN, bWithNumber,
2591cdf0e10cSrcweir                                                   bWithNumber, bWithSpacesForLevel )
2592cdf0e10cSrcweir            : String();
2593cdf0e10cSrcweir }
2594cdf0e10cSrcweir 
getListItems(tSortedNodeNumList & orNodeNumList) const2595cdf0e10cSrcweir void SwDoc::getListItems( tSortedNodeNumList& orNodeNumList ) const
2596cdf0e10cSrcweir {
2597cdf0e10cSrcweir     orNodeNumList.clear();
2598cdf0e10cSrcweir     orNodeNumList.reserve( mpListItemsList->size() );
2599cdf0e10cSrcweir 
2600cdf0e10cSrcweir     tImplSortedNodeNumList::iterator aIter;
2601cdf0e10cSrcweir     tImplSortedNodeNumList::iterator aEndIter = mpListItemsList->end();
2602cdf0e10cSrcweir     for ( aIter = mpListItemsList->begin(); aIter != aEndIter; ++aIter )
2603cdf0e10cSrcweir     {
2604cdf0e10cSrcweir         orNodeNumList.push_back( (*aIter) );
2605cdf0e10cSrcweir     }
2606cdf0e10cSrcweir }
2607cdf0e10cSrcweir 
getNumItems(tSortedNodeNumList & orNodeNumList) const2608cdf0e10cSrcweir void SwDoc::getNumItems( tSortedNodeNumList& orNodeNumList ) const
2609cdf0e10cSrcweir {
2610cdf0e10cSrcweir     orNodeNumList.clear();
2611cdf0e10cSrcweir     orNodeNumList.reserve( mpListItemsList->size() );
2612cdf0e10cSrcweir 
2613cdf0e10cSrcweir     tImplSortedNodeNumList::iterator aIter;
2614cdf0e10cSrcweir     tImplSortedNodeNumList::iterator aEndIter = mpListItemsList->end();
2615cdf0e10cSrcweir     for ( aIter = mpListItemsList->begin(); aIter != aEndIter; ++aIter )
2616cdf0e10cSrcweir     {
2617cdf0e10cSrcweir         const SwNodeNum* pNodeNum = (*aIter);
2618cdf0e10cSrcweir         if ( pNodeNum->IsCounted() &&
2619cdf0e10cSrcweir              pNodeNum->GetTxtNode() && pNodeNum->GetTxtNode()->HasNumber() )
2620cdf0e10cSrcweir         {
2621cdf0e10cSrcweir             orNodeNumList.push_back( pNodeNum );
2622cdf0e10cSrcweir         }
2623cdf0e10cSrcweir     }
2624cdf0e10cSrcweir }
2625cdf0e10cSrcweir 
262634760e49SOliver-Rainer Wittmann 
2627cdf0e10cSrcweir // implementation for interface <IDocumentOutlineNodes>
getOutlineNodesCount() const2628cdf0e10cSrcweir sal_Int32 SwDoc::getOutlineNodesCount() const
2629cdf0e10cSrcweir {
2630cdf0e10cSrcweir     return GetNodes().GetOutLineNds().Count();
2631cdf0e10cSrcweir }
2632cdf0e10cSrcweir 
getOutlineLevel(const sal_Int32 nIdx) const2633cdf0e10cSrcweir int SwDoc::getOutlineLevel( const sal_Int32 nIdx ) const
2634cdf0e10cSrcweir {
2635cdf0e10cSrcweir     return GetNodes().GetOutLineNds()[ static_cast<sal_uInt16>(nIdx) ]->
2636cdf0e10cSrcweir                                            // GetTxtNode()->GetOutlineLevel();              //#outline level,zhaojianwei
2637cdf0e10cSrcweir                                 GetTxtNode()->GetAttrOutlineLevel()-1;  //<-end,zhaojianwei
2638cdf0e10cSrcweir }
2639cdf0e10cSrcweir 
getOutlineText(const sal_Int32 nIdx,const bool bWithNumber,const bool bWithSpacesForLevel) const2640cdf0e10cSrcweir String SwDoc::getOutlineText( const sal_Int32 nIdx,
2641cdf0e10cSrcweir                               const bool bWithNumber,
2642cdf0e10cSrcweir                               const bool bWithSpacesForLevel ) const
2643cdf0e10cSrcweir {
2644cdf0e10cSrcweir     return GetNodes().GetOutLineNds()[ static_cast<sal_uInt16>(nIdx) ]->
2645cdf0e10cSrcweir                 GetTxtNode()->GetExpandTxt( 0, STRING_LEN, bWithNumber,
2646cdf0e10cSrcweir                                             bWithNumber, bWithSpacesForLevel );
2647cdf0e10cSrcweir }
2648cdf0e10cSrcweir 
getOutlineNode(const sal_Int32 nIdx) const2649cdf0e10cSrcweir SwTxtNode* SwDoc::getOutlineNode( const sal_Int32 nIdx ) const
2650cdf0e10cSrcweir {
2651cdf0e10cSrcweir     return GetNodes().GetOutLineNds()[ static_cast<sal_uInt16>(nIdx) ]->GetTxtNode();
2652cdf0e10cSrcweir }
2653cdf0e10cSrcweir 
getOutlineNodes(IDocumentOutlineNodes::tSortedOutlineNodeList & orOutlineNodeList) const2654cdf0e10cSrcweir void SwDoc::getOutlineNodes( IDocumentOutlineNodes::tSortedOutlineNodeList& orOutlineNodeList ) const
2655cdf0e10cSrcweir {
2656cdf0e10cSrcweir     orOutlineNodeList.clear();
2657cdf0e10cSrcweir     orOutlineNodeList.reserve( getOutlineNodesCount() );
2658cdf0e10cSrcweir 
2659cdf0e10cSrcweir     const sal_uInt16 nOutlCount( static_cast<sal_uInt16>(getOutlineNodesCount()) );
2660cdf0e10cSrcweir     for ( sal_uInt16 i = 0; i < nOutlCount; ++i )
2661cdf0e10cSrcweir     {
2662cdf0e10cSrcweir         orOutlineNodeList.push_back(
2663cdf0e10cSrcweir             GetNodes().GetOutLineNds()[i]->GetTxtNode() );
2664cdf0e10cSrcweir     }
2665cdf0e10cSrcweir }
2666cdf0e10cSrcweir // <--
2667cdf0e10cSrcweir 
2668cdf0e10cSrcweir // --> OD 2008-03-26 #refactorlists#
2669cdf0e10cSrcweir // implementation of interface IDocumentListsAccess
createList(String sListId,const String sDefaultListStyleName)2670cdf0e10cSrcweir SwList* SwDoc::createList( String sListId,
2671cdf0e10cSrcweir                            const String sDefaultListStyleName )
2672cdf0e10cSrcweir {
2673cdf0e10cSrcweir     if ( sListId.Len() == 0 )
2674cdf0e10cSrcweir     {
2675cdf0e10cSrcweir         sListId = listfunc::CreateUniqueListId( *this );
2676cdf0e10cSrcweir     }
2677cdf0e10cSrcweir 
2678cdf0e10cSrcweir     if ( getListByName( sListId ) )
2679cdf0e10cSrcweir     {
2680cdf0e10cSrcweir         ASSERT( false,
2681cdf0e10cSrcweir                 "<SwDoc::createList(..)> - provided list id already used. Serious defect -> please inform OD." );
2682cdf0e10cSrcweir         return 0;
2683cdf0e10cSrcweir     }
2684cdf0e10cSrcweir 
2685cdf0e10cSrcweir     SwNumRule* pDefaultNumRuleForNewList = FindNumRulePtr( sDefaultListStyleName );
2686cdf0e10cSrcweir     if ( !pDefaultNumRuleForNewList )
2687cdf0e10cSrcweir     {
2688cdf0e10cSrcweir         ASSERT( false,
2689cdf0e10cSrcweir                 "<SwDoc::createList(..)> - for provided default list style name no list style is found. Serious defect -> please inform OD." );
2690cdf0e10cSrcweir         return 0;
2691cdf0e10cSrcweir     }
2692cdf0e10cSrcweir 
2693cdf0e10cSrcweir     SwList* pNewList = new SwList( sListId, *pDefaultNumRuleForNewList, GetNodes() );
2694cdf0e10cSrcweir     maLists[sListId] = pNewList;
2695cdf0e10cSrcweir 
2696cdf0e10cSrcweir     return pNewList;
2697cdf0e10cSrcweir }
2698cdf0e10cSrcweir 
deleteList(const String sListId)2699cdf0e10cSrcweir void SwDoc::deleteList( const String sListId )
2700cdf0e10cSrcweir {
2701cdf0e10cSrcweir     SwList* pList = getListByName( sListId );
2702cdf0e10cSrcweir     if ( pList )
2703cdf0e10cSrcweir     {
2704cdf0e10cSrcweir         maLists.erase( sListId );
2705cdf0e10cSrcweir         delete pList;
2706cdf0e10cSrcweir     }
2707cdf0e10cSrcweir }
2708cdf0e10cSrcweir 
getListByName(const String sListId) const2709cdf0e10cSrcweir SwList* SwDoc::getListByName( const String sListId ) const
2710cdf0e10cSrcweir {
2711cdf0e10cSrcweir     SwList* pList = 0;
2712cdf0e10cSrcweir 
2713cdf0e10cSrcweir     std::hash_map< String, SwList*, StringHash >::const_iterator
2714cdf0e10cSrcweir                                             aListIter = maLists.find( sListId );
2715cdf0e10cSrcweir     if ( aListIter != maLists.end() )
2716cdf0e10cSrcweir     {
2717cdf0e10cSrcweir         pList = (*aListIter).second;
2718cdf0e10cSrcweir     }
2719cdf0e10cSrcweir 
2720cdf0e10cSrcweir     return pList;
2721cdf0e10cSrcweir }
2722cdf0e10cSrcweir 
createListForListStyle(const String sListStyleName)2723cdf0e10cSrcweir SwList* SwDoc::createListForListStyle( const String sListStyleName )
2724cdf0e10cSrcweir {
2725cdf0e10cSrcweir     if ( sListStyleName.Len() == 0 )
2726cdf0e10cSrcweir     {
2727cdf0e10cSrcweir         ASSERT( false,
2728cdf0e10cSrcweir                 "<SwDoc::createListForListStyle(..)> - no list style name provided. Serious defect -> please inform OD." );
2729cdf0e10cSrcweir         return 0;
2730cdf0e10cSrcweir     }
2731cdf0e10cSrcweir 
2732cdf0e10cSrcweir     if ( getListForListStyle( sListStyleName ) )
2733cdf0e10cSrcweir     {
2734cdf0e10cSrcweir         ASSERT( false,
2735cdf0e10cSrcweir                 "<SwDoc::createListForListStyle(..)> - a list for the provided list style name already exists. Serious defect -> please inform OD." );
2736cdf0e10cSrcweir         return 0;
2737cdf0e10cSrcweir     }
2738cdf0e10cSrcweir 
2739cdf0e10cSrcweir     SwNumRule* pNumRule = FindNumRulePtr( sListStyleName );
2740cdf0e10cSrcweir     if ( !pNumRule )
2741cdf0e10cSrcweir     {
2742cdf0e10cSrcweir         ASSERT( false,
2743cdf0e10cSrcweir                 "<SwDoc::createListForListStyle(..)> - for provided list style name no list style is found. Serious defect -> please inform OD." );
2744cdf0e10cSrcweir         return 0;
2745cdf0e10cSrcweir     }
2746cdf0e10cSrcweir 
2747cdf0e10cSrcweir     String sListId( pNumRule->GetDefaultListId() ); // can be empty String
2748cdf0e10cSrcweir     if ( getListByName( sListId ) )
2749cdf0e10cSrcweir     {
2750cdf0e10cSrcweir         sListId = String();
2751cdf0e10cSrcweir     }
2752cdf0e10cSrcweir     SwList* pNewList = createList( sListId, sListStyleName );
2753cdf0e10cSrcweir     maListStyleLists[sListStyleName] = pNewList;
2754cdf0e10cSrcweir     pNumRule->SetDefaultListId( pNewList->GetListId() );
2755cdf0e10cSrcweir 
2756cdf0e10cSrcweir     return pNewList;
2757cdf0e10cSrcweir }
2758cdf0e10cSrcweir 
getListForListStyle(const String sListStyleName) const2759cdf0e10cSrcweir SwList* SwDoc::getListForListStyle( const String sListStyleName ) const
2760cdf0e10cSrcweir {
2761cdf0e10cSrcweir     SwList* pList = 0;
2762cdf0e10cSrcweir 
2763cdf0e10cSrcweir     std::hash_map< String, SwList*, StringHash >::const_iterator
2764cdf0e10cSrcweir                             aListIter = maListStyleLists.find( sListStyleName );
2765cdf0e10cSrcweir     if ( aListIter != maListStyleLists.end() )
2766cdf0e10cSrcweir     {
2767cdf0e10cSrcweir         pList = (*aListIter).second;
2768cdf0e10cSrcweir     }
2769cdf0e10cSrcweir 
2770cdf0e10cSrcweir     return pList;
2771cdf0e10cSrcweir }
2772cdf0e10cSrcweir 
deleteListForListStyle(const String sListStyleName)2773cdf0e10cSrcweir void SwDoc::deleteListForListStyle( const String sListStyleName )
2774cdf0e10cSrcweir {
2775cdf0e10cSrcweir     String sListId;
2776cdf0e10cSrcweir     {
2777cdf0e10cSrcweir         SwList* pList = getListForListStyle( sListStyleName );
2778cdf0e10cSrcweir         ASSERT( pList,
2779cdf0e10cSrcweir                 "<SwDoc::deleteListForListStyle(..)> - misusage of method: no list found for given list style name" );
2780cdf0e10cSrcweir         if ( pList )
2781cdf0e10cSrcweir         {
2782cdf0e10cSrcweir             sListId = pList->GetListId();
2783cdf0e10cSrcweir         }
2784cdf0e10cSrcweir     }
2785cdf0e10cSrcweir     if ( sListId.Len() > 0 )
2786cdf0e10cSrcweir     {
2787cdf0e10cSrcweir         maListStyleLists.erase( sListStyleName );
2788cdf0e10cSrcweir         deleteList( sListId );
2789cdf0e10cSrcweir     }
2790cdf0e10cSrcweir }
2791cdf0e10cSrcweir // <--
2792cdf0e10cSrcweir // --> OD 2008-07-08 #i91400#
trackChangeOfListStyleName(const String sListStyleName,const String sNewListStyleName)2793cdf0e10cSrcweir void SwDoc::trackChangeOfListStyleName( const String sListStyleName,
2794cdf0e10cSrcweir                                         const String sNewListStyleName )
2795cdf0e10cSrcweir {
2796cdf0e10cSrcweir     SwList* pList = getListForListStyle( sListStyleName );
2797cdf0e10cSrcweir     ASSERT( pList,
2798cdf0e10cSrcweir             "<SwDoc::changeOfListStyleName(..)> - misusage of method: no list found for given list style name" );
2799cdf0e10cSrcweir 
2800cdf0e10cSrcweir     if ( pList != 0 )
2801cdf0e10cSrcweir     {
2802cdf0e10cSrcweir         maListStyleLists.erase( sListStyleName );
2803cdf0e10cSrcweir         maListStyleLists[sNewListStyleName] = pList;
2804cdf0e10cSrcweir     }
2805cdf0e10cSrcweir }
2806cdf0e10cSrcweir // <--
2807cdf0e10cSrcweir 
2808cdf0e10cSrcweir // --> OD 2008-03-13 #refactorlists#
2809cdf0e10cSrcweir namespace listfunc
2810cdf0e10cSrcweir {
MakeListIdUnique(const SwDoc & rDoc,const String aSuggestedUniqueListId)2811cdf0e10cSrcweir     const String MakeListIdUnique( const SwDoc& rDoc,
2812cdf0e10cSrcweir                                    const String aSuggestedUniqueListId )
2813cdf0e10cSrcweir     {
2814cdf0e10cSrcweir         long nHitCount = 0;
2815cdf0e10cSrcweir         String aTmpStr = aSuggestedUniqueListId;
2816cdf0e10cSrcweir         while ( rDoc.getListByName( aTmpStr ) )
2817cdf0e10cSrcweir         {
2818cdf0e10cSrcweir             ++nHitCount;
2819cdf0e10cSrcweir             aTmpStr = aSuggestedUniqueListId;
2820cdf0e10cSrcweir             aTmpStr += String::CreateFromInt32( nHitCount );
2821cdf0e10cSrcweir         }
2822cdf0e10cSrcweir 
2823cdf0e10cSrcweir         return aTmpStr;
2824cdf0e10cSrcweir     }
CreateUniqueListId(const SwDoc & rDoc)2825cdf0e10cSrcweir     const String CreateUniqueListId( const SwDoc& rDoc )
2826cdf0e10cSrcweir     {
2827cdf0e10cSrcweir         // --> OD 2008-08-06 #i92478#
2828cdf0e10cSrcweir         String aNewListId = String::CreateFromAscii( "list" );
2829cdf0e10cSrcweir         // <--
28303d14cea3SMichael Stahl         // --> OD #o12311627#
28313d14cea3SMichael Stahl         static rtlRandomPool s_RandomPool( rtl_random_createPool() );
28323d14cea3SMichael Stahl         sal_Int64 n;
28333d14cea3SMichael Stahl         rtl_random_getBytes( s_RandomPool, &n, sizeof(n) );
28343d14cea3SMichael Stahl         aNewListId += String::CreateFromInt64( (n < 0 ? -n : n) );
2835cdf0e10cSrcweir         // <--
2836cdf0e10cSrcweir 
2837cdf0e10cSrcweir         return MakeListIdUnique( rDoc, aNewListId );
2838cdf0e10cSrcweir     }
2839cdf0e10cSrcweir }
2840cdf0e10cSrcweir // <--
2841