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