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 <UndoSort.hxx>
28
29 #include <doc.hxx>
30 #include <swundo.hxx> // fuer die UndoIds
31 #include <pam.hxx>
32 #include <swtable.hxx>
33 #include <ndtxt.hxx>
34 #include <UndoCore.hxx>
35 #include <UndoTable.hxx>
36 #include <sortopt.hxx>
37 #include <docsort.hxx>
38 #include <redline.hxx>
39 #include <node2lay.hxx>
40
41
42 /*--------------------------------------------------------------------
43 Beschreibung: Undo fuers Sorting
44 --------------------------------------------------------------------*/
45
46
SV_IMPL_PTRARR(SwSortList,SwSortUndoElement *)47 SV_IMPL_PTRARR(SwSortList, SwSortUndoElement*)
48 SV_IMPL_PTRARR(SwUndoSortList, SwNodeIndex*)
49
50
51 SwSortUndoElement::~SwSortUndoElement()
52 {
53 // sind String Pointer gespeichert ??
54 if( 0xffffffff != SORT_TXT_TBL.TXT.nKenn )
55 {
56 delete SORT_TXT_TBL.TBL.pSource;
57 delete SORT_TXT_TBL.TBL.pTarget;
58 }
59 }
60
61
SwUndoSort(const SwPaM & rRg,const SwSortOptions & rOpt)62 SwUndoSort::SwUndoSort(const SwPaM& rRg, const SwSortOptions& rOpt)
63 : SwUndo(UNDO_SORT_TXT), SwUndRng(rRg), pUndoTblAttr( 0 ),
64 pRedlData( 0 )
65 {
66 pSortOpt = new SwSortOptions(rOpt);
67 }
68
SwUndoSort(sal_uLong nStt,sal_uLong nEnd,const SwTableNode & rTblNd,const SwSortOptions & rOpt,sal_Bool bSaveTable)69 SwUndoSort::SwUndoSort( sal_uLong nStt, sal_uLong nEnd, const SwTableNode& rTblNd,
70 const SwSortOptions& rOpt, sal_Bool bSaveTable )
71 : SwUndo(UNDO_SORT_TBL), pUndoTblAttr( 0 ), pRedlData( 0 )
72 {
73 nSttNode = nStt;
74 nEndNode = nEnd;
75 nTblNd = rTblNd.GetIndex();
76
77 pSortOpt = new SwSortOptions(rOpt);
78 if( bSaveTable )
79 pUndoTblAttr = new SwUndoAttrTbl( rTblNd );
80 }
81
~SwUndoSort()82 SwUndoSort::~SwUndoSort()
83 {
84 delete pSortOpt;
85 delete pUndoTblAttr;
86 delete pRedlData;
87 }
88
UndoImpl(::sw::UndoRedoContext & rContext)89 void SwUndoSort::UndoImpl(::sw::UndoRedoContext & rContext)
90 {
91 SwDoc & rDoc = rContext.GetDoc();
92 if(pSortOpt->bTable)
93 {
94 // Undo Tabelle
95 RemoveIdxFromSection( rDoc, nSttNode, &nEndNode );
96
97 if( pUndoTblAttr )
98 {
99 pUndoTblAttr->UndoImpl(rContext);
100 }
101
102 SwTableNode* pTblNd = rDoc.GetNodes()[ nTblNd ]->GetTableNode();
103
104 // --> FME 2004-11-26 #i37739# A simple 'MakeFrms' after the node sorting
105 // does not work if the table is inside a frame and has no prev/next.
106 SwNode2Layout aNode2Layout( *pTblNd );
107 // <--
108
109 pTblNd->DelFrms();
110 const SwTable& rTbl = pTblNd->GetTable();
111
112 SwMovedBoxes aMovedList;
113 for( sal_uInt16 i=0; i < aSortList.Count(); i++)
114 {
115 const SwTableBox* pSource = rTbl.GetTblBox(
116 *aSortList[i]->SORT_TXT_TBL.TBL.pSource );
117 const SwTableBox* pTarget = rTbl.GetTblBox(
118 *aSortList[i]->SORT_TXT_TBL.TBL.pTarget );
119
120 // zurueckverschieben
121 MoveCell(&rDoc, pTarget, pSource,
122 USHRT_MAX != aMovedList.GetPos(pSource) );
123
124 // schon Verschobenen in der Liste merken
125 aMovedList.Insert(pTarget, aMovedList.Count() );
126 }
127
128 // Restore table frames:
129 // --> FME 2004-11-26 #i37739# A simple 'MakeFrms' after the node sorting
130 // does not work if the table is inside a frame and has no prev/next.
131 const sal_uLong nIdx = pTblNd->GetIndex();
132 aNode2Layout.RestoreUpperFrms( rDoc.GetNodes(), nIdx, nIdx + 1 );
133 // <--
134 }
135 else
136 {
137 // Undo Text
138 SwPaM & rPam( AddUndoRedoPaM(rContext) );
139 RemoveIdxFromRange(rPam, true);
140
141 // fuer die sorted Positions einen Index anlegen.
142 // JP 25.11.97: Die IndexList muss aber nach SourcePosition
143 // aufsteigend sortiert aufgebaut werden
144 SwUndoSortList aIdxList( (sal_uInt8)aSortList.Count() );
145 sal_uInt16 i;
146
147 for( i = 0; i < aSortList.Count(); ++i)
148 for( sal_uInt16 ii=0; ii < aSortList.Count(); ++ii )
149 if( aSortList[ii]->SORT_TXT_TBL.TXT.nSource == nSttNode + i )
150 {
151 SwNodeIndex* pIdx = new SwNodeIndex( rDoc.GetNodes(),
152 aSortList[ii]->SORT_TXT_TBL.TXT.nTarget );
153 aIdxList.C40_INSERT(SwNodeIndex, pIdx, i );
154 break;
155 }
156
157 for(i=0; i < aSortList.Count(); ++i)
158 {
159 SwNodeIndex aIdx( rDoc.GetNodes(), nSttNode + i );
160 SwNodeRange aRg( *aIdxList[i], 0, *aIdxList[i], 1 );
161 rDoc.MoveNodeRange(aRg, aIdx,
162 IDocumentContentOperations::DOC_MOVEDEFAULT);
163 }
164 // Indixes loeschen
165 aIdxList.DeleteAndDestroy(0, aIdxList.Count());
166 SetPaM(rPam, true);
167 }
168 }
169
RedoImpl(::sw::UndoRedoContext & rContext)170 void SwUndoSort::RedoImpl(::sw::UndoRedoContext & rContext)
171 {
172 SwDoc & rDoc = rContext.GetDoc();
173
174 if(pSortOpt->bTable)
175 {
176 // Redo bei Tabelle
177 RemoveIdxFromSection( rDoc, nSttNode, &nEndNode );
178
179 SwTableNode* pTblNd = rDoc.GetNodes()[ nTblNd ]->GetTableNode();
180
181 // --> FME 2004-11-26 #i37739# A simple 'MakeFrms' after the node sorting
182 // does not work if the table is inside a frame and has no prev/next.
183 SwNode2Layout aNode2Layout( *pTblNd );
184 // <--
185
186 pTblNd->DelFrms();
187 const SwTable& rTbl = pTblNd->GetTable();
188
189 SwMovedBoxes aMovedList;
190 for(sal_uInt16 i=0; i < aSortList.Count(); ++i)
191 {
192 const SwTableBox* pSource = rTbl.GetTblBox(
193 (const String&) *aSortList[i]->SORT_TXT_TBL.TBL.pSource );
194 const SwTableBox* pTarget = rTbl.GetTblBox(
195 (const String&) *aSortList[i]->SORT_TXT_TBL.TBL.pTarget );
196
197 // zurueckverschieben
198 MoveCell(&rDoc, pSource, pTarget,
199 USHRT_MAX != aMovedList.GetPos( pTarget ) );
200 // schon Verschobenen in der Liste merken
201 aMovedList.Insert( pSource, aMovedList.Count() );
202 }
203
204 if( pUndoTblAttr )
205 {
206 pUndoTblAttr->RedoImpl(rContext);
207 }
208
209 // Restore table frames:
210 // --> FME 2004-11-26 #i37739# A simple 'MakeFrms' after the node sorting
211 // does not work if the table is inside a frame and has no prev/next.
212 const sal_uLong nIdx = pTblNd->GetIndex();
213 aNode2Layout.RestoreUpperFrms( rDoc.GetNodes(), nIdx, nIdx + 1 );
214 // <--
215 }
216 else
217 {
218 // Redo for Text
219 SwPaM & rPam( AddUndoRedoPaM(rContext) );
220 SetPaM(rPam);
221 RemoveIdxFromRange(rPam, true);
222
223 SwUndoSortList aIdxList( (sal_uInt8)aSortList.Count() );
224 sal_uInt16 i;
225
226 for( i = 0; i < aSortList.Count(); ++i)
227 { // aktuelle Pos ist die Ausgangslage
228 SwNodeIndex* pIdx = new SwNodeIndex( rDoc.GetNodes(),
229 aSortList[i]->SORT_TXT_TBL.TXT.nSource);
230 aIdxList.C40_INSERT( SwNodeIndex, pIdx, i );
231 }
232
233 for(i=0; i < aSortList.Count(); ++i)
234 {
235 SwNodeIndex aIdx( rDoc.GetNodes(), nSttNode + i);
236 SwNodeRange aRg( *aIdxList[i], 0, *aIdxList[i], 1 );
237 rDoc.MoveNodeRange(aRg, aIdx,
238 IDocumentContentOperations::DOC_MOVEDEFAULT);
239 }
240 // Indixes loeschen
241 aIdxList.DeleteAndDestroy(0, aIdxList.Count());
242 SetPaM(rPam, true);
243 SwTxtNode const*const pTNd = rPam.GetNode()->GetTxtNode();
244 if( pTNd )
245 {
246 rPam.GetPoint()->nContent = pTNd->GetTxt().Len();
247 }
248 }
249 }
250
RepeatImpl(::sw::RepeatContext & rContext)251 void SwUndoSort::RepeatImpl(::sw::RepeatContext & rContext)
252 {
253 // table not repeat capable
254 if(!pSortOpt->bTable)
255 {
256 SwPaM *const pPam = & rContext.GetRepeatPaM();
257 SwDoc& rDoc = *pPam->GetDoc();
258
259 if( !rDoc.IsIdxInTbl( pPam->Start()->nNode ) )
260 rDoc.SortText(*pPam, *pSortOpt);
261 }
262 }
263
Insert(const String & rOrgPos,const String & rNewPos)264 void SwUndoSort::Insert( const String& rOrgPos, const String& rNewPos)
265 {
266 SwSortUndoElement* pEle = new SwSortUndoElement(rOrgPos, rNewPos);
267 aSortList.C40_INSERT( SwSortUndoElement, pEle, aSortList.Count() );
268 }
269
Insert(sal_uLong nOrgPos,sal_uLong nNewPos)270 void SwUndoSort::Insert( sal_uLong nOrgPos, sal_uLong nNewPos)
271 {
272 SwSortUndoElement* pEle = new SwSortUndoElement(nOrgPos, nNewPos);
273 aSortList.C40_INSERT( SwSortUndoElement, pEle, aSortList.Count() );
274 }
275
276