xref: /trunk/main/sw/source/core/undo/untbl.cxx (revision 300d4866)
1efeef26fSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3efeef26fSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4efeef26fSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5efeef26fSAndrew Rist  * distributed with this work for additional information
6efeef26fSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7efeef26fSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8efeef26fSAndrew Rist  * "License"); you may not use this file except in compliance
9efeef26fSAndrew Rist  * with the License.  You may obtain a copy of the License at
10efeef26fSAndrew Rist  *
11efeef26fSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12efeef26fSAndrew Rist  *
13efeef26fSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14efeef26fSAndrew Rist  * software distributed under the License is distributed on an
15efeef26fSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16efeef26fSAndrew Rist  * KIND, either express or implied.  See the License for the
17efeef26fSAndrew Rist  * specific language governing permissions and limitations
18efeef26fSAndrew Rist  * under the License.
19efeef26fSAndrew Rist  *
20efeef26fSAndrew Rist  *************************************************************/
21efeef26fSAndrew Rist 
22efeef26fSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sw.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <UndoTable.hxx>
28cdf0e10cSrcweir 
29cdf0e10cSrcweir #include <UndoRedline.hxx>
30cdf0e10cSrcweir #include <UndoDelete.hxx>
31cdf0e10cSrcweir #include <UndoSplitMove.hxx>
32cdf0e10cSrcweir #include <UndoCore.hxx>
33cdf0e10cSrcweir #include <hintids.hxx>
34cdf0e10cSrcweir #include <hints.hxx>
35cdf0e10cSrcweir #include <editeng/brkitem.hxx>
36cdf0e10cSrcweir #include <fmtornt.hxx>
37cdf0e10cSrcweir #include <fmtpdsc.hxx>
38cdf0e10cSrcweir #include <doc.hxx>
39cdf0e10cSrcweir #include <IDocumentUndoRedo.hxx>
40cdf0e10cSrcweir #include <editsh.hxx>
41cdf0e10cSrcweir #include <docary.hxx>
42cdf0e10cSrcweir #include <ndtxt.hxx>
43cdf0e10cSrcweir #include <swtable.hxx>
44cdf0e10cSrcweir #include <pam.hxx>
45cdf0e10cSrcweir #include <cntfrm.hxx>
46cdf0e10cSrcweir #include <tblsel.hxx>
47cdf0e10cSrcweir #include <swundo.hxx>			// fuer die UndoIds
48cdf0e10cSrcweir #include <rolbck.hxx>
49cdf0e10cSrcweir #include <ddefld.hxx>
50cdf0e10cSrcweir #include <tabcol.hxx>
51cdf0e10cSrcweir #include <tabfrm.hxx>
52cdf0e10cSrcweir #include <rowfrm.hxx>
53cdf0e10cSrcweir #include <cellfrm.hxx>
54cdf0e10cSrcweir #include <swcache.hxx>
55cdf0e10cSrcweir #include <tblafmt.hxx>
56cdf0e10cSrcweir #include <poolfmt.hxx>
57cdf0e10cSrcweir #include <mvsave.hxx>
58cdf0e10cSrcweir #include <cellatr.hxx>
59cdf0e10cSrcweir #include <swtblfmt.hxx>
60cdf0e10cSrcweir #include <swddetbl.hxx>
61cdf0e10cSrcweir #include <redline.hxx>
62cdf0e10cSrcweir #include <node2lay.hxx>
63cdf0e10cSrcweir #include <tblrwcl.hxx>
64cdf0e10cSrcweir #include <fmtanchr.hxx>
65cdf0e10cSrcweir #include <comcore.hrc>
66cdf0e10cSrcweir #include <unochart.hxx>
67cdf0e10cSrcweir #include <switerator.hxx>
68cdf0e10cSrcweir 
69cdf0e10cSrcweir #ifndef DBG_UTIL
70cdf0e10cSrcweir #define CHECK_TABLE(t)
71cdf0e10cSrcweir #else
72cdf0e10cSrcweir #ifdef DEBUG
73cdf0e10cSrcweir #define CHECK_TABLE(t) (t).CheckConsistency();
74cdf0e10cSrcweir #else
75cdf0e10cSrcweir #define CHECK_TABLE(t)
76cdf0e10cSrcweir #endif
77cdf0e10cSrcweir #endif
78cdf0e10cSrcweir 
79cdf0e10cSrcweir #ifndef DBG_UTIL
80cdf0e10cSrcweir     #define _DEBUG_REDLINE( pDoc )
81cdf0e10cSrcweir #else
82cdf0e10cSrcweir 	void lcl_DebugRedline( const SwDoc* pDoc );
83cdf0e10cSrcweir 	#define _DEBUG_REDLINE( pDoc ) lcl_DebugRedline( pDoc );
84cdf0e10cSrcweir #endif
85cdf0e10cSrcweir 
86cdf0e10cSrcweir extern void ClearFEShellTabCols();
87cdf0e10cSrcweir 
88cdf0e10cSrcweir typedef SfxItemSet* SfxItemSetPtr;
89cdf0e10cSrcweir SV_DECL_PTRARR_DEL( SfxItemSets, SfxItemSetPtr, 10, 5 )
90cdf0e10cSrcweir 
91cdf0e10cSrcweir typedef SwUndoSaveSection* SwUndoSaveSectionPtr;
92cdf0e10cSrcweir SV_DECL_PTRARR_DEL( SwUndoSaveSections, SwUndoSaveSectionPtr, 0, 10 )
93cdf0e10cSrcweir 
94cdf0e10cSrcweir typedef SwUndoMove* SwUndoMovePtr;
95cdf0e10cSrcweir SV_DECL_PTRARR_DEL( SwUndoMoves, SwUndoMovePtr, 0, 10 )
96cdf0e10cSrcweir 
97cdf0e10cSrcweir struct SwTblToTxtSave;
98cdf0e10cSrcweir typedef SwTblToTxtSave* SwTblToTxtSavePtr;
99cdf0e10cSrcweir SV_DECL_PTRARR_DEL( SwTblToTxtSaves, SwTblToTxtSavePtr, 0, 10 )
100cdf0e10cSrcweir 
101cdf0e10cSrcweir struct _UndoTblCpyTbl_Entry
102cdf0e10cSrcweir {
103cdf0e10cSrcweir 	sal_uLong nBoxIdx, nOffset;
104cdf0e10cSrcweir 	SfxItemSet* pBoxNumAttr;
105cdf0e10cSrcweir 	SwUndo* pUndo;
106cdf0e10cSrcweir 
107cdf0e10cSrcweir     // Was the last paragraph of the new and the first paragraph of the old content joined?
108cdf0e10cSrcweir     bool bJoin; // For redlining only
109cdf0e10cSrcweir 
110cdf0e10cSrcweir     _UndoTblCpyTbl_Entry( const SwTableBox& rBox );
111cdf0e10cSrcweir 	~_UndoTblCpyTbl_Entry();
112cdf0e10cSrcweir };
113cdf0e10cSrcweir typedef _UndoTblCpyTbl_Entry* _UndoTblCpyTbl_EntryPtr;
114cdf0e10cSrcweir SV_DECL_PTRARR_DEL( _UndoTblCpyTbl_Entries, _UndoTblCpyTbl_EntryPtr, 0, 10 )
115cdf0e10cSrcweir 
116cdf0e10cSrcweir class _SaveBox;
117cdf0e10cSrcweir class _SaveLine;
118cdf0e10cSrcweir 
119cdf0e10cSrcweir class _SaveTable
120cdf0e10cSrcweir {
121cdf0e10cSrcweir 	friend class _SaveBox;
122cdf0e10cSrcweir 	friend class _SaveLine;
123cdf0e10cSrcweir 	SfxItemSet aTblSet;
124cdf0e10cSrcweir 	_SaveLine* pLine;
125cdf0e10cSrcweir 	const SwTable* pSwTable;
126cdf0e10cSrcweir 	SfxItemSets aSets;
127cdf0e10cSrcweir 	SwFrmFmts aFrmFmts;
128cdf0e10cSrcweir 	sal_uInt16 nLineCount;
129cdf0e10cSrcweir 	sal_Bool bModifyBox : 1;
130cdf0e10cSrcweir 	sal_Bool bSaveFormula : 1;
131cdf0e10cSrcweir     sal_Bool bNewModel : 1;
132cdf0e10cSrcweir 
133cdf0e10cSrcweir public:
134cdf0e10cSrcweir 	_SaveTable( const SwTable& rTbl, sal_uInt16 nLnCnt = USHRT_MAX,
135cdf0e10cSrcweir 				sal_Bool bSaveFml = sal_True );
136cdf0e10cSrcweir 	~_SaveTable();
137cdf0e10cSrcweir 
138cdf0e10cSrcweir 	sal_uInt16 AddFmt( SwFrmFmt* pFmt, bool bIsLine );
139cdf0e10cSrcweir 	void NewFrmFmt( const SwTableLine* , const SwTableBox*, sal_uInt16 nFmtPos,
140cdf0e10cSrcweir 					SwFrmFmt* pOldFmt );
141cdf0e10cSrcweir 
142cdf0e10cSrcweir 	void RestoreAttr( SwTable& rTbl, sal_Bool bModifyBox = sal_False );
143cdf0e10cSrcweir 	void SaveCntntAttrs( SwDoc* pDoc );
144cdf0e10cSrcweir 	void CreateNew( SwTable& rTbl, sal_Bool bCreateFrms = sal_True,
145cdf0e10cSrcweir 					sal_Bool bRestoreChart = sal_True );
IsNewModel() const146cdf0e10cSrcweir     sal_Bool IsNewModel() const { return bNewModel; }
147cdf0e10cSrcweir };
148cdf0e10cSrcweir 
149cdf0e10cSrcweir class _SaveLine
150cdf0e10cSrcweir {
151cdf0e10cSrcweir 	friend class _SaveTable;
152cdf0e10cSrcweir 	friend class _SaveBox;
153cdf0e10cSrcweir 
154cdf0e10cSrcweir 	_SaveLine* pNext;
155cdf0e10cSrcweir 	_SaveBox* pBox;
156cdf0e10cSrcweir 	sal_uInt16 nItemSet;
157cdf0e10cSrcweir 
158cdf0e10cSrcweir public:
159cdf0e10cSrcweir 
160cdf0e10cSrcweir 	_SaveLine( _SaveLine* pPrev, const SwTableLine& rLine, _SaveTable& rSTbl );
161cdf0e10cSrcweir 	~_SaveLine();
162cdf0e10cSrcweir 
163cdf0e10cSrcweir 	void RestoreAttr( SwTableLine& rLine, _SaveTable& rSTbl );
164cdf0e10cSrcweir 	void SaveCntntAttrs( SwDoc* pDoc );
165cdf0e10cSrcweir 
166cdf0e10cSrcweir 	void CreateNew( SwTable& rTbl, SwTableBox& rParent, _SaveTable& rSTbl  );
167cdf0e10cSrcweir };
168cdf0e10cSrcweir 
169cdf0e10cSrcweir class _SaveBox
170cdf0e10cSrcweir {
171cdf0e10cSrcweir 	friend class _SaveLine;
172cdf0e10cSrcweir 
173cdf0e10cSrcweir 	_SaveBox* pNext;
174cdf0e10cSrcweir 	sal_uLong nSttNode;
175cdf0e10cSrcweir     long nRowSpan;
176cdf0e10cSrcweir 	sal_uInt16 nItemSet;
177cdf0e10cSrcweir 	union
178cdf0e10cSrcweir 	{
179cdf0e10cSrcweir 		SfxItemSets* pCntntAttrs;
180cdf0e10cSrcweir 		_SaveLine* pLine;
181cdf0e10cSrcweir 	} Ptrs;
182cdf0e10cSrcweir 
183cdf0e10cSrcweir public:
184cdf0e10cSrcweir 	_SaveBox( _SaveBox* pPrev, const SwTableBox& rBox, _SaveTable& rSTbl );
185cdf0e10cSrcweir 	~_SaveBox();
186cdf0e10cSrcweir 
187cdf0e10cSrcweir 	void RestoreAttr( SwTableBox& rBox, _SaveTable& rSTbl );
188cdf0e10cSrcweir 	void SaveCntntAttrs( SwDoc* pDoc );
189cdf0e10cSrcweir 
190cdf0e10cSrcweir 	void CreateNew( SwTable& rTbl, SwTableLine& rParent, _SaveTable& rSTbl );
191cdf0e10cSrcweir };
192cdf0e10cSrcweir 
193cdf0e10cSrcweir void InsertSort( SvUShorts& rArr, sal_uInt16 nIdx, sal_uInt16* pInsPos = 0 );
194cdf0e10cSrcweir void InsertSort( SvULongs& rArr, sal_uLong nIdx, sal_uInt16* pInsPos = 0 );
195cdf0e10cSrcweir 
196cdf0e10cSrcweir #if defined( JP_DEBUG ) && defined(DBG_UTIL)
197cdf0e10cSrcweir #include "shellio.hxx"
198cdf0e10cSrcweir void DumpDoc( SwDoc* pDoc, const String& rFileNm );
199cdf0e10cSrcweir void CheckTable( const SwTable& );
200cdf0e10cSrcweir #define DUMPDOC(p,s)	DumpDoc( p, s);
201cdf0e10cSrcweir #define CHECKTABLE(t) CheckTable( t );
202cdf0e10cSrcweir #else
203cdf0e10cSrcweir #define DUMPDOC(p,s)
204cdf0e10cSrcweir #define CHECKTABLE(t)
205cdf0e10cSrcweir #endif
206cdf0e10cSrcweir 
207cdf0e10cSrcweir /* #130880: Crash in undo of table to text when the table has (freshly) merged cells
208cdf0e10cSrcweir The order of cell content nodes in the nodes array is not given by the recursive table structure.
209cdf0e10cSrcweir The algorithmn must not rely on this even it holds for a fresh loaded table in odt file format.
210cdf0e10cSrcweir So we need to remember not only the start node position but the end node position as well.
211cdf0e10cSrcweir */
212cdf0e10cSrcweir 
213cdf0e10cSrcweir struct SwTblToTxtSave
214cdf0e10cSrcweir {
215cdf0e10cSrcweir     sal_uLong m_nSttNd;
216cdf0e10cSrcweir     sal_uLong m_nEndNd;
217cdf0e10cSrcweir     xub_StrLen m_nCntnt;
218cdf0e10cSrcweir     SwHistory* m_pHstry;
219cdf0e10cSrcweir     // metadata references for first and last paragraph in cell
220cdf0e10cSrcweir     ::boost::shared_ptr< ::sfx2::MetadatableUndo > m_pMetadataUndoStart;
221cdf0e10cSrcweir     ::boost::shared_ptr< ::sfx2::MetadatableUndo > m_pMetadataUndoEnd;
222cdf0e10cSrcweir 
223cdf0e10cSrcweir     SwTblToTxtSave( SwDoc& rDoc, sal_uLong nNd, sal_uLong nEndIdx, xub_StrLen nCntnt );
~SwTblToTxtSaveSwTblToTxtSave224cdf0e10cSrcweir     ~SwTblToTxtSave() { delete m_pHstry; }
225cdf0e10cSrcweir };
226cdf0e10cSrcweir 
227cdf0e10cSrcweir SV_IMPL_PTRARR( SfxItemSets, SfxItemSetPtr )
228cdf0e10cSrcweir SV_IMPL_PTRARR( SwUndoSaveSections, SwUndoSaveSectionPtr )
229cdf0e10cSrcweir SV_IMPL_PTRARR( SwUndoMoves, SwUndoMovePtr )
230cdf0e10cSrcweir SV_IMPL_PTRARR( SwTblToTxtSaves, SwTblToTxtSavePtr )
231cdf0e10cSrcweir SV_IMPL_PTRARR( _UndoTblCpyTbl_Entries, _UndoTblCpyTbl_EntryPtr )
232cdf0e10cSrcweir 
233cdf0e10cSrcweir sal_uInt16 __FAR_DATA aSave_BoxCntntSet[] = {
234cdf0e10cSrcweir 	RES_CHRATR_COLOR, RES_CHRATR_CROSSEDOUT,
235cdf0e10cSrcweir 	RES_CHRATR_FONT, RES_CHRATR_FONTSIZE,
236cdf0e10cSrcweir 	RES_CHRATR_POSTURE,	RES_CHRATR_POSTURE,
237cdf0e10cSrcweir 	RES_CHRATR_SHADOWED, RES_CHRATR_WEIGHT,
238cdf0e10cSrcweir 	RES_PARATR_ADJUST, RES_PARATR_ADJUST,
239cdf0e10cSrcweir 	0 };
240cdf0e10cSrcweir 
241cdf0e10cSrcweir 
242cdf0e10cSrcweir 
SwUndoInsTbl(const SwPosition & rPos,sal_uInt16 nCl,sal_uInt16 nRw,sal_uInt16 nAdj,const SwInsertTableOptions & rInsTblOpts,const SwTableAutoFmt * pTAFmt,const SvUShorts * pColArr,const String & rName)243cdf0e10cSrcweir SwUndoInsTbl::SwUndoInsTbl( const SwPosition& rPos, sal_uInt16 nCl, sal_uInt16 nRw,
244cdf0e10cSrcweir                             sal_uInt16 nAdj, const SwInsertTableOptions& rInsTblOpts,
245cdf0e10cSrcweir 							const SwTableAutoFmt* pTAFmt,
246cdf0e10cSrcweir 							const SvUShorts* pColArr,
247cdf0e10cSrcweir                             const String & rName)
248cdf0e10cSrcweir 	: SwUndo( UNDO_INSTABLE ),
249cdf0e10cSrcweir     aInsTblOpts( rInsTblOpts ), pDDEFldType( 0 ), pColWidth( 0 ), pRedlData( 0 ), pAutoFmt( 0 ),
250cdf0e10cSrcweir 	nSttNode( rPos.nNode.GetIndex() ), nRows( nRw ), nCols( nCl ), nAdjust( nAdj )
251cdf0e10cSrcweir {
252cdf0e10cSrcweir 	if( pColArr )
253cdf0e10cSrcweir 	{
254cdf0e10cSrcweir 		pColWidth = new SvUShorts( 0, 1 );
255cdf0e10cSrcweir 		pColWidth->Insert( pColArr, 0 );
256cdf0e10cSrcweir 	}
257cdf0e10cSrcweir 	if( pTAFmt )
258cdf0e10cSrcweir 		pAutoFmt = new SwTableAutoFmt( *pTAFmt );
259cdf0e10cSrcweir 
260cdf0e10cSrcweir 	// Redline beachten
261cdf0e10cSrcweir 	SwDoc& rDoc = *rPos.nNode.GetNode().GetDoc();
262cdf0e10cSrcweir 	if( rDoc.IsRedlineOn() )
263cdf0e10cSrcweir 	{
264cdf0e10cSrcweir 		pRedlData = new SwRedlineData( nsRedlineType_t::REDLINE_INSERT, rDoc.GetRedlineAuthor() );
265cdf0e10cSrcweir 		SetRedlineMode( rDoc.GetRedlineMode() );
266cdf0e10cSrcweir 	}
267cdf0e10cSrcweir 
268cdf0e10cSrcweir 	sTblNm = rName;
269cdf0e10cSrcweir }
270cdf0e10cSrcweir 
271cdf0e10cSrcweir 
~SwUndoInsTbl()272cdf0e10cSrcweir SwUndoInsTbl::~SwUndoInsTbl()
273cdf0e10cSrcweir {
274cdf0e10cSrcweir 	delete pDDEFldType;
275cdf0e10cSrcweir 	delete pColWidth;
276cdf0e10cSrcweir 	delete pRedlData;
277cdf0e10cSrcweir 	delete pAutoFmt;
278cdf0e10cSrcweir }
279cdf0e10cSrcweir 
UndoImpl(::sw::UndoRedoContext & rContext)280cdf0e10cSrcweir void SwUndoInsTbl::UndoImpl(::sw::UndoRedoContext & rContext)
281cdf0e10cSrcweir {
282cdf0e10cSrcweir     SwDoc & rDoc = rContext.GetDoc();
283cdf0e10cSrcweir 	SwNodeIndex aIdx( rDoc.GetNodes(), nSttNode );
284cdf0e10cSrcweir 
285cdf0e10cSrcweir 	SwTableNode* pTblNd = aIdx.GetNode().GetTableNode();
286cdf0e10cSrcweir 	ASSERT( pTblNd, "kein TabellenNode" );
287cdf0e10cSrcweir 	pTblNd->DelFrms();
288cdf0e10cSrcweir 
289cdf0e10cSrcweir 	if( IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ))
290cdf0e10cSrcweir 		rDoc.DeleteRedline( *pTblNd, true, USHRT_MAX );
291cdf0e10cSrcweir 	RemoveIdxFromSection( rDoc, nSttNode );
292cdf0e10cSrcweir 
293cdf0e10cSrcweir 	// harte SeitenUmbrueche am nachfolgenden Node verschieben
294cdf0e10cSrcweir 	SwCntntNode* pNextNd = rDoc.GetNodes()[ pTblNd->EndOfSectionIndex()+1 ]->GetCntntNode();
295cdf0e10cSrcweir 	if( pNextNd )
296cdf0e10cSrcweir 	{
297cdf0e10cSrcweir 		SwFrmFmt* pTableFmt = pTblNd->GetTable().GetFrmFmt();
298cdf0e10cSrcweir 		const SfxPoolItem *pItem;
299cdf0e10cSrcweir 
300cdf0e10cSrcweir 		if( SFX_ITEM_SET == pTableFmt->GetItemState( RES_PAGEDESC,
301cdf0e10cSrcweir 			sal_False, &pItem ) )
302cdf0e10cSrcweir 			pNextNd->SetAttr( *pItem );
303cdf0e10cSrcweir 
304cdf0e10cSrcweir 		if( SFX_ITEM_SET == pTableFmt->GetItemState( RES_BREAK,
305cdf0e10cSrcweir 			sal_False, &pItem ) )
306cdf0e10cSrcweir 			pNextNd->SetAttr( *pItem );
307cdf0e10cSrcweir 	}
308cdf0e10cSrcweir 
309cdf0e10cSrcweir 
310cdf0e10cSrcweir 	sTblNm = pTblNd->GetTable().GetFrmFmt()->GetName();
311cdf0e10cSrcweir 	if( pTblNd->GetTable().IsA( TYPE( SwDDETable )) )
312cdf0e10cSrcweir 		pDDEFldType = (SwDDEFieldType*)((SwDDETable&)pTblNd->GetTable()).
313cdf0e10cSrcweir 										GetDDEFldType()->Copy();
314cdf0e10cSrcweir 
315cdf0e10cSrcweir 	rDoc.GetNodes().Delete( aIdx, pTblNd->EndOfSectionIndex() -
316cdf0e10cSrcweir 								aIdx.GetIndex() + 1 );
317cdf0e10cSrcweir 
318cdf0e10cSrcweir     SwPaM & rPam( rContext.GetCursorSupplier().CreateNewShellCursor() );
319cdf0e10cSrcweir     rPam.DeleteMark();
320cdf0e10cSrcweir     rPam.GetPoint()->nNode = aIdx;
321cdf0e10cSrcweir     rPam.GetPoint()->nContent.Assign( rPam.GetCntntNode(), 0 );
322cdf0e10cSrcweir }
323cdf0e10cSrcweir 
324cdf0e10cSrcweir 
RedoImpl(::sw::UndoRedoContext & rContext)325cdf0e10cSrcweir void SwUndoInsTbl::RedoImpl(::sw::UndoRedoContext & rContext)
326cdf0e10cSrcweir {
327cdf0e10cSrcweir     SwDoc & rDoc = rContext.GetDoc();
328cdf0e10cSrcweir 
329cdf0e10cSrcweir     SwPosition const aPos(SwNodeIndex(rDoc.GetNodes(), nSttNode));
330cdf0e10cSrcweir     const SwTable* pTbl = rDoc.InsertTable( aInsTblOpts, aPos, nRows, nCols,
331cdf0e10cSrcweir                                             nAdjust,
332cdf0e10cSrcweir                                             pAutoFmt, pColWidth );
333cdf0e10cSrcweir 	((SwFrmFmt*)pTbl->GetFrmFmt())->SetName( sTblNm );
334cdf0e10cSrcweir 	SwTableNode* pTblNode = (SwTableNode*)rDoc.GetNodes()[nSttNode]->GetTableNode();
335cdf0e10cSrcweir 
336cdf0e10cSrcweir 	if( pDDEFldType )
337cdf0e10cSrcweir 	{
338cdf0e10cSrcweir 		SwDDEFieldType* pNewType = (SwDDEFieldType*)rDoc.InsertFldType(
339cdf0e10cSrcweir 															*pDDEFldType);
340cdf0e10cSrcweir 		SwDDETable* pDDETbl = new SwDDETable( pTblNode->GetTable(), pNewType );
341cdf0e10cSrcweir 		pTblNode->SetNewTable( pDDETbl );		// setze die DDE-Tabelle
342cdf0e10cSrcweir 		delete pDDEFldType, pDDEFldType = 0;
343cdf0e10cSrcweir 	}
344cdf0e10cSrcweir 
345cdf0e10cSrcweir 	if( (pRedlData && IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() )) ||
346cdf0e10cSrcweir 		( !( nsRedlineMode_t::REDLINE_IGNORE & GetRedlineMode() ) &&
347cdf0e10cSrcweir 			rDoc.GetRedlineTbl().Count() ))
348cdf0e10cSrcweir 	{
349cdf0e10cSrcweir 		SwPaM aPam( *pTblNode->EndOfSectionNode(), *pTblNode, 1 );
350cdf0e10cSrcweir 		SwCntntNode* pCNd = aPam.GetCntntNode( sal_False );
351cdf0e10cSrcweir 		if( pCNd )
352cdf0e10cSrcweir 			aPam.GetMark()->nContent.Assign( pCNd, 0 );
353cdf0e10cSrcweir 
354cdf0e10cSrcweir 		if( pRedlData && IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ) )
355cdf0e10cSrcweir 		{
356cdf0e10cSrcweir 			RedlineMode_t eOld = rDoc.GetRedlineMode();
357cdf0e10cSrcweir 			rDoc.SetRedlineMode_intern((RedlineMode_t)(eOld & ~nsRedlineMode_t::REDLINE_IGNORE));
358cdf0e10cSrcweir 
359cdf0e10cSrcweir 			rDoc.AppendRedline( new SwRedline( *pRedlData, aPam ), true);
360cdf0e10cSrcweir 			rDoc.SetRedlineMode_intern( eOld );
361cdf0e10cSrcweir 		}
362cdf0e10cSrcweir 		else
363cdf0e10cSrcweir 			rDoc.SplitRedline( aPam );
364cdf0e10cSrcweir 	}
365cdf0e10cSrcweir }
366cdf0e10cSrcweir 
367cdf0e10cSrcweir 
RepeatImpl(::sw::RepeatContext & rContext)368cdf0e10cSrcweir void SwUndoInsTbl::RepeatImpl(::sw::RepeatContext & rContext)
369cdf0e10cSrcweir {
370cdf0e10cSrcweir     rContext.GetDoc().InsertTable(
371cdf0e10cSrcweir             aInsTblOpts, *rContext.GetRepeatPaM().GetPoint(),
372cdf0e10cSrcweir             nRows, nCols, nAdjust, pAutoFmt, pColWidth );
373cdf0e10cSrcweir }
374cdf0e10cSrcweir 
GetRewriter() const375cdf0e10cSrcweir SwRewriter SwUndoInsTbl::GetRewriter() const
376cdf0e10cSrcweir {
377cdf0e10cSrcweir     SwRewriter aRewriter;
378cdf0e10cSrcweir 
379cdf0e10cSrcweir     aRewriter.AddRule(UNDO_ARG1, SW_RES(STR_START_QUOTE));
380cdf0e10cSrcweir     aRewriter.AddRule(UNDO_ARG2, sTblNm);
381cdf0e10cSrcweir     aRewriter.AddRule(UNDO_ARG3, SW_RES(STR_END_QUOTE));
382cdf0e10cSrcweir 
383cdf0e10cSrcweir     return aRewriter;
384cdf0e10cSrcweir }
385cdf0e10cSrcweir 
386cdf0e10cSrcweir // -----------------------------------------------------
387cdf0e10cSrcweir 
SwTblToTxtSave(SwDoc & rDoc,sal_uLong nNd,sal_uLong nEndIdx,xub_StrLen nCnt)388cdf0e10cSrcweir SwTblToTxtSave::SwTblToTxtSave( SwDoc& rDoc, sal_uLong nNd, sal_uLong nEndIdx, xub_StrLen nCnt )
389cdf0e10cSrcweir     : m_nSttNd( nNd ), m_nEndNd( nEndIdx), m_nCntnt( nCnt ), m_pHstry( 0 )
390cdf0e10cSrcweir {
391cdf0e10cSrcweir 	// Attributierung des gejointen Node merken.
392cdf0e10cSrcweir 	SwTxtNode* pNd = rDoc.GetNodes()[ nNd ]->GetTxtNode();
393cdf0e10cSrcweir 	if( pNd )
394cdf0e10cSrcweir 	{
395cdf0e10cSrcweir 		m_pHstry = new SwHistory;
396cdf0e10cSrcweir 
397cdf0e10cSrcweir 		m_pHstry->Add( pNd->GetTxtColl(), nNd, ND_TEXTNODE );
398cdf0e10cSrcweir         if ( pNd->GetpSwpHints() )
399cdf0e10cSrcweir         {
400cdf0e10cSrcweir             m_pHstry->CopyAttr( pNd->GetpSwpHints(), nNd, 0,
401cdf0e10cSrcweir                         pNd->GetTxt().Len(), false );
402cdf0e10cSrcweir         }
403cdf0e10cSrcweir         if( pNd->HasSwAttrSet() )
404cdf0e10cSrcweir             m_pHstry->CopyFmtAttr( *pNd->GetpSwAttrSet(), nNd );
405cdf0e10cSrcweir 
406cdf0e10cSrcweir 		if( !m_pHstry->Count() )
407cdf0e10cSrcweir 			delete m_pHstry, m_pHstry = 0;
408cdf0e10cSrcweir 
409cdf0e10cSrcweir         // METADATA: store
410cdf0e10cSrcweir         m_pMetadataUndoStart = pNd->CreateUndo();
411cdf0e10cSrcweir     }
412cdf0e10cSrcweir 
413cdf0e10cSrcweir     // we also need to store the metadata reference of the _last_ paragraph
414cdf0e10cSrcweir     // we subtract 1 to account for the removed cell start/end node pair
415cdf0e10cSrcweir     // (after SectionUp, the end of the range points to the node after the cell)
416cdf0e10cSrcweir     if ( nEndIdx - 1 > nNd )
417cdf0e10cSrcweir     {
418cdf0e10cSrcweir         SwTxtNode* pLastNode( rDoc.GetNodes()[ nEndIdx - 1 ]->GetTxtNode() );
419cdf0e10cSrcweir         if( pLastNode )
420cdf0e10cSrcweir         {
421cdf0e10cSrcweir             // METADATA: store
422cdf0e10cSrcweir             m_pMetadataUndoEnd = pLastNode->CreateUndo();
423cdf0e10cSrcweir         }
424cdf0e10cSrcweir     }
425cdf0e10cSrcweir }
426cdf0e10cSrcweir 
SwUndoTblToTxt(const SwTable & rTbl,sal_Unicode cCh)427cdf0e10cSrcweir SwUndoTblToTxt::SwUndoTblToTxt( const SwTable& rTbl, sal_Unicode cCh )
428cdf0e10cSrcweir     : SwUndo( UNDO_TABLETOTEXT ),
429cdf0e10cSrcweir     sTblNm( rTbl.GetFrmFmt()->GetName() ), pDDEFldType( 0 ), pHistory( 0 ),
430cdf0e10cSrcweir 	nSttNd( 0 ), nEndNd( 0 ),
431cdf0e10cSrcweir     nAdjust( static_cast<sal_uInt16>(rTbl.GetFrmFmt()->GetHoriOrient().GetHoriOrient()) ),
432cdf0e10cSrcweir 	cTrenner( cCh ), nHdlnRpt( rTbl.GetRowsToRepeat() )
433cdf0e10cSrcweir {
434cdf0e10cSrcweir 	pTblSave = new _SaveTable( rTbl );
435cdf0e10cSrcweir 	pBoxSaves = new SwTblToTxtSaves( (sal_uInt8)rTbl.GetTabSortBoxes().Count() );
436cdf0e10cSrcweir 
437cdf0e10cSrcweir 	if( rTbl.IsA( TYPE( SwDDETable ) ) )
438cdf0e10cSrcweir 		pDDEFldType = (SwDDEFieldType*)((SwDDETable&)rTbl).GetDDEFldType()->Copy();
439cdf0e10cSrcweir 
440cdf0e10cSrcweir 	bCheckNumFmt = rTbl.GetFrmFmt()->GetDoc()->IsInsTblFormatNum();
441cdf0e10cSrcweir 
442cdf0e10cSrcweir 	pHistory = new SwHistory;
443cdf0e10cSrcweir 	const SwTableNode* pTblNd = rTbl.GetTableNode();
444cdf0e10cSrcweir 	sal_uLong nTblStt = pTblNd->GetIndex(), nTblEnd = pTblNd->EndOfSectionIndex();
445cdf0e10cSrcweir 
446cdf0e10cSrcweir 	const SwSpzFrmFmts& rFrmFmtTbl = *pTblNd->GetDoc()->GetSpzFrmFmts();
447cdf0e10cSrcweir 	for( sal_uInt16 n = 0; n < rFrmFmtTbl.Count(); ++n )
448cdf0e10cSrcweir 	{
449cdf0e10cSrcweir         SwFrmFmt* pFmt = rFrmFmtTbl[ n ];
450cdf0e10cSrcweir         SwFmtAnchor const*const pAnchor = &pFmt->GetAnchor();
451cdf0e10cSrcweir         SwPosition const*const pAPos = pAnchor->GetCntntAnchor();
452cdf0e10cSrcweir         if (pAPos &&
453cdf0e10cSrcweir             ((FLY_AT_CHAR == pAnchor->GetAnchorId()) ||
454cdf0e10cSrcweir              (FLY_AT_PARA == pAnchor->GetAnchorId())) &&
455cdf0e10cSrcweir 			nTblStt <= pAPos->nNode.GetIndex() &&
456cdf0e10cSrcweir 			pAPos->nNode.GetIndex() < nTblEnd )
457cdf0e10cSrcweir 		{
458cdf0e10cSrcweir 			pHistory->Add( *pFmt );
459cdf0e10cSrcweir 		}
460cdf0e10cSrcweir 	}
461cdf0e10cSrcweir 
462cdf0e10cSrcweir 	if( !pHistory->Count() )
463cdf0e10cSrcweir 		delete pHistory, pHistory = 0;
464cdf0e10cSrcweir }
465cdf0e10cSrcweir 
466cdf0e10cSrcweir 
~SwUndoTblToTxt()467cdf0e10cSrcweir SwUndoTblToTxt::~SwUndoTblToTxt()
468cdf0e10cSrcweir {
469cdf0e10cSrcweir 	delete pDDEFldType;
470cdf0e10cSrcweir 	delete pTblSave;
471cdf0e10cSrcweir 	delete pBoxSaves;
472cdf0e10cSrcweir 	delete pHistory;
473cdf0e10cSrcweir }
474cdf0e10cSrcweir 
475cdf0e10cSrcweir 
476cdf0e10cSrcweir 
UndoImpl(::sw::UndoRedoContext & rContext)477cdf0e10cSrcweir void SwUndoTblToTxt::UndoImpl(::sw::UndoRedoContext & rContext)
478cdf0e10cSrcweir {
479cdf0e10cSrcweir 	SwDoc & rDoc = rContext.GetDoc();
480cdf0e10cSrcweir     SwPaM *const pPam(& rContext.GetCursorSupplier().CreateNewShellCursor());
481cdf0e10cSrcweir 
482cdf0e10cSrcweir 	SwNodeIndex aFrmIdx( rDoc.GetNodes(), nSttNd );
483cdf0e10cSrcweir 	SwNodeIndex aEndIdx( rDoc.GetNodes(), nEndNd );
484cdf0e10cSrcweir 
485cdf0e10cSrcweir 	pPam->GetPoint()->nNode = aFrmIdx;
486cdf0e10cSrcweir 	pPam->SetMark();
487cdf0e10cSrcweir 	pPam->GetPoint()->nNode = aEndIdx;
488cdf0e10cSrcweir 	rDoc.DelNumRules( *pPam );
489cdf0e10cSrcweir 	pPam->DeleteMark();
490cdf0e10cSrcweir 
491cdf0e10cSrcweir 	// dann sammel mal alle Uppers ein
492cdf0e10cSrcweir 	SwNode2Layout aNode2Layout( aFrmIdx.GetNode() );
493cdf0e10cSrcweir 
494cdf0e10cSrcweir 	// erzeuge die TabelleNode Structur
495cdf0e10cSrcweir 	SwTableNode* pTblNd = rDoc.GetNodes().UndoTableToText( nSttNd, nEndNd, *pBoxSaves );
496cdf0e10cSrcweir     pTblNd->GetTable().SetTableModel( pTblSave->IsNewModel() );
497cdf0e10cSrcweir 	SwTableFmt* pTableFmt = rDoc.MakeTblFrmFmt( sTblNm, rDoc.GetDfltFrmFmt() );
498cdf0e10cSrcweir     pTblNd->GetTable().RegisterToFormat( *pTableFmt );
499cdf0e10cSrcweir     pTblNd->GetTable().SetRowsToRepeat( nHdlnRpt );
500cdf0e10cSrcweir 
501cdf0e10cSrcweir 	// erzeuge die alte Tabellen Struktur
502cdf0e10cSrcweir 	pTblSave->CreateNew( pTblNd->GetTable() );
503cdf0e10cSrcweir 
504cdf0e10cSrcweir 	if( pDDEFldType )
505cdf0e10cSrcweir 	{
506cdf0e10cSrcweir 		SwDDEFieldType* pNewType = (SwDDEFieldType*)rDoc.InsertFldType(
507cdf0e10cSrcweir 															*pDDEFldType);
508cdf0e10cSrcweir 		SwDDETable* pDDETbl = new SwDDETable( pTblNd->GetTable(), pNewType );
509cdf0e10cSrcweir 		pTblNd->SetNewTable( pDDETbl, sal_False );		// setze die DDE-Tabelle
510cdf0e10cSrcweir 		delete pDDEFldType, pDDEFldType = 0;
511cdf0e10cSrcweir 	}
512cdf0e10cSrcweir 
513cdf0e10cSrcweir 	if( bCheckNumFmt )
514cdf0e10cSrcweir 	{
515cdf0e10cSrcweir 		SwTableSortBoxes& rBxs = pTblNd->GetTable().GetTabSortBoxes();
516cdf0e10cSrcweir 		for( sal_uInt16 nBoxes = rBxs.Count(); nBoxes; )
517cdf0e10cSrcweir 			rDoc.ChkBoxNumFmt( *rBxs[ --nBoxes ], sal_False );
518cdf0e10cSrcweir 	}
519cdf0e10cSrcweir 
520cdf0e10cSrcweir 	if( pHistory )
521cdf0e10cSrcweir 	{
522cdf0e10cSrcweir 		sal_uInt16 nTmpEnd = pHistory->GetTmpEnd();
523cdf0e10cSrcweir 		pHistory->TmpRollback( &rDoc, 0 );
524cdf0e10cSrcweir 		pHistory->SetTmpEnd( nTmpEnd );
525cdf0e10cSrcweir 	}
526cdf0e10cSrcweir 
527cdf0e10cSrcweir 	aNode2Layout.RestoreUpperFrms( rDoc.GetNodes(),
528cdf0e10cSrcweir 								   pTblNd->GetIndex(), pTblNd->GetIndex()+1 );
529cdf0e10cSrcweir 
530cdf0e10cSrcweir 	// will man eine TabellenSelektion ??
531cdf0e10cSrcweir 	pPam->DeleteMark();
532cdf0e10cSrcweir 	pPam->GetPoint()->nNode = *pTblNd->EndOfSectionNode();
533cdf0e10cSrcweir 	pPam->SetMark();
534cdf0e10cSrcweir 	pPam->GetPoint()->nNode = *pPam->GetNode()->StartOfSectionNode();
535cdf0e10cSrcweir 	pPam->Move( fnMoveForward, fnGoCntnt );
536cdf0e10cSrcweir 	pPam->Exchange();
537cdf0e10cSrcweir 	pPam->Move( fnMoveBackward, fnGoCntnt );
538cdf0e10cSrcweir 
539cdf0e10cSrcweir 	ClearFEShellTabCols();
540cdf0e10cSrcweir }
541cdf0e10cSrcweir 
542cdf0e10cSrcweir 	// steht im untbl.cxx und darf nur vom Undoobject gerufen werden
UndoTableToText(sal_uLong nSttNd,sal_uLong nEndNd,const SwTblToTxtSaves & rSavedData)543cdf0e10cSrcweir SwTableNode* SwNodes::UndoTableToText( sal_uLong nSttNd, sal_uLong nEndNd,
544cdf0e10cSrcweir 								const SwTblToTxtSaves& rSavedData )
545cdf0e10cSrcweir {
546cdf0e10cSrcweir 	SwNodeIndex aSttIdx( *this, nSttNd );
547cdf0e10cSrcweir 	SwNodeIndex aEndIdx( *this, nEndNd+1 );
548cdf0e10cSrcweir 
549cdf0e10cSrcweir 	SwTableNode * pTblNd = new SwTableNode( aSttIdx );
550cdf0e10cSrcweir 	SwEndNode* pEndNd = new SwEndNode( aEndIdx, *pTblNd  );
551cdf0e10cSrcweir 
552cdf0e10cSrcweir 	aEndIdx = *pEndNd;
553cdf0e10cSrcweir 
554cdf0e10cSrcweir 	/* Set pTblNd as start of section for all nodes in [nSttNd, nEndNd].
555cdf0e10cSrcweir        Delete all Frames attached to the nodes in that range. */
556cdf0e10cSrcweir 	SwNode* pNd;
557cdf0e10cSrcweir 	{
558cdf0e10cSrcweir 		sal_uLong n, nTmpEnd = aEndIdx.GetIndex();
559cdf0e10cSrcweir 		for( n = pTblNd->GetIndex() + 1; n < nTmpEnd; ++n )
560cdf0e10cSrcweir         {
561cdf0e10cSrcweir 			if( ( pNd = (*this)[ n ] )->IsCntntNode() )
562cdf0e10cSrcweir 				((SwCntntNode*)pNd)->DelFrms();
563cdf0e10cSrcweir             pNd->pStartOfSection = pTblNd;
564cdf0e10cSrcweir         }
565cdf0e10cSrcweir 	}
566cdf0e10cSrcweir 
567cdf0e10cSrcweir 	// dann die Tabellen Struktur teilweise aufbauen. Erstmal eine Line
568cdf0e10cSrcweir 	// in der alle Boxen stehen! Die korrekte Struktur kommt dann aus der
569cdf0e10cSrcweir 	// SaveStruct
570cdf0e10cSrcweir 	SwTableBoxFmt* pBoxFmt = GetDoc()->MakeTableBoxFmt();
571cdf0e10cSrcweir 	SwTableLineFmt* pLineFmt = GetDoc()->MakeTableLineFmt();
572cdf0e10cSrcweir 	SwTableLine* pLine = new SwTableLine( pLineFmt, rSavedData.Count(), 0 );
573cdf0e10cSrcweir 	pTblNd->GetTable().GetTabLines().C40_INSERT( SwTableLine, pLine, 0 );
574cdf0e10cSrcweir 
575cdf0e10cSrcweir 	SvULongs aBkmkArr( 0, 4 );
576cdf0e10cSrcweir 	for( sal_uInt16 n = rSavedData.Count(); n; )
577cdf0e10cSrcweir 	{
578cdf0e10cSrcweir 		SwTblToTxtSave* pSave = rSavedData[ --n ];
579cdf0e10cSrcweir         // if the start node was merged with last from prev. cell,
580cdf0e10cSrcweir         // subtract 1 from index to get the merged paragraph, and split that
581cdf0e10cSrcweir 		aSttIdx = pSave->m_nSttNd - ( ( USHRT_MAX != pSave->m_nCntnt ) ? 1 : 0);
582cdf0e10cSrcweir 		SwTxtNode* pTxtNd = aSttIdx.GetNode().GetTxtNode();
583cdf0e10cSrcweir 
584cdf0e10cSrcweir 		if( USHRT_MAX != pSave->m_nCntnt )
585cdf0e10cSrcweir 		{
586cdf0e10cSrcweir 			// an der ContentPosition splitten, das vorherige Zeichen
587cdf0e10cSrcweir 			// loeschen (ist der Trenner!)
588cdf0e10cSrcweir 			ASSERT( pTxtNd, "Wo ist der TextNode geblieben?" );
589cdf0e10cSrcweir 			SwIndex aCntPos( pTxtNd, pSave->m_nCntnt - 1 );
590cdf0e10cSrcweir 
591cdf0e10cSrcweir             pTxtNd->EraseText( aCntPos, 1 );
592cdf0e10cSrcweir             SwCntntNode* pNewNd = pTxtNd->SplitCntntNode(
593cdf0e10cSrcweir 										SwPosition( aSttIdx, aCntPos ));
594cdf0e10cSrcweir 			if( aBkmkArr.Count() )
595cdf0e10cSrcweir 				_RestoreCntntIdx( aBkmkArr, *pNewNd, pSave->m_nCntnt,
596cdf0e10cSrcweir 													 pSave->m_nCntnt + 1 );
597cdf0e10cSrcweir 		}
598cdf0e10cSrcweir 		else
599cdf0e10cSrcweir 		{
600cdf0e10cSrcweir 			if( aBkmkArr.Count() )
601cdf0e10cSrcweir 				aBkmkArr.Remove( 0, aBkmkArr.Count() );
602cdf0e10cSrcweir 			if( pTxtNd )
603cdf0e10cSrcweir 				_SaveCntntIdx( GetDoc(), aSttIdx.GetIndex(),
604cdf0e10cSrcweir 								pTxtNd->GetTxt().Len(), aBkmkArr );
605cdf0e10cSrcweir 		}
606cdf0e10cSrcweir 
607cdf0e10cSrcweir 		if( pTxtNd )
608cdf0e10cSrcweir 		{
609cdf0e10cSrcweir             // METADATA: restore
610cdf0e10cSrcweir             pTxtNd->GetTxtNode()->RestoreMetadata(pSave->m_pMetadataUndoStart);
611cdf0e10cSrcweir             if( pTxtNd->HasSwAttrSet() )
612cdf0e10cSrcweir 				pTxtNd->ResetAllAttr();
613cdf0e10cSrcweir 
614cdf0e10cSrcweir 			if( pTxtNd->GetpSwpHints() )
615cdf0e10cSrcweir                 pTxtNd->ClearSwpHintsArr( false );
616cdf0e10cSrcweir 		}
617cdf0e10cSrcweir 
618cdf0e10cSrcweir         if( pSave->m_pHstry )
619cdf0e10cSrcweir         {
620cdf0e10cSrcweir             sal_uInt16 nTmpEnd = pSave->m_pHstry->GetTmpEnd();
621cdf0e10cSrcweir             pSave->m_pHstry->TmpRollback( GetDoc(), 0 );
622cdf0e10cSrcweir             pSave->m_pHstry->SetTmpEnd( nTmpEnd );
623cdf0e10cSrcweir         }
624cdf0e10cSrcweir 
625cdf0e10cSrcweir         // METADATA: restore
626cdf0e10cSrcweir         // end points to node after cell
627cdf0e10cSrcweir         if ( pSave->m_nEndNd - 1 > pSave->m_nSttNd )
628cdf0e10cSrcweir         {
629cdf0e10cSrcweir             SwTxtNode* pLastNode = (*this)[ pSave->m_nEndNd - 1 ]->GetTxtNode();
630cdf0e10cSrcweir             if (pLastNode)
631cdf0e10cSrcweir             {
632cdf0e10cSrcweir                 pLastNode->RestoreMetadata(pSave->m_pMetadataUndoEnd);
633cdf0e10cSrcweir             }
634cdf0e10cSrcweir         }
635cdf0e10cSrcweir 
636cdf0e10cSrcweir         aEndIdx = pSave->m_nEndNd;
637cdf0e10cSrcweir 		SwStartNode* pSttNd = new SwStartNode( aSttIdx, ND_STARTNODE,
638cdf0e10cSrcweir 												SwTableBoxStartNode );
639cdf0e10cSrcweir 		pSttNd->pStartOfSection = pTblNd;
640cdf0e10cSrcweir 		new SwEndNode( aEndIdx, *pSttNd );
641cdf0e10cSrcweir 
642cdf0e10cSrcweir 		for( sal_uLong i = aSttIdx.GetIndex(); i < aEndIdx.GetIndex()-1; ++i )
643cdf0e10cSrcweir 		{
644cdf0e10cSrcweir 			pNd = (*this)[ i ];
645cdf0e10cSrcweir 			pNd->pStartOfSection = pSttNd;
646cdf0e10cSrcweir 			if( pNd->IsStartNode() )
647cdf0e10cSrcweir 				i = pNd->EndOfSectionIndex();
648cdf0e10cSrcweir 		}
649cdf0e10cSrcweir 
650cdf0e10cSrcweir 		SwTableBox* pBox = new SwTableBox( pBoxFmt, *pSttNd, pLine );
651cdf0e10cSrcweir 		pLine->GetTabBoxes().C40_INSERT( SwTableBox, pBox, 0 );
652cdf0e10cSrcweir 	}
653cdf0e10cSrcweir 	return pTblNd;
654cdf0e10cSrcweir }
655cdf0e10cSrcweir 
656cdf0e10cSrcweir 
RedoImpl(::sw::UndoRedoContext & rContext)657cdf0e10cSrcweir void SwUndoTblToTxt::RedoImpl(::sw::UndoRedoContext & rContext)
658cdf0e10cSrcweir {
659cdf0e10cSrcweir     SwDoc & rDoc = rContext.GetDoc();
660cdf0e10cSrcweir     SwPaM *const pPam(& rContext.GetCursorSupplier().CreateNewShellCursor());
661cdf0e10cSrcweir 
662cdf0e10cSrcweir 	pPam->GetPoint()->nNode = nSttNd;
663cdf0e10cSrcweir 	pPam->GetPoint()->nContent.Assign( 0, 0 );
664cdf0e10cSrcweir 	SwNodeIndex aSaveIdx( pPam->GetPoint()->nNode, -1 );
665cdf0e10cSrcweir 
666cdf0e10cSrcweir 	pPam->SetMark();            // alle Indizies abmelden
667cdf0e10cSrcweir 	pPam->DeleteMark();
668cdf0e10cSrcweir 
669cdf0e10cSrcweir 	SwTableNode* pTblNd = pPam->GetNode()->GetTableNode();
670cdf0e10cSrcweir 	ASSERT( pTblNd, "keinen TableNode gefunden" );
671cdf0e10cSrcweir 
672cdf0e10cSrcweir 	if( pTblNd->GetTable().IsA( TYPE( SwDDETable )) )
673cdf0e10cSrcweir 		pDDEFldType = (SwDDEFieldType*)((SwDDETable&)pTblNd->GetTable()).
674cdf0e10cSrcweir 												GetDDEFldType()->Copy();
675cdf0e10cSrcweir 
676cdf0e10cSrcweir 	rDoc.TableToText( pTblNd, cTrenner );
677cdf0e10cSrcweir 
678cdf0e10cSrcweir 	aSaveIdx++;
679cdf0e10cSrcweir 	SwCntntNode* pCNd = aSaveIdx.GetNode().GetCntntNode();
680cdf0e10cSrcweir 	if( !pCNd && 0 == ( pCNd = rDoc.GetNodes().GoNext( &aSaveIdx ) ) &&
681cdf0e10cSrcweir 		0 == ( pCNd = rDoc.GetNodes().GoPrevious( &aSaveIdx )) )
682cdf0e10cSrcweir     {
683cdf0e10cSrcweir 		ASSERT( sal_False, "wo steht denn nun der TextNode" );
684cdf0e10cSrcweir     }
685cdf0e10cSrcweir 
686cdf0e10cSrcweir 	pPam->GetPoint()->nNode = aSaveIdx;
687cdf0e10cSrcweir 	pPam->GetPoint()->nContent.Assign( pCNd, 0 );
688cdf0e10cSrcweir 
689cdf0e10cSrcweir 	pPam->SetMark();            // alle Indizies abmelden
690cdf0e10cSrcweir 	pPam->DeleteMark();
691cdf0e10cSrcweir }
692cdf0e10cSrcweir 
693cdf0e10cSrcweir 
RepeatImpl(::sw::RepeatContext & rContext)694cdf0e10cSrcweir void SwUndoTblToTxt::RepeatImpl(::sw::RepeatContext & rContext)
695cdf0e10cSrcweir {
696cdf0e10cSrcweir     SwPaM *const pPam = & rContext.GetRepeatPaM();
697cdf0e10cSrcweir     SwTableNode *const pTblNd = pPam->GetNode()->FindTableNode();
698cdf0e10cSrcweir 	if( pTblNd )
699cdf0e10cSrcweir     {
700cdf0e10cSrcweir         // move cursor out of table
701cdf0e10cSrcweir 		pPam->GetPoint()->nNode = *pTblNd->EndOfSectionNode();
702cdf0e10cSrcweir 		pPam->Move( fnMoveForward, fnGoCntnt );
703cdf0e10cSrcweir 		pPam->SetMark();
704cdf0e10cSrcweir 		pPam->DeleteMark();
705cdf0e10cSrcweir 
706cdf0e10cSrcweir         rContext.GetDoc().TableToText( pTblNd, cTrenner );
707cdf0e10cSrcweir     }
708cdf0e10cSrcweir }
709cdf0e10cSrcweir 
SetRange(const SwNodeRange & rRg)710cdf0e10cSrcweir void SwUndoTblToTxt::SetRange( const SwNodeRange& rRg )
711cdf0e10cSrcweir {
712cdf0e10cSrcweir 	nSttNd = rRg.aStart.GetIndex();
713cdf0e10cSrcweir 	nEndNd = rRg.aEnd.GetIndex();
714cdf0e10cSrcweir }
715cdf0e10cSrcweir 
AddBoxPos(SwDoc & rDoc,sal_uLong nNdIdx,sal_uLong nEndIdx,xub_StrLen nCntntIdx)716cdf0e10cSrcweir void SwUndoTblToTxt::AddBoxPos( SwDoc& rDoc, sal_uLong nNdIdx, sal_uLong nEndIdx, xub_StrLen nCntntIdx )
717cdf0e10cSrcweir {
718cdf0e10cSrcweir 	SwTblToTxtSave* pNew = new SwTblToTxtSave( rDoc, nNdIdx, nEndIdx, nCntntIdx );
719cdf0e10cSrcweir 	pBoxSaves->Insert( pNew, pBoxSaves->Count() );
720cdf0e10cSrcweir }
721cdf0e10cSrcweir 
722cdf0e10cSrcweir // -----------------------------------------------------
723cdf0e10cSrcweir 
SwUndoTxtToTbl(const SwPaM & rRg,const SwInsertTableOptions & rInsTblOpts,sal_Unicode cCh,sal_uInt16 nAdj,const SwTableAutoFmt * pAFmt)724cdf0e10cSrcweir SwUndoTxtToTbl::SwUndoTxtToTbl( const SwPaM& rRg,
725cdf0e10cSrcweir                                 const SwInsertTableOptions& rInsTblOpts,
726cdf0e10cSrcweir                                 sal_Unicode cCh, sal_uInt16 nAdj,
727cdf0e10cSrcweir                                 const SwTableAutoFmt* pAFmt )
728cdf0e10cSrcweir     : SwUndo( UNDO_TEXTTOTABLE ), SwUndRng( rRg ), aInsTblOpts( rInsTblOpts ),
729cdf0e10cSrcweir       pDelBoxes( 0 ), pAutoFmt( 0 ),
730cdf0e10cSrcweir       pHistory( 0 ), cTrenner( cCh ), nAdjust( nAdj )
731cdf0e10cSrcweir {
732cdf0e10cSrcweir 	if( pAFmt )
733cdf0e10cSrcweir 		pAutoFmt = new SwTableAutoFmt( *pAFmt );
734cdf0e10cSrcweir 
735cdf0e10cSrcweir 	const SwPosition* pEnd = rRg.End();
736cdf0e10cSrcweir 	SwNodes& rNds = rRg.GetDoc()->GetNodes();
737cdf0e10cSrcweir 	bSplitEnd = pEnd->nContent.GetIndex() && ( pEnd->nContent.GetIndex()
738cdf0e10cSrcweir 						!= pEnd->nNode.GetNode().GetCntntNode()->Len() ||
739cdf0e10cSrcweir 				pEnd->nNode.GetIndex() >= rNds.GetEndOfContent().GetIndex()-1 );
740cdf0e10cSrcweir }
741cdf0e10cSrcweir 
~SwUndoTxtToTbl()742cdf0e10cSrcweir SwUndoTxtToTbl::~SwUndoTxtToTbl()
743cdf0e10cSrcweir {
744cdf0e10cSrcweir 	delete pDelBoxes;
745cdf0e10cSrcweir 	delete pAutoFmt;
746cdf0e10cSrcweir }
747cdf0e10cSrcweir 
UndoImpl(::sw::UndoRedoContext & rContext)748cdf0e10cSrcweir void SwUndoTxtToTbl::UndoImpl(::sw::UndoRedoContext & rContext)
749cdf0e10cSrcweir {
750cdf0e10cSrcweir     SwDoc & rDoc = rContext.GetDoc();
751cdf0e10cSrcweir 
752cdf0e10cSrcweir 	sal_uLong nTblNd = nSttNode;
753cdf0e10cSrcweir 	if( nSttCntnt )
754cdf0e10cSrcweir 		++nTblNd;		// Node wurde vorher gesplittet
755cdf0e10cSrcweir 	SwNodeIndex aIdx( rDoc.GetNodes(), nTblNd );
756cdf0e10cSrcweir     SwTableNode *const pTNd = aIdx.GetNode().GetTableNode();
757cdf0e10cSrcweir     OSL_ENSURE( pTNd, "SwUndoTxtToTbl: no TableNode" );
758cdf0e10cSrcweir 
759cdf0e10cSrcweir 	RemoveIdxFromSection( rDoc, nTblNd );
760cdf0e10cSrcweir 
761cdf0e10cSrcweir 	sTblNm = pTNd->GetTable().GetFrmFmt()->GetName();
762cdf0e10cSrcweir 
763cdf0e10cSrcweir 	if( pHistory )
764cdf0e10cSrcweir 	{
765cdf0e10cSrcweir 		pHistory->TmpRollback( &rDoc, 0 );
766cdf0e10cSrcweir 		pHistory->SetTmpEnd( pHistory->Count() );
767cdf0e10cSrcweir 	}
768cdf0e10cSrcweir 
769cdf0e10cSrcweir 	if( pDelBoxes )
770cdf0e10cSrcweir 	{
771cdf0e10cSrcweir 		SwTable& rTbl = pTNd->GetTable();
772cdf0e10cSrcweir 		for( sal_uInt16 n = pDelBoxes->Count(); n; )
773cdf0e10cSrcweir 		{
774cdf0e10cSrcweir 			SwTableBox* pBox = rTbl.GetTblBox( (*pDelBoxes)[ --n ] );
775cdf0e10cSrcweir 			if( pBox )
776cdf0e10cSrcweir 				::_DeleteBox( rTbl, pBox, 0, sal_False, sal_False );
777cdf0e10cSrcweir 			else {
778870262e3SDon Lewis 				ASSERT( sal_False, "Where was the box?" );
779cdf0e10cSrcweir             }
780cdf0e10cSrcweir 		}
781cdf0e10cSrcweir 	}
782cdf0e10cSrcweir 
783cdf0e10cSrcweir 	SwNodeIndex aEndIdx( *pTNd->EndOfSectionNode() );
784cdf0e10cSrcweir 	rDoc.TableToText( pTNd, 0x0b == cTrenner ? 0x09 : cTrenner );
785cdf0e10cSrcweir 
786cdf0e10cSrcweir     // join again at start?
787cdf0e10cSrcweir     SwPaM aPam(rDoc.GetNodes().GetEndOfContent());
788cdf0e10cSrcweir     SwPosition *const pPos = aPam.GetPoint();
789cdf0e10cSrcweir 	if( nSttCntnt )
790cdf0e10cSrcweir 	{
791cdf0e10cSrcweir 		pPos->nNode = nTblNd;
792cdf0e10cSrcweir         pPos->nContent.Assign(pPos->nNode.GetNode().GetCntntNode(), 0);
793cdf0e10cSrcweir         if (aPam.Move(fnMoveBackward, fnGoCntnt))
794cdf0e10cSrcweir         {
795cdf0e10cSrcweir             SwNodeIndex & rIdx = aPam.GetPoint()->nNode;
796cdf0e10cSrcweir 
797cdf0e10cSrcweir 			// dann die Crsr/etc. nochmal relativ verschieben
798cdf0e10cSrcweir 			RemoveIdxRel( rIdx.GetIndex()+1, *pPos );
799cdf0e10cSrcweir 
800cdf0e10cSrcweir 			rIdx.GetNode().GetCntntNode()->JoinNext();
801cdf0e10cSrcweir 		}
802cdf0e10cSrcweir 	}
803cdf0e10cSrcweir 
804cdf0e10cSrcweir     // join again at end?
805cdf0e10cSrcweir 	if( bSplitEnd )
806cdf0e10cSrcweir 	{
807cdf0e10cSrcweir 		SwNodeIndex& rIdx = pPos->nNode;
808cdf0e10cSrcweir 		rIdx = nEndNode;
809cdf0e10cSrcweir 		SwTxtNode* pTxtNd = rIdx.GetNode().GetTxtNode();
810cdf0e10cSrcweir 		if( pTxtNd && pTxtNd->CanJoinNext() )
811cdf0e10cSrcweir         {
812cdf0e10cSrcweir             aPam.GetMark()->nContent.Assign( 0, 0 );
813cdf0e10cSrcweir             aPam.GetPoint()->nContent.Assign( 0, 0 );
814cdf0e10cSrcweir 
815cdf0e10cSrcweir 			// dann die Crsr/etc. nochmal relativ verschieben
816cdf0e10cSrcweir 			pPos->nContent.Assign( pTxtNd, pTxtNd->GetTxt().Len() );
817cdf0e10cSrcweir 			RemoveIdxRel( nEndNode + 1, *pPos );
818cdf0e10cSrcweir 
819cdf0e10cSrcweir 			pTxtNd->JoinNext();
820cdf0e10cSrcweir 		}
821cdf0e10cSrcweir 	}
822cdf0e10cSrcweir 
823cdf0e10cSrcweir     AddUndoRedoPaM(rContext);
824cdf0e10cSrcweir }
825cdf0e10cSrcweir 
826cdf0e10cSrcweir 
RedoImpl(::sw::UndoRedoContext & rContext)827cdf0e10cSrcweir void SwUndoTxtToTbl::RedoImpl(::sw::UndoRedoContext & rContext)
828cdf0e10cSrcweir {
829cdf0e10cSrcweir     SwPaM & rPam( AddUndoRedoPaM(rContext) );
830cdf0e10cSrcweir     RemoveIdxFromRange(rPam, false);
831cdf0e10cSrcweir     SetPaM(rPam);
832cdf0e10cSrcweir 
833cdf0e10cSrcweir     SwTable const*const pTable = rContext.GetDoc().TextToTable(
834cdf0e10cSrcweir                 aInsTblOpts, rPam, cTrenner, nAdjust, pAutoFmt );
835cdf0e10cSrcweir 	((SwFrmFmt*)pTable->GetFrmFmt())->SetName( sTblNm );
836cdf0e10cSrcweir }
837cdf0e10cSrcweir 
838cdf0e10cSrcweir 
RepeatImpl(::sw::RepeatContext & rContext)839cdf0e10cSrcweir void SwUndoTxtToTbl::RepeatImpl(::sw::RepeatContext & rContext)
840cdf0e10cSrcweir {
841cdf0e10cSrcweir     // no Table In Table
842cdf0e10cSrcweir     if (!rContext.GetRepeatPaM().GetNode()->FindTableNode())
843cdf0e10cSrcweir     {
844cdf0e10cSrcweir         rContext.GetDoc().TextToTable( aInsTblOpts, rContext.GetRepeatPaM(),
845cdf0e10cSrcweir                                         cTrenner, nAdjust,
846cdf0e10cSrcweir                                         pAutoFmt );
847cdf0e10cSrcweir     }
848cdf0e10cSrcweir }
849cdf0e10cSrcweir 
AddFillBox(const SwTableBox & rBox)850cdf0e10cSrcweir void SwUndoTxtToTbl::AddFillBox( const SwTableBox& rBox )
851cdf0e10cSrcweir {
852cdf0e10cSrcweir 	if( !pDelBoxes )
853cdf0e10cSrcweir 		pDelBoxes = new SvULongs;
854cdf0e10cSrcweir 	pDelBoxes->Insert( rBox.GetSttIdx(), pDelBoxes->Count() );
855cdf0e10cSrcweir }
856cdf0e10cSrcweir 
GetHistory()857cdf0e10cSrcweir SwHistory& SwUndoTxtToTbl::GetHistory()
858cdf0e10cSrcweir {
859cdf0e10cSrcweir 	if( !pHistory )
860cdf0e10cSrcweir 		pHistory = new SwHistory;
861cdf0e10cSrcweir 	return *pHistory;
862cdf0e10cSrcweir }
863cdf0e10cSrcweir 
864cdf0e10cSrcweir // -----------------------------------------------------
865cdf0e10cSrcweir 
SwUndoTblHeadline(const SwTable & rTbl,sal_uInt16 nOldHdl,sal_uInt16 nNewHdl)866cdf0e10cSrcweir SwUndoTblHeadline::SwUndoTblHeadline( const SwTable& rTbl, sal_uInt16 nOldHdl,
867cdf0e10cSrcweir                                       sal_uInt16 nNewHdl )
868cdf0e10cSrcweir 	: SwUndo( UNDO_TABLEHEADLINE ),
869cdf0e10cSrcweir     nOldHeadline( nOldHdl ),
870cdf0e10cSrcweir     nNewHeadline( nNewHdl )
871cdf0e10cSrcweir {
872cdf0e10cSrcweir 	ASSERT( rTbl.GetTabSortBoxes().Count(), "Tabelle ohne Inhalt" );
873cdf0e10cSrcweir 	const SwStartNode *pSttNd = rTbl.GetTabSortBoxes()[ 0 ]->GetSttNd();
874cdf0e10cSrcweir 	ASSERT( pSttNd, "Box ohne Inhalt" );
875cdf0e10cSrcweir 
876cdf0e10cSrcweir 	nTblNd = pSttNd->StartOfSectionIndex();
877cdf0e10cSrcweir }
878cdf0e10cSrcweir 
UndoImpl(::sw::UndoRedoContext & rContext)879cdf0e10cSrcweir void SwUndoTblHeadline::UndoImpl(::sw::UndoRedoContext & rContext)
880cdf0e10cSrcweir {
881cdf0e10cSrcweir     SwDoc & rDoc = rContext.GetDoc();
882cdf0e10cSrcweir 	SwTableNode* pTNd = rDoc.GetNodes()[ nTblNd ]->GetTableNode();
883cdf0e10cSrcweir 	ASSERT( pTNd, "keinen Tabellen-Node gefunden" );
884cdf0e10cSrcweir 
885cdf0e10cSrcweir     rDoc.SetRowsToRepeat( pTNd->GetTable(), nOldHeadline );
886cdf0e10cSrcweir }
887cdf0e10cSrcweir 
RedoImpl(::sw::UndoRedoContext & rContext)888cdf0e10cSrcweir void SwUndoTblHeadline::RedoImpl(::sw::UndoRedoContext & rContext)
889cdf0e10cSrcweir {
890cdf0e10cSrcweir     SwDoc & rDoc = rContext.GetDoc();
891cdf0e10cSrcweir 
892cdf0e10cSrcweir 	SwTableNode* pTNd = rDoc.GetNodes()[ nTblNd ]->GetTableNode();
893cdf0e10cSrcweir 	ASSERT( pTNd, "keinen Tabellen-Node gefunden" );
894cdf0e10cSrcweir 
895cdf0e10cSrcweir     rDoc.SetRowsToRepeat( pTNd->GetTable(), nNewHeadline );
896cdf0e10cSrcweir }
897cdf0e10cSrcweir 
RepeatImpl(::sw::RepeatContext & rContext)898cdf0e10cSrcweir void SwUndoTblHeadline::RepeatImpl(::sw::RepeatContext & rContext)
899cdf0e10cSrcweir {
900cdf0e10cSrcweir     SwTableNode *const pTblNd =
901cdf0e10cSrcweir         rContext.GetRepeatPaM().GetNode()->FindTableNode();
902cdf0e10cSrcweir 	if( pTblNd )
903cdf0e10cSrcweir     {
904cdf0e10cSrcweir         rContext.GetDoc().SetRowsToRepeat( pTblNd->GetTable(), nNewHeadline );
905cdf0e10cSrcweir     }
906cdf0e10cSrcweir }
907cdf0e10cSrcweir 
908cdf0e10cSrcweir 
909cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////
910cdf0e10cSrcweir 
911cdf0e10cSrcweir 
_SaveTable(const SwTable & rTbl,sal_uInt16 nLnCnt,sal_Bool bSaveFml)912cdf0e10cSrcweir _SaveTable::_SaveTable( const SwTable& rTbl, sal_uInt16 nLnCnt, sal_Bool bSaveFml )
913cdf0e10cSrcweir 	: aTblSet( *rTbl.GetFrmFmt()->GetAttrSet().GetPool(), aTableSetRange ),
914cdf0e10cSrcweir 	pSwTable( &rTbl ), nLineCount( nLnCnt ), bSaveFormula( bSaveFml )
915cdf0e10cSrcweir {
916cdf0e10cSrcweir 	bModifyBox = sal_False;
917cdf0e10cSrcweir     bNewModel = rTbl.IsNewModel();
918cdf0e10cSrcweir 	aTblSet.Put( rTbl.GetFrmFmt()->GetAttrSet() );
919cdf0e10cSrcweir 	pLine = new _SaveLine( 0, *rTbl.GetTabLines()[ 0 ], *this );
920cdf0e10cSrcweir 
921cdf0e10cSrcweir 	_SaveLine* pLn = pLine;
922cdf0e10cSrcweir 	if( USHRT_MAX == nLnCnt )
923cdf0e10cSrcweir 		nLnCnt = rTbl.GetTabLines().Count();
924cdf0e10cSrcweir 	for( sal_uInt16 n = 1; n < nLnCnt; ++n )
925cdf0e10cSrcweir 		pLn = new _SaveLine( pLn, *rTbl.GetTabLines()[ n ], *this );
926cdf0e10cSrcweir 
927cdf0e10cSrcweir 	aFrmFmts.Remove( 0, aFrmFmts.Count() );
928cdf0e10cSrcweir 	pSwTable = 0;
929cdf0e10cSrcweir }
930cdf0e10cSrcweir 
931cdf0e10cSrcweir 
~_SaveTable()932cdf0e10cSrcweir _SaveTable::~_SaveTable()
933cdf0e10cSrcweir {
934cdf0e10cSrcweir 	delete pLine;
935cdf0e10cSrcweir }
936cdf0e10cSrcweir 
937cdf0e10cSrcweir 
AddFmt(SwFrmFmt * pFmt,bool bIsLine)938cdf0e10cSrcweir sal_uInt16 _SaveTable::AddFmt( SwFrmFmt* pFmt, bool bIsLine )
939cdf0e10cSrcweir {
940cdf0e10cSrcweir 	sal_uInt16 nRet = aFrmFmts.GetPos( pFmt );
941cdf0e10cSrcweir 	if( USHRT_MAX == nRet )
942cdf0e10cSrcweir 	{
943cdf0e10cSrcweir 		// Kopie vom ItemSet anlegen
944cdf0e10cSrcweir 		SfxItemSet* pSet = new SfxItemSet( *pFmt->GetAttrSet().GetPool(),
945cdf0e10cSrcweir             bIsLine ? aTableLineSetRange : aTableBoxSetRange );
946cdf0e10cSrcweir 		pSet->Put( pFmt->GetAttrSet() );
947cdf0e10cSrcweir 		//JP 20.04.98: Bug 49502 - wenn eine Formel gesetzt ist, nie den
948cdf0e10cSrcweir 		//				Value mit sichern. Der muss gegebenfalls neu
949cdf0e10cSrcweir 		//				errechnet werden!
950cdf0e10cSrcweir 		//JP 30.07.98: Bug 54295 - Formeln immer im Klartext speichern
951cdf0e10cSrcweir 		const SfxPoolItem* pItem;
952cdf0e10cSrcweir 		if( SFX_ITEM_SET == pSet->GetItemState( RES_BOXATR_FORMULA, sal_True, &pItem ))
953cdf0e10cSrcweir 		{
954cdf0e10cSrcweir 			pSet->ClearItem( RES_BOXATR_VALUE );
955cdf0e10cSrcweir 			if( pSwTable && bSaveFormula )
956cdf0e10cSrcweir 			{
957cdf0e10cSrcweir 				SwTableFmlUpdate aMsgHnt( pSwTable );
958cdf0e10cSrcweir 				aMsgHnt.eFlags = TBL_BOXNAME;
959cdf0e10cSrcweir 				((SwTblBoxFormula*)pItem)->ChgDefinedIn( pFmt );
960cdf0e10cSrcweir 				((SwTblBoxFormula*)pItem)->ChangeState( &aMsgHnt );
961cdf0e10cSrcweir 				((SwTblBoxFormula*)pItem)->ChgDefinedIn( 0 );
962cdf0e10cSrcweir 			}
963cdf0e10cSrcweir 		}
964cdf0e10cSrcweir 		aSets.Insert( pSet, (nRet = aSets.Count() ) );
965cdf0e10cSrcweir 		aFrmFmts.Insert( pFmt, nRet );
966cdf0e10cSrcweir 	}
967cdf0e10cSrcweir 	return nRet;
968cdf0e10cSrcweir }
969cdf0e10cSrcweir 
970cdf0e10cSrcweir 
RestoreAttr(SwTable & rTbl,sal_Bool bMdfyBox)971cdf0e10cSrcweir void _SaveTable::RestoreAttr( SwTable& rTbl, sal_Bool bMdfyBox )
972cdf0e10cSrcweir {
973cdf0e10cSrcweir 	sal_uInt16 n;
974cdf0e10cSrcweir 
975cdf0e10cSrcweir 	bModifyBox = bMdfyBox;
976cdf0e10cSrcweir 
977cdf0e10cSrcweir 	// zuerst die Attribute des TabellenFrmFormates zurueck holen
978cdf0e10cSrcweir 	SwFrmFmt* pFmt = rTbl.GetFrmFmt();
979cdf0e10cSrcweir 	SfxItemSet& rFmtSet  = (SfxItemSet&)pFmt->GetAttrSet();
980cdf0e10cSrcweir 	rFmtSet.ClearItem();
981cdf0e10cSrcweir 	rFmtSet.Put( aTblSet );
982cdf0e10cSrcweir 
983cdf0e10cSrcweir 	if( pFmt->IsInCache() )
984cdf0e10cSrcweir 	{
985cdf0e10cSrcweir 		SwFrm::GetCache().Delete( pFmt );
986cdf0e10cSrcweir 		pFmt->SetInCache( sal_False );
987cdf0e10cSrcweir 	}
988cdf0e10cSrcweir 
989cdf0e10cSrcweir 	// zur Sicherheit alle Tableframes invalidieren
990cdf0e10cSrcweir 	SwIterator<SwTabFrm,SwFmt> aIter( *pFmt );
991cdf0e10cSrcweir 	for( SwTabFrm* pLast = aIter.First(); pLast; pLast = aIter.Next() )
992cdf0e10cSrcweir 		if( pLast->GetTable() == &rTbl )
993cdf0e10cSrcweir 		{
994cdf0e10cSrcweir 			pLast->InvalidateAll();
995cdf0e10cSrcweir 			pLast->SetCompletePaint();
996cdf0e10cSrcweir 		}
997cdf0e10cSrcweir 
998cdf0e10cSrcweir 	// FrmFmts mit Defaults (0) fuellen
999cdf0e10cSrcweir 	pFmt = 0;
1000cdf0e10cSrcweir 	for( n = aSets.Count(); n; --n )
1001cdf0e10cSrcweir 		aFrmFmts.Insert( pFmt, aFrmFmts.Count() );
1002cdf0e10cSrcweir 
1003cdf0e10cSrcweir 	sal_uInt16 nLnCnt = nLineCount;
1004cdf0e10cSrcweir 	if( USHRT_MAX == nLnCnt )
1005cdf0e10cSrcweir 		nLnCnt = rTbl.GetTabLines().Count();
1006cdf0e10cSrcweir 
1007cdf0e10cSrcweir 	_SaveLine* pLn = pLine;
1008cdf0e10cSrcweir 	for( n = 0; n < nLnCnt; ++n, pLn = pLn->pNext )
1009cdf0e10cSrcweir 	{
1010cdf0e10cSrcweir 		if( !pLn )
1011cdf0e10cSrcweir 		{
1012870262e3SDon Lewis 			ASSERT( sal_False, "Number of Lines has changed" );
1013cdf0e10cSrcweir 			break;
1014cdf0e10cSrcweir 		}
1015cdf0e10cSrcweir 
1016cdf0e10cSrcweir 		pLn->RestoreAttr( *rTbl.GetTabLines()[ n ], *this );
1017cdf0e10cSrcweir 	}
1018cdf0e10cSrcweir 
1019cdf0e10cSrcweir 	aFrmFmts.Remove( 0, aFrmFmts.Count() );
1020cdf0e10cSrcweir 	bModifyBox = sal_False;
1021cdf0e10cSrcweir }
1022cdf0e10cSrcweir 
1023cdf0e10cSrcweir 
SaveCntntAttrs(SwDoc * pDoc)1024cdf0e10cSrcweir void _SaveTable::SaveCntntAttrs( SwDoc* pDoc )
1025cdf0e10cSrcweir {
1026cdf0e10cSrcweir 	pLine->SaveCntntAttrs( pDoc );
1027cdf0e10cSrcweir }
1028cdf0e10cSrcweir 
1029cdf0e10cSrcweir 
CreateNew(SwTable & rTbl,sal_Bool bCreateFrms,sal_Bool bRestoreChart)1030cdf0e10cSrcweir void _SaveTable::CreateNew( SwTable& rTbl, sal_Bool bCreateFrms,
1031cdf0e10cSrcweir 							sal_Bool bRestoreChart )
1032cdf0e10cSrcweir {
1033cdf0e10cSrcweir 	sal_uInt16 n;
1034cdf0e10cSrcweir 
1035cdf0e10cSrcweir 	_FndBox aTmpBox( 0, 0 );
1036cdf0e10cSrcweir 	//if( bRestoreChart )
1037cdf0e10cSrcweir     //    // ? TL_CHART2: notification or locking of controller required ?
1038cdf0e10cSrcweir 	aTmpBox.DelFrms( rTbl );
1039cdf0e10cSrcweir 
1040cdf0e10cSrcweir     // zuerst die Attribute des TabellenFrmFormates zurueck holen
1041cdf0e10cSrcweir 	SwFrmFmt* pFmt = rTbl.GetFrmFmt();
1042cdf0e10cSrcweir 	SfxItemSet& rFmtSet  = (SfxItemSet&)pFmt->GetAttrSet();
1043cdf0e10cSrcweir 	rFmtSet.ClearItem();
1044cdf0e10cSrcweir 	rFmtSet.Put( aTblSet );
1045cdf0e10cSrcweir 
1046cdf0e10cSrcweir 	if( pFmt->IsInCache() )
1047cdf0e10cSrcweir 	{
1048cdf0e10cSrcweir 		SwFrm::GetCache().Delete( pFmt );
1049cdf0e10cSrcweir 		pFmt->SetInCache( sal_False );
1050cdf0e10cSrcweir 	}
1051cdf0e10cSrcweir 
1052cdf0e10cSrcweir 	// SwTableBox muss ein Format haben!!
1053cdf0e10cSrcweir 	SwTableBox aParent( (SwTableBoxFmt*)pFmt, rTbl.GetTabLines().Count(), 0 );
1054cdf0e10cSrcweir 
1055cdf0e10cSrcweir 	// FrmFmts mit Defaults (0) fuellen
1056cdf0e10cSrcweir 	pFmt = 0;
1057cdf0e10cSrcweir 	for( n = aSets.Count(); n; --n )
1058cdf0e10cSrcweir 		aFrmFmts.Insert( pFmt, aFrmFmts.Count() );
1059cdf0e10cSrcweir 
1060cdf0e10cSrcweir 	pLine->CreateNew( rTbl, aParent, *this );
1061cdf0e10cSrcweir 	aFrmFmts.Remove( 0, aFrmFmts.Count() );
1062cdf0e10cSrcweir 
1063cdf0e10cSrcweir 	// die neuen Lines eintragen, die alten loeschen
1064cdf0e10cSrcweir 	sal_uInt16 nOldLines = nLineCount;
1065cdf0e10cSrcweir 	if( USHRT_MAX == nLineCount )
1066cdf0e10cSrcweir 		nOldLines = rTbl.GetTabLines().Count();
1067cdf0e10cSrcweir 
1068cdf0e10cSrcweir     SwDoc *pDoc = rTbl.GetFrmFmt()->GetDoc();
1069cdf0e10cSrcweir     SwChartDataProvider *pPCD = pDoc->GetChartDataProvider();
1070cdf0e10cSrcweir     for( n = 0; n < aParent.GetTabLines().Count(); ++n )
1071cdf0e10cSrcweir     {
1072cdf0e10cSrcweir         SwTableLine* pLn = aParent.GetTabLines()[ n ];
1073cdf0e10cSrcweir         pLn->SetUpper( 0 );
1074cdf0e10cSrcweir         if( n < nOldLines )
1075cdf0e10cSrcweir         {
1076cdf0e10cSrcweir             SwTableLine* pOld = rTbl.GetTabLines()[ n ];
1077cdf0e10cSrcweir 
1078cdf0e10cSrcweir             // TL_CHART2: notify chart about boxes to be removed
1079cdf0e10cSrcweir             const SwTableBoxes &rBoxes = pOld->GetTabBoxes();
1080cdf0e10cSrcweir             sal_uInt16 nBoxes = rBoxes.Count();
1081cdf0e10cSrcweir             for (sal_uInt16 k = 0;  k < nBoxes;  ++k)
1082cdf0e10cSrcweir             {
1083cdf0e10cSrcweir                 SwTableBox *pBox = rBoxes[k];
1084cdf0e10cSrcweir                 if (pPCD)
1085cdf0e10cSrcweir                     pPCD->DeleteBox( &rTbl, *pBox );
1086cdf0e10cSrcweir             }
1087cdf0e10cSrcweir 
1088cdf0e10cSrcweir             rTbl.GetTabLines().C40_REPLACE( SwTableLine, pLn, n );
1089cdf0e10cSrcweir             delete pOld;
1090cdf0e10cSrcweir         }
1091cdf0e10cSrcweir         else
1092cdf0e10cSrcweir             rTbl.GetTabLines().C40_INSERT( SwTableLine, pLn, n );
1093cdf0e10cSrcweir     }
1094cdf0e10cSrcweir 
1095cdf0e10cSrcweir     if( n < nOldLines )
1096cdf0e10cSrcweir     {
1097cdf0e10cSrcweir         // remove remaining lines...
1098cdf0e10cSrcweir 
1099cdf0e10cSrcweir         for (sal_uInt16 k1 = 0; k1 < nOldLines - n;  ++k1)
1100cdf0e10cSrcweir         {
1101cdf0e10cSrcweir             const SwTableBoxes &rBoxes = rTbl.GetTabLines()[n + k1]->GetTabBoxes();
1102cdf0e10cSrcweir             sal_uInt16 nBoxes = rBoxes.Count();
1103cdf0e10cSrcweir             for (sal_uInt16 k2 = 0;  k2 < nBoxes;  ++k2)
1104cdf0e10cSrcweir             {
1105cdf0e10cSrcweir                 SwTableBox *pBox = rBoxes[k2];
1106cdf0e10cSrcweir                 // TL_CHART2: notify chart about boxes to be removed
1107cdf0e10cSrcweir                 if (pPCD)
1108cdf0e10cSrcweir                     pPCD->DeleteBox( &rTbl, *pBox );
1109cdf0e10cSrcweir             }
1110cdf0e10cSrcweir         }
1111cdf0e10cSrcweir 
1112cdf0e10cSrcweir         rTbl.GetTabLines().DeleteAndDestroy( n, nOldLines - n );
1113cdf0e10cSrcweir     }
1114cdf0e10cSrcweir 
1115cdf0e10cSrcweir 	aParent.GetTabLines().Remove( 0, n );
1116cdf0e10cSrcweir 
1117cdf0e10cSrcweir 	if( bCreateFrms )
1118cdf0e10cSrcweir 		aTmpBox.MakeFrms( rTbl );
1119cdf0e10cSrcweir 	if( bRestoreChart )
1120cdf0e10cSrcweir     {
1121cdf0e10cSrcweir 		// TL_CHART2: need to inform chart of probably changed cell names
1122cdf0e10cSrcweir         pDoc->UpdateCharts( rTbl.GetFrmFmt()->GetName() );
1123cdf0e10cSrcweir     }
1124cdf0e10cSrcweir }
1125cdf0e10cSrcweir 
1126cdf0e10cSrcweir 
NewFrmFmt(const SwTableLine * pTblLn,const SwTableBox * pTblBx,sal_uInt16 nFmtPos,SwFrmFmt * pOldFmt)1127cdf0e10cSrcweir void _SaveTable::NewFrmFmt( const SwTableLine* pTblLn, const SwTableBox* pTblBx,
1128cdf0e10cSrcweir 							sal_uInt16 nFmtPos, SwFrmFmt* pOldFmt )
1129cdf0e10cSrcweir {
1130cdf0e10cSrcweir 	SwDoc* pDoc = pOldFmt->GetDoc();
1131cdf0e10cSrcweir 
1132cdf0e10cSrcweir 	SwFrmFmt* pFmt = aFrmFmts[ nFmtPos ];
1133cdf0e10cSrcweir 	if( !pFmt )
1134cdf0e10cSrcweir 	{
1135cdf0e10cSrcweir 		if( pTblLn )
1136cdf0e10cSrcweir 			pFmt = pDoc->MakeTableLineFmt();
1137cdf0e10cSrcweir 		else
1138cdf0e10cSrcweir 			pFmt = pDoc->MakeTableBoxFmt();
1139cdf0e10cSrcweir         pFmt->SetFmtAttr( *aSets[ nFmtPos ] );
1140cdf0e10cSrcweir 		aFrmFmts.Replace( pFmt, nFmtPos );
1141cdf0e10cSrcweir 	}
1142cdf0e10cSrcweir 
1143cdf0e10cSrcweir 	//Erstmal die Frms ummelden.
1144cdf0e10cSrcweir 	SwIterator<SwTabFrm,SwFmt> aIter( *pOldFmt );
1145cdf0e10cSrcweir 	for( SwFrm* pLast = aIter.First(); pLast; pLast = aIter.Next() )
1146cdf0e10cSrcweir     {
1147cdf0e10cSrcweir 		if( pTblLn ? ((SwRowFrm*)pLast)->GetTabLine() == pTblLn
1148cdf0e10cSrcweir 					: ((SwCellFrm*)pLast)->GetTabBox() == pTblBx )
1149cdf0e10cSrcweir 		{
1150cdf0e10cSrcweir 			pLast->RegisterToFormat(*pFmt);
1151cdf0e10cSrcweir 			pLast->InvalidateAll();
1152cdf0e10cSrcweir 			pLast->ReinitializeFrmSizeAttrFlags();
1153cdf0e10cSrcweir             if ( !pTblLn )
1154cdf0e10cSrcweir             {
1155cdf0e10cSrcweir                 ((SwCellFrm*)pLast)->SetDerivedVert( sal_False );
1156cdf0e10cSrcweir                 ((SwCellFrm*)pLast)->CheckDirChange();
1157cdf0e10cSrcweir             }
1158cdf0e10cSrcweir 		}
1159cdf0e10cSrcweir     }
1160cdf0e10cSrcweir 
1161cdf0e10cSrcweir 	//Jetzt noch mich selbst ummelden.
1162cdf0e10cSrcweir     if ( pTblLn )
1163cdf0e10cSrcweir         const_cast<SwTableLine*>(pTblLn)->RegisterToFormat( *pFmt );
1164cdf0e10cSrcweir     else if ( pTblBx )
1165cdf0e10cSrcweir         const_cast<SwTableBox*>(pTblBx)->RegisterToFormat( *pFmt );
1166cdf0e10cSrcweir 
1167cdf0e10cSrcweir 	if( bModifyBox && !pTblLn )
1168cdf0e10cSrcweir 	{
1169cdf0e10cSrcweir         const SfxPoolItem& rOld = pOldFmt->GetFmtAttr( RES_BOXATR_FORMAT ),
1170cdf0e10cSrcweir                          & rNew = pFmt->GetFmtAttr( RES_BOXATR_FORMAT );
1171cdf0e10cSrcweir 		if( rOld != rNew )
1172cdf0e10cSrcweir 			pFmt->ModifyNotification( (SfxPoolItem*)&rOld, (SfxPoolItem*)&rNew );
1173cdf0e10cSrcweir 	}
1174cdf0e10cSrcweir 
1175cdf0e10cSrcweir 	if( !pOldFmt->GetDepends() )
1176cdf0e10cSrcweir 		delete pOldFmt;
1177cdf0e10cSrcweir 
1178cdf0e10cSrcweir }
1179cdf0e10cSrcweir 
1180cdf0e10cSrcweir 
_SaveLine(_SaveLine * pPrev,const SwTableLine & rLine,_SaveTable & rSTbl)1181cdf0e10cSrcweir _SaveLine::_SaveLine( _SaveLine* pPrev, const SwTableLine& rLine, _SaveTable& rSTbl )
1182cdf0e10cSrcweir 	: pNext( 0 )
1183cdf0e10cSrcweir {
1184cdf0e10cSrcweir 	if( pPrev )
1185cdf0e10cSrcweir 		pPrev->pNext = this;
1186cdf0e10cSrcweir 
1187cdf0e10cSrcweir 	nItemSet = rSTbl.AddFmt( rLine.GetFrmFmt(), true );
1188cdf0e10cSrcweir 
1189cdf0e10cSrcweir 	pBox = new _SaveBox( 0, *rLine.GetTabBoxes()[ 0 ], rSTbl );
1190cdf0e10cSrcweir 	_SaveBox* pBx = pBox;
1191cdf0e10cSrcweir 	for( sal_uInt16 n = 1; n < rLine.GetTabBoxes().Count(); ++n )
1192cdf0e10cSrcweir 		pBx = new _SaveBox( pBx, *rLine.GetTabBoxes()[ n ], rSTbl );
1193cdf0e10cSrcweir }
1194cdf0e10cSrcweir 
1195cdf0e10cSrcweir 
~_SaveLine()1196cdf0e10cSrcweir _SaveLine::~_SaveLine()
1197cdf0e10cSrcweir {
1198cdf0e10cSrcweir 	delete pBox;
1199cdf0e10cSrcweir 	delete pNext;
1200cdf0e10cSrcweir }
1201cdf0e10cSrcweir 
1202cdf0e10cSrcweir 
RestoreAttr(SwTableLine & rLine,_SaveTable & rSTbl)1203cdf0e10cSrcweir void _SaveLine::RestoreAttr( SwTableLine& rLine, _SaveTable& rSTbl )
1204cdf0e10cSrcweir {
1205cdf0e10cSrcweir 	rSTbl.NewFrmFmt( &rLine, 0, nItemSet, rLine.GetFrmFmt() );
1206cdf0e10cSrcweir 
1207cdf0e10cSrcweir 	_SaveBox* pBx = pBox;
1208cdf0e10cSrcweir 	for( sal_uInt16 n = 0; n < rLine.GetTabBoxes().Count(); ++n, pBx = pBx->pNext )
1209cdf0e10cSrcweir 	{
1210cdf0e10cSrcweir 		if( !pBx )
1211cdf0e10cSrcweir 		{
1212870262e3SDon Lewis 			ASSERT( sal_False, "Number of boxes has changed" );
1213cdf0e10cSrcweir 			break;
1214cdf0e10cSrcweir 		}
1215cdf0e10cSrcweir 		pBx->RestoreAttr( *rLine.GetTabBoxes()[ n ], rSTbl );
1216cdf0e10cSrcweir 	}
1217cdf0e10cSrcweir }
1218cdf0e10cSrcweir 
1219cdf0e10cSrcweir 
SaveCntntAttrs(SwDoc * pDoc)1220cdf0e10cSrcweir void _SaveLine::SaveCntntAttrs( SwDoc* pDoc )
1221cdf0e10cSrcweir {
1222cdf0e10cSrcweir 	pBox->SaveCntntAttrs( pDoc );
1223cdf0e10cSrcweir 	if( pNext )
1224cdf0e10cSrcweir 		pNext->SaveCntntAttrs( pDoc );
1225cdf0e10cSrcweir }
1226cdf0e10cSrcweir 
1227cdf0e10cSrcweir 
CreateNew(SwTable & rTbl,SwTableBox & rParent,_SaveTable & rSTbl)1228cdf0e10cSrcweir void _SaveLine::CreateNew( SwTable& rTbl, SwTableBox& rParent, _SaveTable& rSTbl )
1229cdf0e10cSrcweir {
1230cdf0e10cSrcweir 	SwTableLineFmt* pFmt = (SwTableLineFmt*)rSTbl.aFrmFmts[ nItemSet ];
1231cdf0e10cSrcweir 	if( !pFmt )
1232cdf0e10cSrcweir 	{
1233cdf0e10cSrcweir 		SwDoc* pDoc = rTbl.GetFrmFmt()->GetDoc();
1234cdf0e10cSrcweir 		pFmt = pDoc->MakeTableLineFmt();
1235cdf0e10cSrcweir         pFmt->SetFmtAttr( *rSTbl.aSets[ nItemSet ] );
1236cdf0e10cSrcweir 		rSTbl.aFrmFmts.Replace( pFmt, nItemSet );
1237cdf0e10cSrcweir 	}
1238cdf0e10cSrcweir 	SwTableLine* pNew = new SwTableLine( pFmt, 1, &rParent );
1239cdf0e10cSrcweir 
1240cdf0e10cSrcweir     rParent.GetTabLines().C40_INSERT( SwTableLine, pNew, rParent.GetTabLines().Count() );
1241cdf0e10cSrcweir 
1242cdf0e10cSrcweir     // HB, #127868# robustness: in some cases - which I
1243cdf0e10cSrcweir     // cannot reproduce nor see from the code - pNew seems
1244cdf0e10cSrcweir     // to be set to NULL in C40_INSERT.
1245cdf0e10cSrcweir     ASSERT(pNew, "Table line just created set to NULL in C40_INSERT");
1246cdf0e10cSrcweir 
1247cdf0e10cSrcweir     if (pNew)
1248cdf0e10cSrcweir     {
1249cdf0e10cSrcweir         pBox->CreateNew( rTbl, *pNew, rSTbl );
1250cdf0e10cSrcweir     }
1251cdf0e10cSrcweir 
1252cdf0e10cSrcweir 	if( pNext )
1253cdf0e10cSrcweir 		pNext->CreateNew( rTbl, rParent, rSTbl );
1254cdf0e10cSrcweir }
1255cdf0e10cSrcweir 
1256cdf0e10cSrcweir 
_SaveBox(_SaveBox * pPrev,const SwTableBox & rBox,_SaveTable & rSTbl)1257cdf0e10cSrcweir _SaveBox::_SaveBox( _SaveBox* pPrev, const SwTableBox& rBox, _SaveTable& rSTbl )
1258cdf0e10cSrcweir 	: pNext( 0 ), nSttNode( ULONG_MAX ), nRowSpan(0)
1259cdf0e10cSrcweir {
1260cdf0e10cSrcweir 	Ptrs.pLine = 0;
1261cdf0e10cSrcweir 
1262cdf0e10cSrcweir 	if( pPrev )
1263cdf0e10cSrcweir 		pPrev->pNext = this;
1264cdf0e10cSrcweir 
1265cdf0e10cSrcweir 	nItemSet = rSTbl.AddFmt( rBox.GetFrmFmt(), false );
1266cdf0e10cSrcweir 
1267cdf0e10cSrcweir 	if( rBox.GetSttNd() )
1268cdf0e10cSrcweir     {
1269cdf0e10cSrcweir 		nSttNode = rBox.GetSttIdx();
1270cdf0e10cSrcweir         nRowSpan = rBox.getRowSpan();
1271cdf0e10cSrcweir     }
1272cdf0e10cSrcweir 	else
1273cdf0e10cSrcweir 	{
1274cdf0e10cSrcweir 		Ptrs.pLine = new _SaveLine( 0, *rBox.GetTabLines()[ 0 ], rSTbl );
1275cdf0e10cSrcweir 
1276cdf0e10cSrcweir 		_SaveLine* pLn = Ptrs.pLine;
1277cdf0e10cSrcweir 		for( sal_uInt16 n = 1; n < rBox.GetTabLines().Count(); ++n )
1278cdf0e10cSrcweir 			pLn = new _SaveLine( pLn, *rBox.GetTabLines()[ n ], rSTbl );
1279cdf0e10cSrcweir 	}
1280cdf0e10cSrcweir }
1281cdf0e10cSrcweir 
1282cdf0e10cSrcweir 
~_SaveBox()1283cdf0e10cSrcweir _SaveBox::~_SaveBox()
1284cdf0e10cSrcweir {
1285cdf0e10cSrcweir 	if( ULONG_MAX == nSttNode )		// keine EndBox
1286cdf0e10cSrcweir 		delete Ptrs.pLine;
1287cdf0e10cSrcweir 	else
1288cdf0e10cSrcweir 		delete Ptrs.pCntntAttrs;
1289cdf0e10cSrcweir 	delete pNext;
1290cdf0e10cSrcweir }
1291cdf0e10cSrcweir 
1292cdf0e10cSrcweir 
RestoreAttr(SwTableBox & rBox,_SaveTable & rSTbl)1293cdf0e10cSrcweir void _SaveBox::RestoreAttr( SwTableBox& rBox, _SaveTable& rSTbl )
1294cdf0e10cSrcweir {
1295cdf0e10cSrcweir 	rSTbl.NewFrmFmt( 0, &rBox, nItemSet, rBox.GetFrmFmt() );
1296cdf0e10cSrcweir 
1297cdf0e10cSrcweir 	if( ULONG_MAX == nSttNode )		// keine EndBox
1298cdf0e10cSrcweir 	{
1299cdf0e10cSrcweir 		if( !rBox.GetTabLines().Count() )
1300cdf0e10cSrcweir 		{
1301870262e3SDon Lewis 			ASSERT( sal_False, "Number of Lines has changed" );
1302cdf0e10cSrcweir 		}
1303cdf0e10cSrcweir 		else
1304cdf0e10cSrcweir 		{
1305cdf0e10cSrcweir 			_SaveLine* pLn = Ptrs.pLine;
1306cdf0e10cSrcweir 			for( sal_uInt16 n = 0; n < rBox.GetTabLines().Count(); ++n, pLn = pLn->pNext )
1307cdf0e10cSrcweir 			{
1308cdf0e10cSrcweir 				if( !pLn )
1309cdf0e10cSrcweir 				{
1310870262e3SDon Lewis 					ASSERT( sal_False, "Number of Lines has changed" );
1311cdf0e10cSrcweir 					break;
1312cdf0e10cSrcweir 				}
1313cdf0e10cSrcweir 
1314cdf0e10cSrcweir 				pLn->RestoreAttr( *rBox.GetTabLines()[ n ], rSTbl );
1315cdf0e10cSrcweir 			}
1316cdf0e10cSrcweir 		}
1317cdf0e10cSrcweir 	}
1318cdf0e10cSrcweir 	else if( rBox.GetSttNd() && rBox.GetSttIdx() == nSttNode )
1319cdf0e10cSrcweir 	{
1320cdf0e10cSrcweir 		if( Ptrs.pCntntAttrs )
1321cdf0e10cSrcweir 		{
1322cdf0e10cSrcweir 			SwNodes& rNds = rBox.GetFrmFmt()->GetDoc()->GetNodes();
1323cdf0e10cSrcweir 			sal_uInt16 nSet = 0;
1324cdf0e10cSrcweir 			sal_uLong nEnd = rBox.GetSttNd()->EndOfSectionIndex();
1325cdf0e10cSrcweir 			for( sal_uLong n = nSttNode + 1; n < nEnd; ++n )
1326cdf0e10cSrcweir 			{
1327cdf0e10cSrcweir 				SwCntntNode* pCNd = rNds[ n ]->GetCntntNode();
1328cdf0e10cSrcweir 				if( pCNd )
1329cdf0e10cSrcweir 				{
1330cdf0e10cSrcweir 					SfxItemSet* pSet = (*Ptrs.pCntntAttrs)[ nSet++ ];
1331cdf0e10cSrcweir 					if( pSet )
1332cdf0e10cSrcweir 					{
1333cdf0e10cSrcweir 						sal_uInt16 *pRstAttr = aSave_BoxCntntSet;
1334cdf0e10cSrcweir 						while( *pRstAttr )
1335cdf0e10cSrcweir 						{
1336cdf0e10cSrcweir 							pCNd->ResetAttr( *pRstAttr, *(pRstAttr+1) );
1337cdf0e10cSrcweir 							pRstAttr += 2;
1338cdf0e10cSrcweir 						}
1339cdf0e10cSrcweir 						pCNd->SetAttr( *pSet );
1340cdf0e10cSrcweir 					}
1341cdf0e10cSrcweir 					else
1342cdf0e10cSrcweir 						pCNd->ResetAllAttr();
1343cdf0e10cSrcweir 				}
1344cdf0e10cSrcweir 			}
1345cdf0e10cSrcweir 		}
1346cdf0e10cSrcweir 	}
1347cdf0e10cSrcweir 	else
1348cdf0e10cSrcweir 	{
1349870262e3SDon Lewis 		ASSERT( sal_False, "Box no longer at the same node" );
1350cdf0e10cSrcweir 	}
1351cdf0e10cSrcweir }
1352cdf0e10cSrcweir 
1353cdf0e10cSrcweir 
SaveCntntAttrs(SwDoc * pDoc)1354cdf0e10cSrcweir void _SaveBox::SaveCntntAttrs( SwDoc* pDoc )
1355cdf0e10cSrcweir {
1356cdf0e10cSrcweir 	if( ULONG_MAX == nSttNode )		// keine EndBox
1357cdf0e10cSrcweir 	{
1358cdf0e10cSrcweir 		// weiter in der Line
1359cdf0e10cSrcweir 		Ptrs.pLine->SaveCntntAttrs( pDoc );
1360cdf0e10cSrcweir 	}
1361cdf0e10cSrcweir 	else
1362cdf0e10cSrcweir 	{
1363cdf0e10cSrcweir 		sal_uLong nEnd = pDoc->GetNodes()[ nSttNode ]->EndOfSectionIndex();
1364cdf0e10cSrcweir 		Ptrs.pCntntAttrs = new SfxItemSets( (sal_uInt8)(nEnd - nSttNode - 1 ), 5 );
1365cdf0e10cSrcweir 		for( sal_uLong n = nSttNode + 1; n < nEnd; ++n )
1366cdf0e10cSrcweir 		{
1367cdf0e10cSrcweir 			SwCntntNode* pCNd = pDoc->GetNodes()[ n ]->GetCntntNode();
1368cdf0e10cSrcweir 			if( pCNd )
1369cdf0e10cSrcweir 			{
1370cdf0e10cSrcweir 				SfxItemSet* pSet = 0;
1371cdf0e10cSrcweir                 if( pCNd->HasSwAttrSet() )
1372cdf0e10cSrcweir 				{
1373cdf0e10cSrcweir 					pSet = new SfxItemSet( pDoc->GetAttrPool(),
1374cdf0e10cSrcweir 											aSave_BoxCntntSet );
1375cdf0e10cSrcweir 					pSet->Put( *pCNd->GetpSwAttrSet() );
1376cdf0e10cSrcweir 				}
1377cdf0e10cSrcweir 
1378cdf0e10cSrcweir 				Ptrs.pCntntAttrs->Insert( pSet, Ptrs.pCntntAttrs->Count() );
1379cdf0e10cSrcweir 			}
1380cdf0e10cSrcweir 		}
1381cdf0e10cSrcweir 	}
1382cdf0e10cSrcweir 	if( pNext )
1383cdf0e10cSrcweir 		pNext->SaveCntntAttrs( pDoc );
1384cdf0e10cSrcweir }
1385cdf0e10cSrcweir 
1386cdf0e10cSrcweir 
CreateNew(SwTable & rTbl,SwTableLine & rParent,_SaveTable & rSTbl)1387cdf0e10cSrcweir void _SaveBox::CreateNew( SwTable& rTbl, SwTableLine& rParent, _SaveTable& rSTbl )
1388cdf0e10cSrcweir {
1389cdf0e10cSrcweir 	SwTableBoxFmt* pFmt = (SwTableBoxFmt*)rSTbl.aFrmFmts[ nItemSet ];
1390cdf0e10cSrcweir 	if( !pFmt )
1391cdf0e10cSrcweir 	{
1392cdf0e10cSrcweir 		SwDoc* pDoc = rTbl.GetFrmFmt()->GetDoc();
1393cdf0e10cSrcweir 		pFmt = pDoc->MakeTableBoxFmt();
1394cdf0e10cSrcweir         pFmt->SetFmtAttr( *rSTbl.aSets[ nItemSet ] );
1395cdf0e10cSrcweir 		rSTbl.aFrmFmts.Replace( pFmt, nItemSet );
1396cdf0e10cSrcweir 	}
1397cdf0e10cSrcweir 
1398cdf0e10cSrcweir 	if( ULONG_MAX == nSttNode )		// keine EndBox
1399cdf0e10cSrcweir 	{
1400cdf0e10cSrcweir 		SwTableBox* pNew = new SwTableBox( pFmt, 1, &rParent );
1401cdf0e10cSrcweir 		rParent.GetTabBoxes().C40_INSERT( SwTableBox, pNew, rParent.GetTabBoxes().Count() );
1402cdf0e10cSrcweir 
1403cdf0e10cSrcweir 		Ptrs.pLine->CreateNew( rTbl, *pNew, rSTbl );
1404cdf0e10cSrcweir 	}
1405cdf0e10cSrcweir 	else
1406cdf0e10cSrcweir 	{
1407cdf0e10cSrcweir 		// Box zum StartNode in der alten Tabelle suchen
1408cdf0e10cSrcweir 		SwTableBox* pBox = rTbl.GetTblBox( nSttNode );
1409cdf0e10cSrcweir 		ASSERT( pBox, "Wo ist meine TabellenBox geblieben?" );
1410cdf0e10cSrcweir 
1411cdf0e10cSrcweir 		SwFrmFmt* pOld = pBox->GetFrmFmt();
1412cdf0e10cSrcweir         pBox->RegisterToFormat( *pFmt );
1413cdf0e10cSrcweir 		if( !pOld->GetDepends() )
1414cdf0e10cSrcweir 			delete pOld;
1415cdf0e10cSrcweir 
1416cdf0e10cSrcweir         pBox->setRowSpan( nRowSpan );
1417cdf0e10cSrcweir 
1418cdf0e10cSrcweir 		SwTableBoxes* pTBoxes = &pBox->GetUpper()->GetTabBoxes();
1419cdf0e10cSrcweir 		pTBoxes->Remove( pTBoxes->C40_GETPOS( SwTableBox, pBox ) );
1420cdf0e10cSrcweir 
1421cdf0e10cSrcweir 		pBox->SetUpper( &rParent );
1422cdf0e10cSrcweir 		pTBoxes = &rParent.GetTabBoxes();
1423cdf0e10cSrcweir 		pTBoxes->C40_INSERT( SwTableBox, pBox, pTBoxes->Count() );
1424cdf0e10cSrcweir 	}
1425cdf0e10cSrcweir 
1426cdf0e10cSrcweir 	if( pNext )
1427cdf0e10cSrcweir 		pNext->CreateNew( rTbl, rParent, rSTbl );
1428cdf0e10cSrcweir }
1429cdf0e10cSrcweir 
1430cdf0e10cSrcweir 
1431cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////
1432cdf0e10cSrcweir 
1433cdf0e10cSrcweir // UndoObject fuer Attribut Aenderung an der Tabelle
1434cdf0e10cSrcweir 
1435cdf0e10cSrcweir 
SwUndoAttrTbl(const SwTableNode & rTblNd,sal_Bool bClearTabCols)1436cdf0e10cSrcweir SwUndoAttrTbl::SwUndoAttrTbl( const SwTableNode& rTblNd, sal_Bool bClearTabCols )
1437cdf0e10cSrcweir 	: SwUndo( UNDO_TABLE_ATTR ),
1438cdf0e10cSrcweir 	nSttNode( rTblNd.GetIndex() )
1439cdf0e10cSrcweir {
1440cdf0e10cSrcweir 	bClearTabCol = bClearTabCols;
1441cdf0e10cSrcweir 	pSaveTbl = new _SaveTable( rTblNd.GetTable() );
1442cdf0e10cSrcweir }
1443cdf0e10cSrcweir 
~SwUndoAttrTbl()1444cdf0e10cSrcweir SwUndoAttrTbl::~SwUndoAttrTbl()
1445cdf0e10cSrcweir {
1446cdf0e10cSrcweir 	delete pSaveTbl;
1447cdf0e10cSrcweir }
1448cdf0e10cSrcweir 
UndoImpl(::sw::UndoRedoContext & rContext)1449cdf0e10cSrcweir void SwUndoAttrTbl::UndoImpl(::sw::UndoRedoContext & rContext)
1450cdf0e10cSrcweir {
1451cdf0e10cSrcweir     SwDoc & rDoc = rContext.GetDoc();
1452cdf0e10cSrcweir 	SwTableNode* pTblNd = rDoc.GetNodes()[ nSttNode ]->GetTableNode();
1453cdf0e10cSrcweir 	ASSERT( pTblNd, "kein TabellenNode" );
1454cdf0e10cSrcweir 
1455cdf0e10cSrcweir     if (pTblNd)
1456cdf0e10cSrcweir     {
1457cdf0e10cSrcweir         _SaveTable* pOrig = new _SaveTable( pTblNd->GetTable() );
1458cdf0e10cSrcweir         pSaveTbl->RestoreAttr( pTblNd->GetTable() );
1459cdf0e10cSrcweir         delete pSaveTbl;
1460cdf0e10cSrcweir         pSaveTbl = pOrig;
1461cdf0e10cSrcweir     }
1462cdf0e10cSrcweir 
1463cdf0e10cSrcweir 	if( bClearTabCol )
1464cdf0e10cSrcweir 		ClearFEShellTabCols();
1465cdf0e10cSrcweir }
1466cdf0e10cSrcweir 
RedoImpl(::sw::UndoRedoContext & rContext)1467cdf0e10cSrcweir void SwUndoAttrTbl::RedoImpl(::sw::UndoRedoContext & rContext)
1468cdf0e10cSrcweir {
1469cdf0e10cSrcweir     UndoImpl(rContext);
1470cdf0e10cSrcweir }
1471cdf0e10cSrcweir 
1472cdf0e10cSrcweir 
1473cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////
1474cdf0e10cSrcweir 
1475cdf0e10cSrcweir // UndoObject fuer AutoFormat an der Tabelle
1476cdf0e10cSrcweir 
1477cdf0e10cSrcweir 
SwUndoTblAutoFmt(const SwTableNode & rTblNd,const SwTableAutoFmt & rAFmt)1478cdf0e10cSrcweir SwUndoTblAutoFmt::SwUndoTblAutoFmt( const SwTableNode& rTblNd,
1479cdf0e10cSrcweir 									const SwTableAutoFmt& rAFmt )
1480cdf0e10cSrcweir 	: SwUndo( UNDO_TABLE_AUTOFMT ),
1481cdf0e10cSrcweir     nSttNode( rTblNd.GetIndex() ),
1482cdf0e10cSrcweir 	bSaveCntntAttr( sal_False )
1483cdf0e10cSrcweir {
1484cdf0e10cSrcweir 	pSaveTbl = new _SaveTable( rTblNd.GetTable() );
1485cdf0e10cSrcweir 
1486cdf0e10cSrcweir 	if( rAFmt.IsFont() || rAFmt.IsJustify() )
1487cdf0e10cSrcweir 	{
1488cdf0e10cSrcweir 		// dann auch noch ueber die ContentNodes der EndBoxen und
1489cdf0e10cSrcweir 		// und alle Absatz-Attribute zusammen sammeln
1490cdf0e10cSrcweir 		pSaveTbl->SaveCntntAttrs( (SwDoc*)rTblNd.GetDoc() );
1491cdf0e10cSrcweir 		bSaveCntntAttr = sal_True;
1492cdf0e10cSrcweir 	}
1493cdf0e10cSrcweir }
1494cdf0e10cSrcweir 
~SwUndoTblAutoFmt()1495cdf0e10cSrcweir SwUndoTblAutoFmt::~SwUndoTblAutoFmt()
1496cdf0e10cSrcweir {
1497cdf0e10cSrcweir 	delete pSaveTbl;
1498cdf0e10cSrcweir }
1499cdf0e10cSrcweir 
SaveBoxCntnt(const SwTableBox & rBox)1500cdf0e10cSrcweir void SwUndoTblAutoFmt::SaveBoxCntnt( const SwTableBox& rBox )
1501cdf0e10cSrcweir {
1502cdf0e10cSrcweir     ::boost::shared_ptr<SwUndoTblNumFmt> const p(new SwUndoTblNumFmt(rBox));
1503cdf0e10cSrcweir     m_Undos.push_back(p);
1504cdf0e10cSrcweir }
1505cdf0e10cSrcweir 
1506cdf0e10cSrcweir 
1507cdf0e10cSrcweir void
UndoRedo(bool const bUndo,::sw::UndoRedoContext & rContext)1508cdf0e10cSrcweir SwUndoTblAutoFmt::UndoRedo(bool const bUndo, ::sw::UndoRedoContext & rContext)
1509cdf0e10cSrcweir {
1510cdf0e10cSrcweir     SwDoc & rDoc = rContext.GetDoc();
1511cdf0e10cSrcweir 	SwTableNode* pTblNd = rDoc.GetNodes()[ nSttNode ]->GetTableNode();
1512cdf0e10cSrcweir 	ASSERT( pTblNd, "kein TabellenNode" );
1513cdf0e10cSrcweir 
1514cdf0e10cSrcweir 	_SaveTable* pOrig = new _SaveTable( pTblNd->GetTable() );
1515cdf0e10cSrcweir 		// dann auch noch ueber die ContentNodes der EndBoxen und
1516cdf0e10cSrcweir 		// und alle Absatz-Attribute zusammen sammeln
1517cdf0e10cSrcweir 	if( bSaveCntntAttr )
1518cdf0e10cSrcweir 		pOrig->SaveCntntAttrs( &rDoc );
1519cdf0e10cSrcweir 
1520cdf0e10cSrcweir     if (bUndo)
1521cdf0e10cSrcweir     {
1522cdf0e10cSrcweir         for (size_t n = m_Undos.size(); 0 < n; --n)
1523cdf0e10cSrcweir         {
1524cdf0e10cSrcweir             m_Undos.at(n-1)->UndoImpl(rContext);
1525cdf0e10cSrcweir         }
1526cdf0e10cSrcweir     }
1527cdf0e10cSrcweir 
1528cdf0e10cSrcweir 	pSaveTbl->RestoreAttr( pTblNd->GetTable(), !bUndo );
1529cdf0e10cSrcweir 	delete pSaveTbl;
1530cdf0e10cSrcweir 	pSaveTbl = pOrig;
1531cdf0e10cSrcweir }
1532cdf0e10cSrcweir 
UndoImpl(::sw::UndoRedoContext & rContext)1533cdf0e10cSrcweir void SwUndoTblAutoFmt::UndoImpl(::sw::UndoRedoContext & rContext)
1534cdf0e10cSrcweir {
1535cdf0e10cSrcweir     UndoRedo(true, rContext);
1536cdf0e10cSrcweir }
1537cdf0e10cSrcweir 
RedoImpl(::sw::UndoRedoContext & rContext)1538cdf0e10cSrcweir void SwUndoTblAutoFmt::RedoImpl(::sw::UndoRedoContext & rContext)
1539cdf0e10cSrcweir {
1540cdf0e10cSrcweir     UndoRedo(false, rContext);
1541cdf0e10cSrcweir }
1542cdf0e10cSrcweir 
1543cdf0e10cSrcweir 
1544cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////
1545cdf0e10cSrcweir 
SwUndoTblNdsChg(SwUndoId nAction,const SwSelBoxes & rBoxes,const SwTableNode & rTblNd,long nMn,long nMx,sal_uInt16 nCnt,sal_Bool bFlg,sal_Bool bSmHght)1546cdf0e10cSrcweir SwUndoTblNdsChg::SwUndoTblNdsChg( SwUndoId nAction,
1547cdf0e10cSrcweir 									const SwSelBoxes& rBoxes,
1548cdf0e10cSrcweir 									const SwTableNode& rTblNd,
1549cdf0e10cSrcweir                                     long nMn, long nMx,
1550cdf0e10cSrcweir                                     sal_uInt16 nCnt, sal_Bool bFlg, sal_Bool bSmHght )
1551cdf0e10cSrcweir 	: SwUndo( nAction ),
1552cdf0e10cSrcweir 	aBoxes( rBoxes.Count() < 255 ? (sal_uInt8)rBoxes.Count() : 255, 10 ),
1553cdf0e10cSrcweir     nMin( nMn ), nMax( nMx ),
1554cdf0e10cSrcweir 	nSttNode( rTblNd.GetIndex() ), nCurrBox( 0 ),
1555cdf0e10cSrcweir 	nCount( nCnt ), nRelDiff( 0 ), nAbsDiff( 0 ),
1556cdf0e10cSrcweir 	nSetColType( USHRT_MAX ),
1557cdf0e10cSrcweir     bFlag( bFlg ),
1558cdf0e10cSrcweir     bSameHeight( bSmHght )
1559cdf0e10cSrcweir {
1560cdf0e10cSrcweir 	Ptrs.pNewSttNds = 0;
1561cdf0e10cSrcweir 
1562cdf0e10cSrcweir 	const SwTable& rTbl = rTblNd.GetTable();
1563cdf0e10cSrcweir 	pSaveTbl = new _SaveTable( rTbl );
1564cdf0e10cSrcweir 
1565cdf0e10cSrcweir 	// und die Selektion merken
1566cdf0e10cSrcweir 	for( sal_uInt16 n = 0; n < rBoxes.Count(); ++n )
1567cdf0e10cSrcweir 		aBoxes.Insert( rBoxes[n]->GetSttIdx(), n );
1568cdf0e10cSrcweir }
1569cdf0e10cSrcweir 
1570cdf0e10cSrcweir 
SwUndoTblNdsChg(SwUndoId nAction,const SwSelBoxes & rBoxes,const SwTableNode & rTblNd)1571cdf0e10cSrcweir SwUndoTblNdsChg::SwUndoTblNdsChg( SwUndoId nAction,
1572cdf0e10cSrcweir 									const SwSelBoxes& rBoxes,
1573cdf0e10cSrcweir 									const SwTableNode& rTblNd )
1574cdf0e10cSrcweir 	: SwUndo( nAction ),
1575cdf0e10cSrcweir 	aBoxes( rBoxes.Count() < 255 ? (sal_uInt8)rBoxes.Count() : 255, 10 ),
1576cdf0e10cSrcweir     nMin( 0 ), nMax( 0 ),
1577cdf0e10cSrcweir 	nSttNode( rTblNd.GetIndex() ), nCurrBox( 0 ),
1578cdf0e10cSrcweir 	nCount( 0 ), nRelDiff( 0 ), nAbsDiff( 0 ),
1579cdf0e10cSrcweir 	nSetColType( USHRT_MAX ),
1580cdf0e10cSrcweir 	bFlag( sal_False ),
1581cdf0e10cSrcweir 	bSameHeight( sal_False )
1582cdf0e10cSrcweir {
1583cdf0e10cSrcweir 	Ptrs.pNewSttNds = 0;
1584cdf0e10cSrcweir 
1585cdf0e10cSrcweir 	const SwTable& rTbl = rTblNd.GetTable();
1586cdf0e10cSrcweir 	pSaveTbl = new _SaveTable( rTbl );
1587cdf0e10cSrcweir 
1588cdf0e10cSrcweir 	// und die Selektion merken
1589cdf0e10cSrcweir 	for( sal_uInt16 n = 0; n < rBoxes.Count(); ++n )
1590cdf0e10cSrcweir 		aBoxes.Insert( rBoxes[n]->GetSttIdx(), n );
1591cdf0e10cSrcweir }
1592cdf0e10cSrcweir 
ReNewBoxes(const SwSelBoxes & rBoxes)1593cdf0e10cSrcweir void SwUndoTblNdsChg::ReNewBoxes( const SwSelBoxes& rBoxes )
1594cdf0e10cSrcweir {
1595cdf0e10cSrcweir     if( rBoxes.Count() != aBoxes.Count() )
1596cdf0e10cSrcweir     {
1597cdf0e10cSrcweir         aBoxes.Remove( 0, aBoxes.Count() );
1598cdf0e10cSrcweir         for( sal_uInt16 n = 0; n < rBoxes.Count(); ++n )
1599cdf0e10cSrcweir             aBoxes.Insert( rBoxes[n]->GetSttIdx(), n );
1600cdf0e10cSrcweir     }
1601cdf0e10cSrcweir }
1602cdf0e10cSrcweir 
~SwUndoTblNdsChg()1603cdf0e10cSrcweir SwUndoTblNdsChg::~SwUndoTblNdsChg()
1604cdf0e10cSrcweir {
1605cdf0e10cSrcweir 	delete pSaveTbl;
1606cdf0e10cSrcweir 
1607cdf0e10cSrcweir 	if( IsDelBox() )
1608cdf0e10cSrcweir 		delete Ptrs.pDelSects;
1609cdf0e10cSrcweir 	else
1610cdf0e10cSrcweir 		delete Ptrs.pNewSttNds;
1611cdf0e10cSrcweir }
1612cdf0e10cSrcweir 
SaveNewBoxes(const SwTableNode & rTblNd,const SwTableSortBoxes & rOld)1613cdf0e10cSrcweir void SwUndoTblNdsChg::SaveNewBoxes( const SwTableNode& rTblNd,
1614cdf0e10cSrcweir 									const SwTableSortBoxes& rOld )
1615cdf0e10cSrcweir {
1616cdf0e10cSrcweir 	const SwTable& rTbl = rTblNd.GetTable();
1617cdf0e10cSrcweir 	const SwTableSortBoxes& rTblBoxes = rTbl.GetTabSortBoxes();
1618cdf0e10cSrcweir 	sal_uInt16 n;
1619cdf0e10cSrcweir 	sal_uInt16 i;
1620cdf0e10cSrcweir 
1621cdf0e10cSrcweir 	ASSERT( ! IsDelBox(), "falsche Action" );
1622cdf0e10cSrcweir 	Ptrs.pNewSttNds = new SvULongs( (sal_uInt8)(rTblBoxes.Count() - rOld.Count()), 5 );
1623cdf0e10cSrcweir 
1624cdf0e10cSrcweir 	for( n = 0, i = 0; n < rOld.Count(); ++i )
1625cdf0e10cSrcweir 	{
1626cdf0e10cSrcweir 		if( rOld[ n ] == rTblBoxes[ i ] )
1627cdf0e10cSrcweir 			++n;
1628cdf0e10cSrcweir 		else
1629cdf0e10cSrcweir 			// neue Box: sortiert einfuegen!!
1630cdf0e10cSrcweir 			InsertSort( *Ptrs.pNewSttNds, rTblBoxes[ i ]->GetSttIdx() );
1631cdf0e10cSrcweir 	}
1632cdf0e10cSrcweir 
1633cdf0e10cSrcweir 	for( ; i < rTblBoxes.Count(); ++i )
1634cdf0e10cSrcweir 		// neue Box: sortiert einfuegen!!
1635cdf0e10cSrcweir 		InsertSort( *Ptrs.pNewSttNds, rTblBoxes[ i ]->GetSttIdx() );
1636cdf0e10cSrcweir }
1637cdf0e10cSrcweir 
1638cdf0e10cSrcweir 
lcl_FindTableLine(const SwTable & rTable,const SwTableBox & rBox)1639cdf0e10cSrcweir SwTableLine* lcl_FindTableLine( const SwTable& rTable,
1640cdf0e10cSrcweir                                 const SwTableBox& rBox )
1641cdf0e10cSrcweir {
1642cdf0e10cSrcweir     SwTableLine* pRet = NULL;
1643cdf0e10cSrcweir     // i63949: For nested cells we have to take nLineNo - 1, too, not 0!
1644cdf0e10cSrcweir     const SwTableLines &rTableLines = ( rBox.GetUpper()->GetUpper() != NULL ) ?
1645cdf0e10cSrcweir                                   rBox.GetUpper()->GetUpper()->GetTabLines()
1646cdf0e10cSrcweir                                 : rTable.GetTabLines();
1647cdf0e10cSrcweir     const SwTableLine* pLine = rBox.GetUpper();
1648cdf0e10cSrcweir     sal_uInt16 nLineNo = rTableLines.C40_GETPOS( SwTableLine, pLine );
1649cdf0e10cSrcweir     pRet = rTableLines[nLineNo - 1];
1650cdf0e10cSrcweir 
1651cdf0e10cSrcweir     return pRet;
1652cdf0e10cSrcweir }
1653cdf0e10cSrcweir 
lcl_FindParentLines(const SwTable & rTable,const SwTableBox & rBox)1654cdf0e10cSrcweir const SwTableLines& lcl_FindParentLines( const SwTable& rTable,
1655cdf0e10cSrcweir 				                       const SwTableBox& rBox )
1656cdf0e10cSrcweir {
1657cdf0e10cSrcweir     const SwTableLines& rRet =
1658cdf0e10cSrcweir 		( rBox.GetUpper()->GetUpper() != NULL ) ?
1659cdf0e10cSrcweir 			rBox.GetUpper()->GetUpper()->GetTabLines() :
1660cdf0e10cSrcweir 			rTable.GetTabLines();
1661cdf0e10cSrcweir 
1662cdf0e10cSrcweir 	return rRet;
1663cdf0e10cSrcweir }
1664cdf0e10cSrcweir 
1665cdf0e10cSrcweir 
SaveNewBoxes(const SwTableNode & rTblNd,const SwTableSortBoxes & rOld,const SwSelBoxes & rBoxes,const SvULongs & rNodeCnts)1666cdf0e10cSrcweir void SwUndoTblNdsChg::SaveNewBoxes( const SwTableNode& rTblNd,
1667cdf0e10cSrcweir 									const SwTableSortBoxes& rOld,
1668cdf0e10cSrcweir 									const SwSelBoxes& rBoxes,
1669cdf0e10cSrcweir 									const SvULongs& rNodeCnts )
1670cdf0e10cSrcweir {
1671cdf0e10cSrcweir 	const SwTable& rTbl = rTblNd.GetTable();
1672cdf0e10cSrcweir 	const SwTableSortBoxes& rTblBoxes = rTbl.GetTabSortBoxes();
1673cdf0e10cSrcweir 
1674cdf0e10cSrcweir 	ASSERT( ! IsDelBox(), "falsche Action" );
1675cdf0e10cSrcweir 	Ptrs.pNewSttNds = new SvULongs( (sal_uInt8)(rTblBoxes.Count() - rOld.Count()), 5 );
1676cdf0e10cSrcweir 
1677cdf0e10cSrcweir 	ASSERT( rTbl.IsNewModel() || rOld.Count() + nCount * rBoxes.Count() == rTblBoxes.Count(),
1678cdf0e10cSrcweir 		"unexpected boxes" );
1679cdf0e10cSrcweir 	ASSERT( rOld.Count() <= rTblBoxes.Count(), "more unexpected boxes" );
1680cdf0e10cSrcweir 	for( sal_uInt16 n = 0, i = 0; i < rTblBoxes.Count(); ++i )
1681cdf0e10cSrcweir 	{
1682cdf0e10cSrcweir 		if( ( n < rOld.Count() ) &&
1683cdf0e10cSrcweir 			( rOld[ n ] == rTblBoxes[ i ] ) )
1684cdf0e10cSrcweir         {
1685cdf0e10cSrcweir             // box already known? Then nothing to be done.
1686cdf0e10cSrcweir 			++n;
1687cdf0e10cSrcweir         }
1688cdf0e10cSrcweir 		else
1689cdf0e10cSrcweir 		{
1690cdf0e10cSrcweir 			// new box found: insert (obey sort order)
1691cdf0e10cSrcweir 			sal_uInt16 nInsPos;
1692cdf0e10cSrcweir 			const SwTableBox* pBox = rTblBoxes[ i ];
1693cdf0e10cSrcweir 			InsertSort( *Ptrs.pNewSttNds, pBox->GetSttIdx(), &nInsPos );
1694cdf0e10cSrcweir 
1695cdf0e10cSrcweir 			// find the source box. It must be one in rBoxes.
1696cdf0e10cSrcweir             // We found the right one if it's in the same column as pBox.
1697cdf0e10cSrcweir             // No, if more than one selected cell in the same column has been splitted,
1698cdf0e10cSrcweir             // we have to look for the nearest one (i65201)!
1699cdf0e10cSrcweir 			const SwTableBox* pSourceBox = NULL;
1700cdf0e10cSrcweir 			const SwTableBox* pCheckBox = NULL;
1701cdf0e10cSrcweir 			const SwTableLine* pBoxLine = pBox->GetUpper();
1702cdf0e10cSrcweir 			sal_uInt16 nLineDiff = lcl_FindParentLines(rTbl,*pBox).C40_GETPOS(SwTableLine,pBoxLine);
1703cdf0e10cSrcweir             sal_uInt16 nLineNo = 0;
1704cdf0e10cSrcweir             for( sal_uInt16 j = 0; j < rBoxes.Count(); ++j )
1705cdf0e10cSrcweir             {
1706cdf0e10cSrcweir 				pCheckBox = rBoxes[j];
1707cdf0e10cSrcweir                 if( pCheckBox->GetUpper()->GetUpper() == pBox->GetUpper()->GetUpper() )
1708cdf0e10cSrcweir                 {
1709cdf0e10cSrcweir                     const SwTableLine* pCheckLine = pCheckBox->GetUpper();
1710cdf0e10cSrcweir                     sal_uInt16 nCheckLine = lcl_FindParentLines( rTbl, *pCheckBox ).
1711cdf0e10cSrcweir                     C40_GETPOS( SwTableLine, pCheckLine );
1712cdf0e10cSrcweir                     if( ( !pSourceBox || nCheckLine > nLineNo ) && nCheckLine < nLineDiff )
1713cdf0e10cSrcweir                     {
1714cdf0e10cSrcweir                         nLineNo = nCheckLine;
1715cdf0e10cSrcweir                         pSourceBox = pCheckBox;
1716cdf0e10cSrcweir                     }
1717cdf0e10cSrcweir                 }
1718cdf0e10cSrcweir 			}
1719cdf0e10cSrcweir 
1720cdf0e10cSrcweir 			// find the line number difference
1721cdf0e10cSrcweir             // (to help determine bNodesMoved flag below)
1722cdf0e10cSrcweir 			nLineDiff = nLineDiff - nLineNo;
1723cdf0e10cSrcweir             ASSERT( pSourceBox, "Splitted source box not found!" );
1724cdf0e10cSrcweir             // find out how many nodes the source box used to have
1725cdf0e10cSrcweir             // (to help determine bNodesMoved flag below)
1726cdf0e10cSrcweir             sal_uInt16 nNdsPos = 0;
1727cdf0e10cSrcweir             while( rBoxes[ nNdsPos ] != pSourceBox )
1728cdf0e10cSrcweir                 ++nNdsPos;
1729cdf0e10cSrcweir             sal_uLong nNodes = rNodeCnts[ nNdsPos ];
1730cdf0e10cSrcweir 
1731cdf0e10cSrcweir             // When a new table cell is created, it either gets a new
1732cdf0e10cSrcweir             // node, or it gets node(s) from elsewhere. The undo must
1733cdf0e10cSrcweir             // know, of course, and thus we must determine here just
1734cdf0e10cSrcweir             // where pBox's nodes are from:
1735cdf0e10cSrcweir             // If 1) the source box has lost nodes, and
1736cdf0e10cSrcweir             //    2) we're in the node range that got nodes
1737cdf0e10cSrcweir             // then pBox received nodes from elsewhere.
1738cdf0e10cSrcweir             // If bNodesMoved is set for pBox the undo must move the
1739cdf0e10cSrcweir             // boxes back, otherwise it must delete them.
174086e1cf34SPedro Giffuni             // The bNodesMoved flag is stored in a separate array
1741cdf0e10cSrcweir             // which mirrors Ptrs.pNewSttNds, i.e. Ptrs.pNewSttNds[i]
1742cdf0e10cSrcweir             // and aMvBoxes[i] belong together.
1743cdf0e10cSrcweir             sal_Bool bNodesMoved =
1744cdf0e10cSrcweir                 ( nNodes != ( pSourceBox->GetSttNd()->EndOfSectionIndex() -
1745cdf0e10cSrcweir                               pSourceBox->GetSttIdx() ) )
1746cdf0e10cSrcweir                 && ( nNodes - 1 > nLineDiff );
1747cdf0e10cSrcweir 			aMvBoxes.insert( aMvBoxes.begin() + nInsPos, bNodesMoved );
1748cdf0e10cSrcweir 		}
1749cdf0e10cSrcweir 	}
1750cdf0e10cSrcweir }
1751cdf0e10cSrcweir 
1752cdf0e10cSrcweir 
SaveSection(SwStartNode * pSttNd)1753cdf0e10cSrcweir void SwUndoTblNdsChg::SaveSection( SwStartNode* pSttNd )
1754cdf0e10cSrcweir {
1755cdf0e10cSrcweir 	ASSERT( IsDelBox(), "falsche Action" );
1756cdf0e10cSrcweir 	if( !Ptrs.pDelSects )
1757cdf0e10cSrcweir 		Ptrs.pDelSects = new SwUndoSaveSections( 10, 5 );
1758cdf0e10cSrcweir 
1759cdf0e10cSrcweir 	SwTableNode* pTblNd = pSttNd->FindTableNode();
1760cdf0e10cSrcweir 	SwUndoSaveSection* pSave = new SwUndoSaveSection;
1761cdf0e10cSrcweir 	pSave->SaveSection( pSttNd->GetDoc(), SwNodeIndex( *pSttNd ));
1762cdf0e10cSrcweir 
1763cdf0e10cSrcweir 	Ptrs.pDelSects->Insert( pSave, Ptrs.pDelSects->Count() );
1764cdf0e10cSrcweir 	nSttNode = pTblNd->GetIndex();
1765cdf0e10cSrcweir }
1766cdf0e10cSrcweir 
1767cdf0e10cSrcweir 
UndoImpl(::sw::UndoRedoContext & rContext)1768cdf0e10cSrcweir void SwUndoTblNdsChg::UndoImpl(::sw::UndoRedoContext & rContext)
1769cdf0e10cSrcweir {
1770cdf0e10cSrcweir     SwDoc & rDoc = rContext.GetDoc();
1771cdf0e10cSrcweir 	SwNodeIndex aIdx( rDoc.GetNodes(), nSttNode );
1772cdf0e10cSrcweir 
1773cdf0e10cSrcweir     SwTableNode *const pTblNd = aIdx.GetNode().GetTableNode();
1774cdf0e10cSrcweir     OSL_ENSURE( pTblNd, "SwUndoTblNdsChg: no TableNode" );
1775cdf0e10cSrcweir 
1776cdf0e10cSrcweir 	SwTableFmlUpdate aMsgHnt( &pTblNd->GetTable() );
1777cdf0e10cSrcweir 	aMsgHnt.eFlags = TBL_BOXPTR;
1778cdf0e10cSrcweir 	rDoc.UpdateTblFlds( &aMsgHnt );
1779cdf0e10cSrcweir 
1780cdf0e10cSrcweir     CHECK_TABLE( pTblNd->GetTable() )
1781cdf0e10cSrcweir 
1782cdf0e10cSrcweir 	_FndBox aTmpBox( 0, 0 );
1783cdf0e10cSrcweir     // ? TL_CHART2: notification or locking of controller required ?
1784cdf0e10cSrcweir 
1785cdf0e10cSrcweir     SwChartDataProvider *pPCD = rDoc.GetChartDataProvider();
1786cdf0e10cSrcweir     std::vector< SwTableBox* > aDelBoxes;
1787cdf0e10cSrcweir 	if( IsDelBox() )
1788cdf0e10cSrcweir 	{
1789cdf0e10cSrcweir 		// Trick: die fehlenden Boxen in irgendeine Line einfuegen, beim
1790cdf0e10cSrcweir 		// CreateNew werden sie korrekt verbunden.
1791cdf0e10cSrcweir 		SwTableBox* pCpyBox = pTblNd->GetTable().GetTabSortBoxes()[0];
1792cdf0e10cSrcweir 		SwTableBoxes& rLnBoxes = pCpyBox->GetUpper()->GetTabBoxes();
1793cdf0e10cSrcweir 
1794cdf0e10cSrcweir 		// die Sections wieder herstellen
1795cdf0e10cSrcweir 		for( sal_uInt16 n = Ptrs.pDelSects->Count(); n; )
1796cdf0e10cSrcweir 		{
1797cdf0e10cSrcweir 			SwUndoSaveSection* pSave = (*Ptrs.pDelSects)[ --n ];
1798cdf0e10cSrcweir 			pSave->RestoreSection( &rDoc, &aIdx, SwTableBoxStartNode );
1799cdf0e10cSrcweir 			if( pSave->GetHistory() )
1800cdf0e10cSrcweir 				pSave->GetHistory()->Rollback( &rDoc );
1801cdf0e10cSrcweir 			SwTableBox* pBox = new SwTableBox( (SwTableBoxFmt*)pCpyBox->GetFrmFmt(), aIdx,
1802cdf0e10cSrcweir 												pCpyBox->GetUpper() );
1803cdf0e10cSrcweir 			rLnBoxes.C40_INSERT( SwTableBox, pBox, rLnBoxes.Count() );
1804cdf0e10cSrcweir 		}
1805cdf0e10cSrcweir 		Ptrs.pDelSects->DeleteAndDestroy( 0, Ptrs.pDelSects->Count() );
1806cdf0e10cSrcweir 	}
1807cdf0e10cSrcweir 	else if( !aMvBoxes.empty() )
1808cdf0e10cSrcweir 	{
1809cdf0e10cSrcweir 		// dann muessen Nodes verschoben und nicht geloescht werden!
1810cdf0e10cSrcweir 		// Dafuer brauchen wir aber ein temp Array
1811cdf0e10cSrcweir 		SvULongs aTmp( 0, 5);
1812cdf0e10cSrcweir 		aTmp.Insert( Ptrs.pNewSttNds, 0 );
1813cdf0e10cSrcweir 
1814cdf0e10cSrcweir 		// von hinten anfangen
1815cdf0e10cSrcweir 		for( sal_uInt16 n = aTmp.Count(); n; )
1816cdf0e10cSrcweir 		{
1817cdf0e10cSrcweir 			// Box aus der Tabellen-Struktur entfernen
1818cdf0e10cSrcweir 			sal_uLong nIdx = aTmp[ --n ];
1819cdf0e10cSrcweir 			SwTableBox* pBox = pTblNd->GetTable().GetTblBox( nIdx );
1820cdf0e10cSrcweir 			ASSERT( pBox, "Wo ist meine TabellenBox geblieben?" );
1821cdf0e10cSrcweir 
1822cdf0e10cSrcweir 			// TL_CHART2: notify chart about box to be removed
1823cdf0e10cSrcweir             if (pPCD)
1824cdf0e10cSrcweir                 pPCD->DeleteBox( &pTblNd->GetTable(), *pBox );
1825cdf0e10cSrcweir 
1826cdf0e10cSrcweir 			if( aMvBoxes[ n ] )
1827cdf0e10cSrcweir 			{
1828cdf0e10cSrcweir 				SwNodeRange aRg( *pBox->GetSttNd(), 1,
1829cdf0e10cSrcweir 							*pBox->GetSttNd()->EndOfSectionNode() );
1830cdf0e10cSrcweir 
1831cdf0e10cSrcweir 				SwTableLine* pLine = lcl_FindTableLine( pTblNd->GetTable(), *pBox );
1832cdf0e10cSrcweir 				SwNodeIndex aInsPos( *(pLine->GetTabBoxes()[0]->GetSttNd()), 2 );
1833cdf0e10cSrcweir 
1834cdf0e10cSrcweir 				// alle StartNode Indizies anpassen
1835cdf0e10cSrcweir 				sal_uInt16 i = n;
1836cdf0e10cSrcweir 				sal_uLong nSttIdx = aInsPos.GetIndex() - 2,
1837cdf0e10cSrcweir 					   nNdCnt = aRg.aEnd.GetIndex() - aRg.aStart.GetIndex();
1838cdf0e10cSrcweir 				while( i && aTmp[ --i ] > nSttIdx )
1839cdf0e10cSrcweir 					aTmp[ i ] += nNdCnt;
1840cdf0e10cSrcweir 
1841cdf0e10cSrcweir 				// erst die Box loeschen
1842cdf0e10cSrcweir 				delete pBox;
1843cdf0e10cSrcweir 				// dann die Nodes verschieben,
1844cdf0e10cSrcweir 				rDoc.GetNodes()._MoveNodes( aRg, rDoc.GetNodes(), aInsPos, sal_False );
1845cdf0e10cSrcweir 			}
1846cdf0e10cSrcweir 			else
1847cdf0e10cSrcweir 				rDoc.DeleteSection( rDoc.GetNodes()[ nIdx ] );
1848cdf0e10cSrcweir             aDelBoxes.insert( aDelBoxes.end(), pBox );
1849cdf0e10cSrcweir 		}
1850cdf0e10cSrcweir 	}
1851cdf0e10cSrcweir 	else
1852cdf0e10cSrcweir     {
1853cdf0e10cSrcweir 		// Remove nodes from nodes array (backwards!)
1854cdf0e10cSrcweir 		for( sal_uInt16 n = Ptrs.pNewSttNds->Count(); n; )
1855cdf0e10cSrcweir 		{
1856cdf0e10cSrcweir 			sal_uLong nIdx = (*Ptrs.pNewSttNds)[ --n ];
1857cdf0e10cSrcweir 			SwTableBox* pBox = pTblNd->GetTable().GetTblBox( nIdx );
1858cdf0e10cSrcweir 			ASSERT( pBox, "Where's my table box?" );
1859cdf0e10cSrcweir 			// TL_CHART2: notify chart about box to be removed
1860cdf0e10cSrcweir             if (pPCD)
1861cdf0e10cSrcweir                 pPCD->DeleteBox( &pTblNd->GetTable(), *pBox );
1862cdf0e10cSrcweir             aDelBoxes.insert( aDelBoxes.end(), pBox );
1863cdf0e10cSrcweir 			rDoc.DeleteSection( rDoc.GetNodes()[ nIdx ] );
1864cdf0e10cSrcweir         }
1865cdf0e10cSrcweir     }
1866cdf0e10cSrcweir     // Remove boxes from table structure
1867cdf0e10cSrcweir     for( sal_uInt16 n = 0; n < aDelBoxes.size(); ++n )
1868cdf0e10cSrcweir     {
1869cdf0e10cSrcweir         SwTableBox* pCurrBox = aDelBoxes[n];
1870cdf0e10cSrcweir         SwTableBoxes* pTBoxes = &pCurrBox->GetUpper()->GetTabBoxes();
1871cdf0e10cSrcweir         pTBoxes->Remove( pTBoxes->C40_GETPOS( SwTableBox, pCurrBox ) );
1872cdf0e10cSrcweir         delete pCurrBox;
1873cdf0e10cSrcweir     }
1874cdf0e10cSrcweir 
1875cdf0e10cSrcweir 	pSaveTbl->CreateNew( pTblNd->GetTable(), sal_True, sal_False );
1876cdf0e10cSrcweir 
1877cdf0e10cSrcweir 	// TL_CHART2: need to inform chart of probably changed cell names
1878cdf0e10cSrcweir     rDoc.UpdateCharts( pTblNd->GetTable().GetFrmFmt()->GetName() );
1879cdf0e10cSrcweir 
1880cdf0e10cSrcweir 	if( IsDelBox() )
1881cdf0e10cSrcweir 		nSttNode = pTblNd->GetIndex();
1882cdf0e10cSrcweir 	ClearFEShellTabCols();
1883cdf0e10cSrcweir     CHECK_TABLE( pTblNd->GetTable() )
1884cdf0e10cSrcweir }
1885cdf0e10cSrcweir 
1886cdf0e10cSrcweir 
RedoImpl(::sw::UndoRedoContext & rContext)1887cdf0e10cSrcweir void SwUndoTblNdsChg::RedoImpl(::sw::UndoRedoContext & rContext)
1888cdf0e10cSrcweir {
1889cdf0e10cSrcweir     SwDoc & rDoc = rContext.GetDoc();
1890cdf0e10cSrcweir 
1891cdf0e10cSrcweir 	SwTableNode* pTblNd = rDoc.GetNodes()[ nSttNode ]->GetTableNode();
1892cdf0e10cSrcweir 	ASSERT( pTblNd, "kein TabellenNode" );
1893cdf0e10cSrcweir     CHECK_TABLE( pTblNd->GetTable() )
1894cdf0e10cSrcweir 
1895cdf0e10cSrcweir 	SwSelBoxes aSelBoxes;
1896cdf0e10cSrcweir 	for( sal_uInt16 n = 0; n < aBoxes.Count(); ++n )
1897cdf0e10cSrcweir 	{
1898cdf0e10cSrcweir 		SwTableBox* pBox = pTblNd->GetTable().GetTblBox( aBoxes[ n ] );
1899cdf0e10cSrcweir 		aSelBoxes.Insert( pBox );
1900cdf0e10cSrcweir 	}
1901cdf0e10cSrcweir 
1902cdf0e10cSrcweir 	// SelBoxes erzeugen und InsertCell/-Row/SplitTbl aufrufen
1903cdf0e10cSrcweir 	switch( GetId() )
1904cdf0e10cSrcweir 	{
1905cdf0e10cSrcweir 	case UNDO_TABLE_INSCOL:
1906cdf0e10cSrcweir 		if( USHRT_MAX == nSetColType )
1907cdf0e10cSrcweir 			rDoc.InsertCol( aSelBoxes, nCount, bFlag );
1908cdf0e10cSrcweir 		else
1909cdf0e10cSrcweir 		{
1910cdf0e10cSrcweir 			SwTableBox* pBox = pTblNd->GetTable().GetTblBox( nCurrBox );
1911cdf0e10cSrcweir 			rDoc.SetColRowWidthHeight( *pBox, nSetColType, nAbsDiff,
1912cdf0e10cSrcweir 										nRelDiff );
1913cdf0e10cSrcweir 		}
1914cdf0e10cSrcweir 		break;
1915cdf0e10cSrcweir 
1916cdf0e10cSrcweir 	case UNDO_TABLE_INSROW:
1917cdf0e10cSrcweir 		if( USHRT_MAX == nSetColType )
1918cdf0e10cSrcweir 			rDoc.InsertRow( aSelBoxes, nCount, bFlag );
1919cdf0e10cSrcweir 		else
1920cdf0e10cSrcweir 		{
1921cdf0e10cSrcweir 			SwTable& rTbl = pTblNd->GetTable();
1922cdf0e10cSrcweir 			SwTableBox* pBox = rTbl.GetTblBox( nCurrBox );
1923cdf0e10cSrcweir 			TblChgMode eOldMode = rTbl.GetTblChgMode();
1924cdf0e10cSrcweir 			rTbl.SetTblChgMode( (TblChgMode)nCount );
1925cdf0e10cSrcweir 			rDoc.SetColRowWidthHeight( *pBox, nSetColType, nAbsDiff, nRelDiff );
1926cdf0e10cSrcweir 			rTbl.SetTblChgMode( eOldMode );
1927cdf0e10cSrcweir 		}
1928cdf0e10cSrcweir 		break;
1929cdf0e10cSrcweir 
1930cdf0e10cSrcweir 	case UNDO_TABLE_SPLIT:
1931cdf0e10cSrcweir         rDoc.SplitTbl( aSelBoxes, bFlag, nCount, bSameHeight );
1932cdf0e10cSrcweir 		break;
1933cdf0e10cSrcweir 	case UNDO_TABLE_DELBOX:
1934cdf0e10cSrcweir     case UNDO_ROW_DELETE:
1935cdf0e10cSrcweir     case UNDO_COL_DELETE:
1936cdf0e10cSrcweir 		if( USHRT_MAX == nSetColType )
1937cdf0e10cSrcweir 		{
1938cdf0e10cSrcweir 			SwTableFmlUpdate aMsgHnt( &pTblNd->GetTable() );
1939cdf0e10cSrcweir 			aMsgHnt.eFlags = TBL_BOXPTR;
1940cdf0e10cSrcweir 			rDoc.UpdateTblFlds( &aMsgHnt );
1941cdf0e10cSrcweir             SwTable &rTable = pTblNd->GetTable();
1942cdf0e10cSrcweir             if( nMax > nMin && rTable.IsNewModel() )
1943cdf0e10cSrcweir                 rTable.PrepareDeleteCol( nMin, nMax );
1944cdf0e10cSrcweir 			rTable.DeleteSel( &rDoc, aSelBoxes, 0, this, sal_True, sal_True );
1945cdf0e10cSrcweir 		}
1946cdf0e10cSrcweir 		else
1947cdf0e10cSrcweir 		{
1948cdf0e10cSrcweir 			SwTable& rTbl = pTblNd->GetTable();
1949cdf0e10cSrcweir 
1950cdf0e10cSrcweir 			SwTableFmlUpdate aMsgHnt( &rTbl );
1951cdf0e10cSrcweir 			aMsgHnt.eFlags = TBL_BOXPTR;
1952cdf0e10cSrcweir 			rDoc.UpdateTblFlds( &aMsgHnt );
1953cdf0e10cSrcweir 
1954cdf0e10cSrcweir 			SwTableBox* pBox = rTbl.GetTblBox( nCurrBox );
1955cdf0e10cSrcweir 			TblChgMode eOldMode = rTbl.GetTblChgMode();
1956cdf0e10cSrcweir 			rTbl.SetTblChgMode( (TblChgMode)nCount );
1957cdf0e10cSrcweir 
1958cdf0e10cSrcweir             // need the SaveSections!
1959cdf0e10cSrcweir             rDoc.GetIDocumentUndoRedo().DoUndo( true );
1960cdf0e10cSrcweir 			SwUndoTblNdsChg* pUndo = 0;
1961cdf0e10cSrcweir 
1962cdf0e10cSrcweir 			switch( nSetColType & 0xff )
1963cdf0e10cSrcweir 			{
1964cdf0e10cSrcweir 			case nsTblChgWidthHeightType::WH_COL_LEFT:
1965cdf0e10cSrcweir 			case nsTblChgWidthHeightType::WH_COL_RIGHT:
1966cdf0e10cSrcweir 			case nsTblChgWidthHeightType::WH_CELL_LEFT:
1967cdf0e10cSrcweir 			case nsTblChgWidthHeightType::WH_CELL_RIGHT:
1968cdf0e10cSrcweir 				 rTbl.SetColWidth( *pBox, nSetColType, nAbsDiff,
1969cdf0e10cSrcweir 									nRelDiff, (SwUndo**)&pUndo );
1970cdf0e10cSrcweir 				break;
1971cdf0e10cSrcweir 			case nsTblChgWidthHeightType::WH_ROW_TOP:
1972cdf0e10cSrcweir 			case nsTblChgWidthHeightType::WH_ROW_BOTTOM:
1973cdf0e10cSrcweir 			case nsTblChgWidthHeightType::WH_CELL_TOP:
1974cdf0e10cSrcweir 			case nsTblChgWidthHeightType::WH_CELL_BOTTOM:
1975cdf0e10cSrcweir 				rTbl.SetRowHeight( *pBox, nSetColType, nAbsDiff,
1976cdf0e10cSrcweir 									nRelDiff, (SwUndo**)&pUndo );
1977cdf0e10cSrcweir 				break;
1978cdf0e10cSrcweir 			}
1979cdf0e10cSrcweir 
1980cdf0e10cSrcweir 			if( pUndo )
1981cdf0e10cSrcweir 			{
1982cdf0e10cSrcweir 				Ptrs.pDelSects->Insert( pUndo->Ptrs.pDelSects, 0 );
1983cdf0e10cSrcweir 				pUndo->Ptrs.pDelSects->Remove( 0, pUndo->Ptrs.pDelSects->Count() );
1984cdf0e10cSrcweir 
1985cdf0e10cSrcweir 				delete pUndo;
1986cdf0e10cSrcweir 			}
1987cdf0e10cSrcweir             rDoc.GetIDocumentUndoRedo().DoUndo( false );
1988cdf0e10cSrcweir 
1989cdf0e10cSrcweir 			rTbl.SetTblChgMode( eOldMode );
1990cdf0e10cSrcweir 		}
1991cdf0e10cSrcweir 		nSttNode = pTblNd->GetIndex();
1992cdf0e10cSrcweir 		break;
1993cdf0e10cSrcweir     default:
1994cdf0e10cSrcweir         ;
1995cdf0e10cSrcweir 	}
1996cdf0e10cSrcweir 	ClearFEShellTabCols();
1997cdf0e10cSrcweir     CHECK_TABLE( pTblNd->GetTable() )
1998cdf0e10cSrcweir }
1999cdf0e10cSrcweir 
2000cdf0e10cSrcweir 
2001cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////
2002cdf0e10cSrcweir 
SwUndoTblMerge(const SwPaM & rTblSel)2003cdf0e10cSrcweir SwUndoTblMerge::SwUndoTblMerge( const SwPaM& rTblSel )
2004cdf0e10cSrcweir 	: SwUndo( UNDO_TABLE_MERGE ), SwUndRng( rTblSel ), pHistory( 0 )
2005cdf0e10cSrcweir {
2006cdf0e10cSrcweir 	const SwTableNode* pTblNd = rTblSel.GetNode()->FindTableNode();
2007cdf0e10cSrcweir 	ASSERT( pTblNd, "Wo ist TabllenNode" )
2008cdf0e10cSrcweir 	pSaveTbl = new _SaveTable( pTblNd->GetTable() );
2009cdf0e10cSrcweir 	pMoves = new SwUndoMoves;
2010cdf0e10cSrcweir 	nTblNode = pTblNd->GetIndex();
2011cdf0e10cSrcweir }
2012cdf0e10cSrcweir 
~SwUndoTblMerge()2013cdf0e10cSrcweir SwUndoTblMerge::~SwUndoTblMerge()
2014cdf0e10cSrcweir {
2015cdf0e10cSrcweir 	delete pSaveTbl;
2016cdf0e10cSrcweir 	delete pMoves;
2017cdf0e10cSrcweir 	delete pHistory;
2018cdf0e10cSrcweir }
2019cdf0e10cSrcweir 
UndoImpl(::sw::UndoRedoContext & rContext)2020cdf0e10cSrcweir void SwUndoTblMerge::UndoImpl(::sw::UndoRedoContext & rContext)
2021cdf0e10cSrcweir {
2022cdf0e10cSrcweir     SwDoc & rDoc = rContext.GetDoc();
2023cdf0e10cSrcweir 	SwNodeIndex aIdx( rDoc.GetNodes(), nTblNode );
2024cdf0e10cSrcweir 
2025cdf0e10cSrcweir     SwTableNode *const pTblNd = aIdx.GetNode().GetTableNode();
2026cdf0e10cSrcweir     OSL_ENSURE( pTblNd, "SwUndoTblMerge: no TableNode" );
2027cdf0e10cSrcweir 
2028cdf0e10cSrcweir 	SwTableFmlUpdate aMsgHnt( &pTblNd->GetTable() );
2029cdf0e10cSrcweir 	aMsgHnt.eFlags = TBL_BOXPTR;
2030cdf0e10cSrcweir 	rDoc.UpdateTblFlds( &aMsgHnt );
2031cdf0e10cSrcweir 
2032cdf0e10cSrcweir     _FndBox aTmpBox( 0, 0 );
2033cdf0e10cSrcweir     // ? TL_CHART2: notification or locking of controller required ?
2034cdf0e10cSrcweir 
2035cdf0e10cSrcweir 
2036cdf0e10cSrcweir 	// 1. die geloeschten Boxen wiederherstellen:
2037cdf0e10cSrcweir 
2038cdf0e10cSrcweir 	// Trick: die fehlenden Boxen in irgendeine Line einfuegen, beim
2039cdf0e10cSrcweir 	// CreateNew werden sie korrekt verbunden.
2040cdf0e10cSrcweir 	SwTableBox *pBox, *pCpyBox = pTblNd->GetTable().GetTabSortBoxes()[0];
2041cdf0e10cSrcweir 	SwTableBoxes& rLnBoxes = pCpyBox->GetUpper()->GetTabBoxes();
2042cdf0e10cSrcweir 
2043cdf0e10cSrcweir DUMPDOC( &rDoc, "d:\\tmp\\tab_a.db" )
2044cdf0e10cSrcweir CHECKTABLE(pTblNd->GetTable())
2045cdf0e10cSrcweir 
2046cdf0e10cSrcweir 	SwSelBoxes aSelBoxes;
2047cdf0e10cSrcweir 	SwTxtFmtColl* pColl = rDoc.GetTxtCollFromPool( RES_POOLCOLL_STANDARD );
2048cdf0e10cSrcweir 	sal_uInt16 n;
2049cdf0e10cSrcweir 
2050cdf0e10cSrcweir 	for( n = 0; n < aBoxes.Count(); ++n )
2051cdf0e10cSrcweir 	{
2052cdf0e10cSrcweir 		aIdx = aBoxes[ n ];
2053cdf0e10cSrcweir 		SwStartNode* pSttNd = rDoc.GetNodes().MakeTextSection( aIdx,
2054cdf0e10cSrcweir 											SwTableBoxStartNode, pColl );
2055cdf0e10cSrcweir 		pBox = new SwTableBox( (SwTableBoxFmt*)pCpyBox->GetFrmFmt(), *pSttNd,
2056cdf0e10cSrcweir 								pCpyBox->GetUpper() );
2057cdf0e10cSrcweir 		rLnBoxes.C40_INSERT( SwTableBox, pBox, rLnBoxes.Count() );
2058cdf0e10cSrcweir 
2059cdf0e10cSrcweir 		aSelBoxes.Insert( pBox );
2060cdf0e10cSrcweir 	}
2061cdf0e10cSrcweir 
2062cdf0e10cSrcweir DUMPDOC( &rDoc, "d:\\tmp\\tab_b.db" )
2063cdf0e10cSrcweir CHECKTABLE(pTblNd->GetTable())
2064cdf0e10cSrcweir 
2065cdf0e10cSrcweir     SwChartDataProvider *pPCD = rDoc.GetChartDataProvider();
2066cdf0e10cSrcweir 	// 2. die eingefuegten Boxen loeschen
2067cdf0e10cSrcweir 	// die Nodes loeschen (von Hinten!!)
2068cdf0e10cSrcweir 	for( n = aNewSttNds.Count(); n; )
2069cdf0e10cSrcweir 	{
2070cdf0e10cSrcweir 		// Box aus der Tabellen-Struktur entfernen
2071cdf0e10cSrcweir 		sal_uLong nIdx = aNewSttNds[ --n ];
2072cdf0e10cSrcweir 
2073cdf0e10cSrcweir 		if( !nIdx && n )
2074cdf0e10cSrcweir 		{
2075cdf0e10cSrcweir 			nIdx = aNewSttNds[ --n ];
2076cdf0e10cSrcweir 			pBox = pTblNd->GetTable().GetTblBox( nIdx );
2077cdf0e10cSrcweir 			ASSERT( pBox, "Wo ist meine TabellenBox geblieben?" );
2078cdf0e10cSrcweir 
2079cdf0e10cSrcweir             if( !pSaveTbl->IsNewModel() )
2080cdf0e10cSrcweir                 rDoc.GetNodes().MakeTxtNode( SwNodeIndex(
2081cdf0e10cSrcweir 					*pBox->GetSttNd()->EndOfSectionNode() ), pColl );
2082cdf0e10cSrcweir 
2083cdf0e10cSrcweir 			// das war der Trenner, -> die verschobenen herstellen
2084cdf0e10cSrcweir 			for( sal_uInt16 i = pMoves->Count(); i; )
2085cdf0e10cSrcweir 			{
2086cdf0e10cSrcweir 				SwTxtNode* pTxtNd = 0;
2087cdf0e10cSrcweir 				sal_uInt16 nDelPos = 0;
2088cdf0e10cSrcweir 				SwUndoMove* pUndo = (*pMoves)[ --i ];
2089cdf0e10cSrcweir 				if( !pUndo->IsMoveRange() )
2090cdf0e10cSrcweir 				{
2091cdf0e10cSrcweir 					pTxtNd = rDoc.GetNodes()[ pUndo->GetDestSttNode() ]->GetTxtNode();
2092cdf0e10cSrcweir 					nDelPos = pUndo->GetDestSttCntnt() - 1;
2093cdf0e10cSrcweir                 }
2094cdf0e10cSrcweir                 pUndo->UndoImpl(rContext);
209569a74367SOliver-Rainer Wittmann                 if( pUndo->IsMoveRange() )
209669a74367SOliver-Rainer Wittmann                 {
209769a74367SOliver-Rainer Wittmann                     // den ueberfluessigen Node loeschen
209869a74367SOliver-Rainer Wittmann                     aIdx = pUndo->GetEndNode();
2099cdf0e10cSrcweir                     SwCntntNode *pCNd = aIdx.GetNode().GetCntntNode();
2100cdf0e10cSrcweir                     if( pCNd )
2101cdf0e10cSrcweir                     {
2102cdf0e10cSrcweir                         SwNodeIndex aTmp( aIdx, -1 );
2103cdf0e10cSrcweir                         SwCntntNode *pMove = aTmp.GetNode().GetCntntNode();
2104cdf0e10cSrcweir                         if( pMove )
2105cdf0e10cSrcweir                             pCNd->MoveTo( *pMove );
2106cdf0e10cSrcweir                     }
210769a74367SOliver-Rainer Wittmann                     rDoc.GetNodes().Delete( aIdx, 1 );
210869a74367SOliver-Rainer Wittmann                 }
210969a74367SOliver-Rainer Wittmann                 else if( pTxtNd )
211069a74367SOliver-Rainer Wittmann                 {
211169a74367SOliver-Rainer Wittmann                     // evt. noch ueberflussige Attribute loeschen
211269a74367SOliver-Rainer Wittmann                     SwIndex aTmpIdx( pTxtNd, nDelPos );
211369a74367SOliver-Rainer Wittmann                     if( pTxtNd->GetpSwpHints() && pTxtNd->GetpSwpHints()->Count() )
211469a74367SOliver-Rainer Wittmann                         pTxtNd->RstTxtAttr( aTmpIdx, pTxtNd->GetTxt().Len() - nDelPos + 1 );
211569a74367SOliver-Rainer Wittmann                     // das Trennzeichen loeschen
2116cdf0e10cSrcweir                     pTxtNd->EraseText( aTmpIdx, 1 );
2117cdf0e10cSrcweir                 }
2118cdf0e10cSrcweir DUMPDOC( &rDoc, String( "d:\\tmp\\tab_") + String( aNewSttNds.Count() - i ) +
2119cdf0e10cSrcweir 				String(".db") )
2120cdf0e10cSrcweir 			}
2121cdf0e10cSrcweir 			nIdx = pBox->GetSttIdx();
2122cdf0e10cSrcweir 		}
2123cdf0e10cSrcweir 		else
2124cdf0e10cSrcweir 			pBox = pTblNd->GetTable().GetTblBox( nIdx );
2125cdf0e10cSrcweir 
2126cdf0e10cSrcweir         if( !pSaveTbl->IsNewModel() )
2127cdf0e10cSrcweir         {
2128cdf0e10cSrcweir             // TL_CHART2: notify chart about box to be removed
2129cdf0e10cSrcweir             if (pPCD)
2130cdf0e10cSrcweir                 pPCD->DeleteBox( &pTblNd->GetTable(), *pBox );
2131cdf0e10cSrcweir 
2132cdf0e10cSrcweir             SwTableBoxes* pTBoxes = &pBox->GetUpper()->GetTabBoxes();
2133cdf0e10cSrcweir             pTBoxes->Remove( pTBoxes->C40_GETPOS( SwTableBox, pBox ) );
2134cdf0e10cSrcweir 
2135cdf0e10cSrcweir 
2136cdf0e10cSrcweir             // Indizies aus dem Bereich loeschen
2137cdf0e10cSrcweir             {
2138cdf0e10cSrcweir                 SwNodeIndex aTmpIdx( *pBox->GetSttNd() );
2139cdf0e10cSrcweir                 rDoc.CorrAbs( SwNodeIndex( aTmpIdx, 1 ),
2140cdf0e10cSrcweir                             SwNodeIndex( *aTmpIdx.GetNode().EndOfSectionNode() ),
2141cdf0e10cSrcweir                             SwPosition( aTmpIdx, SwIndex( 0, 0 )), sal_True );
2142cdf0e10cSrcweir             }
2143cdf0e10cSrcweir 
2144cdf0e10cSrcweir             delete pBox;
2145cdf0e10cSrcweir             rDoc.DeleteSection( rDoc.GetNodes()[ nIdx ] );
2146cdf0e10cSrcweir         }
2147cdf0e10cSrcweir 	}
2148cdf0e10cSrcweir DUMPDOC( &rDoc, "d:\\tmp\\tab_z.db" )
2149cdf0e10cSrcweir CHECKTABLE(pTblNd->GetTable())
2150cdf0e10cSrcweir 
2151cdf0e10cSrcweir 
2152cdf0e10cSrcweir 	pSaveTbl->CreateNew( pTblNd->GetTable(), sal_True, sal_False );
2153cdf0e10cSrcweir 
2154cdf0e10cSrcweir     // TL_CHART2: need to inform chart of probably changed cell names
2155cdf0e10cSrcweir     rDoc.UpdateCharts( pTblNd->GetTable().GetFrmFmt()->GetName() );
2156cdf0e10cSrcweir 
2157cdf0e10cSrcweir 	if( pHistory )
2158cdf0e10cSrcweir 	{
2159cdf0e10cSrcweir 		pHistory->TmpRollback( &rDoc, 0 );
2160cdf0e10cSrcweir 		pHistory->SetTmpEnd( pHistory->Count() );
2161cdf0e10cSrcweir 	}
2162cdf0e10cSrcweir //	nTblNode = pTblNd->GetIndex();
2163cdf0e10cSrcweir 
2164cdf0e10cSrcweir     SwPaM *const pPam(& rContext.GetCursorSupplier().CreateNewShellCursor());
2165cdf0e10cSrcweir 	pPam->DeleteMark();
2166cdf0e10cSrcweir 	pPam->GetPoint()->nNode = nSttNode;
2167cdf0e10cSrcweir 	pPam->GetPoint()->nContent.Assign( pPam->GetCntntNode(), nSttCntnt );
2168cdf0e10cSrcweir 	pPam->SetMark();
2169cdf0e10cSrcweir 	pPam->DeleteMark();
2170cdf0e10cSrcweir 
2171cdf0e10cSrcweir CHECKTABLE(pTblNd->GetTable())
2172cdf0e10cSrcweir 	ClearFEShellTabCols();
2173cdf0e10cSrcweir }
2174cdf0e10cSrcweir 
RedoImpl(::sw::UndoRedoContext & rContext)2175cdf0e10cSrcweir void SwUndoTblMerge::RedoImpl(::sw::UndoRedoContext & rContext)
2176cdf0e10cSrcweir {
2177cdf0e10cSrcweir     SwDoc & rDoc = rContext.GetDoc();
2178cdf0e10cSrcweir     SwPaM & rPam( AddUndoRedoPaM(rContext) );
2179cdf0e10cSrcweir     rDoc.MergeTbl(rPam);
2180cdf0e10cSrcweir }
2181cdf0e10cSrcweir 
MoveBoxCntnt(SwDoc * pDoc,SwNodeRange & rRg,SwNodeIndex & rPos)2182cdf0e10cSrcweir void SwUndoTblMerge::MoveBoxCntnt( SwDoc* pDoc, SwNodeRange& rRg, SwNodeIndex& rPos )
2183cdf0e10cSrcweir {
2184cdf0e10cSrcweir 	SwNodeIndex aTmp( rRg.aStart, -1 ), aTmp2( rPos, -1 );
2185cdf0e10cSrcweir 	SwUndoMove* pUndo = new SwUndoMove( pDoc, rRg, rPos );
2186cdf0e10cSrcweir     ::sw::UndoGuard const undoGuard(pDoc->GetIDocumentUndoRedo());
2187cdf0e10cSrcweir     pDoc->MoveNodeRange( rRg, rPos, (pSaveTbl->IsNewModel()) ?
2188cdf0e10cSrcweir         IDocumentContentOperations::DOC_NO_DELFRMS :
2189cdf0e10cSrcweir         IDocumentContentOperations::DOC_MOVEDEFAULT );
2190cdf0e10cSrcweir 	aTmp++;
2191cdf0e10cSrcweir 	aTmp2++;
2192cdf0e10cSrcweir 	pUndo->SetDestRange( aTmp2, rPos, aTmp );
2193cdf0e10cSrcweir 
2194cdf0e10cSrcweir 	pMoves->Insert( pUndo, pMoves->Count() );
2195cdf0e10cSrcweir }
2196cdf0e10cSrcweir 
SetSelBoxes(const SwSelBoxes & rBoxes)2197cdf0e10cSrcweir void SwUndoTblMerge::SetSelBoxes( const SwSelBoxes& rBoxes )
2198cdf0e10cSrcweir {
2199cdf0e10cSrcweir 	// die Selektion merken
2200cdf0e10cSrcweir 	for( sal_uInt16 n = 0; n < rBoxes.Count(); ++n )
2201cdf0e10cSrcweir 		InsertSort( aBoxes, rBoxes[n]->GetSttIdx() );
2202cdf0e10cSrcweir 
2203cdf0e10cSrcweir 	// als Trennung fuers einfuegen neuer Boxen nach dem Verschieben!
2204cdf0e10cSrcweir 	aNewSttNds.Insert( (sal_uLong)0, aNewSttNds.Count() );
2205cdf0e10cSrcweir 
2206cdf0e10cSrcweir      // The new table model does not delete overlapped cells (by row span),
2207cdf0e10cSrcweir      // so the rBoxes array might be empty even some cells have been merged.
2208cdf0e10cSrcweir     if( rBoxes.Count() )
2209cdf0e10cSrcweir         nTblNode = rBoxes[ 0 ]->GetSttNd()->FindTableNode()->GetIndex();
2210cdf0e10cSrcweir }
2211cdf0e10cSrcweir 
SaveCollection(const SwTableBox & rBox)2212cdf0e10cSrcweir void SwUndoTblMerge::SaveCollection( const SwTableBox& rBox )
2213cdf0e10cSrcweir {
2214cdf0e10cSrcweir 	if( !pHistory )
2215cdf0e10cSrcweir 		pHistory = new SwHistory;
2216cdf0e10cSrcweir 
2217cdf0e10cSrcweir 	SwNodeIndex aIdx( *rBox.GetSttNd(), 1 );
2218cdf0e10cSrcweir 	SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode();
2219cdf0e10cSrcweir 	if( !pCNd )
2220cdf0e10cSrcweir 		pCNd = aIdx.GetNodes().GoNext( &aIdx );
2221cdf0e10cSrcweir 
2222cdf0e10cSrcweir 	pHistory->Add( pCNd->GetFmtColl(), aIdx.GetIndex(), pCNd->GetNodeType());
2223cdf0e10cSrcweir     if( pCNd->HasSwAttrSet() )
2224cdf0e10cSrcweir         pHistory->CopyFmtAttr( *pCNd->GetpSwAttrSet(), aIdx.GetIndex() );
2225cdf0e10cSrcweir }
2226cdf0e10cSrcweir 
2227cdf0e10cSrcweir 
2228cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////
2229cdf0e10cSrcweir 
SwUndoTblNumFmt(const SwTableBox & rBox,const SfxItemSet * pNewSet)2230cdf0e10cSrcweir SwUndoTblNumFmt::SwUndoTblNumFmt( const SwTableBox& rBox,
2231cdf0e10cSrcweir 									const SfxItemSet* pNewSet )
2232cdf0e10cSrcweir 	: SwUndo( UNDO_TBLNUMFMT ),
2233cdf0e10cSrcweir 	pBoxSet( 0 ), pHistory( 0 ), nFmtIdx( NUMBERFORMAT_TEXT )
2234cdf0e10cSrcweir {
2235cdf0e10cSrcweir 	bNewFmt = bNewFml = bNewValue = sal_False;
2236cdf0e10cSrcweir 	nNode = rBox.GetSttIdx();
2237cdf0e10cSrcweir 
2238cdf0e10cSrcweir 	nNdPos = rBox.IsValidNumTxtNd( 0 == pNewSet );
2239cdf0e10cSrcweir     SwDoc* pDoc = rBox.GetFrmFmt()->GetDoc();
2240cdf0e10cSrcweir 
2241cdf0e10cSrcweir 	if( ULONG_MAX != nNdPos )
2242cdf0e10cSrcweir 	{
2243cdf0e10cSrcweir 		SwTxtNode* pTNd = pDoc->GetNodes()[ nNdPos ]->GetTxtNode();
2244cdf0e10cSrcweir 
2245cdf0e10cSrcweir 		pHistory = new SwHistory;
2246cdf0e10cSrcweir 		SwRegHistory aRHst( *rBox.GetSttNd(), pHistory );
2247cdf0e10cSrcweir         // always save all text atttibutes because of possibly overlapping
2248cdf0e10cSrcweir         // areas of on/off
2249cdf0e10cSrcweir         pHistory->CopyAttr( pTNd->GetpSwpHints(), nNdPos, 0,
2250cdf0e10cSrcweir                             pTNd->GetTxt().Len(), true );
2251cdf0e10cSrcweir 
2252cdf0e10cSrcweir         if( pTNd->HasSwAttrSet() )
2253cdf0e10cSrcweir             pHistory->CopyFmtAttr( *pTNd->GetpSwAttrSet(), nNdPos );
2254cdf0e10cSrcweir 
2255cdf0e10cSrcweir 		aStr = pTNd->GetTxt();
2256cdf0e10cSrcweir 		if( pTNd->GetpSwpHints() )
2257cdf0e10cSrcweir 			pTNd->GetpSwpHints()->DeRegister();
2258cdf0e10cSrcweir     }
2259cdf0e10cSrcweir 
2260cdf0e10cSrcweir     pBoxSet = new SfxItemSet( pDoc->GetAttrPool(), aTableBoxSetRange );
2261cdf0e10cSrcweir     pBoxSet->Put( rBox.GetFrmFmt()->GetAttrSet() );
2262cdf0e10cSrcweir 
2263cdf0e10cSrcweir     if( pNewSet )
2264cdf0e10cSrcweir     {
2265cdf0e10cSrcweir         const SfxPoolItem* pItem;
2266cdf0e10cSrcweir         if( SFX_ITEM_SET == pNewSet->GetItemState( RES_BOXATR_FORMAT,
2267cdf0e10cSrcweir                 sal_False, &pItem ))
2268cdf0e10cSrcweir         {
2269cdf0e10cSrcweir             bNewFmt = sal_True;
2270cdf0e10cSrcweir             nNewFmtIdx = ((SwTblBoxNumFormat*)pItem)->GetValue();
2271cdf0e10cSrcweir         }
2272cdf0e10cSrcweir         if( SFX_ITEM_SET == pNewSet->GetItemState( RES_BOXATR_FORMULA,
2273cdf0e10cSrcweir                 sal_False, &pItem ))
2274cdf0e10cSrcweir         {
2275cdf0e10cSrcweir             bNewFml = sal_True;
2276cdf0e10cSrcweir             aNewFml = ((SwTblBoxFormula*)pItem)->GetFormula();
2277cdf0e10cSrcweir         }
2278cdf0e10cSrcweir         if( SFX_ITEM_SET == pNewSet->GetItemState( RES_BOXATR_VALUE,
2279cdf0e10cSrcweir                 sal_False, &pItem ))
2280cdf0e10cSrcweir         {
2281cdf0e10cSrcweir             bNewValue = sal_True;
2282cdf0e10cSrcweir             fNewNum = ((SwTblBoxValue*)pItem)->GetValue();
2283cdf0e10cSrcweir         }
2284cdf0e10cSrcweir 	}
2285cdf0e10cSrcweir 
2286cdf0e10cSrcweir 	// wird die History ueberhaupt benoetigt ??
2287cdf0e10cSrcweir 	if( pHistory && !pHistory->Count() )
2288cdf0e10cSrcweir 		DELETEZ( pHistory );
2289cdf0e10cSrcweir }
2290cdf0e10cSrcweir 
~SwUndoTblNumFmt()2291cdf0e10cSrcweir SwUndoTblNumFmt::~SwUndoTblNumFmt()
2292cdf0e10cSrcweir {
2293cdf0e10cSrcweir 	delete pHistory;
2294cdf0e10cSrcweir 	delete pBoxSet;
2295cdf0e10cSrcweir }
2296cdf0e10cSrcweir 
UndoImpl(::sw::UndoRedoContext & rContext)2297cdf0e10cSrcweir void SwUndoTblNumFmt::UndoImpl(::sw::UndoRedoContext & rContext)
2298cdf0e10cSrcweir {
2299cdf0e10cSrcweir 	ASSERT( pBoxSet, "Where's the stored item set?" )
2300cdf0e10cSrcweir 
2301cdf0e10cSrcweir     SwDoc & rDoc = rContext.GetDoc();
2302cdf0e10cSrcweir 	SwStartNode* pSttNd = rDoc.GetNodes()[ nNode ]->
2303cdf0e10cSrcweir 							FindSttNodeByType( SwTableBoxStartNode );
2304cdf0e10cSrcweir 	ASSERT( pSttNd, "ohne StartNode kein TabellenBox" );
2305cdf0e10cSrcweir 	SwTableBox* pBox = pSttNd->FindTableNode()->GetTable().GetTblBox(
2306cdf0e10cSrcweir 									pSttNd->GetIndex() );
2307cdf0e10cSrcweir 	ASSERT( pBox, "keine TabellenBox gefunden" );
2308cdf0e10cSrcweir 
2309cdf0e10cSrcweir 	SwTableBoxFmt* pFmt = rDoc.MakeTableBoxFmt();
2310cdf0e10cSrcweir     pFmt->SetFmtAttr( *pBoxSet );
2311cdf0e10cSrcweir 	pBox->ChgFrmFmt( pFmt );
2312cdf0e10cSrcweir 
2313cdf0e10cSrcweir     if( ULONG_MAX == nNdPos )
2314cdf0e10cSrcweir         return;
2315cdf0e10cSrcweir 
2316cdf0e10cSrcweir 	SwTxtNode* pTxtNd = rDoc.GetNodes()[ nNdPos ]->GetTxtNode();
2317cdf0e10cSrcweir 	// wenn mehr als ein Node geloescht wurde, dann wurden auch
2318cdf0e10cSrcweir 	// alle "Node"-Attribute gespeichert
2319cdf0e10cSrcweir     if( pTxtNd->HasSwAttrSet() )
2320cdf0e10cSrcweir 		pTxtNd->ResetAllAttr();
2321cdf0e10cSrcweir 
2322cdf0e10cSrcweir 	if( pTxtNd->GetpSwpHints() && aStr.Len() )
2323cdf0e10cSrcweir         pTxtNd->ClearSwpHintsArr( true );
2324cdf0e10cSrcweir 
2325cdf0e10cSrcweir     // ChgTextToNum(..) only acts when the strings are different. We
2326cdf0e10cSrcweir     // need to do the same here.
2327cdf0e10cSrcweir     if( pTxtNd->GetTxt() != aStr )
2328cdf0e10cSrcweir     {
2329cdf0e10cSrcweir         rDoc.DeleteRedline( *( pBox->GetSttNd() ), false, USHRT_MAX );
2330cdf0e10cSrcweir 
2331cdf0e10cSrcweir         SwIndex aIdx( pTxtNd, 0 );
2332cdf0e10cSrcweir         if( aStr.Len() )
2333cdf0e10cSrcweir         {
2334cdf0e10cSrcweir             pTxtNd->EraseText( aIdx );
2335cdf0e10cSrcweir             pTxtNd->InsertText( aStr, aIdx,
2336cdf0e10cSrcweir                 IDocumentContentOperations::INS_NOHINTEXPAND );
2337cdf0e10cSrcweir         }
2338cdf0e10cSrcweir     }
2339cdf0e10cSrcweir 
2340cdf0e10cSrcweir 	if( pHistory )
2341cdf0e10cSrcweir 	{
2342cdf0e10cSrcweir 		sal_uInt16 nTmpEnd = pHistory->GetTmpEnd();
2343cdf0e10cSrcweir 		pHistory->TmpRollback( &rDoc, 0 );
2344cdf0e10cSrcweir 		pHistory->SetTmpEnd( nTmpEnd );
2345cdf0e10cSrcweir 	}
2346cdf0e10cSrcweir 
2347cdf0e10cSrcweir     SwPaM *const pPam(& rContext.GetCursorSupplier().CreateNewShellCursor());
2348cdf0e10cSrcweir 	pPam->DeleteMark();
2349cdf0e10cSrcweir 	pPam->GetPoint()->nNode = nNode + 1;
2350cdf0e10cSrcweir 	pPam->GetPoint()->nContent.Assign( pTxtNd, 0 );
2351cdf0e10cSrcweir }
2352cdf0e10cSrcweir 
2353cdf0e10cSrcweir /** switch the RedlineMode on the given document, using
2354cdf0e10cSrcweir  * SetRedlineMode_intern. This class set the mode in the constructor,
2355cdf0e10cSrcweir  * and changes it back in the destructor, i.e. it uses the
2356cdf0e10cSrcweir  * initialization-is-resource-acquisition idiom.
2357cdf0e10cSrcweir  */
2358cdf0e10cSrcweir class RedlineModeInternGuard
2359cdf0e10cSrcweir {
2360cdf0e10cSrcweir     SwDoc& mrDoc;
2361cdf0e10cSrcweir     RedlineMode_t meOldRedlineMode;
2362cdf0e10cSrcweir 
2363cdf0e10cSrcweir public:
2364cdf0e10cSrcweir     RedlineModeInternGuard(
2365cdf0e10cSrcweir         SwDoc& rDoc,                      /// change mode of this document
2366cdf0e10cSrcweir         RedlineMode_t eNewRedlineMode,    /// new redline mode
2367cdf0e10cSrcweir         RedlineMode_t eRedlineModeMask  = (RedlineMode_t)(nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_IGNORE /*change only bits set in this mask*/));
2368cdf0e10cSrcweir 
2369cdf0e10cSrcweir     ~RedlineModeInternGuard();
2370cdf0e10cSrcweir };
2371cdf0e10cSrcweir 
RedlineModeInternGuard(SwDoc & rDoc,RedlineMode_t eNewRedlineMode,RedlineMode_t eRedlineModeMask)2372cdf0e10cSrcweir RedlineModeInternGuard::RedlineModeInternGuard(
2373cdf0e10cSrcweir     SwDoc& rDoc,
2374cdf0e10cSrcweir     RedlineMode_t eNewRedlineMode,
2375cdf0e10cSrcweir     RedlineMode_t eRedlineModeMask )
2376cdf0e10cSrcweir     : mrDoc( rDoc ),
2377cdf0e10cSrcweir       meOldRedlineMode( rDoc.GetRedlineMode() )
2378cdf0e10cSrcweir {
2379cdf0e10cSrcweir     mrDoc.SetRedlineMode_intern((RedlineMode_t)( ( meOldRedlineMode & ~eRedlineModeMask ) |
2380cdf0e10cSrcweir 									 ( eNewRedlineMode & eRedlineModeMask ) ));
2381cdf0e10cSrcweir }
2382cdf0e10cSrcweir 
~RedlineModeInternGuard()2383cdf0e10cSrcweir RedlineModeInternGuard::~RedlineModeInternGuard()
2384cdf0e10cSrcweir {
2385cdf0e10cSrcweir     mrDoc.SetRedlineMode_intern( meOldRedlineMode );
2386cdf0e10cSrcweir }
2387cdf0e10cSrcweir 
2388cdf0e10cSrcweir 
2389cdf0e10cSrcweir 
RedoImpl(::sw::UndoRedoContext & rContext)2390cdf0e10cSrcweir void SwUndoTblNumFmt::RedoImpl(::sw::UndoRedoContext & rContext)
2391cdf0e10cSrcweir {
2392cdf0e10cSrcweir 	// konnte die Box veraendert werden ?
2393cdf0e10cSrcweir 	if( !pBoxSet )
2394cdf0e10cSrcweir 		return ;
2395cdf0e10cSrcweir 
2396cdf0e10cSrcweir     SwDoc & rDoc = rContext.GetDoc();
2397cdf0e10cSrcweir     SwPaM *const pPam(& rContext.GetCursorSupplier().CreateNewShellCursor());
2398cdf0e10cSrcweir 
2399cdf0e10cSrcweir 	pPam->DeleteMark();
2400cdf0e10cSrcweir 	pPam->GetPoint()->nNode = nNode;
2401cdf0e10cSrcweir 
2402cdf0e10cSrcweir     SwNode * pNd = & pPam->GetPoint()->nNode.GetNode();
2403cdf0e10cSrcweir 	SwStartNode* pSttNd = pNd->FindSttNodeByType( SwTableBoxStartNode );
2404cdf0e10cSrcweir 	ASSERT( pSttNd, "ohne StartNode kein TabellenBox" );
2405cdf0e10cSrcweir 	SwTableBox* pBox = pSttNd->FindTableNode()->GetTable().GetTblBox(
2406cdf0e10cSrcweir 									pSttNd->GetIndex() );
2407cdf0e10cSrcweir 	ASSERT( pBox, "keine TabellenBox gefunden" );
2408cdf0e10cSrcweir 
2409cdf0e10cSrcweir 	SwFrmFmt* pBoxFmt = pBox->ClaimFrmFmt();
2410cdf0e10cSrcweir 	if(	bNewFmt || bNewFml || bNewValue )
2411cdf0e10cSrcweir 	{
2412cdf0e10cSrcweir 		SfxItemSet aBoxSet( rDoc.GetAttrPool(),
2413cdf0e10cSrcweir 								RES_BOXATR_FORMAT, RES_BOXATR_VALUE );
2414cdf0e10cSrcweir 
2415cdf0e10cSrcweir 		// JP 15.01.99: Nur Attribute zuruecksetzen reicht nicht.
2416cdf0e10cSrcweir 		//				Sorge dafuer, das der Text auch entsprechend
2417cdf0e10cSrcweir 		//				formatiert wird!
2418cdf0e10cSrcweir 		pBoxFmt->LockModify();
2419cdf0e10cSrcweir 
2420cdf0e10cSrcweir 		if( bNewFml )
2421cdf0e10cSrcweir 			aBoxSet.Put( SwTblBoxFormula( aNewFml ));
2422cdf0e10cSrcweir 		else
2423cdf0e10cSrcweir             pBoxFmt->ResetFmtAttr( RES_BOXATR_FORMULA );
2424cdf0e10cSrcweir 		if( bNewFmt )
2425cdf0e10cSrcweir 			aBoxSet.Put( SwTblBoxNumFormat( nNewFmtIdx ));
2426cdf0e10cSrcweir 		else
2427cdf0e10cSrcweir             pBoxFmt->ResetFmtAttr( RES_BOXATR_FORMAT );
2428cdf0e10cSrcweir 		if( bNewValue )
2429cdf0e10cSrcweir 			aBoxSet.Put( SwTblBoxValue( fNewNum ));
2430cdf0e10cSrcweir 		else
2431cdf0e10cSrcweir             pBoxFmt->ResetFmtAttr( RES_BOXATR_VALUE );
2432cdf0e10cSrcweir 		pBoxFmt->UnlockModify();
2433cdf0e10cSrcweir 
2434cdf0e10cSrcweir         // dvo: When redlining is (was) enabled, setting the attribute
2435cdf0e10cSrcweir         // will also change the cell content. To allow this, the
2436cdf0e10cSrcweir         // REDLINE_IGNORE flag must be removed during Redo. #108450#
2437cdf0e10cSrcweir         RedlineModeInternGuard aGuard( rDoc, nsRedlineMode_t::REDLINE_NONE, nsRedlineMode_t::REDLINE_IGNORE );
2438cdf0e10cSrcweir         pBoxFmt->SetFmtAttr( aBoxSet );
2439cdf0e10cSrcweir 	}
2440cdf0e10cSrcweir 	else if( NUMBERFORMAT_TEXT != nFmtIdx )
2441cdf0e10cSrcweir 	{
2442cdf0e10cSrcweir 		SfxItemSet aBoxSet( rDoc.GetAttrPool(),
2443cdf0e10cSrcweir 							RES_BOXATR_FORMAT, RES_BOXATR_VALUE );
2444cdf0e10cSrcweir 
2445cdf0e10cSrcweir 		aBoxSet.Put( SwTblBoxNumFormat( nFmtIdx ));
2446cdf0e10cSrcweir 		aBoxSet.Put( SwTblBoxValue( fNum ));
2447cdf0e10cSrcweir 
2448cdf0e10cSrcweir 		// JP 15.01.99: Nur Attribute zuruecksetzen reicht nicht.
2449cdf0e10cSrcweir 		//				Sorge dafuer, das der Text auch entsprechend
2450cdf0e10cSrcweir 		//				formatiert wird!
2451cdf0e10cSrcweir 		pBoxFmt->LockModify();
2452cdf0e10cSrcweir         pBoxFmt->ResetFmtAttr( RES_BOXATR_FORMULA );
2453cdf0e10cSrcweir 		pBoxFmt->UnlockModify();
2454cdf0e10cSrcweir 
2455cdf0e10cSrcweir         // dvo: When redlining is (was) enabled, setting the attribute
2456cdf0e10cSrcweir         // will also change the cell content. To allow this, the
2457cdf0e10cSrcweir         // REDLINE_IGNORE flag must be removed during Redo. #108450#
2458cdf0e10cSrcweir         RedlineModeInternGuard aGuard( rDoc, nsRedlineMode_t::REDLINE_NONE, nsRedlineMode_t::REDLINE_IGNORE );
2459cdf0e10cSrcweir         pBoxFmt->SetFmtAttr( aBoxSet );
2460cdf0e10cSrcweir 	}
2461cdf0e10cSrcweir 	else
2462cdf0e10cSrcweir 	{
2463cdf0e10cSrcweir 		// es ist keine Zahl
2464cdf0e10cSrcweir 
2465cdf0e10cSrcweir 		// JP 15.01.99: Nur Attribute zuruecksetzen reicht nicht.
2466cdf0e10cSrcweir 		//				Sorge dafuer, das der Text auch entsprechend
2467cdf0e10cSrcweir 		//				formatiert wird!
2468cdf0e10cSrcweir         pBoxFmt->SetFmtAttr( *GetDfltAttr( RES_BOXATR_FORMAT ));
2469cdf0e10cSrcweir 
2470cdf0e10cSrcweir         pBoxFmt->ResetFmtAttr( RES_BOXATR_FORMAT, RES_BOXATR_VALUE );
2471cdf0e10cSrcweir 	}
2472cdf0e10cSrcweir 
2473cdf0e10cSrcweir 	if( bNewFml )
2474cdf0e10cSrcweir 	{
2475cdf0e10cSrcweir 		// egal was gesetzt wurde, ein Update der Tabelle macht sich immer gut
2476cdf0e10cSrcweir 		SwTableFmlUpdate aTblUpdate( &pSttNd->FindTableNode()->GetTable() );
2477cdf0e10cSrcweir 		rDoc.UpdateTblFlds( &aTblUpdate );
2478cdf0e10cSrcweir 	}
2479cdf0e10cSrcweir 
2480cdf0e10cSrcweir 	if( !pNd->IsCntntNode() )
2481cdf0e10cSrcweir 		pNd = rDoc.GetNodes().GoNext( &pPam->GetPoint()->nNode );
2482cdf0e10cSrcweir 	pPam->GetPoint()->nContent.Assign( (SwCntntNode*)pNd, 0 );
2483cdf0e10cSrcweir }
2484cdf0e10cSrcweir 
SetBox(const SwTableBox & rBox)2485cdf0e10cSrcweir void SwUndoTblNumFmt::SetBox( const SwTableBox& rBox )
2486cdf0e10cSrcweir {
2487cdf0e10cSrcweir 	nNode = rBox.GetSttIdx();
2488cdf0e10cSrcweir }
2489cdf0e10cSrcweir 
2490cdf0e10cSrcweir 
2491cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////
2492cdf0e10cSrcweir 
_UndoTblCpyTbl_Entry(const SwTableBox & rBox)2493cdf0e10cSrcweir _UndoTblCpyTbl_Entry::_UndoTblCpyTbl_Entry( const SwTableBox& rBox )
2494cdf0e10cSrcweir 	: nBoxIdx( rBox.GetSttIdx() ), nOffset( 0 ),
2495cdf0e10cSrcweir 	pBoxNumAttr( 0 ), pUndo( 0 ), bJoin( false )
2496cdf0e10cSrcweir {
2497cdf0e10cSrcweir }
2498cdf0e10cSrcweir 
~_UndoTblCpyTbl_Entry()2499cdf0e10cSrcweir _UndoTblCpyTbl_Entry::~_UndoTblCpyTbl_Entry()
2500cdf0e10cSrcweir {
2501cdf0e10cSrcweir 	delete pUndo;
2502cdf0e10cSrcweir 	delete pBoxNumAttr;
2503cdf0e10cSrcweir }
2504cdf0e10cSrcweir 
2505cdf0e10cSrcweir 
SwUndoTblCpyTbl()2506cdf0e10cSrcweir SwUndoTblCpyTbl::SwUndoTblCpyTbl()
2507cdf0e10cSrcweir 	: SwUndo( UNDO_TBLCPYTBL ), pInsRowUndo( 0 )
2508cdf0e10cSrcweir {
2509cdf0e10cSrcweir 	pArr = new _UndoTblCpyTbl_Entries;
2510cdf0e10cSrcweir }
2511cdf0e10cSrcweir 
~SwUndoTblCpyTbl()2512cdf0e10cSrcweir SwUndoTblCpyTbl::~SwUndoTblCpyTbl()
2513cdf0e10cSrcweir {
2514cdf0e10cSrcweir 	delete pArr;
2515cdf0e10cSrcweir 	delete pInsRowUndo;
2516cdf0e10cSrcweir }
2517cdf0e10cSrcweir 
UndoImpl(::sw::UndoRedoContext & rContext)2518cdf0e10cSrcweir void SwUndoTblCpyTbl::UndoImpl(::sw::UndoRedoContext & rContext)
2519cdf0e10cSrcweir {
2520cdf0e10cSrcweir     SwDoc & rDoc = rContext.GetDoc();
2521cdf0e10cSrcweir     _DEBUG_REDLINE( &rDoc )
2522cdf0e10cSrcweir 
2523cdf0e10cSrcweir 	SwTableNode* pTblNd = 0;
2524cdf0e10cSrcweir 	for( sal_uInt16 n = pArr->Count(); n; )
2525cdf0e10cSrcweir 	{
2526cdf0e10cSrcweir 		_UndoTblCpyTbl_Entry* pEntry = (*pArr)[ --n ];
2527cdf0e10cSrcweir 		sal_uLong nSttPos = pEntry->nBoxIdx + pEntry->nOffset;
2528cdf0e10cSrcweir         SwStartNode* pSNd = rDoc.GetNodes()[ nSttPos ]->StartOfSectionNode();
2529cdf0e10cSrcweir 		if( !pTblNd )
2530cdf0e10cSrcweir 			pTblNd = pSNd->FindTableNode();
2531cdf0e10cSrcweir 
2532cdf0e10cSrcweir 		SwTableBox& rBox = *pTblNd->GetTable().GetTblBox( nSttPos );
2533cdf0e10cSrcweir 
2534cdf0e10cSrcweir 		SwNodeIndex aInsIdx( *rBox.GetSttNd(), 1 );
2535cdf0e10cSrcweir 		rDoc.GetNodes().MakeTxtNode( aInsIdx, (SwTxtFmtColl*)rDoc.GetDfltTxtFmtColl() );
2536cdf0e10cSrcweir 
2537cdf0e10cSrcweir         // b62341295: Redline for copying tables
2538cdf0e10cSrcweir         const SwNode *pEndNode = rBox.GetSttNd()->EndOfSectionNode();
2539cdf0e10cSrcweir 		SwPaM aPam( aInsIdx.GetNode(), *pEndNode );
2540cdf0e10cSrcweir         SwUndoDelete* pUndo = 0;
2541cdf0e10cSrcweir 
2542cdf0e10cSrcweir         if( IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ) )
2543cdf0e10cSrcweir         {
2544cdf0e10cSrcweir             bool bDeleteCompleteParagraph = false;
2545cdf0e10cSrcweir             bool bShiftPam = false;
2546cdf0e10cSrcweir             // There are a couple of different situations to consider during redlining
2547cdf0e10cSrcweir             if( pEntry->pUndo )
2548cdf0e10cSrcweir             {
2549cdf0e10cSrcweir                 SwUndoDelete *const pUndoDelete =
2550cdf0e10cSrcweir                     dynamic_cast<SwUndoDelete*>(pEntry->pUndo);
2551cdf0e10cSrcweir                 SwUndoRedlineDelete *const pUndoRedlineDelete =
2552cdf0e10cSrcweir                     dynamic_cast<SwUndoRedlineDelete*>(pEntry->pUndo);
2553cdf0e10cSrcweir                 OSL_ASSERT(pUndoDelete || pUndoRedlineDelete);
2554cdf0e10cSrcweir                 if (pUndoRedlineDelete)
2555cdf0e10cSrcweir                 {
2556cdf0e10cSrcweir                     // The old content was not empty or he has been merged with the new content
2557cdf0e10cSrcweir                     bDeleteCompleteParagraph = !pEntry->bJoin; // bJoin is set when merged
2558cdf0e10cSrcweir                     // Set aTmpIdx to the beginning fo the old content
2559cdf0e10cSrcweir                     SwNodeIndex aTmpIdx( *pEndNode,
2560cdf0e10cSrcweir                             pUndoRedlineDelete->NodeDiff()-1 );
2561cdf0e10cSrcweir                     SwTxtNode *pTxt = aTmpIdx.GetNode().GetTxtNode();
2562cdf0e10cSrcweir                     if( pTxt )
2563cdf0e10cSrcweir                     {
2564cdf0e10cSrcweir                         aPam.GetPoint()->nNode = *pTxt;
2565cdf0e10cSrcweir                         aPam.GetPoint()->nContent.Assign( pTxt,
2566cdf0e10cSrcweir                                 pUndoRedlineDelete->ContentStart() );
2567cdf0e10cSrcweir                     }
2568cdf0e10cSrcweir                     else
2569cdf0e10cSrcweir                         *aPam.GetPoint() = SwPosition( aTmpIdx );
2570cdf0e10cSrcweir                 }
2571cdf0e10cSrcweir                 else if (pUndoDelete && pUndoDelete->IsDelFullPara())
2572cdf0e10cSrcweir                 {
2573cdf0e10cSrcweir                     // When the old content was an empty paragraph, but could not be joined
2574cdf0e10cSrcweir                     // with the new content (e.g. because of a section or table)
2575cdf0e10cSrcweir                     // We "save" the aPam.Point, we go one step backwards (because later on the
2576cdf0e10cSrcweir                     // empty paragraph will be inserted by the undo) and set the "ShiftPam-flag
2577cdf0e10cSrcweir                     // for step forward later on.
2578cdf0e10cSrcweir                     bDeleteCompleteParagraph = true;
2579cdf0e10cSrcweir                     bShiftPam = true;
2580cdf0e10cSrcweir                     SwNodeIndex aTmpIdx( *pEndNode, -1 );
2581cdf0e10cSrcweir                     SwTxtNode *pTxt = aTmpIdx.GetNode().GetTxtNode();
2582cdf0e10cSrcweir                     if( pTxt )
2583cdf0e10cSrcweir                     {
2584cdf0e10cSrcweir                         aPam.GetPoint()->nNode = *pTxt;
2585cdf0e10cSrcweir                         aPam.GetPoint()->nContent.Assign( pTxt, 0 );
2586cdf0e10cSrcweir                     }
2587cdf0e10cSrcweir                     else
2588cdf0e10cSrcweir                         *aPam.GetPoint() = SwPosition( aTmpIdx );
2589cdf0e10cSrcweir                 }
2590cdf0e10cSrcweir             }
2591cdf0e10cSrcweir             rDoc.DeleteRedline( aPam, true, USHRT_MAX );
2592cdf0e10cSrcweir 
2593cdf0e10cSrcweir             if( pEntry->pUndo )
2594cdf0e10cSrcweir             {
2595cdf0e10cSrcweir                 pEntry->pUndo->UndoImpl(rContext);
2596cdf0e10cSrcweir                 delete pEntry->pUndo;
2597cdf0e10cSrcweir                 pEntry->pUndo = 0;
2598cdf0e10cSrcweir             }
2599cdf0e10cSrcweir             if( bShiftPam )
2600cdf0e10cSrcweir             {
2601cdf0e10cSrcweir                 // The aPam.Point is at the moment at the last position of the new content and has to be
2602*300d4866SJohn Bampton                 // moved to the first position of the old content for the SwUndoDelete operation
2603cdf0e10cSrcweir                 SwNodeIndex aTmpIdx( aPam.GetPoint()->nNode, 1 );
2604cdf0e10cSrcweir                 SwTxtNode *pTxt = aTmpIdx.GetNode().GetTxtNode();
2605cdf0e10cSrcweir                 if( pTxt )
2606cdf0e10cSrcweir                 {
2607cdf0e10cSrcweir                     aPam.GetPoint()->nNode = *pTxt;
2608cdf0e10cSrcweir                     aPam.GetPoint()->nContent.Assign( pTxt, 0 );
2609cdf0e10cSrcweir                 }
2610cdf0e10cSrcweir                 else
2611cdf0e10cSrcweir                     *aPam.GetPoint() = SwPosition( aTmpIdx );
2612cdf0e10cSrcweir             }
2613cdf0e10cSrcweir             pUndo = new SwUndoDelete( aPam, bDeleteCompleteParagraph, sal_True );
2614cdf0e10cSrcweir         }
2615cdf0e10cSrcweir         else
2616cdf0e10cSrcweir         {
2617cdf0e10cSrcweir             pUndo = new SwUndoDelete( aPam, true );
2618cdf0e10cSrcweir             if( pEntry->pUndo )
2619cdf0e10cSrcweir             {
2620cdf0e10cSrcweir                 pEntry->pUndo->UndoImpl(rContext);
2621cdf0e10cSrcweir                 delete pEntry->pUndo;
2622cdf0e10cSrcweir                 pEntry->pUndo = 0;
2623cdf0e10cSrcweir             }
2624cdf0e10cSrcweir         }
2625cdf0e10cSrcweir 		pEntry->pUndo = pUndo;
2626cdf0e10cSrcweir 
2627cdf0e10cSrcweir 		aInsIdx = rBox.GetSttIdx() + 1;
2628cdf0e10cSrcweir 		rDoc.GetNodes().Delete( aInsIdx, 1 );
2629cdf0e10cSrcweir 
2630cdf0e10cSrcweir 		SfxItemSet aTmpSet( rDoc.GetAttrPool(), RES_BOXATR_FORMAT, RES_BOXATR_VALUE,
2631cdf0e10cSrcweir 												RES_VERT_ORIENT, RES_VERT_ORIENT, 0 );
2632cdf0e10cSrcweir 		aTmpSet.Put( rBox.GetFrmFmt()->GetAttrSet() );
2633cdf0e10cSrcweir 		if( aTmpSet.Count() )
2634cdf0e10cSrcweir 		{
2635cdf0e10cSrcweir 			SwFrmFmt* pBoxFmt = rBox.ClaimFrmFmt();
2636cdf0e10cSrcweir             pBoxFmt->ResetFmtAttr( RES_BOXATR_FORMAT, RES_BOXATR_VALUE );
2637cdf0e10cSrcweir             pBoxFmt->ResetFmtAttr( RES_VERT_ORIENT );
2638cdf0e10cSrcweir 		}
2639cdf0e10cSrcweir 
2640cdf0e10cSrcweir 		if( pEntry->pBoxNumAttr )
2641cdf0e10cSrcweir 		{
2642cdf0e10cSrcweir             rBox.ClaimFrmFmt()->SetFmtAttr( *pEntry->pBoxNumAttr );
2643cdf0e10cSrcweir 			delete pEntry->pBoxNumAttr, pEntry->pBoxNumAttr = 0;
2644cdf0e10cSrcweir 		}
2645cdf0e10cSrcweir 
2646cdf0e10cSrcweir 		if( aTmpSet.Count() )
2647cdf0e10cSrcweir 		{
2648cdf0e10cSrcweir 			pEntry->pBoxNumAttr = new SfxItemSet( rDoc.GetAttrPool(),
2649cdf0e10cSrcweir 									RES_BOXATR_FORMAT, RES_BOXATR_VALUE,
2650cdf0e10cSrcweir 									RES_VERT_ORIENT, RES_VERT_ORIENT, 0 );
2651cdf0e10cSrcweir 			pEntry->pBoxNumAttr->Put( aTmpSet );
2652cdf0e10cSrcweir 		}
2653cdf0e10cSrcweir 
2654cdf0e10cSrcweir 		pEntry->nOffset = rBox.GetSttIdx() - pEntry->nBoxIdx;
2655cdf0e10cSrcweir 	}
2656cdf0e10cSrcweir 
2657cdf0e10cSrcweir 	if( pInsRowUndo )
2658cdf0e10cSrcweir     {
2659cdf0e10cSrcweir         pInsRowUndo->UndoImpl(rContext);
2660cdf0e10cSrcweir     }
2661cdf0e10cSrcweir     _DEBUG_REDLINE( &rDoc )
2662cdf0e10cSrcweir }
2663cdf0e10cSrcweir 
RedoImpl(::sw::UndoRedoContext & rContext)2664cdf0e10cSrcweir void SwUndoTblCpyTbl::RedoImpl(::sw::UndoRedoContext & rContext)
2665cdf0e10cSrcweir {
2666cdf0e10cSrcweir     SwDoc & rDoc = rContext.GetDoc();
2667cdf0e10cSrcweir     _DEBUG_REDLINE( &rDoc )
2668cdf0e10cSrcweir 
2669cdf0e10cSrcweir 	if( pInsRowUndo )
2670cdf0e10cSrcweir     {
2671cdf0e10cSrcweir         pInsRowUndo->RedoImpl(rContext);
2672cdf0e10cSrcweir     }
2673cdf0e10cSrcweir 
2674cdf0e10cSrcweir 	SwTableNode* pTblNd = 0;
2675cdf0e10cSrcweir 	for( sal_uInt16 n = 0; n < pArr->Count(); ++n )
2676cdf0e10cSrcweir 	{
2677cdf0e10cSrcweir 		_UndoTblCpyTbl_Entry* pEntry = (*pArr)[ n ];
2678cdf0e10cSrcweir 		sal_uLong nSttPos = pEntry->nBoxIdx + pEntry->nOffset;
2679cdf0e10cSrcweir         SwStartNode* pSNd = rDoc.GetNodes()[ nSttPos ]->StartOfSectionNode();
2680cdf0e10cSrcweir 		if( !pTblNd )
2681cdf0e10cSrcweir 			pTblNd = pSNd->FindTableNode();
2682cdf0e10cSrcweir 
2683cdf0e10cSrcweir 		SwTableBox& rBox = *pTblNd->GetTable().GetTblBox( nSttPos );
2684cdf0e10cSrcweir 
2685cdf0e10cSrcweir 		SwNodeIndex aInsIdx( *rBox.GetSttNd(), 1 );
2686cdf0e10cSrcweir 
2687cdf0e10cSrcweir         // b62341295: Redline for copying tables - Start.
2688cdf0e10cSrcweir 		rDoc.GetNodes().MakeTxtNode( aInsIdx, (SwTxtFmtColl*)rDoc.GetDfltTxtFmtColl() );
2689cdf0e10cSrcweir 		SwPaM aPam( aInsIdx.GetNode(), *rBox.GetSttNd()->EndOfSectionNode());
2690cdf0e10cSrcweir         SwUndo* pUndo = IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ) ? 0 : new SwUndoDelete( aPam, sal_True );
2691cdf0e10cSrcweir 		if( pEntry->pUndo )
2692cdf0e10cSrcweir         {
2693cdf0e10cSrcweir             pEntry->pUndo->UndoImpl(rContext);
2694cdf0e10cSrcweir             if( IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ) )
2695cdf0e10cSrcweir             {
2696cdf0e10cSrcweir                 // PrepareRedline has to be called with the beginning of the old content
2697cdf0e10cSrcweir                 // When new and old content has been joined, the rIter.pAktPam has been set
2698cdf0e10cSrcweir                 // by the Undo operation to this point.
2699cdf0e10cSrcweir                 // Otherwise aInsIdx has been moved during the Undo operation
2700cdf0e10cSrcweir                 if( pEntry->bJoin )
2701cdf0e10cSrcweir                 {
2702cdf0e10cSrcweir                     SwPaM const& rLastPam =
2703cdf0e10cSrcweir                         rContext.GetCursorSupplier().GetCurrentShellCursor();
2704cdf0e10cSrcweir                     pUndo = PrepareRedline( &rDoc, rBox, *rLastPam.GetPoint(),
2705cdf0e10cSrcweir                                             pEntry->bJoin, true );
2706cdf0e10cSrcweir                 }
2707cdf0e10cSrcweir                 else
2708cdf0e10cSrcweir                 {
2709cdf0e10cSrcweir                     SwPosition aTmpPos( aInsIdx );
2710cdf0e10cSrcweir                     pUndo = PrepareRedline( &rDoc, rBox, aTmpPos, pEntry->bJoin, true );
2711cdf0e10cSrcweir                 }
2712cdf0e10cSrcweir             }
2713cdf0e10cSrcweir 			delete pEntry->pUndo;
2714cdf0e10cSrcweir             pEntry->pUndo = 0;
2715cdf0e10cSrcweir 		}
2716cdf0e10cSrcweir 		pEntry->pUndo = pUndo;
2717cdf0e10cSrcweir         // b62341295: Redline for copying tables - End.
2718cdf0e10cSrcweir 
2719cdf0e10cSrcweir 		aInsIdx = rBox.GetSttIdx() + 1;
2720cdf0e10cSrcweir 		rDoc.GetNodes().Delete( aInsIdx, 1 );
2721cdf0e10cSrcweir 
2722cdf0e10cSrcweir 		SfxItemSet aTmpSet( rDoc.GetAttrPool(), RES_BOXATR_FORMAT, RES_BOXATR_VALUE,
2723cdf0e10cSrcweir 												RES_VERT_ORIENT, RES_VERT_ORIENT, 0 );
2724cdf0e10cSrcweir 		aTmpSet.Put( rBox.GetFrmFmt()->GetAttrSet() );
2725cdf0e10cSrcweir 		if( aTmpSet.Count() )
2726cdf0e10cSrcweir 		{
2727cdf0e10cSrcweir 			SwFrmFmt* pBoxFmt = rBox.ClaimFrmFmt();
2728cdf0e10cSrcweir             pBoxFmt->ResetFmtAttr( RES_BOXATR_FORMAT, RES_BOXATR_VALUE );
2729cdf0e10cSrcweir             pBoxFmt->ResetFmtAttr( RES_VERT_ORIENT );
2730cdf0e10cSrcweir 		}
2731cdf0e10cSrcweir 		if( pEntry->pBoxNumAttr )
2732cdf0e10cSrcweir 		{
2733cdf0e10cSrcweir             rBox.ClaimFrmFmt()->SetFmtAttr( *pEntry->pBoxNumAttr );
2734cdf0e10cSrcweir 			delete pEntry->pBoxNumAttr, pEntry->pBoxNumAttr = 0;
2735cdf0e10cSrcweir 		}
2736cdf0e10cSrcweir 
2737cdf0e10cSrcweir 		if( aTmpSet.Count() )
2738cdf0e10cSrcweir 		{
2739cdf0e10cSrcweir 			pEntry->pBoxNumAttr = new SfxItemSet( rDoc.GetAttrPool(),
2740cdf0e10cSrcweir 									RES_BOXATR_FORMAT, RES_BOXATR_VALUE,
2741cdf0e10cSrcweir 									RES_VERT_ORIENT, RES_VERT_ORIENT, 0 );
2742cdf0e10cSrcweir 			pEntry->pBoxNumAttr->Put( aTmpSet );
2743cdf0e10cSrcweir 		}
2744cdf0e10cSrcweir 
2745cdf0e10cSrcweir 		pEntry->nOffset = rBox.GetSttIdx() - pEntry->nBoxIdx;
2746cdf0e10cSrcweir 	}
2747cdf0e10cSrcweir     _DEBUG_REDLINE( &rDoc )
2748cdf0e10cSrcweir }
2749cdf0e10cSrcweir 
AddBoxBefore(const SwTableBox & rBox,sal_Bool bDelCntnt)2750cdf0e10cSrcweir void SwUndoTblCpyTbl::AddBoxBefore( const SwTableBox& rBox, sal_Bool bDelCntnt )
2751cdf0e10cSrcweir {
2752cdf0e10cSrcweir     if( pArr->Count() && !bDelCntnt )
2753cdf0e10cSrcweir 		return;
2754cdf0e10cSrcweir 
2755cdf0e10cSrcweir 	_UndoTblCpyTbl_Entry* pEntry = new _UndoTblCpyTbl_Entry( rBox );
2756cdf0e10cSrcweir 	pArr->Insert( pEntry, pArr->Count() );
2757cdf0e10cSrcweir 
2758cdf0e10cSrcweir 	SwDoc* pDoc = rBox.GetFrmFmt()->GetDoc();
2759cdf0e10cSrcweir     _DEBUG_REDLINE( pDoc )
2760cdf0e10cSrcweir 	if( bDelCntnt )
2761cdf0e10cSrcweir 	{
2762cdf0e10cSrcweir 		SwNodeIndex aInsIdx( *rBox.GetSttNd(), 1 );
2763cdf0e10cSrcweir 		pDoc->GetNodes().MakeTxtNode( aInsIdx, (SwTxtFmtColl*)pDoc->GetDfltTxtFmtColl() );
2764cdf0e10cSrcweir 		SwPaM aPam( aInsIdx.GetNode(), *rBox.GetSttNd()->EndOfSectionNode() );
2765cdf0e10cSrcweir 
2766cdf0e10cSrcweir         if( !pDoc->IsRedlineOn() )
2767cdf0e10cSrcweir             pEntry->pUndo = new SwUndoDelete( aPam, sal_True );
2768cdf0e10cSrcweir 	}
2769cdf0e10cSrcweir 
2770cdf0e10cSrcweir 	pEntry->pBoxNumAttr = new SfxItemSet( pDoc->GetAttrPool(),
2771cdf0e10cSrcweir 									RES_BOXATR_FORMAT, RES_BOXATR_VALUE,
2772cdf0e10cSrcweir 									RES_VERT_ORIENT, RES_VERT_ORIENT, 0 );
2773cdf0e10cSrcweir 	pEntry->pBoxNumAttr->Put( rBox.GetFrmFmt()->GetAttrSet() );
2774cdf0e10cSrcweir 	if( !pEntry->pBoxNumAttr->Count() )
2775cdf0e10cSrcweir 		delete pEntry->pBoxNumAttr, pEntry->pBoxNumAttr = 0;
2776cdf0e10cSrcweir     _DEBUG_REDLINE( pDoc )
2777cdf0e10cSrcweir }
2778cdf0e10cSrcweir 
AddBoxAfter(const SwTableBox & rBox,const SwNodeIndex & rIdx,sal_Bool bDelCntnt)2779cdf0e10cSrcweir void SwUndoTblCpyTbl::AddBoxAfter( const SwTableBox& rBox, const SwNodeIndex& rIdx, sal_Bool bDelCntnt )
2780cdf0e10cSrcweir {
2781cdf0e10cSrcweir 	_UndoTblCpyTbl_Entry* pEntry = (*pArr)[ pArr->Count() - 1 ];
2782cdf0e10cSrcweir 
2783cdf0e10cSrcweir 	// wurde der Inhalt geloescht, so loesche jetzt auch noch den temp.
2784cdf0e10cSrcweir 	// erzeugten Node
2785cdf0e10cSrcweir 	if( bDelCntnt )
2786cdf0e10cSrcweir 	{
2787cdf0e10cSrcweir         SwDoc* pDoc = rBox.GetFrmFmt()->GetDoc();
2788cdf0e10cSrcweir         _DEBUG_REDLINE( pDoc )
2789cdf0e10cSrcweir 
2790cdf0e10cSrcweir         if( pDoc->IsRedlineOn() )
2791cdf0e10cSrcweir         {
2792cdf0e10cSrcweir             SwPosition aTmpPos( rIdx );
2793cdf0e10cSrcweir             pEntry->pUndo = PrepareRedline( pDoc, rBox, aTmpPos, pEntry->bJoin, false );
2794cdf0e10cSrcweir         }
2795cdf0e10cSrcweir 		SwNodeIndex aDelIdx( *rBox.GetSttNd(), 1 );
2796cdf0e10cSrcweir 		rBox.GetFrmFmt()->GetDoc()->GetNodes().Delete( aDelIdx, 1 );
2797cdf0e10cSrcweir         _DEBUG_REDLINE( pDoc )
2798cdf0e10cSrcweir     }
2799cdf0e10cSrcweir 
2800cdf0e10cSrcweir 	pEntry->nOffset = rBox.GetSttIdx() - pEntry->nBoxIdx;
2801cdf0e10cSrcweir }
2802cdf0e10cSrcweir 
2803cdf0e10cSrcweir // PrepareRedline is called from AddBoxAfter() and from Redo() in slightly different situations.
2804cdf0e10cSrcweir // bRedo is set by calling from Redo()
2805cdf0e10cSrcweir // rJoin is false by calling from AddBoxAfter() and will be set if the old and new content has
2806cdf0e10cSrcweir // been merged.
2807cdf0e10cSrcweir // rJoin is true if Redo() is calling and the content has already been merged
2808cdf0e10cSrcweir 
PrepareRedline(SwDoc * pDoc,const SwTableBox & rBox,const SwPosition & rPos,bool & rJoin,bool bRedo)2809cdf0e10cSrcweir SwUndo* SwUndoTblCpyTbl::PrepareRedline( SwDoc* pDoc, const SwTableBox& rBox,
2810cdf0e10cSrcweir     const SwPosition& rPos, bool& rJoin, bool bRedo )
2811cdf0e10cSrcweir {
2812cdf0e10cSrcweir     SwUndo *pUndo = 0;
2813cdf0e10cSrcweir     // b62341295: Redline for copying tables
2814cdf0e10cSrcweir     // What's to do?
2815cdf0e10cSrcweir     // Mark the cell content before rIdx as insertion,
2816cdf0e10cSrcweir     // mark the cell content behind rIdx as deletion
2817cdf0e10cSrcweir     // merge text nodes at rIdx if possible
2818cdf0e10cSrcweir     RedlineMode_t eOld = pDoc->GetRedlineMode();
2819cdf0e10cSrcweir     pDoc->SetRedlineMode_intern((RedlineMode_t)( ( eOld | nsRedlineMode_t::REDLINE_DONTCOMBINE_REDLINES ) &
2820cdf0e10cSrcweir 									 ~nsRedlineMode_t::REDLINE_IGNORE ));
2821cdf0e10cSrcweir     SwPosition aInsertEnd( rPos );
2822cdf0e10cSrcweir     SwTxtNode* pTxt;
2823cdf0e10cSrcweir     if( !rJoin )
2824cdf0e10cSrcweir     {
2825cdf0e10cSrcweir         // If the content is not merged, the end of the insertion is at the end of the node
2826cdf0e10cSrcweir         // _before_ the given position rPos
2827cdf0e10cSrcweir         --aInsertEnd.nNode;
2828cdf0e10cSrcweir         pTxt = aInsertEnd.nNode.GetNode().GetTxtNode();
2829cdf0e10cSrcweir         if( pTxt )
2830cdf0e10cSrcweir         {
2831cdf0e10cSrcweir             aInsertEnd.nContent.Assign( pTxt, pTxt->GetTxt().Len() );
2832cdf0e10cSrcweir             if( !bRedo && rPos.nNode.GetNode().GetTxtNode() )
2833cdf0e10cSrcweir             {   // Try to merge, if not called by Redo()
2834cdf0e10cSrcweir                 rJoin = true;
2835cdf0e10cSrcweir                 pTxt->JoinNext();
2836cdf0e10cSrcweir             }
2837cdf0e10cSrcweir         }
2838cdf0e10cSrcweir         else
2839cdf0e10cSrcweir             aInsertEnd.nContent = SwIndex( 0 );
2840cdf0e10cSrcweir     }
2841cdf0e10cSrcweir     // For joined (merged) contents the start of deletionm and end of insertion are identical
2842cdf0e10cSrcweir     // otherwise adjacent nodes.
2843cdf0e10cSrcweir     SwPosition aDeleteStart( rJoin ? aInsertEnd : rPos );
2844cdf0e10cSrcweir     if( !rJoin )
2845cdf0e10cSrcweir     {
2846cdf0e10cSrcweir         pTxt = aDeleteStart.nNode.GetNode().GetTxtNode();
2847cdf0e10cSrcweir         if( pTxt )
2848cdf0e10cSrcweir             aDeleteStart.nContent.Assign( pTxt, 0 );
2849cdf0e10cSrcweir     }
2850cdf0e10cSrcweir     SwPosition aCellEnd( SwNodeIndex( *rBox.GetSttNd()->EndOfSectionNode(), -1 ) );
2851cdf0e10cSrcweir     pTxt = aCellEnd.nNode.GetNode().GetTxtNode();
2852cdf0e10cSrcweir     if( pTxt )
2853cdf0e10cSrcweir         aCellEnd.nContent.Assign( pTxt, pTxt->GetTxt().Len() );
2854cdf0e10cSrcweir     if( aDeleteStart != aCellEnd )
2855cdf0e10cSrcweir     {   // If the old (deleted) part is not empty, here we are...
2856cdf0e10cSrcweir         SwPaM aDeletePam( aDeleteStart, aCellEnd );
2857cdf0e10cSrcweir         pUndo = new SwUndoRedlineDelete( aDeletePam, UNDO_DELETE );
2858cdf0e10cSrcweir         pDoc->AppendRedline( new SwRedline( nsRedlineType_t::REDLINE_DELETE, aDeletePam ), true );
2859cdf0e10cSrcweir     }
2860cdf0e10cSrcweir     else if( !rJoin ) // If the old part is empty and joined, we are finished
2861cdf0e10cSrcweir     {   // if it is not joined, we have to delete this empty paragraph
2862cdf0e10cSrcweir         aCellEnd = SwPosition(
2863cdf0e10cSrcweir             SwNodeIndex( *rBox.GetSttNd()->EndOfSectionNode() ));
2864cdf0e10cSrcweir         SwPaM aTmpPam( aDeleteStart, aCellEnd );
2865cdf0e10cSrcweir         pUndo = new SwUndoDelete( aTmpPam, sal_True );
2866cdf0e10cSrcweir     }
2867cdf0e10cSrcweir     SwPosition aCellStart( SwNodeIndex( *rBox.GetSttNd(), 2 ) );
2868cdf0e10cSrcweir     pTxt = aCellStart.nNode.GetNode().GetTxtNode();
2869cdf0e10cSrcweir     if( pTxt )
2870cdf0e10cSrcweir         aCellStart.nContent.Assign( pTxt, 0 );
2871cdf0e10cSrcweir     if( aCellStart != aInsertEnd ) // An empty insertion will not been marked
2872cdf0e10cSrcweir     {
2873cdf0e10cSrcweir         SwPaM aTmpPam( aCellStart, aInsertEnd );
2874cdf0e10cSrcweir         pDoc->AppendRedline( new SwRedline( nsRedlineType_t::REDLINE_INSERT, aTmpPam ), true );
2875cdf0e10cSrcweir     }
2876cdf0e10cSrcweir 
2877cdf0e10cSrcweir     pDoc->SetRedlineMode_intern( eOld );
2878cdf0e10cSrcweir     return pUndo;
2879cdf0e10cSrcweir }
2880cdf0e10cSrcweir 
2881cdf0e10cSrcweir 
InsertRow(SwTable & rTbl,const SwSelBoxes & rBoxes,sal_uInt16 nCnt)2882cdf0e10cSrcweir sal_Bool SwUndoTblCpyTbl::InsertRow( SwTable& rTbl, const SwSelBoxes& rBoxes,
2883cdf0e10cSrcweir 								sal_uInt16 nCnt )
2884cdf0e10cSrcweir {
2885cdf0e10cSrcweir 	SwTableNode* pTblNd = (SwTableNode*)rTbl.GetTabSortBoxes()[0]->
2886cdf0e10cSrcweir 								GetSttNd()->FindTableNode();
2887cdf0e10cSrcweir 
2888cdf0e10cSrcweir 	SwTableSortBoxes aTmpLst( 0, 5 );
2889cdf0e10cSrcweir 	pInsRowUndo = new SwUndoTblNdsChg( UNDO_TABLE_INSROW, rBoxes, *pTblNd,
2890cdf0e10cSrcweir 									   0, 0, nCnt, sal_True, sal_False );
2891cdf0e10cSrcweir 	aTmpLst.Insert( &rTbl.GetTabSortBoxes(), 0, rTbl.GetTabSortBoxes().Count() );
2892cdf0e10cSrcweir 
2893cdf0e10cSrcweir 	sal_Bool bRet = rTbl.InsertRow( rTbl.GetFrmFmt()->GetDoc(), rBoxes, nCnt, sal_True );
2894cdf0e10cSrcweir 	if( bRet )
2895cdf0e10cSrcweir 		pInsRowUndo->SaveNewBoxes( *pTblNd, aTmpLst );
2896cdf0e10cSrcweir 	else
2897cdf0e10cSrcweir 		delete pInsRowUndo, pInsRowUndo = 0;
2898cdf0e10cSrcweir 	return bRet;
2899cdf0e10cSrcweir }
2900cdf0e10cSrcweir 
IsEmpty() const2901cdf0e10cSrcweir sal_Bool SwUndoTblCpyTbl::IsEmpty() const
2902cdf0e10cSrcweir {
2903cdf0e10cSrcweir 	return !pInsRowUndo && !pArr->Count();
2904cdf0e10cSrcweir }
2905cdf0e10cSrcweir 
2906cdf0e10cSrcweir 
2907cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////
2908cdf0e10cSrcweir 
SwUndoCpyTbl()2909cdf0e10cSrcweir SwUndoCpyTbl::SwUndoCpyTbl()
2910cdf0e10cSrcweir 	: SwUndo( UNDO_CPYTBL ), pDel( 0 ), nTblNode( 0 )
2911cdf0e10cSrcweir {
2912cdf0e10cSrcweir }
2913cdf0e10cSrcweir 
~SwUndoCpyTbl()2914cdf0e10cSrcweir SwUndoCpyTbl::~SwUndoCpyTbl()
2915cdf0e10cSrcweir {
2916cdf0e10cSrcweir 	delete pDel;
2917cdf0e10cSrcweir }
2918cdf0e10cSrcweir 
UndoImpl(::sw::UndoRedoContext & rContext)2919cdf0e10cSrcweir void SwUndoCpyTbl::UndoImpl(::sw::UndoRedoContext & rContext)
2920cdf0e10cSrcweir {
2921cdf0e10cSrcweir     SwDoc & rDoc = rContext.GetDoc();
2922cdf0e10cSrcweir 	SwTableNode* pTNd = rDoc.GetNodes()[ nTblNode ]->GetTableNode();
2923cdf0e10cSrcweir 
2924cdf0e10cSrcweir 	// harte SeitenUmbrueche am nachfolgenden Node verschieben
2925cdf0e10cSrcweir 	SwCntntNode* pNextNd = rDoc.GetNodes()[ pTNd->EndOfSectionIndex()+1 ]->GetCntntNode();
2926cdf0e10cSrcweir 	if( pNextNd )
2927cdf0e10cSrcweir 	{
2928cdf0e10cSrcweir 		SwFrmFmt* pTableFmt = pTNd->GetTable().GetFrmFmt();
2929cdf0e10cSrcweir 		const SfxPoolItem *pItem;
2930cdf0e10cSrcweir 
2931cdf0e10cSrcweir 		if( SFX_ITEM_SET == pTableFmt->GetItemState( RES_PAGEDESC,
2932cdf0e10cSrcweir 			sal_False, &pItem ) )
2933cdf0e10cSrcweir 			pNextNd->SetAttr( *pItem );
2934cdf0e10cSrcweir 
2935cdf0e10cSrcweir 		if( SFX_ITEM_SET == pTableFmt->GetItemState( RES_BREAK,
2936cdf0e10cSrcweir 			sal_False, &pItem ) )
2937cdf0e10cSrcweir 			pNextNd->SetAttr( *pItem );
2938cdf0e10cSrcweir 	}
2939cdf0e10cSrcweir 
2940cdf0e10cSrcweir 	SwPaM aPam( *pTNd, *pTNd->EndOfSectionNode(), 0 , 1 );
2941cdf0e10cSrcweir 	pDel = new SwUndoDelete( aPam, sal_True );
2942cdf0e10cSrcweir }
2943cdf0e10cSrcweir 
RedoImpl(::sw::UndoRedoContext & rContext)2944cdf0e10cSrcweir void SwUndoCpyTbl::RedoImpl(::sw::UndoRedoContext & rContext)
2945cdf0e10cSrcweir {
2946cdf0e10cSrcweir     pDel->UndoImpl(rContext);
2947cdf0e10cSrcweir 	delete pDel, pDel = 0;
2948cdf0e10cSrcweir }
2949cdf0e10cSrcweir 
2950cdf0e10cSrcweir 
2951cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////
2952cdf0e10cSrcweir 
SwUndoSplitTbl(const SwTableNode & rTblNd,SwSaveRowSpan * pRowSp,sal_uInt16 eMode,sal_Bool bNewSize)2953cdf0e10cSrcweir SwUndoSplitTbl::SwUndoSplitTbl( const SwTableNode& rTblNd,
2954cdf0e10cSrcweir     SwSaveRowSpan* pRowSp, sal_uInt16 eMode, sal_Bool bNewSize )
2955cdf0e10cSrcweir 	: SwUndo( UNDO_SPLIT_TABLE ),
2956cdf0e10cSrcweir     nTblNode( rTblNd.GetIndex() ), nOffset( 0 ), mpSaveRowSpan( pRowSp ), pSavTbl( 0 ),
2957cdf0e10cSrcweir 	pHistory( 0 ), nMode( eMode ), nFmlEnd( 0 ), bCalcNewSize( bNewSize )
2958cdf0e10cSrcweir {
2959cdf0e10cSrcweir 	switch( nMode )
2960cdf0e10cSrcweir 	{
2961cdf0e10cSrcweir 	case HEADLINE_BOXATRCOLLCOPY:
2962cdf0e10cSrcweir 			pHistory = new SwHistory;
2963cdf0e10cSrcweir 			// kein break;
2964cdf0e10cSrcweir 	case HEADLINE_BORDERCOPY:
2965cdf0e10cSrcweir 	case HEADLINE_BOXATTRCOPY:
2966cdf0e10cSrcweir 		pSavTbl = new _SaveTable( rTblNd.GetTable(), 1, sal_False );
2967cdf0e10cSrcweir 		break;
2968cdf0e10cSrcweir 	}
2969cdf0e10cSrcweir }
2970cdf0e10cSrcweir 
~SwUndoSplitTbl()2971cdf0e10cSrcweir SwUndoSplitTbl::~SwUndoSplitTbl()
2972cdf0e10cSrcweir {
2973cdf0e10cSrcweir 	delete pSavTbl;
2974cdf0e10cSrcweir 	delete pHistory;
2975cdf0e10cSrcweir     delete mpSaveRowSpan;
2976cdf0e10cSrcweir }
2977cdf0e10cSrcweir 
UndoImpl(::sw::UndoRedoContext & rContext)2978cdf0e10cSrcweir void SwUndoSplitTbl::UndoImpl(::sw::UndoRedoContext & rContext)
2979cdf0e10cSrcweir {
2980cdf0e10cSrcweir     SwDoc *const pDoc = & rContext.GetDoc();
2981cdf0e10cSrcweir     SwPaM *const pPam(& rContext.GetCursorSupplier().CreateNewShellCursor());
2982cdf0e10cSrcweir 
2983cdf0e10cSrcweir 	pPam->DeleteMark();
2984cdf0e10cSrcweir 	SwNodeIndex& rIdx = pPam->GetPoint()->nNode;
2985cdf0e10cSrcweir 	rIdx = nTblNode + nOffset;
2986cdf0e10cSrcweir 
2987cdf0e10cSrcweir 	//Den implizit erzeugten Absatz wieder entfernen.
2988cdf0e10cSrcweir 	pDoc->GetNodes().Delete( rIdx, 1 );
2989cdf0e10cSrcweir 
2990cdf0e10cSrcweir 	rIdx = nTblNode + nOffset;
2991cdf0e10cSrcweir 	SwTableNode* pTblNd = rIdx.GetNode().GetTableNode();
2992cdf0e10cSrcweir 	SwTable& rTbl = pTblNd->GetTable();
2993cdf0e10cSrcweir 
2994cdf0e10cSrcweir 	SwTableFmlUpdate aMsgHnt( &rTbl );
2995cdf0e10cSrcweir 	aMsgHnt.eFlags = TBL_BOXPTR;
2996cdf0e10cSrcweir 	pDoc->UpdateTblFlds( &aMsgHnt );
2997cdf0e10cSrcweir 
2998cdf0e10cSrcweir 	switch( nMode )
2999cdf0e10cSrcweir 	{
3000cdf0e10cSrcweir 	case HEADLINE_BOXATRCOLLCOPY:
3001cdf0e10cSrcweir 		if( pHistory )
3002cdf0e10cSrcweir 			pHistory->TmpRollback( pDoc, nFmlEnd );
3003cdf0e10cSrcweir 
3004cdf0e10cSrcweir 		// kein break
3005cdf0e10cSrcweir 	case HEADLINE_BOXATTRCOPY:
3006cdf0e10cSrcweir 	case HEADLINE_BORDERCOPY:
3007cdf0e10cSrcweir 		{
3008cdf0e10cSrcweir 			pSavTbl->CreateNew( rTbl, sal_False );
3009cdf0e10cSrcweir 			pSavTbl->RestoreAttr( rTbl );
3010cdf0e10cSrcweir 		}
3011cdf0e10cSrcweir 		break;
3012cdf0e10cSrcweir 
3013cdf0e10cSrcweir 	case HEADLINE_CNTNTCOPY:
3014cdf0e10cSrcweir 		// die erzeugte 1. Line muss wieder entfernt werden
3015cdf0e10cSrcweir 		{
3016cdf0e10cSrcweir 			SwSelBoxes aSelBoxes;
3017cdf0e10cSrcweir 			SwTableBox* pBox = rTbl.GetTblBox( nTblNode + nOffset + 1 );
3018cdf0e10cSrcweir 			rTbl.SelLineFromBox( pBox, aSelBoxes, sal_True );
3019cdf0e10cSrcweir             _FndBox aTmpBox( 0, 0 );
3020cdf0e10cSrcweir             aTmpBox.SetTableLines( aSelBoxes, rTbl );
3021cdf0e10cSrcweir             aTmpBox.DelFrms( rTbl );
3022cdf0e10cSrcweir 			rTbl.DeleteSel( pDoc, aSelBoxes, 0, 0, sal_False, sal_False );
3023cdf0e10cSrcweir 		}
3024cdf0e10cSrcweir 		break;
3025cdf0e10cSrcweir 	}
3026cdf0e10cSrcweir 
3027cdf0e10cSrcweir 	pDoc->GetNodes().MergeTable( rIdx );
3028cdf0e10cSrcweir 
3029cdf0e10cSrcweir 	if( pHistory )
3030cdf0e10cSrcweir 	{
3031cdf0e10cSrcweir 		pHistory->TmpRollback( pDoc, 0 );
3032cdf0e10cSrcweir 		pHistory->SetTmpEnd( pHistory->Count() );
3033cdf0e10cSrcweir 	}
3034cdf0e10cSrcweir     if( mpSaveRowSpan )
3035cdf0e10cSrcweir     {
3036cdf0e10cSrcweir         pTblNd = rIdx.GetNode().FindTableNode();
3037cdf0e10cSrcweir         if( pTblNd )
3038cdf0e10cSrcweir             pTblNd->GetTable().RestoreRowSpan( *mpSaveRowSpan );
3039cdf0e10cSrcweir     }
3040cdf0e10cSrcweir 	ClearFEShellTabCols();
3041cdf0e10cSrcweir }
3042cdf0e10cSrcweir 
RedoImpl(::sw::UndoRedoContext & rContext)3043cdf0e10cSrcweir void SwUndoSplitTbl::RedoImpl(::sw::UndoRedoContext & rContext)
3044cdf0e10cSrcweir {
3045cdf0e10cSrcweir     SwDoc *const pDoc = & rContext.GetDoc();
3046cdf0e10cSrcweir     SwPaM *const pPam(& rContext.GetCursorSupplier().CreateNewShellCursor());
3047cdf0e10cSrcweir 
3048cdf0e10cSrcweir 	pPam->DeleteMark();
3049cdf0e10cSrcweir 	pPam->GetPoint()->nNode = nTblNode;
3050cdf0e10cSrcweir 	pDoc->SplitTable( *pPam->GetPoint(), nMode, bCalcNewSize );
3051cdf0e10cSrcweir 
3052cdf0e10cSrcweir 	ClearFEShellTabCols();
3053cdf0e10cSrcweir }
3054cdf0e10cSrcweir 
RepeatImpl(::sw::RepeatContext & rContext)3055cdf0e10cSrcweir void SwUndoSplitTbl::RepeatImpl(::sw::RepeatContext & rContext)
3056cdf0e10cSrcweir {
3057cdf0e10cSrcweir     SwPaM *const pPam = & rContext.GetRepeatPaM();
3058cdf0e10cSrcweir     SwDoc *const pDoc = & rContext.GetDoc();
3059cdf0e10cSrcweir 
3060cdf0e10cSrcweir 	pDoc->SplitTable( *pPam->GetPoint(), nMode, bCalcNewSize );
3061cdf0e10cSrcweir 	ClearFEShellTabCols();
3062cdf0e10cSrcweir }
3063cdf0e10cSrcweir 
SaveFormula(SwHistory & rHistory)3064cdf0e10cSrcweir void SwUndoSplitTbl::SaveFormula( SwHistory& rHistory )
3065cdf0e10cSrcweir {
3066cdf0e10cSrcweir 	if( !pHistory )
3067cdf0e10cSrcweir 		pHistory = new SwHistory;
3068cdf0e10cSrcweir 
3069cdf0e10cSrcweir 	nFmlEnd = rHistory.Count();
3070cdf0e10cSrcweir 	pHistory->Move( 0, &rHistory );
3071cdf0e10cSrcweir }
3072cdf0e10cSrcweir 
3073cdf0e10cSrcweir 
3074cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////
3075cdf0e10cSrcweir 
SwUndoMergeTbl(const SwTableNode & rTblNd,const SwTableNode & rDelTblNd,sal_Bool bWithPrv,sal_uInt16 nMd)3076cdf0e10cSrcweir SwUndoMergeTbl::SwUndoMergeTbl( const SwTableNode& rTblNd,
3077cdf0e10cSrcweir 								const SwTableNode& rDelTblNd,
3078cdf0e10cSrcweir 								sal_Bool bWithPrv, sal_uInt16 nMd )
3079cdf0e10cSrcweir 	: SwUndo( UNDO_MERGE_TABLE ), pSavTbl( 0 ),
3080cdf0e10cSrcweir 	pHistory( 0 ), nMode( nMd ), bWithPrev( bWithPrv )
3081cdf0e10cSrcweir {
3082cdf0e10cSrcweir 	// Endnode der letzen Tabellenzelle merken, die auf der Position verbleibt
3083cdf0e10cSrcweir 	if( bWithPrev )
3084cdf0e10cSrcweir 		nTblNode = rDelTblNd.EndOfSectionIndex() - 1;
3085cdf0e10cSrcweir 	else
3086cdf0e10cSrcweir 		nTblNode = rTblNd.EndOfSectionIndex() - 1;
3087cdf0e10cSrcweir 
3088cdf0e10cSrcweir 	aName = rDelTblNd.GetTable().GetFrmFmt()->GetName();
3089cdf0e10cSrcweir 	pSavTbl = new _SaveTable( rDelTblNd.GetTable() );
3090cdf0e10cSrcweir 
3091cdf0e10cSrcweir 	pSavHdl = bWithPrev ? new _SaveTable( rTblNd.GetTable(), 1 ) : 0;
3092cdf0e10cSrcweir }
3093cdf0e10cSrcweir 
~SwUndoMergeTbl()3094cdf0e10cSrcweir SwUndoMergeTbl::~SwUndoMergeTbl()
3095cdf0e10cSrcweir {
3096cdf0e10cSrcweir 	delete pSavTbl;
3097cdf0e10cSrcweir 	delete pSavHdl;
3098cdf0e10cSrcweir 	delete pHistory;
3099cdf0e10cSrcweir }
3100cdf0e10cSrcweir 
UndoImpl(::sw::UndoRedoContext & rContext)3101cdf0e10cSrcweir void SwUndoMergeTbl::UndoImpl(::sw::UndoRedoContext & rContext)
3102cdf0e10cSrcweir {
3103cdf0e10cSrcweir     SwDoc *const pDoc = & rContext.GetDoc();
3104cdf0e10cSrcweir     SwPaM *const pPam(& rContext.GetCursorSupplier().CreateNewShellCursor());
3105cdf0e10cSrcweir 
3106cdf0e10cSrcweir 	pPam->DeleteMark();
3107cdf0e10cSrcweir 	SwNodeIndex& rIdx = pPam->GetPoint()->nNode;
3108cdf0e10cSrcweir 	rIdx = nTblNode;
3109cdf0e10cSrcweir 
3110cdf0e10cSrcweir 	SwTableNode* pTblNd = rIdx.GetNode().FindTableNode();
3111cdf0e10cSrcweir 	SwTable* pTbl = &pTblNd->GetTable();
3112cdf0e10cSrcweir 
3113cdf0e10cSrcweir 	SwTableFmlUpdate aMsgHnt( pTbl );
3114cdf0e10cSrcweir 	aMsgHnt.eFlags = TBL_BOXPTR;
3115cdf0e10cSrcweir 	pDoc->UpdateTblFlds( &aMsgHnt );
3116cdf0e10cSrcweir 
3117cdf0e10cSrcweir 	//Lines fuer das Layout-Update herausuchen.
3118cdf0e10cSrcweir 	_FndBox aFndBox( 0, 0 );
3119cdf0e10cSrcweir 	aFndBox.SetTableLines( *pTbl );
3120cdf0e10cSrcweir 	aFndBox.DelFrms( *pTbl );
3121cdf0e10cSrcweir     // ? TL_CHART2: notification or locking of controller required ?
3122cdf0e10cSrcweir 
3123cdf0e10cSrcweir 	SwTableNode* pNew = pDoc->GetNodes().SplitTable( rIdx, sal_True, sal_False );
3124cdf0e10cSrcweir 
3125cdf0e10cSrcweir 	//Layout updaten
3126cdf0e10cSrcweir 	aFndBox.MakeFrms( *pTbl );
3127cdf0e10cSrcweir     // ? TL_CHART2: notification or locking of controller required ?
3128cdf0e10cSrcweir 
3129cdf0e10cSrcweir 	if( bWithPrev )
3130cdf0e10cSrcweir 	{
3131cdf0e10cSrcweir 		// den Namen umsetzen
3132cdf0e10cSrcweir 		pNew->GetTable().GetFrmFmt()->SetName( pTbl->GetFrmFmt()->GetName() );
3133cdf0e10cSrcweir 		pSavHdl->RestoreAttr( pNew->GetTable() );
3134cdf0e10cSrcweir 	}
3135cdf0e10cSrcweir 	else
3136cdf0e10cSrcweir 		pTbl = &pNew->GetTable();
3137cdf0e10cSrcweir 	pTbl->GetFrmFmt()->SetName( aName );
3138cdf0e10cSrcweir 
3139cdf0e10cSrcweir //	pSavTbl->CreateNew( *pTbl, sal_False );
3140cdf0e10cSrcweir 	pSavTbl->RestoreAttr( *pTbl );
3141cdf0e10cSrcweir 
3142cdf0e10cSrcweir 
3143cdf0e10cSrcweir 	if( pHistory )
3144cdf0e10cSrcweir 	{
3145cdf0e10cSrcweir 		pHistory->TmpRollback( pDoc, 0 );
3146cdf0e10cSrcweir 		pHistory->SetTmpEnd( pHistory->Count() );
3147cdf0e10cSrcweir 	}
3148cdf0e10cSrcweir 
3149cdf0e10cSrcweir 	// fuer die neue Tabelle die Frames anlegen
3150cdf0e10cSrcweir 	SwNodeIndex aTmpIdx( *pNew );
3151cdf0e10cSrcweir 	pNew->MakeFrms( &aTmpIdx );
3152cdf0e10cSrcweir 
3153cdf0e10cSrcweir 	// Cursor  irgendwo in den Content stellen
3154cdf0e10cSrcweir 	SwCntntNode* pCNd = pDoc->GetNodes().GoNext( &rIdx );
3155cdf0e10cSrcweir 	pPam->GetPoint()->nContent.Assign( pCNd, 0 );
3156cdf0e10cSrcweir 
3157cdf0e10cSrcweir 	ClearFEShellTabCols();
3158cdf0e10cSrcweir 
3159cdf0e10cSrcweir     // TL_CHART2: need to inform chart of probably changed cell names
3160cdf0e10cSrcweir     SwChartDataProvider *pPCD = pDoc->GetChartDataProvider();
3161cdf0e10cSrcweir     if (pPCD)
3162cdf0e10cSrcweir     {
3163cdf0e10cSrcweir         pDoc->UpdateCharts( pTbl->GetFrmFmt()->GetName() );
3164cdf0e10cSrcweir         pDoc->UpdateCharts( pNew->GetTable().GetFrmFmt()->GetName() );
3165cdf0e10cSrcweir     }
3166cdf0e10cSrcweir }
3167cdf0e10cSrcweir 
RedoImpl(::sw::UndoRedoContext & rContext)3168cdf0e10cSrcweir void SwUndoMergeTbl::RedoImpl(::sw::UndoRedoContext & rContext)
3169cdf0e10cSrcweir {
3170cdf0e10cSrcweir     SwDoc *const pDoc = & rContext.GetDoc();
3171cdf0e10cSrcweir     SwPaM *const pPam(& rContext.GetCursorSupplier().CreateNewShellCursor());
3172cdf0e10cSrcweir 
3173cdf0e10cSrcweir 	pPam->DeleteMark();
3174cdf0e10cSrcweir 	pPam->GetPoint()->nNode = nTblNode;
3175cdf0e10cSrcweir 	if( bWithPrev )
3176cdf0e10cSrcweir 		pPam->GetPoint()->nNode = nTblNode + 3;
3177cdf0e10cSrcweir 	else
3178cdf0e10cSrcweir 		pPam->GetPoint()->nNode = nTblNode;
3179cdf0e10cSrcweir 
3180cdf0e10cSrcweir 	pDoc->MergeTable( *pPam->GetPoint(), bWithPrev, nMode );
3181cdf0e10cSrcweir 
3182cdf0e10cSrcweir 	ClearFEShellTabCols();
3183cdf0e10cSrcweir }
3184cdf0e10cSrcweir 
RepeatImpl(::sw::RepeatContext & rContext)3185cdf0e10cSrcweir void SwUndoMergeTbl::RepeatImpl(::sw::RepeatContext & rContext)
3186cdf0e10cSrcweir {
3187cdf0e10cSrcweir     SwDoc *const pDoc = & rContext.GetDoc();
3188cdf0e10cSrcweir     SwPaM *const pPam = & rContext.GetRepeatPaM();
3189cdf0e10cSrcweir 
3190cdf0e10cSrcweir 	pDoc->MergeTable( *pPam->GetPoint(), bWithPrev, nMode );
3191cdf0e10cSrcweir 	ClearFEShellTabCols();
3192cdf0e10cSrcweir }
3193cdf0e10cSrcweir 
SaveFormula(SwHistory & rHistory)3194cdf0e10cSrcweir void SwUndoMergeTbl::SaveFormula( SwHistory& rHistory )
3195cdf0e10cSrcweir {
3196cdf0e10cSrcweir 	if( !pHistory )
3197cdf0e10cSrcweir 		pHistory = new SwHistory;
3198cdf0e10cSrcweir 	pHistory->Move( 0, &rHistory );
3199cdf0e10cSrcweir }
3200cdf0e10cSrcweir 
3201cdf0e10cSrcweir 
3202cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////
3203cdf0e10cSrcweir 
InsertSort(SvUShorts & rArr,sal_uInt16 nIdx,sal_uInt16 * pInsPos)3204cdf0e10cSrcweir void InsertSort( SvUShorts& rArr, sal_uInt16 nIdx, sal_uInt16* pInsPos )
3205cdf0e10cSrcweir {
3206cdf0e10cSrcweir 	sal_uInt16 nO	= rArr.Count(), nM, nU = 0;
3207cdf0e10cSrcweir 	if( nO > 0 )
3208cdf0e10cSrcweir 	{
3209cdf0e10cSrcweir 		nO--;
3210cdf0e10cSrcweir 		while( nU <= nO )
3211cdf0e10cSrcweir 		{
3212cdf0e10cSrcweir 			nM = nU + ( nO - nU ) / 2;
3213cdf0e10cSrcweir 			if( *(rArr.GetData() + nM) == nIdx )
3214cdf0e10cSrcweir 			{
3215cdf0e10cSrcweir 				ASSERT( sal_False, "Index ist schon vorhanden, darf nie sein!" );
3216cdf0e10cSrcweir 				return;
3217cdf0e10cSrcweir 			}
3218cdf0e10cSrcweir 			if( *(rArr.GetData() + nM) < nIdx )
3219cdf0e10cSrcweir 				nU = nM + 1;
3220cdf0e10cSrcweir 			else if( nM == 0 )
3221cdf0e10cSrcweir 				break;
3222cdf0e10cSrcweir 			else
3223cdf0e10cSrcweir 				nO = nM - 1;
3224cdf0e10cSrcweir 		}
3225cdf0e10cSrcweir 	}
3226cdf0e10cSrcweir 	rArr.Insert( nIdx, nU );
3227cdf0e10cSrcweir 	if( pInsPos )
3228cdf0e10cSrcweir 		*pInsPos = nU;
3229cdf0e10cSrcweir }
3230cdf0e10cSrcweir 
InsertSort(SvULongs & rArr,sal_uLong nIdx,sal_uInt16 * pInsPos)3231cdf0e10cSrcweir void InsertSort( SvULongs& rArr, sal_uLong nIdx, sal_uInt16* pInsPos )
3232cdf0e10cSrcweir {
3233cdf0e10cSrcweir 	sal_uInt16 nO	= rArr.Count(), nM, nU = 0;
3234cdf0e10cSrcweir 	if( nO > 0 )
3235cdf0e10cSrcweir 	{
3236cdf0e10cSrcweir 		nO--;
3237cdf0e10cSrcweir 		while( nU <= nO )
3238cdf0e10cSrcweir 		{
3239cdf0e10cSrcweir 			nM = nU + ( nO - nU ) / 2;
3240cdf0e10cSrcweir 			if( *(rArr.GetData() + nM) == nIdx )
3241cdf0e10cSrcweir 			{
3242cdf0e10cSrcweir 				ASSERT( sal_False, "Index ist schon vorhanden, darf nie sein!" );
3243cdf0e10cSrcweir 				return;
3244cdf0e10cSrcweir 			}
3245cdf0e10cSrcweir 			if( *(rArr.GetData() + nM) < nIdx )
3246cdf0e10cSrcweir 				nU = nM + 1;
3247cdf0e10cSrcweir 			else if( nM == 0 )
3248cdf0e10cSrcweir 				break;
3249cdf0e10cSrcweir 			else
3250cdf0e10cSrcweir 				nO = nM - 1;
3251cdf0e10cSrcweir 		}
3252cdf0e10cSrcweir 	}
3253cdf0e10cSrcweir 	rArr.Insert( nIdx, nU );
3254cdf0e10cSrcweir 	if( pInsPos )
3255cdf0e10cSrcweir 		*pInsPos = nU;
3256cdf0e10cSrcweir }
3257cdf0e10cSrcweir 
3258cdf0e10cSrcweir #if defined( JP_DEBUG ) && defined(DBG_UTIL)
3259cdf0e10cSrcweir 
3260cdf0e10cSrcweir 
DumpDoc(SwDoc * pDoc,const String & rFileNm)3261cdf0e10cSrcweir void DumpDoc( SwDoc* pDoc, const String& rFileNm )
3262cdf0e10cSrcweir {
3263cdf0e10cSrcweir 	Writer* pWrt = SwIoSystem::GetWriter( "DEBUG" );
3264cdf0e10cSrcweir 	if( pWrt )
3265cdf0e10cSrcweir 	{
3266cdf0e10cSrcweir 		SvFileStream aStream( rFileNm, STREAM_STD_WRITE );
3267cdf0e10cSrcweir 		SwPaM* pPam = new SwPaM( pDoc, SwPosition( pDoc->GetNodes().EndOfContent ,
3268cdf0e10cSrcweir 												 pDoc->GetNodes().EndOfContent ));
3269cdf0e10cSrcweir 		pPam->Move( fnMoveBackward, fnGoDoc );
3270cdf0e10cSrcweir 		pPam->SetMark();
3271cdf0e10cSrcweir 		pPam->Move( fnMoveForward, fnGoDoc );
3272cdf0e10cSrcweir 
3273cdf0e10cSrcweir 		pWrt->Write( pPam, *pDoc, aStream, rFileNm.GetStr() );
3274cdf0e10cSrcweir 
3275cdf0e10cSrcweir 		delete pPam;
3276cdf0e10cSrcweir 	}
3277cdf0e10cSrcweir }
CheckTable(const SwTable & rTbl)3278cdf0e10cSrcweir void CheckTable( const SwTable& rTbl )
3279cdf0e10cSrcweir {
3280cdf0e10cSrcweir 	const SwNodes& rNds = rTbl.GetFrmFmt()->GetDoc()->GetNodes();
3281cdf0e10cSrcweir 	const SwTableSortBoxes& rSrtArr = pTblNd->GetTable().GetTabSortBoxes();
3282cdf0e10cSrcweir 	for( sal_uInt16 n = 0; n < rSrtArr.Count(); ++n )
3283cdf0e10cSrcweir 	{
3284cdf0e10cSrcweir 		const SwTableBox* pBox = rSrtArr[ n ];
3285cdf0e10cSrcweir 		const SwNode* pNd = pBox->GetSttNd();
3286cdf0e10cSrcweir 		ASSERT( rNds[ *pBox->GetSttIdx() ] == pNd, "Box mit falchem StartNode"  );
3287cdf0e10cSrcweir 	}
3288cdf0e10cSrcweir }
3289cdf0e10cSrcweir #endif
3290cdf0e10cSrcweir 
3291cdf0e10cSrcweir 
3292