xref: /trunk/main/sw/source/core/edit/edglbldc.cxx (revision cdf0e10c)
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