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