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