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