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