xref: /trunk/main/sw/source/core/undo/unsort.cxx (revision efeef26f)
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