xref: /AOO41X/main/sw/source/core/edit/edglbldc.cxx (revision efeef26f81c84063fb0a91bde3856d4a51172d90)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26 
27 #include <doc.hxx>
28 #include <IDocumentUndoRedo.hxx>
29 #include <editsh.hxx>
30 #include <pam.hxx>
31 #include <ndtxt.hxx>
32 #include <docary.hxx>
33 #include <swwait.hxx>
34 #include <swundo.hxx>       // fuer die UndoIds
35 #include <section.hxx>
36 #include <doctxm.hxx>
37 #include <edglbldc.hxx>
38 
39 
SV_IMPL_OP_PTRARR_SORT(SwGlblDocContents,SwGlblDocContentPtr)40 SV_IMPL_OP_PTRARR_SORT( SwGlblDocContents, SwGlblDocContentPtr )
41 
42 sal_Bool SwEditShell::IsGlobalDoc() const
43 {
44     return getIDocumentSettingAccess()->get(IDocumentSettingAccess::GLOBAL_DOCUMENT);
45 }
46 
SetGlblDocSaveLinks(sal_Bool bFlag)47 void SwEditShell::SetGlblDocSaveLinks( sal_Bool bFlag )
48 {
49     getIDocumentSettingAccess()->set(IDocumentSettingAccess::GLOBAL_DOCUMENT_SAVE_LINKS, bFlag);
50     if( !GetDoc()->IsModified() )   // Bug 57028
51     {
52         GetDoc()->GetIDocumentUndoRedo().SetUndoNoResetModified();
53     }
54     GetDoc()->SetModified();
55 }
56 
IsGlblDocSaveLinks() const57 sal_Bool SwEditShell::IsGlblDocSaveLinks() const
58 {
59     return getIDocumentSettingAccess()->get(IDocumentSettingAccess::GLOBAL_DOCUMENT_SAVE_LINKS);
60 }
61 
GetGlobalDocContent(SwGlblDocContents & rArr) const62 sal_uInt16 SwEditShell::GetGlobalDocContent( SwGlblDocContents& rArr ) const
63 {
64     if( rArr.Count() )
65         rArr.DeleteAndDestroy( 0, rArr.Count() );
66 
67     if( !getIDocumentSettingAccess()->get(IDocumentSettingAccess::GLOBAL_DOCUMENT) )
68         return 0;
69 
70     // dann alle gelinkten Bereiche auf der obersten Ebene
71     SwDoc* pMyDoc = GetDoc();
72     const SwSectionFmts& rSectFmts = pMyDoc->GetSections();
73     sal_uInt16 n;
74 
75     for( n = rSectFmts.Count(); n; )
76     {
77         const SwSection* pSect = rSectFmts[ --n ]->GetGlobalDocSection();
78         if( pSect )
79         {
80             SwGlblDocContentPtr pNew;
81             switch( pSect->GetType() )
82             {
83             case TOX_HEADER_SECTION:    break;      // ignore
84             case TOX_CONTENT_SECTION:
85                 ASSERT( pSect->ISA( SwTOXBaseSection ), "keine TOXBaseSection!" );
86                 pNew = new SwGlblDocContent( (SwTOXBaseSection*)pSect );
87                 break;
88 
89             default:
90                 pNew = new SwGlblDocContent( pSect );
91                 break;
92             }
93             if( !rArr.Insert( pNew ) )
94                 delete pNew;
95         }
96     }
97 
98     // und als letztes die Dummies (sonstiger Text) einfuegen
99     SwNode* pNd;
100     sal_uLong nSttIdx = pMyDoc->GetNodes().GetEndOfExtras().GetIndex() + 2;
101     for( n = 0; n < rArr.Count(); ++n )
102     {
103         const SwGlblDocContent& rNew = *rArr[ n ];
104         // suche von StartPos bis rNew.DocPos nach einem Content Node.
105         // Existiert dieser, so muss ein DummyEintrag eingefuegt werden.
106         for( ; nSttIdx < rNew.GetDocPos(); ++nSttIdx )
107             if( ( pNd = pMyDoc->GetNodes()[ nSttIdx ])->IsCntntNode()
108                 || pNd->IsSectionNode() || pNd->IsTableNode() )
109             {
110                 SwGlblDocContentPtr pNew = new SwGlblDocContent( nSttIdx );
111                 if( !rArr.Insert( pNew ) )
112                     delete pNew;
113                 else
114                     ++n;        // auf die naechste Position
115                 break;
116             }
117 
118         // StartPosition aufs Ende setzen
119         nSttIdx = pMyDoc->GetNodes()[ rNew.GetDocPos() ]->EndOfSectionIndex();
120         ++nSttIdx;
121     }
122 
123     // sollte man das Ende auch noch setzen??
124     if( rArr.Count() )
125     {
126         sal_uLong nNdEnd = pMyDoc->GetNodes().GetEndOfContent().GetIndex();
127         for( ; nSttIdx < nNdEnd; ++nSttIdx )
128             if( ( pNd = pMyDoc->GetNodes()[ nSttIdx ])->IsCntntNode()
129                 || pNd->IsSectionNode() || pNd->IsTableNode() )
130             {
131                 SwGlblDocContentPtr pNew = new SwGlblDocContent( nSttIdx );
132                 if( !rArr.Insert( pNew ) )
133                     delete pNew;
134                 break;
135             }
136     }
137     else
138     {
139         SwGlblDocContentPtr pNew = new SwGlblDocContent(
140                     pMyDoc->GetNodes().GetEndOfExtras().GetIndex() + 2 );
141         rArr.Insert( pNew );
142     }
143     return rArr.Count();
144 }
145 
InsertGlobalDocContent(const SwGlblDocContent & rInsPos,SwSectionData & rNew)146 sal_Bool SwEditShell::InsertGlobalDocContent( const SwGlblDocContent& rInsPos,
147         SwSectionData & rNew)
148 {
149     if( !getIDocumentSettingAccess()->get(IDocumentSettingAccess::GLOBAL_DOCUMENT) )
150         return sal_False;
151 
152     SET_CURR_SHELL( this );
153     StartAllAction();
154 
155     SwPaM* pCrsr = GetCrsr();
156     if( pCrsr->GetNext() != pCrsr || IsTableMode() )
157         ClearMark();
158 
159     SwPosition& rPos = *pCrsr->GetPoint();
160     rPos.nNode = rInsPos.GetDocPos();
161 
162     sal_Bool bEndUndo = sal_False;
163     SwDoc* pMyDoc = GetDoc();
164     SwTxtNode *const pTxtNd = rPos.nNode.GetNode().GetTxtNode();
165     if( pTxtNd )
166         rPos.nContent.Assign( pTxtNd, 0 );
167     else
168     {
169         bEndUndo = sal_True;
170         pMyDoc->GetIDocumentUndoRedo().StartUndo( UNDO_START, NULL );
171         rPos.nNode--;
172         pMyDoc->AppendTxtNode( rPos );
173         pCrsr->SetMark();
174     }
175 
176     InsertSection( rNew );
177 
178     if( bEndUndo )
179     {
180         pMyDoc->GetIDocumentUndoRedo().EndUndo( UNDO_END, NULL );
181     }
182     EndAllAction();
183 
184     return sal_True;
185 }
186 
InsertGlobalDocContent(const SwGlblDocContent & rInsPos,const SwTOXBase & rTOX)187 sal_Bool SwEditShell::InsertGlobalDocContent( const SwGlblDocContent& rInsPos,
188                                             const SwTOXBase& rTOX )
189 {
190     if( !getIDocumentSettingAccess()->get(IDocumentSettingAccess::GLOBAL_DOCUMENT) )
191         return sal_False;
192 
193     SET_CURR_SHELL( this );
194     StartAllAction();
195 
196     SwPaM* pCrsr = GetCrsr();
197     if( pCrsr->GetNext() != pCrsr || IsTableMode() )
198         ClearMark();
199 
200     SwPosition& rPos = *pCrsr->GetPoint();
201     rPos.nNode = rInsPos.GetDocPos();
202 
203     sal_Bool bEndUndo = sal_False;
204     SwDoc* pMyDoc = GetDoc();
205     SwTxtNode* pTxtNd = rPos.nNode.GetNode().GetTxtNode();
206     if( pTxtNd && pTxtNd->GetTxt().Len() && rPos.nNode.GetIndex() + 1 !=
207         pMyDoc->GetNodes().GetEndOfContent().GetIndex() )
208         rPos.nContent.Assign( pTxtNd, 0 );
209     else
210     {
211         bEndUndo = sal_True;
212         pMyDoc->GetIDocumentUndoRedo().StartUndo( UNDO_START, NULL );
213         rPos.nNode--;
214         pMyDoc->AppendTxtNode( rPos );
215     }
216 
217     InsertTableOf( rTOX );
218 
219     if( bEndUndo )
220     {
221         pMyDoc->GetIDocumentUndoRedo().EndUndo( UNDO_END, NULL );
222     }
223     EndAllAction();
224 
225     return sal_True;
226 }
227 
InsertGlobalDocContent(const SwGlblDocContent & rInsPos)228 sal_Bool SwEditShell::InsertGlobalDocContent( const SwGlblDocContent& rInsPos )
229 {
230     if( !getIDocumentSettingAccess()->get(IDocumentSettingAccess::GLOBAL_DOCUMENT) )
231         return sal_False;
232 
233     SET_CURR_SHELL( this );
234     StartAllAction();
235 
236     SwPaM* pCrsr = GetCrsr();
237     if( pCrsr->GetNext() != pCrsr || IsTableMode() )
238         ClearMark();
239 
240     SwPosition& rPos = *pCrsr->GetPoint();
241     rPos.nNode = rInsPos.GetDocPos() - 1;
242     rPos.nContent.Assign( 0, 0 );
243 
244     SwDoc* pMyDoc = GetDoc();
245     pMyDoc->AppendTxtNode( rPos );
246     EndAllAction();
247     return sal_True;
248 }
249 
DeleteGlobalDocContent(const SwGlblDocContents & rArr,sal_uInt16 nDelPos)250 sal_Bool SwEditShell::DeleteGlobalDocContent( const SwGlblDocContents& rArr ,
251                                             sal_uInt16 nDelPos )
252 {
253     if( !getIDocumentSettingAccess()->get(IDocumentSettingAccess::GLOBAL_DOCUMENT) )
254         return sal_False;
255 
256     SET_CURR_SHELL( this );
257     StartAllAction();
258     StartUndo( UNDO_START );
259 
260     SwPaM* pCrsr = GetCrsr();
261     if( pCrsr->GetNext() != pCrsr || IsTableMode() )
262         ClearMark();
263 
264     SwPosition& rPos = *pCrsr->GetPoint();
265 
266     SwDoc* pMyDoc = GetDoc();
267     const SwGlblDocContent& rDelPos = *rArr[ nDelPos ];
268     sal_uLong nDelIdx = rDelPos.GetDocPos();
269     if( 1 == rArr.Count() )
270     {
271         // ein Node muss aber da bleiben!
272         rPos.nNode = nDelIdx - 1;
273         rPos.nContent.Assign( 0, 0 );
274 
275         pMyDoc->AppendTxtNode( rPos );
276         ++nDelIdx;
277     }
278 
279     switch( rDelPos.GetType() )
280     {
281     case GLBLDOC_UNKNOWN:
282         {
283             rPos.nNode = nDelIdx;
284             pCrsr->SetMark();
285             if( ++nDelPos < rArr.Count() )
286                 rPos.nNode = rArr[ nDelPos ]->GetDocPos();
287             else
288                 rPos.nNode = pMyDoc->GetNodes().GetEndOfContent();
289             rPos.nNode--;
290             if( !pMyDoc->DelFullPara( *pCrsr ) )
291                 Delete();
292         }
293         break;
294 
295     case GLBLDOC_TOXBASE:
296         {
297             SwTOXBaseSection* pTOX = (SwTOXBaseSection*)rDelPos.GetTOX();
298             pMyDoc->DeleteTOX( *pTOX, sal_True );
299         }
300         break;
301 
302     case GLBLDOC_SECTION:
303         {
304             SwSectionFmt* pSectFmt = (SwSectionFmt*)rDelPos.GetSection()->GetFmt();
305             pMyDoc->DelSectionFmt( pSectFmt, sal_True );
306         }
307         break;
308     }
309 
310     EndUndo( UNDO_END );
311     EndAllAction();
312     return sal_True;
313 }
314 
MoveGlobalDocContent(const SwGlblDocContents & rArr,sal_uInt16 nFromPos,sal_uInt16 nToPos,sal_uInt16 nInsPos)315 sal_Bool SwEditShell::MoveGlobalDocContent( const SwGlblDocContents& rArr ,
316                                         sal_uInt16 nFromPos, sal_uInt16 nToPos,
317                                         sal_uInt16 nInsPos )
318 {
319     if( !getIDocumentSettingAccess()->get(IDocumentSettingAccess::GLOBAL_DOCUMENT) ||
320         nFromPos >= rArr.Count() || nToPos > rArr.Count() ||
321         nInsPos > rArr.Count() || nFromPos >= nToPos ||
322         ( nFromPos <= nInsPos && nInsPos <= nToPos ) )
323         return sal_False;
324 
325     SET_CURR_SHELL( this );
326     StartAllAction();
327 
328     SwPaM* pCrsr = GetCrsr();
329     if( pCrsr->GetNext() != pCrsr || IsTableMode() )
330         ClearMark();
331 
332     SwDoc* pMyDoc = GetDoc();
333     SwNodeRange aRg( pMyDoc->GetNodes(), rArr[ nFromPos ]->GetDocPos() );
334     if( nToPos < rArr.Count() )
335         aRg.aEnd = rArr[ nToPos ]->GetDocPos();
336     else
337         aRg.aEnd = pMyDoc->GetNodes().GetEndOfContent();
338 
339     SwNodeIndex aInsPos( pMyDoc->GetNodes() );
340     if( nInsPos < rArr.Count() )
341         aInsPos = rArr[ nInsPos ]->GetDocPos();
342     else
343         aInsPos  = pMyDoc->GetNodes().GetEndOfContent();
344 
345     bool bRet = pMyDoc->MoveNodeRange( aRg, aInsPos,
346         static_cast<IDocumentContentOperations::SwMoveFlags>(
347               IDocumentContentOperations::DOC_MOVEALLFLYS
348             | IDocumentContentOperations::DOC_CREATEUNDOOBJ ));
349 
350     EndAllAction();
351     return bRet;
352 }
353 
GotoGlobalDocContent(const SwGlblDocContent & rPos)354 sal_Bool SwEditShell::GotoGlobalDocContent( const SwGlblDocContent& rPos )
355 {
356     if( !getIDocumentSettingAccess()->get(IDocumentSettingAccess::GLOBAL_DOCUMENT) )
357         return sal_False;
358 
359     SET_CURR_SHELL( this );
360     SttCrsrMove();
361 
362     SwPaM* pCrsr = GetCrsr();
363     if( pCrsr->GetNext() != pCrsr || IsTableMode() )
364         ClearMark();
365 
366     SwPosition& rCrsrPos = *pCrsr->GetPoint();
367     rCrsrPos.nNode = rPos.GetDocPos();
368 
369     SwDoc* pMyDoc = GetDoc();
370     SwCntntNode * pCNd = rCrsrPos.nNode.GetNode().GetCntntNode();
371     if( !pCNd )
372         pCNd = pMyDoc->GetNodes().GoNext( &rCrsrPos.nNode );
373 
374     rCrsrPos.nContent.Assign( pCNd, 0 );
375 
376     EndCrsrMove();
377     return sal_True;
378 }
379 
SwGlblDocContent(sal_uLong nPos)380 SwGlblDocContent::SwGlblDocContent( sal_uLong nPos )
381 {
382     eType = GLBLDOC_UNKNOWN;
383     PTR.pTOX = 0;
384     nDocPos = nPos;
385 }
386 
SwGlblDocContent(const SwTOXBaseSection * pTOX)387 SwGlblDocContent::SwGlblDocContent( const SwTOXBaseSection* pTOX )
388 {
389     eType = GLBLDOC_TOXBASE;
390     PTR.pTOX = pTOX;
391 
392     const SwSectionNode* pSectNd = pTOX->GetFmt()->GetSectionNode();
393     nDocPos = pSectNd ? pSectNd->GetIndex() : 0;
394 }
395 
SwGlblDocContent(const SwSection * pSect)396 SwGlblDocContent::SwGlblDocContent( const SwSection* pSect )
397 {
398     eType = GLBLDOC_SECTION;
399     PTR.pSect = pSect;
400 
401     const SwSectionNode* pSectNd = pSect->GetFmt()->GetSectionNode();
402     nDocPos = pSectNd ? pSectNd->GetIndex() : 0;
403 }
404 
405 
406 
407