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