1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: unsort.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
34 #include <swundo.hxx> // fuer die UndoIds
36 #include <swtable.hxx>
39 #include <sortopt.hxx>
41 #include <docsort.hxx>
43 #include <redline.hxx>
44 #include <node2lay.hxx>
46 inline SwDoc
& SwUndoIter::GetDoc() const { return *pAktPam
->GetDoc(); }
48 /*--------------------------------------------------------------------
49 Beschreibung: Undo fuers Sorting
50 --------------------------------------------------------------------*/
53 SV_IMPL_PTRARR(SwSortList
, SwSortUndoElement
*)
54 SV_IMPL_PTRARR(SwUndoSortList
, SwNodeIndex
*)
57 SwSortUndoElement::~SwSortUndoElement()
59 // sind String Pointer gespeichert ??
60 if( 0xffffffff != SORT_TXT_TBL
.TXT
.nKenn
)
62 delete SORT_TXT_TBL
.TBL
.pSource
;
63 delete SORT_TXT_TBL
.TBL
.pTarget
;
68 SwUndoSort::SwUndoSort(const SwPaM
& rRg
, const SwSortOptions
& rOpt
)
69 : SwUndo(UNDO_SORT_TXT
), SwUndRng(rRg
), pUndoTblAttr( 0 ),
72 pSortOpt
= new SwSortOptions(rOpt
);
76 SwUndoSort::SwUndoSort( ULONG nStt
, ULONG nEnd
, const SwTableNode
& rTblNd
,
77 const SwSortOptions
& rOpt
, BOOL bSaveTable
)
78 : SwUndo(UNDO_SORT_TBL
), pUndoTblAttr( 0 ), pRedlData( 0 )
82 nTblNd
= rTblNd
.GetIndex();
84 pSortOpt
= new SwSortOptions(rOpt
);
86 pUndoTblAttr
= new SwUndoAttrTbl( rTblNd
);
91 SwUndoSort::~SwUndoSort()
100 void SwUndoSort::Undo( SwUndoIter
& rIter
)
102 SwDoc
& rDoc
= rIter
.GetDoc();
106 RemoveIdxFromSection( rDoc
, nSttNode
, &nEndNode
);
109 pUndoTblAttr
->Undo( rIter
);
111 SwTableNode
* pTblNd
= rDoc
.GetNodes()[ nTblNd
]->GetTableNode();
113 // --> FME 2004-11-26 #i37739# A simple 'MakeFrms' after the node sorting
114 // does not work if the table is inside a frame and has no prev/next.
115 SwNode2Layout
aNode2Layout( *pTblNd
);
119 const SwTable
& rTbl
= pTblNd
->GetTable();
121 SwMovedBoxes aMovedList
;
122 for( USHORT i
=0; i
< aSortList
.Count(); i
++)
124 const SwTableBox
* pSource
= rTbl
.GetTblBox(
125 *aSortList
[i
]->SORT_TXT_TBL
.TBL
.pSource
);
126 const SwTableBox
* pTarget
= rTbl
.GetTblBox(
127 *aSortList
[i
]->SORT_TXT_TBL
.TBL
.pTarget
);
129 // zurueckverschieben
130 MoveCell(&rDoc
, pTarget
, pSource
,
131 USHRT_MAX
!= aMovedList
.GetPos(pSource
) );
133 // schon Verschobenen in der Liste merken
134 aMovedList
.Insert(pTarget
, aMovedList
.Count() );
137 // Restore table frames:
138 // --> FME 2004-11-26 #i37739# A simple 'MakeFrms' after the node sorting
139 // does not work if the table is inside a frame and has no prev/next.
140 const ULONG nIdx
= pTblNd
->GetIndex();
141 aNode2Layout
.RestoreUpperFrms( rDoc
.GetNodes(), nIdx
, nIdx
+ 1 );
147 RemoveIdx( *rIter
.pAktPam
);
149 // fuer die sorted Positions einen Index anlegen.
150 // JP 25.11.97: Die IndexList muss aber nach SourcePosition
151 // aufsteigend sortiert aufgebaut werden
152 SwUndoSortList
aIdxList( (BYTE
)aSortList
.Count() );
155 for( i
= 0; i
< aSortList
.Count(); ++i
)
156 for( USHORT ii
=0; ii
< aSortList
.Count(); ++ii
)
157 if( aSortList
[ii
]->SORT_TXT_TBL
.TXT
.nSource
== nSttNode
+ i
)
159 SwNodeIndex
* pIdx
= new SwNodeIndex( rDoc
.GetNodes(),
160 aSortList
[ii
]->SORT_TXT_TBL
.TXT
.nTarget
);
161 aIdxList
.C40_INSERT(SwNodeIndex
, pIdx
, i
);
165 for(i
=0; i
< aSortList
.Count(); ++i
)
167 SwNodeIndex
aIdx( rDoc
.GetNodes(), nSttNode
+ i
);
168 SwNodeRange
aRg( *aIdxList
[i
], 0, *aIdxList
[i
], 1 );
169 rDoc
.Move(aRg
, aIdx
, IDocumentContentOperations::DOC_MOVEDEFAULT
);
172 aIdxList
.DeleteAndDestroy(0, aIdxList
.Count());
173 SetPaM( rIter
, TRUE
);
178 void SwUndoSort::Redo( SwUndoIter
& rIter
)
180 SwDoc
& rDoc
= rIter
.GetDoc();
185 RemoveIdxFromSection( rDoc
, nSttNode
, &nEndNode
);
187 SwTableNode
* pTblNd
= rDoc
.GetNodes()[ nTblNd
]->GetTableNode();
189 // --> FME 2004-11-26 #i37739# A simple 'MakeFrms' after the node sorting
190 // does not work if the table is inside a frame and has no prev/next.
191 SwNode2Layout
aNode2Layout( *pTblNd
);
195 const SwTable
& rTbl
= pTblNd
->GetTable();
197 SwMovedBoxes aMovedList
;
198 for(USHORT i
=0; i
< aSortList
.Count(); ++i
)
200 const SwTableBox
* pSource
= rTbl
.GetTblBox(
201 (const String
&) *aSortList
[i
]->SORT_TXT_TBL
.TBL
.pSource
);
202 const SwTableBox
* pTarget
= rTbl
.GetTblBox(
203 (const String
&) *aSortList
[i
]->SORT_TXT_TBL
.TBL
.pTarget
);
205 // zurueckverschieben
206 MoveCell(&rDoc
, pSource
, pTarget
,
207 USHRT_MAX
!= aMovedList
.GetPos( pTarget
) );
208 // schon Verschobenen in der Liste merken
209 aMovedList
.Insert( pSource
, aMovedList
.Count() );
213 pUndoTblAttr
->Redo( rIter
);
215 // Restore table frames:
216 // --> FME 2004-11-26 #i37739# A simple 'MakeFrms' after the node sorting
217 // does not work if the table is inside a frame and has no prev/next.
218 const ULONG nIdx
= pTblNd
->GetIndex();
219 aNode2Layout
.RestoreUpperFrms( rDoc
.GetNodes(), nIdx
, nIdx
+ 1 );
225 RemoveIdx( *rIter
.pAktPam
);
227 SwUndoSortList
aIdxList( (BYTE
)aSortList
.Count() );
230 for( i
= 0; i
< aSortList
.Count(); ++i
)
231 { // aktuelle Pos ist die Ausgangslage
232 SwNodeIndex
* pIdx
= new SwNodeIndex( rDoc
.GetNodes(),
233 aSortList
[i
]->SORT_TXT_TBL
.TXT
.nSource
);
234 aIdxList
.C40_INSERT( SwNodeIndex
, pIdx
, i
);
237 for(i
=0; i
< aSortList
.Count(); ++i
)
239 SwNodeIndex
aIdx( rDoc
.GetNodes(), nSttNode
+ i
);
240 SwNodeRange
aRg( *aIdxList
[i
], 0, *aIdxList
[i
], 1 );
241 rDoc
.Move(aRg
, aIdx
, IDocumentContentOperations::DOC_MOVEDEFAULT
);
244 aIdxList
.DeleteAndDestroy(0, aIdxList
.Count());
245 SetPaM( rIter
, TRUE
);
246 const SwTxtNode
* pTNd
= rIter
.pAktPam
->GetNode()->GetTxtNode();
248 rIter
.pAktPam
->GetPoint()->nContent
= pTNd
->GetTxt().Len();
253 void SwUndoSort::Repeat(SwUndoIter
& rIter
)
255 if(!pSortOpt
->bTable
)
257 SwPaM
* pPam
= rIter
.pAktPam
;
258 SwDoc
& rDoc
= *pPam
->GetDoc();
260 if( !rDoc
.IsIdxInTbl( pPam
->Start()->nNode
) )
261 rDoc
.SortText(*pPam
, *pSortOpt
);
263 // Tabelle ist nicht Repeat-Faehig
264 rIter
.pLastUndoObj
= this;
268 void SwUndoSort::RemoveIdx( SwPaM
& rPam
)
271 rPam
.GetPoint()->nNode
= nSttNode
;
273 SwCntntNode
* pCNd
= rPam
.GetCntntNode();
274 xub_StrLen nLen
= pCNd
->Len();
275 if( nLen
>= nSttCntnt
)
277 rPam
.GetPoint()->nContent
.Assign(pCNd
, nLen
);
280 rPam
.GetPoint()->nNode
= nEndNode
;
281 pCNd
= rPam
.GetCntntNode();
283 if( nLen
>= nEndCntnt
)
285 rPam
.GetPoint()->nContent
.Assign(pCNd
, nLen
);
286 RemoveIdxFromRange( rPam
, TRUE
);
290 void SwUndoSort::Insert( const String
& rOrgPos
, const String
& rNewPos
)
292 SwSortUndoElement
* pEle
= new SwSortUndoElement(rOrgPos
, rNewPos
);
293 aSortList
.C40_INSERT( SwSortUndoElement
, pEle
, aSortList
.Count() );
297 void SwUndoSort::Insert( ULONG nOrgPos
, ULONG nNewPos
)
299 SwSortUndoElement
* pEle
= new SwSortUndoElement(nOrgPos
, nNewPos
);
300 aSortList
.C40_INSERT( SwSortUndoElement
, pEle
, aSortList
.Count() );