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 <UndoSort.hxx>
25 #include <swtable.hxx>
27 #include <UndoCore.hxx>
28 #include <UndoTable.hxx>
29 #include <sortopt.hxx>
30 #include <docsort.hxx>
31 #include <node2lay.hxx>
33 SwUndoSort::SwUndoSort(const SwPaM
& rRg
, const SwSortOptions
& rOpt
)
34 : SwUndo(SwUndoId::SORT_TXT
, &rRg
.GetDoc())
38 m_pSortOptions
.reset( new SwSortOptions(rOpt
) );
41 SwUndoSort::SwUndoSort( SwNodeOffset nStt
, SwNodeOffset nEnd
, const SwTableNode
& rTableNd
,
42 const SwSortOptions
& rOpt
, bool bSaveTable
)
43 : SwUndo(SwUndoId::SORT_TBL
, &rTableNd
.GetDoc())
47 m_nTableNode
= rTableNd
.GetIndex();
49 m_pSortOptions
.reset( new SwSortOptions(rOpt
) );
51 m_pUndoAttrTable
.reset( new SwUndoAttrTable( rTableNd
) );
54 SwUndoSort::~SwUndoSort()
56 m_pSortOptions
.reset();
57 m_pUndoAttrTable
.reset();
60 void SwUndoSort::UndoImpl(::sw::UndoRedoContext
& rContext
)
62 SwDoc
& rDoc
= rContext
.GetDoc();
63 if(m_pSortOptions
->bTable
)
66 RemoveIdxFromSection( rDoc
, m_nSttNode
, &m_nEndNode
);
68 if( m_pUndoAttrTable
)
70 m_pUndoAttrTable
->UndoImpl(rContext
);
73 SwTableNode
* pTableNd
= rDoc
.GetNodes()[ m_nTableNode
]->GetTableNode();
75 // #i37739# A simple 'MakeFrames' after the node sorting
76 // does not work if the table is inside a frame and has no prev/next.
77 SwNode2LayoutSaveUpperFrames
aNode2Layout(*pTableNd
);
79 pTableNd
->DelFrames();
80 const SwTable
& rTable
= pTableNd
->GetTable();
82 SwMovedBoxes aMovedList
;
83 for (std::unique_ptr
<SwSortUndoElement
> const& pElement
: m_SortList
)
85 const SwTableBox
* pSource
= rTable
.GetTableBox(pElement
->maSourceString
);
86 const SwTableBox
* pTarget
= rTable
.GetTableBox(pElement
->maTargetString
);
89 MoveCell(&rDoc
, pTarget
, pSource
,
90 USHRT_MAX
!= aMovedList
.GetPos(pSource
) );
92 // store moved entry in list
93 aMovedList
.push_back(pTarget
);
96 // Restore table frames:
97 // #i37739# A simple 'MakeFrames' after the node sorting
98 // does not work if the table is inside a frame and has no prev/next.
99 const SwNodeOffset nIdx
= pTableNd
->GetIndex();
100 aNode2Layout
.RestoreUpperFrames( rDoc
.GetNodes(), nIdx
, nIdx
+ 1 );
105 SwPaM
& rPam( AddUndoRedoPaM(rContext
) );
106 RemoveIdxFromRange(rPam
, true);
108 // create index for (sorted) positions
109 // The IndexList must be created based on (asc.) sorted SourcePosition.
110 std::vector
<SwNodeIndex
> aIdxList
;
111 aIdxList
.reserve(m_SortList
.size());
113 for (size_t i
= 0; i
< m_SortList
.size(); ++i
)
115 for (std::unique_ptr
<SwSortUndoElement
> const& pElement
: m_SortList
)
117 if (pElement
->mnSourceNodeOffset
== (m_nSttNode
+ SwNodeOffset(i
)))
119 aIdxList
.push_back( SwNodeIndex(rDoc
.GetNodes(), pElement
->mnTargetNodeOffset
));
125 for (size_t i
= 0; i
< m_SortList
.size(); ++i
)
127 SwNodeIndex
aIdx( rDoc
.GetNodes(), m_nSttNode
+ SwNodeOffset(i
) );
128 SwNodeRange
aRg( aIdxList
[i
], SwNodeOffset(0), aIdxList
[i
], SwNodeOffset(1) );
129 rDoc
.getIDocumentContentOperations().MoveNodeRange(aRg
, aIdx
.GetNode(),
130 SwMoveFlags::DEFAULT
);
138 void SwUndoSort::RedoImpl(::sw::UndoRedoContext
& rContext
)
140 SwDoc
& rDoc
= rContext
.GetDoc();
142 if(m_pSortOptions
->bTable
)
145 RemoveIdxFromSection( rDoc
, m_nSttNode
, &m_nEndNode
);
147 SwTableNode
* pTableNd
= rDoc
.GetNodes()[ m_nTableNode
]->GetTableNode();
149 // #i37739# A simple 'MakeFrames' after the node sorting
150 // does not work if the table is inside a frame and has no prev/next.
151 SwNode2LayoutSaveUpperFrames
aNode2Layout(*pTableNd
);
153 pTableNd
->DelFrames();
154 const SwTable
& rTable
= pTableNd
->GetTable();
156 SwMovedBoxes aMovedList
;
157 for (std::unique_ptr
<SwSortUndoElement
> const& pElement
: m_SortList
)
159 const SwTableBox
* pSource
= rTable
.GetTableBox(pElement
->maSourceString
);
160 const SwTableBox
* pTarget
= rTable
.GetTableBox(pElement
->maTargetString
);
163 MoveCell(&rDoc
, pSource
, pTarget
,
164 USHRT_MAX
!= aMovedList
.GetPos( pTarget
) );
165 // store moved entry in list
166 aMovedList
.push_back( pSource
);
169 if( m_pUndoAttrTable
)
171 m_pUndoAttrTable
->RedoImpl(rContext
);
174 // Restore table frames:
175 // #i37739# A simple 'MakeFrames' after the node sorting
176 // does not work if the table is inside a frame and has no prev/next.
177 const SwNodeOffset nIdx
= pTableNd
->GetIndex();
178 aNode2Layout
.RestoreUpperFrames( rDoc
.GetNodes(), nIdx
, nIdx
+ 1 );
183 SwPaM
& rPam( AddUndoRedoPaM(rContext
) );
185 RemoveIdxFromRange(rPam
, true);
187 std::vector
<SwNodeIndex
> aIdxList
;
188 aIdxList
.reserve(m_SortList
.size());
190 for (size_t i
= 0; i
< m_SortList
.size(); ++i
)
191 { // current position is starting point
192 aIdxList
.push_back( SwNodeIndex(rDoc
.GetNodes(), m_SortList
[i
]->mnSourceNodeOffset
) );
195 for (size_t i
= 0; i
< m_SortList
.size(); ++i
)
197 SwNodeIndex
aIdx( rDoc
.GetNodes(), m_nSttNode
+ SwNodeOffset(i
));
198 SwNodeRange
aRg( aIdxList
[i
], SwNodeOffset(0), aIdxList
[i
], SwNodeOffset(1) );
199 rDoc
.getIDocumentContentOperations().MoveNodeRange(aRg
, aIdx
.GetNode(),
200 SwMoveFlags::DEFAULT
);
205 SwTextNode
const*const pTNd
= rPam
.GetPointNode().GetTextNode();
208 rPam
.GetPoint()->SetContent( pTNd
->GetText().getLength() );
213 void SwUndoSort::RepeatImpl(::sw::RepeatContext
& rContext
)
215 // table not repeat capable
216 if(!m_pSortOptions
->bTable
)
218 SwPaM
*const pPam
= & rContext
.GetRepeatPaM();
219 SwDoc
& rDoc
= pPam
->GetDoc();
221 if( !SwDoc::IsInTable( pPam
->Start()->GetNode() ) )
222 rDoc
.SortText(*pPam
, *m_pSortOptions
);
226 void SwUndoSort::Insert( const OUString
& rOrgPos
, const OUString
& rNewPos
)
228 m_SortList
.push_back(std::make_unique
<SwSortUndoElement
>(rOrgPos
, rNewPos
));
231 void SwUndoSort::Insert( SwNodeOffset nOrgPos
, SwNodeOffset nNewPos
)
233 m_SortList
.push_back(std::make_unique
<SwSortUndoElement
>(nOrgPos
, nNewPos
));
236 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */