Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <doc.hxx>
21 : #include <IDocumentUndoRedo.hxx>
22 : #include <editsh.hxx>
23 : #include <pam.hxx>
24 : #include <ndtxt.hxx>
25 : #include <docary.hxx>
26 : #include <swwait.hxx>
27 : #include <swundo.hxx>
28 : #include <section.hxx>
29 : #include <doctxm.hxx>
30 : #include <edglbldc.hxx>
31 :
32 0 : sal_Bool SwEditShell::IsGlobalDoc() const
33 : {
34 0 : return getIDocumentSettingAccess()->get(IDocumentSettingAccess::GLOBAL_DOCUMENT);
35 : }
36 :
37 0 : void SwEditShell::SetGlblDocSaveLinks( sal_Bool bFlag )
38 : {
39 0 : getIDocumentSettingAccess()->set(IDocumentSettingAccess::GLOBAL_DOCUMENT_SAVE_LINKS, bFlag);
40 0 : if( !GetDoc()->IsModified() ) // Bug 57028
41 : {
42 0 : GetDoc()->GetIDocumentUndoRedo().SetUndoNoResetModified();
43 : }
44 0 : GetDoc()->SetModified();
45 0 : }
46 :
47 0 : sal_Bool SwEditShell::IsGlblDocSaveLinks() const
48 : {
49 0 : return getIDocumentSettingAccess()->get(IDocumentSettingAccess::GLOBAL_DOCUMENT_SAVE_LINKS);
50 : }
51 :
52 0 : sal_uInt16 SwEditShell::GetGlobalDocContent( SwGlblDocContents& rArr ) const
53 : {
54 0 : rArr.DeleteAndDestroyAll();
55 :
56 0 : if( !getIDocumentSettingAccess()->get(IDocumentSettingAccess::GLOBAL_DOCUMENT) )
57 0 : return 0;
58 :
59 : // then all linked areas on the topmost level
60 0 : SwDoc* pMyDoc = GetDoc();
61 0 : const SwSectionFmts& rSectFmts = pMyDoc->GetSections();
62 : sal_uInt16 n;
63 :
64 0 : for( n = rSectFmts.size(); n; )
65 : {
66 0 : const SwSection* pSect = rSectFmts[ --n ]->GetGlobalDocSection();
67 0 : if( pSect )
68 : {
69 : SwGlblDocContent* pNew;
70 0 : switch( pSect->GetType() )
71 : {
72 : case TOX_HEADER_SECTION:
73 0 : break; // ignore
74 : case TOX_CONTENT_SECTION:
75 : OSL_ENSURE( pSect->ISA( SwTOXBaseSection ), "no TOXBaseSection!" );
76 0 : pNew = new SwGlblDocContent( (SwTOXBaseSection*)pSect );
77 0 : break;
78 :
79 : default:
80 0 : pNew = new SwGlblDocContent( pSect );
81 0 : break;
82 : }
83 0 : if( !rArr.insert( pNew ).second )
84 0 : delete pNew;
85 : }
86 : }
87 :
88 : // and finally add the dummies (other text)
89 : SwNode* pNd;
90 0 : sal_uLong nSttIdx = pMyDoc->GetNodes().GetEndOfExtras().GetIndex() + 2;
91 0 : for( n = 0; n < rArr.size(); ++n )
92 : {
93 0 : const SwGlblDocContent& rNew = *rArr[ n ];
94 : // Search from StartPos until rNew.DocPos for a content node.
95 : // If one exists then a dummy entry is needed.
96 0 : for( ; nSttIdx < rNew.GetDocPos(); ++nSttIdx )
97 0 : if( ( pNd = pMyDoc->GetNodes()[ nSttIdx ])->IsCntntNode()
98 0 : || pNd->IsSectionNode() || pNd->IsTableNode() )
99 : {
100 0 : SwGlblDocContent* pNew = new SwGlblDocContent( nSttIdx );
101 0 : if( !rArr.insert( pNew ).second )
102 0 : delete pNew;
103 : else
104 0 : ++n; // to the next position
105 0 : break;
106 : }
107 :
108 : // set StartPosition to the end
109 0 : nSttIdx = pMyDoc->GetNodes()[ rNew.GetDocPos() ]->EndOfSectionIndex();
110 0 : ++nSttIdx;
111 : }
112 :
113 : // Should the end also be set?
114 0 : if( !rArr.empty() )
115 : {
116 0 : sal_uLong nNdEnd = pMyDoc->GetNodes().GetEndOfContent().GetIndex();
117 0 : for( ; nSttIdx < nNdEnd; ++nSttIdx )
118 0 : if( ( pNd = pMyDoc->GetNodes()[ nSttIdx ])->IsCntntNode()
119 0 : || pNd->IsSectionNode() || pNd->IsTableNode() )
120 : {
121 0 : SwGlblDocContent* pNew = new SwGlblDocContent( nSttIdx );
122 0 : if( !rArr.insert( pNew ).second )
123 0 : delete pNew;
124 0 : break;
125 : }
126 : }
127 : else
128 : {
129 : SwGlblDocContent* pNew = new SwGlblDocContent(
130 0 : pMyDoc->GetNodes().GetEndOfExtras().GetIndex() + 2 );
131 0 : rArr.insert( pNew );
132 : }
133 0 : return rArr.size();
134 : }
135 :
136 0 : sal_Bool SwEditShell::InsertGlobalDocContent( const SwGlblDocContent& rInsPos,
137 : SwSectionData & rNew)
138 : {
139 0 : if( !getIDocumentSettingAccess()->get(IDocumentSettingAccess::GLOBAL_DOCUMENT) )
140 0 : return sal_False;
141 :
142 0 : SET_CURR_SHELL( this );
143 0 : StartAllAction();
144 :
145 0 : SwPaM* pCrsr = GetCrsr();
146 0 : if( pCrsr->GetNext() != pCrsr || IsTableMode() )
147 0 : ClearMark();
148 :
149 0 : SwPosition& rPos = *pCrsr->GetPoint();
150 0 : rPos.nNode = rInsPos.GetDocPos();
151 :
152 0 : bool bEndUndo = false;
153 0 : SwDoc* pMyDoc = GetDoc();
154 0 : SwTxtNode *const pTxtNd = rPos.nNode.GetNode().GetTxtNode();
155 0 : if( pTxtNd )
156 0 : rPos.nContent.Assign( pTxtNd, 0 );
157 : else
158 : {
159 0 : bEndUndo = true;
160 0 : pMyDoc->GetIDocumentUndoRedo().StartUndo( UNDO_START, NULL );
161 0 : rPos.nNode--;
162 0 : pMyDoc->AppendTxtNode( rPos );
163 0 : pCrsr->SetMark();
164 : }
165 :
166 0 : InsertSection( rNew );
167 :
168 0 : if( bEndUndo )
169 : {
170 0 : pMyDoc->GetIDocumentUndoRedo().EndUndo( UNDO_END, NULL );
171 : }
172 0 : EndAllAction();
173 :
174 0 : return sal_True;
175 : }
176 :
177 0 : sal_Bool SwEditShell::InsertGlobalDocContent( const SwGlblDocContent& rInsPos,
178 : const SwTOXBase& rTOX )
179 : {
180 0 : if( !getIDocumentSettingAccess()->get(IDocumentSettingAccess::GLOBAL_DOCUMENT) )
181 0 : return sal_False;
182 :
183 0 : SET_CURR_SHELL( this );
184 0 : StartAllAction();
185 :
186 0 : SwPaM* pCrsr = GetCrsr();
187 0 : if( pCrsr->GetNext() != pCrsr || IsTableMode() )
188 0 : ClearMark();
189 :
190 0 : SwPosition& rPos = *pCrsr->GetPoint();
191 0 : rPos.nNode = rInsPos.GetDocPos();
192 :
193 0 : bool bEndUndo = false;
194 0 : SwDoc* pMyDoc = GetDoc();
195 0 : SwTxtNode* pTxtNd = rPos.nNode.GetNode().GetTxtNode();
196 0 : if (pTxtNd && pTxtNd->GetTxt().getLength() && rPos.nNode.GetIndex() + 1 !=
197 0 : pMyDoc->GetNodes().GetEndOfContent().GetIndex() )
198 0 : rPos.nContent.Assign( pTxtNd, 0 );
199 : else
200 : {
201 0 : bEndUndo = true;
202 0 : pMyDoc->GetIDocumentUndoRedo().StartUndo( UNDO_START, NULL );
203 0 : rPos.nNode--;
204 0 : pMyDoc->AppendTxtNode( rPos );
205 : }
206 :
207 0 : InsertTableOf( rTOX );
208 :
209 0 : if( bEndUndo )
210 : {
211 0 : pMyDoc->GetIDocumentUndoRedo().EndUndo( UNDO_END, NULL );
212 : }
213 0 : EndAllAction();
214 :
215 0 : return sal_True;
216 : }
217 :
218 0 : sal_Bool SwEditShell::InsertGlobalDocContent( const SwGlblDocContent& rInsPos )
219 : {
220 0 : if( !getIDocumentSettingAccess()->get(IDocumentSettingAccess::GLOBAL_DOCUMENT) )
221 0 : return sal_False;
222 :
223 0 : SET_CURR_SHELL( this );
224 0 : StartAllAction();
225 :
226 0 : SwPaM* pCrsr = GetCrsr();
227 0 : if( pCrsr->GetNext() != pCrsr || IsTableMode() )
228 0 : ClearMark();
229 :
230 0 : SwPosition& rPos = *pCrsr->GetPoint();
231 0 : rPos.nNode = rInsPos.GetDocPos() - 1;
232 0 : rPos.nContent.Assign( 0, 0 );
233 :
234 0 : SwDoc* pMyDoc = GetDoc();
235 0 : pMyDoc->AppendTxtNode( rPos );
236 0 : EndAllAction();
237 0 : return sal_True;
238 : }
239 :
240 0 : sal_Bool SwEditShell::DeleteGlobalDocContent( const SwGlblDocContents& rArr ,
241 : size_t nDelPos )
242 : {
243 0 : if( !getIDocumentSettingAccess()->get(IDocumentSettingAccess::GLOBAL_DOCUMENT) )
244 0 : return sal_False;
245 :
246 0 : SET_CURR_SHELL( this );
247 0 : StartAllAction();
248 0 : StartUndo( UNDO_START );
249 :
250 0 : SwPaM* pCrsr = GetCrsr();
251 0 : if( pCrsr->GetNext() != pCrsr || IsTableMode() )
252 0 : ClearMark();
253 :
254 0 : SwPosition& rPos = *pCrsr->GetPoint();
255 :
256 0 : SwDoc* pMyDoc = GetDoc();
257 0 : const SwGlblDocContent& rDelPos = *rArr[ nDelPos ];
258 0 : sal_uLong nDelIdx = rDelPos.GetDocPos();
259 0 : if( 1 == rArr.size() )
260 : {
261 : // we need at least one node!
262 0 : rPos.nNode = nDelIdx - 1;
263 0 : rPos.nContent.Assign( 0, 0 );
264 :
265 0 : pMyDoc->AppendTxtNode( rPos );
266 0 : ++nDelIdx;
267 : }
268 :
269 0 : switch( rDelPos.GetType() )
270 : {
271 : case GLBLDOC_UNKNOWN:
272 : {
273 0 : rPos.nNode = nDelIdx;
274 0 : pCrsr->SetMark();
275 0 : if( ++nDelPos < rArr.size() )
276 0 : rPos.nNode = rArr[ nDelPos ]->GetDocPos();
277 : else
278 0 : rPos.nNode = pMyDoc->GetNodes().GetEndOfContent();
279 0 : rPos.nNode--;
280 0 : if( !pMyDoc->DelFullPara( *pCrsr ) )
281 0 : Delete();
282 : }
283 0 : break;
284 :
285 : case GLBLDOC_TOXBASE:
286 : {
287 0 : SwTOXBaseSection* pTOX = (SwTOXBaseSection*)rDelPos.GetTOX();
288 0 : pMyDoc->DeleteTOX( *pTOX, true );
289 : }
290 0 : break;
291 :
292 : case GLBLDOC_SECTION:
293 : {
294 0 : SwSectionFmt* pSectFmt = (SwSectionFmt*)rDelPos.GetSection()->GetFmt();
295 0 : pMyDoc->DelSectionFmt( pSectFmt, true );
296 : }
297 0 : break;
298 : }
299 :
300 0 : EndUndo( UNDO_END );
301 0 : EndAllAction();
302 0 : return sal_True;
303 : }
304 :
305 0 : sal_Bool SwEditShell::MoveGlobalDocContent( const SwGlblDocContents& rArr ,
306 : size_t nFromPos, size_t nToPos,
307 : size_t nInsPos )
308 : {
309 0 : if( !getIDocumentSettingAccess()->get(IDocumentSettingAccess::GLOBAL_DOCUMENT) ||
310 0 : nFromPos >= rArr.size() || nToPos > rArr.size() ||
311 0 : nInsPos > rArr.size() || nFromPos >= nToPos ||
312 0 : ( nFromPos <= nInsPos && nInsPos <= nToPos ) )
313 0 : return sal_False;
314 :
315 0 : SET_CURR_SHELL( this );
316 0 : StartAllAction();
317 :
318 0 : SwPaM* pCrsr = GetCrsr();
319 0 : if( pCrsr->GetNext() != pCrsr || IsTableMode() )
320 0 : ClearMark();
321 :
322 0 : SwDoc* pMyDoc = GetDoc();
323 0 : SwNodeRange aRg( pMyDoc->GetNodes(), rArr[ nFromPos ]->GetDocPos() );
324 0 : if( nToPos < rArr.size() )
325 0 : aRg.aEnd = rArr[ nToPos ]->GetDocPos();
326 : else
327 0 : aRg.aEnd = pMyDoc->GetNodes().GetEndOfContent();
328 :
329 0 : SwNodeIndex aInsPos( pMyDoc->GetNodes() );
330 0 : if( nInsPos < rArr.size() )
331 0 : aInsPos = rArr[ nInsPos ]->GetDocPos();
332 : else
333 0 : aInsPos = pMyDoc->GetNodes().GetEndOfContent();
334 :
335 : bool bRet = pMyDoc->MoveNodeRange( aRg, aInsPos,
336 : static_cast<IDocumentContentOperations::SwMoveFlags>(
337 : IDocumentContentOperations::DOC_MOVEALLFLYS
338 0 : | IDocumentContentOperations::DOC_CREATEUNDOOBJ ));
339 :
340 0 : EndAllAction();
341 0 : return bRet;
342 : }
343 :
344 0 : sal_Bool SwEditShell::GotoGlobalDocContent( const SwGlblDocContent& rPos )
345 : {
346 0 : if( !getIDocumentSettingAccess()->get(IDocumentSettingAccess::GLOBAL_DOCUMENT) )
347 0 : return sal_False;
348 :
349 0 : SET_CURR_SHELL( this );
350 0 : SttCrsrMove();
351 :
352 0 : SwPaM* pCrsr = GetCrsr();
353 0 : if( pCrsr->GetNext() != pCrsr || IsTableMode() )
354 0 : ClearMark();
355 :
356 0 : SwPosition& rCrsrPos = *pCrsr->GetPoint();
357 0 : rCrsrPos.nNode = rPos.GetDocPos();
358 :
359 0 : SwDoc* pMyDoc = GetDoc();
360 0 : SwCntntNode * pCNd = rCrsrPos.nNode.GetNode().GetCntntNode();
361 0 : if( !pCNd )
362 0 : pCNd = pMyDoc->GetNodes().GoNext( &rCrsrPos.nNode );
363 :
364 0 : rCrsrPos.nContent.Assign( pCNd, 0 );
365 :
366 0 : EndCrsrMove();
367 0 : return sal_True;
368 : }
369 :
370 0 : SwGlblDocContent::SwGlblDocContent( sal_uLong nPos )
371 : {
372 0 : eType = GLBLDOC_UNKNOWN;
373 0 : PTR.pTOX = 0;
374 0 : nDocPos = nPos;
375 0 : }
376 :
377 0 : SwGlblDocContent::SwGlblDocContent( const SwTOXBaseSection* pTOX )
378 : {
379 0 : eType = GLBLDOC_TOXBASE;
380 0 : PTR.pTOX = pTOX;
381 :
382 0 : const SwSectionNode* pSectNd = pTOX->GetFmt()->GetSectionNode();
383 0 : nDocPos = pSectNd ? pSectNd->GetIndex() : 0;
384 0 : }
385 :
386 0 : SwGlblDocContent::SwGlblDocContent( const SwSection* pSect )
387 : {
388 0 : eType = GLBLDOC_SECTION;
389 0 : PTR.pSect = pSect;
390 :
391 0 : const SwSectionNode* pSectNd = pSect->GetFmt()->GetSectionNode();
392 0 : nDocPos = pSectNd ? pSectNd->GetIndex() : 0;
393 0 : }
394 :
395 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|