xref: /trunk/main/sw/source/core/undo/untbl.cxx (revision cf6516809c57e1bb0a940545cca99cdad54d4ce2)
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
10cdf0e10cSrcweir  *
11efeef26fSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
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.
19cdf0e10cSrcweir  *
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);
2095cdf0e10cSrcweir                 if( pUndo->IsMoveRange() )
2096cdf0e10cSrcweir                 {
2097cdf0e10cSrcweir                     // den ueberfluessigen Node loeschen
2098cdf0e10cSrcweir                     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                     }
2107cdf0e10cSrcweir                     rDoc.GetNodes().Delete( aIdx, 1 );
2108cdf0e10cSrcweir                 }
2109cdf0e10cSrcweir                 else if( pTxtNd )
2110cdf0e10cSrcweir                 {
2111cdf0e10cSrcweir                     // evt. noch ueberflussige Attribute loeschen
2112cdf0e10cSrcweir                     SwIndex aTmpIdx( pTxtNd, nDelPos );
2113cdf0e10cSrcweir                     if( pTxtNd->GetpSwpHints() && pTxtNd->GetpSwpHints()->Count() )
211469a74367SOliver-Rainer Wittmann                         pTxtNd->RstTxtAttr( aTmpIdx, pTxtNd->GetTxt().Len() - nDelPos + 1 );
2115cdf0e10cSrcweir                     // 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
3290