Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / sw / source / core / edit / edglbldc.cxx
blobe7772379a8aa5548c2797cdfb5d4ea07ecca2b96
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <doc.hxx>
21 #include <IDocumentUndoRedo.hxx>
22 #include <IDocumentSettingAccess.hxx>
23 #include <IDocumentState.hxx>
24 #include <editsh.hxx>
25 #include <pam.hxx>
26 #include <ndtxt.hxx>
27 #include <docary.hxx>
28 #include <swundo.hxx>
29 #include <section.hxx>
30 #include <doctxm.hxx>
31 #include <edglbldc.hxx>
33 bool SwEditShell::IsGlobalDoc() const
35 return getIDocumentSettingAccess().get(DocumentSettingId::GLOBAL_DOCUMENT);
38 void SwEditShell::SetGlblDocSaveLinks( bool bFlag )
40 getIDocumentSettingAccess().set(DocumentSettingId::GLOBAL_DOCUMENT_SAVE_LINKS, bFlag);
41 if( !GetDoc()->getIDocumentState().IsModified() ) // Bug 57028
43 GetDoc()->GetIDocumentUndoRedo().SetUndoNoResetModified();
45 GetDoc()->getIDocumentState().SetModified();
48 bool SwEditShell::IsGlblDocSaveLinks() const
50 return getIDocumentSettingAccess().get(DocumentSettingId::GLOBAL_DOCUMENT_SAVE_LINKS);
53 void SwEditShell::GetGlobalDocContent( SwGlblDocContents& rArr ) const
55 rArr.clear();
57 if( !getIDocumentSettingAccess().get(DocumentSettingId::GLOBAL_DOCUMENT) )
58 return;
60 // then all linked areas on the topmost level
61 SwDoc* pMyDoc = GetDoc();
62 const SwSectionFormats& rSectFormats = pMyDoc->GetSections();
64 for( auto n = rSectFormats.size(); n; )
66 const SwSection* pSect = rSectFormats[ --n ]->GetGlobalDocSection();
67 if( pSect )
69 std::unique_ptr<SwGlblDocContent> pNew;
70 switch( pSect->GetType() )
72 case SectionType::ToxHeader:
73 break; // ignore
74 case SectionType::ToxContent:
75 assert( dynamic_cast<const SwTOXBaseSection*>( pSect) && "no TOXBaseSection!" );
76 pNew.reset(new SwGlblDocContent( static_cast<const SwTOXBaseSection*>(pSect) ));
77 break;
79 default:
80 pNew.reset(new SwGlblDocContent( pSect ));
81 break;
83 if (pNew)
84 rArr.insert( std::move(pNew) );
88 // and finally add the dummies (other text)
89 SwNode* pNd;
90 SwNodeOffset nSttIdx = pMyDoc->GetNodes().GetEndOfExtras().GetIndex() + 2;
91 for( SwGlblDocContents::size_type n = 0; n < rArr.size(); ++n )
93 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 for( ; nSttIdx < rNew.GetDocPos(); ++nSttIdx )
97 if( ( pNd = pMyDoc->GetNodes()[ nSttIdx ])->IsContentNode()
98 || pNd->IsSectionNode() || pNd->IsTableNode() )
100 std::unique_ptr<SwGlblDocContent> pNew(new SwGlblDocContent( nSttIdx ));
101 if( rArr.insert( std::move(pNew) ).second )
102 ++n; // to the next position
103 break;
106 // set StartPosition to the end
107 nSttIdx = pMyDoc->GetNodes()[ rNew.GetDocPos() ]->EndOfSectionIndex();
108 ++nSttIdx;
111 // Should the end also be set?
112 if( !rArr.empty() )
114 SwNodeOffset nNdEnd = pMyDoc->GetNodes().GetEndOfContent().GetIndex();
115 for( ; nSttIdx < nNdEnd; ++nSttIdx )
116 if( ( pNd = pMyDoc->GetNodes()[ nSttIdx ])->IsContentNode()
117 || pNd->IsSectionNode() || pNd->IsTableNode() )
119 rArr.insert( std::make_unique<SwGlblDocContent>( nSttIdx ) );
120 break;
123 else
125 std::unique_ptr<SwGlblDocContent> pNew(new SwGlblDocContent(
126 pMyDoc->GetNodes().GetEndOfExtras().GetIndex() + 2 ));
127 rArr.insert( std::move(pNew) );
131 void SwEditShell::InsertGlobalDocContent( const SwGlblDocContent& rInsPos,
132 SwSectionData & rNew)
134 if( !getIDocumentSettingAccess().get(DocumentSettingId::GLOBAL_DOCUMENT) )
135 return;
137 CurrShell aCurr( this );
138 StartAllAction();
140 SwPaM* pCursor = GetCursor();
141 if( pCursor->GetNext() != pCursor || IsTableMode() )
142 ClearMark();
144 SwPosition& rPos = *pCursor->GetPoint();
145 rPos.Assign( rInsPos.GetDocPos() );
147 bool bEndUndo = false;
148 SwDoc* pMyDoc = GetDoc();
149 SwTextNode *const pTextNd = rPos.GetNode().GetTextNode();
150 if( !pTextNd )
152 bEndUndo = true;
153 pMyDoc->GetIDocumentUndoRedo().StartUndo( SwUndoId::START, nullptr );
154 rPos.Adjust(SwNodeOffset(-1));
155 pMyDoc->getIDocumentContentOperations().AppendTextNode( rPos );
156 pCursor->SetMark();
159 InsertSection( rNew );
161 if( bEndUndo )
163 pMyDoc->GetIDocumentUndoRedo().EndUndo( SwUndoId::END, nullptr );
165 EndAllAction();
168 bool SwEditShell::InsertGlobalDocContent( const SwGlblDocContent& rInsPos,
169 const SwTOXBase& rTOX )
171 if( !getIDocumentSettingAccess().get(DocumentSettingId::GLOBAL_DOCUMENT) )
172 return false;
174 CurrShell aCurr( this );
175 StartAllAction();
177 SwPaM* pCursor = GetCursor();
178 if( pCursor->GetNext() != pCursor || IsTableMode() )
179 ClearMark();
181 SwPosition& rPos = *pCursor->GetPoint();
182 rPos.Assign(rInsPos.GetDocPos());
184 bool bEndUndo = false;
185 SwDoc* pMyDoc = GetDoc();
186 SwTextNode* pTextNd = rPos.GetNode().GetTextNode();
187 if (!pTextNd || !pTextNd->GetText().getLength() || rPos.GetNodeIndex() + 1 ==
188 pMyDoc->GetNodes().GetEndOfContent().GetIndex() )
190 bEndUndo = true;
191 pMyDoc->GetIDocumentUndoRedo().StartUndo( SwUndoId::START, nullptr );
192 rPos.Adjust(SwNodeOffset(-1));
193 pMyDoc->getIDocumentContentOperations().AppendTextNode( rPos );
196 InsertTableOf( rTOX );
198 if( bEndUndo )
200 pMyDoc->GetIDocumentUndoRedo().EndUndo( SwUndoId::END, nullptr );
202 EndAllAction();
204 return true;
207 bool SwEditShell::InsertGlobalDocContent( const SwGlblDocContent& rInsPos )
209 if( !getIDocumentSettingAccess().get(DocumentSettingId::GLOBAL_DOCUMENT) )
210 return false;
212 CurrShell aCurr( this );
213 StartAllAction();
215 SwPaM* pCursor = GetCursor();
216 if( pCursor->GetNext() != pCursor || IsTableMode() )
217 ClearMark();
219 SwPosition& rPos = *pCursor->GetPoint();
220 rPos.Assign(rInsPos.GetDocPos() - 1);
222 SwDoc* pMyDoc = GetDoc();
223 pMyDoc->getIDocumentContentOperations().AppendTextNode( rPos );
224 EndAllAction();
225 return true;
228 void SwEditShell::DeleteGlobalDocContent( const SwGlblDocContents& rArr ,
229 size_t nDelPos )
231 if( !getIDocumentSettingAccess().get(DocumentSettingId::GLOBAL_DOCUMENT) )
232 return;
234 CurrShell aCurr( this );
235 StartAllAction();
236 StartUndo( SwUndoId::START );
238 SwPaM* pCursor = GetCursor();
239 if( pCursor->GetNext() != pCursor || IsTableMode() )
240 ClearMark();
242 SwPosition& rPos = *pCursor->GetPoint();
244 SwDoc* pMyDoc = GetDoc();
245 const SwGlblDocContent& rDelPos = *rArr[ nDelPos ];
246 SwNodeOffset nDelIdx = rDelPos.GetDocPos();
247 if( 1 == rArr.size() )
249 // we need at least one node!
250 rPos.Assign(nDelIdx - 1);
252 pMyDoc->getIDocumentContentOperations().AppendTextNode( rPos );
253 ++nDelIdx;
256 switch( rDelPos.GetType() )
258 case GLBLDOC_UNKNOWN:
260 rPos.Assign(nDelIdx);
261 pCursor->SetMark();
262 if( ++nDelPos < rArr.size() )
263 rPos.Assign(rArr[ nDelPos ]->GetDocPos(), -1);
264 else
265 rPos.Assign(pMyDoc->GetNodes().GetEndOfContent(), -1);
266 if( !pMyDoc->getIDocumentContentOperations().DelFullPara( *pCursor ) )
267 Delete(false);
269 break;
271 case GLBLDOC_TOXBASE:
273 const SwTOXBaseSection* pTOX = static_cast<const SwTOXBaseSection*>(rDelPos.GetTOX());
274 pMyDoc->DeleteTOX( *pTOX, true );
276 break;
278 case GLBLDOC_SECTION:
280 SwSectionFormat* pSectFormat = const_cast<SwSectionFormat*>(rDelPos.GetSection()->GetFormat());
281 pMyDoc->DelSectionFormat( pSectFormat, true );
283 break;
286 EndUndo( SwUndoId::END );
287 EndAllAction();
290 bool SwEditShell::MoveGlobalDocContent( const SwGlblDocContents& rArr ,
291 size_t nFromPos, size_t nToPos,
292 size_t nInsPos )
294 if( !getIDocumentSettingAccess().get(DocumentSettingId::GLOBAL_DOCUMENT) ||
295 nFromPos >= rArr.size() || nToPos > rArr.size() ||
296 nInsPos > rArr.size() || nFromPos >= nToPos ||
297 ( nFromPos <= nInsPos && nInsPos <= nToPos ) )
298 return false;
300 CurrShell aCurr( this );
301 StartAllAction();
303 SwPaM* pCursor = GetCursor();
304 if( pCursor->GetNext() != pCursor || IsTableMode() )
305 ClearMark();
307 SwDoc* pMyDoc = GetDoc();
308 SwNodeRange aRg( pMyDoc->GetNodes(), rArr[ nFromPos ]->GetDocPos() );
309 if( nToPos < rArr.size() )
310 aRg.aEnd = rArr[ nToPos ]->GetDocPos();
311 else
312 aRg.aEnd = pMyDoc->GetNodes().GetEndOfContent();
314 SwNodeIndex aInsPos( pMyDoc->GetNodes() );
315 if( nInsPos < rArr.size() )
316 aInsPos = rArr[ nInsPos ]->GetDocPos();
317 else
318 aInsPos = pMyDoc->GetNodes().GetEndOfContent();
320 bool bRet = pMyDoc->getIDocumentContentOperations().MoveNodeRange( aRg, aInsPos.GetNode(),
321 SwMoveFlags::CREATEUNDOOBJ );
323 EndAllAction();
324 return bRet;
327 void SwEditShell::GotoGlobalDocContent( const SwGlblDocContent& rPos )
329 if( !getIDocumentSettingAccess().get(DocumentSettingId::GLOBAL_DOCUMENT) )
330 return;
332 CurrShell aCurr( this );
333 SttCursorMove();
335 SwPaM* pCursor = GetCursor();
336 if( pCursor->GetNext() != pCursor || IsTableMode() )
337 ClearMark();
339 SwPosition& rCursorPos = *pCursor->GetPoint();
340 rCursorPos.Assign(rPos.GetDocPos());
342 SwDoc* pMyDoc = GetDoc();
343 SwContentNode * pCNd = rCursorPos.GetNode().GetContentNode();
344 if( !pCNd )
345 pCNd = pMyDoc->GetNodes().GoNext( &rCursorPos );
347 EndCursorMove();
350 SwGlblDocContent::SwGlblDocContent( SwNodeOffset nPos )
352 m_eType = GLBLDOC_UNKNOWN;
353 m_PTR.pTOX = nullptr;
354 m_nDocPos = nPos;
357 SwGlblDocContent::SwGlblDocContent( const SwTOXBaseSection* pTOX )
359 m_eType = GLBLDOC_TOXBASE;
360 m_PTR.pTOX = pTOX;
362 const SwSectionNode* pSectNd = pTOX->GetFormat()->GetSectionNode();
363 m_nDocPos = pSectNd ? pSectNd->GetIndex() : SwNodeOffset(0);
366 SwGlblDocContent::SwGlblDocContent( const SwSection* pSect )
368 m_eType = GLBLDOC_SECTION;
369 m_PTR.pSect = pSect;
371 const SwSectionNode* pSectNd = pSect->GetFormat()->GetSectionNode();
372 m_nDocPos = pSectNd ? pSectNd->GetIndex() : SwNodeOffset(0);
375 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */