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