1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
21 #include <IDocumentUndoRedo.hxx>
22 #include <IDocumentSettingAccess.hxx>
23 #include <IDocumentState.hxx>
29 #include <section.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
57 if( !getIDocumentSettingAccess().get(DocumentSettingId::GLOBAL_DOCUMENT
) )
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();
69 std::unique_ptr
<SwGlblDocContent
> pNew
;
70 switch( pSect
->GetType() )
72 case SectionType::ToxHeader
:
74 case SectionType::ToxContent
:
75 assert( dynamic_cast<const SwTOXBaseSection
*>( pSect
) && "no TOXBaseSection!" );
76 pNew
.reset(new SwGlblDocContent( static_cast<const SwTOXBaseSection
*>(pSect
) ));
80 pNew
.reset(new SwGlblDocContent( pSect
));
84 rArr
.insert( std::move(pNew
) );
88 // and finally add the dummies (other text)
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
106 // set StartPosition to the end
107 nSttIdx
= pMyDoc
->GetNodes()[ rNew
.GetDocPos() ]->EndOfSectionIndex();
111 // Should the end also be set?
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
) );
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
) )
137 CurrShell
aCurr( this );
140 SwPaM
* pCursor
= GetCursor();
141 if( pCursor
->GetNext() != pCursor
|| IsTableMode() )
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();
153 pMyDoc
->GetIDocumentUndoRedo().StartUndo( SwUndoId::START
, nullptr );
154 rPos
.Adjust(SwNodeOffset(-1));
155 pMyDoc
->getIDocumentContentOperations().AppendTextNode( rPos
);
159 InsertSection( rNew
);
163 pMyDoc
->GetIDocumentUndoRedo().EndUndo( SwUndoId::END
, nullptr );
168 bool SwEditShell::InsertGlobalDocContent( const SwGlblDocContent
& rInsPos
,
169 const SwTOXBase
& rTOX
)
171 if( !getIDocumentSettingAccess().get(DocumentSettingId::GLOBAL_DOCUMENT
) )
174 CurrShell
aCurr( this );
177 SwPaM
* pCursor
= GetCursor();
178 if( pCursor
->GetNext() != pCursor
|| IsTableMode() )
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() )
191 pMyDoc
->GetIDocumentUndoRedo().StartUndo( SwUndoId::START
, nullptr );
192 rPos
.Adjust(SwNodeOffset(-1));
193 pMyDoc
->getIDocumentContentOperations().AppendTextNode( rPos
);
196 InsertTableOf( rTOX
);
200 pMyDoc
->GetIDocumentUndoRedo().EndUndo( SwUndoId::END
, nullptr );
207 bool SwEditShell::InsertGlobalDocContent( const SwGlblDocContent
& rInsPos
)
209 if( !getIDocumentSettingAccess().get(DocumentSettingId::GLOBAL_DOCUMENT
) )
212 CurrShell
aCurr( this );
215 SwPaM
* pCursor
= GetCursor();
216 if( pCursor
->GetNext() != pCursor
|| IsTableMode() )
219 SwPosition
& rPos
= *pCursor
->GetPoint();
220 rPos
.Assign(rInsPos
.GetDocPos() - 1);
222 SwDoc
* pMyDoc
= GetDoc();
223 pMyDoc
->getIDocumentContentOperations().AppendTextNode( rPos
);
228 void SwEditShell::DeleteGlobalDocContent( const SwGlblDocContents
& rArr
,
231 if( !getIDocumentSettingAccess().get(DocumentSettingId::GLOBAL_DOCUMENT
) )
234 CurrShell
aCurr( this );
236 StartUndo( SwUndoId::START
);
238 SwPaM
* pCursor
= GetCursor();
239 if( pCursor
->GetNext() != pCursor
|| IsTableMode() )
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
);
256 switch( rDelPos
.GetType() )
258 case GLBLDOC_UNKNOWN
:
260 rPos
.Assign(nDelIdx
);
262 if( ++nDelPos
< rArr
.size() )
263 rPos
.Assign(rArr
[ nDelPos
]->GetDocPos(), -1);
265 rPos
.Assign(pMyDoc
->GetNodes().GetEndOfContent(), -1);
266 if( !pMyDoc
->getIDocumentContentOperations().DelFullPara( *pCursor
) )
271 case GLBLDOC_TOXBASE
:
273 const SwTOXBaseSection
* pTOX
= static_cast<const SwTOXBaseSection
*>(rDelPos
.GetTOX());
274 pMyDoc
->DeleteTOX( *pTOX
, true );
278 case GLBLDOC_SECTION
:
280 SwSectionFormat
* pSectFormat
= const_cast<SwSectionFormat
*>(rDelPos
.GetSection()->GetFormat());
281 pMyDoc
->DelSectionFormat( pSectFormat
, true );
286 EndUndo( SwUndoId::END
);
290 bool SwEditShell::MoveGlobalDocContent( const SwGlblDocContents
& rArr
,
291 size_t nFromPos
, size_t nToPos
,
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
) )
300 CurrShell
aCurr( this );
303 SwPaM
* pCursor
= GetCursor();
304 if( pCursor
->GetNext() != pCursor
|| IsTableMode() )
307 SwDoc
* pMyDoc
= GetDoc();
308 SwNodeRange
aRg( pMyDoc
->GetNodes(), rArr
[ nFromPos
]->GetDocPos() );
309 if( nToPos
< rArr
.size() )
310 aRg
.aEnd
= rArr
[ nToPos
]->GetDocPos();
312 aRg
.aEnd
= pMyDoc
->GetNodes().GetEndOfContent();
314 SwNodeIndex
aInsPos( pMyDoc
->GetNodes() );
315 if( nInsPos
< rArr
.size() )
316 aInsPos
= rArr
[ nInsPos
]->GetDocPos();
318 aInsPos
= pMyDoc
->GetNodes().GetEndOfContent();
320 bool bRet
= pMyDoc
->getIDocumentContentOperations().MoveNodeRange( aRg
, aInsPos
.GetNode(),
321 SwMoveFlags::CREATEUNDOOBJ
);
327 void SwEditShell::GotoGlobalDocContent( const SwGlblDocContent
& rPos
)
329 if( !getIDocumentSettingAccess().get(DocumentSettingId::GLOBAL_DOCUMENT
) )
332 CurrShell
aCurr( this );
335 SwPaM
* pCursor
= GetCursor();
336 if( pCursor
->GetNext() != pCursor
|| IsTableMode() )
339 SwPosition
& rCursorPos
= *pCursor
->GetPoint();
340 rCursorPos
.Assign(rPos
.GetDocPos());
342 SwDoc
* pMyDoc
= GetDoc();
343 SwContentNode
* pCNd
= rCursorPos
.GetNode().GetContentNode();
345 pCNd
= pMyDoc
->GetNodes().GoNext( &rCursorPos
);
350 SwGlblDocContent::SwGlblDocContent( SwNodeOffset nPos
)
352 m_eType
= GLBLDOC_UNKNOWN
;
353 m_PTR
.pTOX
= nullptr;
357 SwGlblDocContent::SwGlblDocContent( const SwTOXBaseSection
* pTOX
)
359 m_eType
= GLBLDOC_TOXBASE
;
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
;
371 const SwSectionNode
* pSectNd
= pSect
->GetFormat()->GetSectionNode();
372 m_nDocPos
= pSectNd
? pSectNd
->GetIndex() : SwNodeOffset(0);
375 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */