1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: untbl.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
35 #include <hintids.hxx>
36 #include <svx/brkitem.hxx>
37 #include <fmtornt.hxx>
38 #include <fmtpdsc.hxx>
43 #include <swtable.hxx>
47 #include <swundo.hxx> // fuer die UndoIds
54 #include <cellfrm.hxx>
55 #include <swcache.hxx>
56 #include <tblafmt.hxx>
57 #include <poolfmt.hxx>
59 #include <cellatr.hxx>
60 #include <swtblfmt.hxx>
61 #include <swddetbl.hxx>
62 #include <redline.hxx>
63 #include <node2lay.hxx>
64 #include <tblrwcl.hxx>
65 #include <fmtanchr.hxx>
66 #include <comcore.hrc>
67 #include <unochart.hxx>
71 #define CHECK_TABLE(t)
74 #define CHECK_TABLE(t) (t).CheckConsistency();
76 #define CHECK_TABLE(t)
81 #define _DEBUG_REDLINE( pDoc )
83 void lcl_DebugRedline( const SwDoc
* pDoc
);
84 #define _DEBUG_REDLINE( pDoc ) lcl_DebugRedline( pDoc );
87 inline SwDoc
& SwUndoIter::GetDoc() const { return *pAktPam
->GetDoc(); }
88 extern void ClearFEShellTabCols();
90 typedef SfxItemSet
* SfxItemSetPtr
;
91 SV_DECL_PTRARR_DEL( SfxItemSets
, SfxItemSetPtr
, 10, 5 )
93 typedef SwUndoSaveSection
* SwUndoSaveSectionPtr
;
94 SV_DECL_PTRARR_DEL( SwUndoSaveSections
, SwUndoSaveSectionPtr
, 0, 10 )
96 typedef SwUndoMove
* SwUndoMovePtr
;
97 SV_DECL_PTRARR_DEL( SwUndoMoves
, SwUndoMovePtr
, 0, 10 )
99 struct SwTblToTxtSave
;
100 typedef SwTblToTxtSave
* SwTblToTxtSavePtr
;
101 SV_DECL_PTRARR_DEL( SwTblToTxtSaves
, SwTblToTxtSavePtr
, 0, 10 )
103 struct _UndoTblCpyTbl_Entry
105 ULONG nBoxIdx
, nOffset
;
106 SfxItemSet
* pBoxNumAttr
;
109 // Was the last paragraph of the new and the first paragraph of the old content joined?
110 bool bJoin
; // For redlining only
112 _UndoTblCpyTbl_Entry( const SwTableBox
& rBox
);
113 ~_UndoTblCpyTbl_Entry();
115 typedef _UndoTblCpyTbl_Entry
* _UndoTblCpyTbl_EntryPtr
;
116 SV_DECL_PTRARR_DEL( _UndoTblCpyTbl_Entries
, _UndoTblCpyTbl_EntryPtr
, 0, 10 )
123 friend class _SaveBox
;
124 friend class _SaveLine
;
127 const SwTable
* pSwTable
;
132 BOOL bSaveFormula
: 1;
136 _SaveTable( const SwTable
& rTbl
, USHORT nLnCnt
= USHRT_MAX
,
137 BOOL bSaveFml
= TRUE
);
140 USHORT
AddFmt( SwFrmFmt
* pFmt
, bool bIsLine
);
141 void NewFrmFmt( const SwClient
* pLnBx
, BOOL bIsLine
, USHORT nFmtPos
,
144 void RestoreAttr( SwTable
& rTbl
, BOOL bModifyBox
= FALSE
);
145 void SaveCntntAttrs( SwDoc
* pDoc
);
146 void CreateNew( SwTable
& rTbl
, BOOL bCreateFrms
= TRUE
,
147 BOOL bRestoreChart
= TRUE
);
148 BOOL
IsNewModel() const { return bNewModel
; }
153 friend class _SaveTable
;
154 friend class _SaveBox
;
162 _SaveLine( _SaveLine
* pPrev
, const SwTableLine
& rLine
, _SaveTable
& rSTbl
);
165 void RestoreAttr( SwTableLine
& rLine
, _SaveTable
& rSTbl
);
166 void SaveCntntAttrs( SwDoc
* pDoc
);
168 void CreateNew( SwTable
& rTbl
, SwTableBox
& rParent
, _SaveTable
& rSTbl
);
173 friend class _SaveLine
;
181 SfxItemSets
* pCntntAttrs
;
186 _SaveBox( _SaveBox
* pPrev
, const SwTableBox
& rBox
, _SaveTable
& rSTbl
);
189 void RestoreAttr( SwTableBox
& rBox
, _SaveTable
& rSTbl
);
190 void SaveCntntAttrs( SwDoc
* pDoc
);
192 void CreateNew( SwTable
& rTbl
, SwTableLine
& rParent
, _SaveTable
& rSTbl
);
195 void InsertSort( SvUShorts
& rArr
, USHORT nIdx
, USHORT
* pInsPos
= 0 );
196 void InsertSort( SvULongs
& rArr
, ULONG nIdx
, USHORT
* pInsPos
= 0 );
198 #if defined( JP_DEBUG ) && !defined( PRODUCT )
199 #include "shellio.hxx"
200 void DumpDoc( SwDoc
* pDoc
, const String
& rFileNm
);
201 void CheckTable( const SwTable
& );
202 #define DUMPDOC(p,s) DumpDoc( p, s);
203 #define CHECKTABLE(t) CheckTable( t );
206 #define CHECKTABLE(t)
209 /* #130880: Crash in undo of table to text when the table has (freshly) merged cells
210 The order of cell content nodes in the nodes array is not given by the recursive table structure.
211 The algorithmn must not rely on this even it holds for a fresh loaded table in odt file format.
212 So we need to remember not only the start node position but the end node position as well.
215 struct SwTblToTxtSave
221 // metadata references for first and last paragraph in cell
222 ::boost::shared_ptr
< ::sfx2::MetadatableUndo
> m_pMetadataUndoStart
;
223 ::boost::shared_ptr
< ::sfx2::MetadatableUndo
> m_pMetadataUndoEnd
;
225 SwTblToTxtSave( SwDoc
& rDoc
, ULONG nNd
, ULONG nEndIdx
, xub_StrLen nCntnt
);
226 ~SwTblToTxtSave() { delete m_pHstry
; }
229 SV_IMPL_PTRARR( SfxItemSets
, SfxItemSetPtr
)
230 SV_IMPL_PTRARR( SwUndoSaveSections
, SwUndoSaveSectionPtr
)
231 SV_IMPL_PTRARR( SwUndoMoves
, SwUndoMovePtr
)
232 SV_IMPL_PTRARR( SwTblToTxtSaves
, SwTblToTxtSavePtr
)
233 SV_IMPL_PTRARR( _UndoTblCpyTbl_Entries
, _UndoTblCpyTbl_EntryPtr
)
235 USHORT __FAR_DATA aSave_BoxCntntSet
[] = {
236 RES_CHRATR_COLOR
, RES_CHRATR_CROSSEDOUT
,
237 RES_CHRATR_FONT
, RES_CHRATR_FONTSIZE
,
238 RES_CHRATR_POSTURE
, RES_CHRATR_POSTURE
,
239 RES_CHRATR_SHADOWED
, RES_CHRATR_WEIGHT
,
240 RES_PARATR_ADJUST
, RES_PARATR_ADJUST
,
245 SwUndoInsTbl::SwUndoInsTbl( const SwPosition
& rPos
, USHORT nCl
, USHORT nRw
,
246 USHORT nAdj
, const SwInsertTableOptions
& rInsTblOpts
,
247 const SwTableAutoFmt
* pTAFmt
,
248 const SvUShorts
* pColArr
,
249 const String
& rName
)
250 : SwUndo( UNDO_INSTABLE
),
251 aInsTblOpts( rInsTblOpts
), pDDEFldType( 0 ), pColWidth( 0 ), pRedlData( 0 ), pAutoFmt( 0 ),
252 nSttNode( rPos
.nNode
.GetIndex() ), nRows( nRw
), nCols( nCl
), nAdjust( nAdj
)
256 pColWidth
= new SvUShorts( 0, 1 );
257 pColWidth
->Insert( pColArr
, 0 );
260 pAutoFmt
= new SwTableAutoFmt( *pTAFmt
);
263 SwDoc
& rDoc
= *rPos
.nNode
.GetNode().GetDoc();
264 if( rDoc
.IsRedlineOn() )
266 pRedlData
= new SwRedlineData( nsRedlineType_t::REDLINE_INSERT
, rDoc
.GetRedlineAuthor() );
267 SetRedlineMode( rDoc
.GetRedlineMode() );
274 SwUndoInsTbl::~SwUndoInsTbl()
282 void SwUndoInsTbl::Undo( SwUndoIter
& rUndoIter
)
284 SwDoc
& rDoc
= rUndoIter
.GetDoc();
285 SwNodeIndex
aIdx( rDoc
.GetNodes(), nSttNode
);
287 SwTableNode
* pTblNd
= aIdx
.GetNode().GetTableNode();
288 ASSERT( pTblNd
, "kein TabellenNode" );
291 if( IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ))
292 rDoc
.DeleteRedline( *pTblNd
, true, USHRT_MAX
);
293 RemoveIdxFromSection( rDoc
, nSttNode
);
295 // harte SeitenUmbrueche am nachfolgenden Node verschieben
296 SwCntntNode
* pNextNd
= rDoc
.GetNodes()[ pTblNd
->EndOfSectionIndex()+1 ]->GetCntntNode();
299 SwFrmFmt
* pTableFmt
= pTblNd
->GetTable().GetFrmFmt();
300 const SfxPoolItem
*pItem
;
302 if( SFX_ITEM_SET
== pTableFmt
->GetItemState( RES_PAGEDESC
,
304 pNextNd
->SetAttr( *pItem
);
306 if( SFX_ITEM_SET
== pTableFmt
->GetItemState( RES_BREAK
,
308 pNextNd
->SetAttr( *pItem
);
312 sTblNm
= pTblNd
->GetTable().GetFrmFmt()->GetName();
313 if( pTblNd
->GetTable().IsA( TYPE( SwDDETable
)) )
314 pDDEFldType
= (SwDDEFieldType
*)((SwDDETable
&)pTblNd
->GetTable()).
315 GetDDEFldType()->Copy();
317 rDoc
.GetNodes().Delete( aIdx
, pTblNd
->EndOfSectionIndex() -
318 aIdx
.GetIndex() + 1 );
320 rUndoIter
.pAktPam
->DeleteMark();
321 rUndoIter
.pAktPam
->GetPoint()->nNode
= aIdx
;
322 rUndoIter
.pAktPam
->GetPoint()->nContent
.Assign(
323 rUndoIter
.pAktPam
->GetCntntNode(), 0 );
327 void SwUndoInsTbl::Redo( SwUndoIter
& rUndoIter
)
329 SwDoc
& rDoc
= rUndoIter
.GetDoc();
331 SwPosition
aPos( *rUndoIter
.pAktPam
->GetPoint() );
332 aPos
.nNode
= nSttNode
;
333 const SwTable
* pTbl
= rDoc
.InsertTable( aInsTblOpts
, aPos
, nRows
, nCols
,
335 pAutoFmt
, pColWidth
);
336 ((SwFrmFmt
*)pTbl
->GetFrmFmt())->SetName( sTblNm
);
337 SwTableNode
* pTblNode
= (SwTableNode
*)rDoc
.GetNodes()[nSttNode
]->GetTableNode();
341 SwDDEFieldType
* pNewType
= (SwDDEFieldType
*)rDoc
.InsertFldType(
343 SwDDETable
* pDDETbl
= new SwDDETable( pTblNode
->GetTable(), pNewType
);
344 pTblNode
->SetNewTable( pDDETbl
); // setze die DDE-Tabelle
345 delete pDDEFldType
, pDDEFldType
= 0;
348 if( (pRedlData
&& IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() )) ||
349 ( !( nsRedlineMode_t::REDLINE_IGNORE
& GetRedlineMode() ) &&
350 rDoc
.GetRedlineTbl().Count() ))
352 SwPaM
aPam( *pTblNode
->EndOfSectionNode(), *pTblNode
, 1 );
353 SwCntntNode
* pCNd
= aPam
.GetCntntNode( FALSE
);
355 aPam
.GetMark()->nContent
.Assign( pCNd
, 0 );
357 if( pRedlData
&& IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ) )
359 RedlineMode_t eOld
= rDoc
.GetRedlineMode();
360 rDoc
.SetRedlineMode_intern((RedlineMode_t
)(eOld
& ~nsRedlineMode_t::REDLINE_IGNORE
));
362 rDoc
.AppendRedline( new SwRedline( *pRedlData
, aPam
), true);
363 rDoc
.SetRedlineMode_intern( eOld
);
366 rDoc
.SplitRedline( aPam
);
371 void SwUndoInsTbl::Repeat( SwUndoIter
& rUndoIter
)
373 rUndoIter
.GetDoc().InsertTable( aInsTblOpts
, *rUndoIter
.pAktPam
->GetPoint(),
374 nRows
, nCols
, nAdjust
,
375 pAutoFmt
, pColWidth
);
378 SwRewriter
SwUndoInsTbl::GetRewriter() const
380 SwRewriter aRewriter
;
382 aRewriter
.AddRule(UNDO_ARG1
, SW_RES(STR_START_QUOTE
));
383 aRewriter
.AddRule(UNDO_ARG2
, sTblNm
);
384 aRewriter
.AddRule(UNDO_ARG3
, SW_RES(STR_END_QUOTE
));
389 // -----------------------------------------------------
391 SwTblToTxtSave::SwTblToTxtSave( SwDoc
& rDoc
, ULONG nNd
, ULONG nEndIdx
, xub_StrLen nCnt
)
392 : m_nSttNd( nNd
), m_nEndNd( nEndIdx
), m_nCntnt( nCnt
), m_pHstry( 0 )
394 // Attributierung des gejointen Node merken.
395 SwTxtNode
* pNd
= rDoc
.GetNodes()[ nNd
]->GetTxtNode();
398 m_pHstry
= new SwHistory
;
400 m_pHstry
->Add( pNd
->GetTxtColl(), nNd
, ND_TEXTNODE
);
401 if ( pNd
->GetpSwpHints() )
403 m_pHstry
->CopyAttr( pNd
->GetpSwpHints(), nNd
, 0,
404 pNd
->GetTxt().Len(), false );
406 if( pNd
->HasSwAttrSet() )
407 m_pHstry
->CopyFmtAttr( *pNd
->GetpSwAttrSet(), nNd
);
409 if( !m_pHstry
->Count() )
410 delete m_pHstry
, m_pHstry
= 0;
413 m_pMetadataUndoStart
= pNd
->CreateUndo();
416 // we also need to store the metadata reference of the _last_ paragraph
417 // we subtract 1 to account for the removed cell start/end node pair
418 // (after SectionUp, the end of the range points to the node after the cell)
419 if ( nEndIdx
- 1 > nNd
)
421 SwTxtNode
* pLastNode( rDoc
.GetNodes()[ nEndIdx
- 1 ]->GetTxtNode() );
425 m_pMetadataUndoEnd
= pLastNode
->CreateUndo();
430 SwUndoTblToTxt::SwUndoTblToTxt( const SwTable
& rTbl
, sal_Unicode cCh
)
431 : SwUndo( UNDO_TABLETOTEXT
),
432 sTblNm( rTbl
.GetFrmFmt()->GetName() ), pDDEFldType( 0 ), pHistory( 0 ),
433 nSttNd( 0 ), nEndNd( 0 ),
434 nAdjust( static_cast<USHORT
>(rTbl
.GetFrmFmt()->GetHoriOrient().GetHoriOrient()) ),
435 cTrenner( cCh
), nHdlnRpt( rTbl
.GetRowsToRepeat() )
437 pTblSave
= new _SaveTable( rTbl
);
438 pBoxSaves
= new SwTblToTxtSaves( (BYTE
)rTbl
.GetTabSortBoxes().Count() );
440 if( rTbl
.IsA( TYPE( SwDDETable
) ) )
441 pDDEFldType
= (SwDDEFieldType
*)((SwDDETable
&)rTbl
).GetDDEFldType()->Copy();
443 bCheckNumFmt
= rTbl
.GetFrmFmt()->GetDoc()->IsInsTblFormatNum();
445 pHistory
= new SwHistory
;
446 const SwTableNode
* pTblNd
= rTbl
.GetTableNode();
447 ULONG nTblStt
= pTblNd
->GetIndex(), nTblEnd
= pTblNd
->EndOfSectionIndex();
449 const SwSpzFrmFmts
& rFrmFmtTbl
= *pTblNd
->GetDoc()->GetSpzFrmFmts();
450 for( USHORT n
= 0; n
< rFrmFmtTbl
.Count(); ++n
)
452 const SwPosition
* pAPos
;
453 SwFrmFmt
* pFmt
= rFrmFmtTbl
[ n
];
454 const SwFmtAnchor
* pAnchor
= &pFmt
->GetAnchor();
455 if( 0 != ( pAPos
= pAnchor
->GetCntntAnchor()) &&
456 ( FLY_AUTO_CNTNT
== pAnchor
->GetAnchorId() ||
457 FLY_AT_CNTNT
== pAnchor
->GetAnchorId() ) &&
458 nTblStt
<= pAPos
->nNode
.GetIndex() &&
459 pAPos
->nNode
.GetIndex() < nTblEnd
)
461 pHistory
->Add( *pFmt
);
465 if( !pHistory
->Count() )
466 delete pHistory
, pHistory
= 0;
470 SwUndoTblToTxt::~SwUndoTblToTxt()
480 void SwUndoTblToTxt::Undo( SwUndoIter
& rUndoIter
)
482 SwDoc
& rDoc
= rUndoIter
.GetDoc();
483 SwPaM
* pPam
= rUndoIter
.pAktPam
;
485 SwNodeIndex
aFrmIdx( rDoc
.GetNodes(), nSttNd
);
486 SwNodeIndex
aEndIdx( rDoc
.GetNodes(), nEndNd
);
488 pPam
->GetPoint()->nNode
= aFrmIdx
;
490 pPam
->GetPoint()->nNode
= aEndIdx
;
491 rDoc
.DelNumRules( *pPam
);
494 // dann sammel mal alle Uppers ein
495 SwNode2Layout
aNode2Layout( aFrmIdx
.GetNode() );
497 // erzeuge die TabelleNode Structur
498 SwTableNode
* pTblNd
= rDoc
.GetNodes().UndoTableToText( nSttNd
, nEndNd
, *pBoxSaves
);
499 pTblNd
->GetTable().SetTableModel( pTblSave
->IsNewModel() );
500 SwTableFmt
* pTableFmt
= rDoc
.MakeTblFrmFmt( sTblNm
, rDoc
.GetDfltFrmFmt() );
501 pTableFmt
->Add( &pTblNd
->GetTable() ); // das Frame-Format setzen
502 pTblNd
->GetTable().SetRowsToRepeat( nHdlnRpt
);
504 // erzeuge die alte Tabellen Struktur
505 pTblSave
->CreateNew( pTblNd
->GetTable() );
509 SwDDEFieldType
* pNewType
= (SwDDEFieldType
*)rDoc
.InsertFldType(
511 SwDDETable
* pDDETbl
= new SwDDETable( pTblNd
->GetTable(), pNewType
);
512 pTblNd
->SetNewTable( pDDETbl
, FALSE
); // setze die DDE-Tabelle
513 delete pDDEFldType
, pDDEFldType
= 0;
518 SwTableSortBoxes
& rBxs
= pTblNd
->GetTable().GetTabSortBoxes();
519 for( USHORT nBoxes
= rBxs
.Count(); nBoxes
; )
520 rDoc
.ChkBoxNumFmt( *rBxs
[ --nBoxes
], FALSE
);
525 USHORT nTmpEnd
= pHistory
->GetTmpEnd();
526 pHistory
->TmpRollback( &rDoc
, 0 );
527 pHistory
->SetTmpEnd( nTmpEnd
);
530 aNode2Layout
.RestoreUpperFrms( rDoc
.GetNodes(),
531 pTblNd
->GetIndex(), pTblNd
->GetIndex()+1 );
533 // will man eine TabellenSelektion ??
535 pPam
->GetPoint()->nNode
= *pTblNd
->EndOfSectionNode();
537 pPam
->GetPoint()->nNode
= *pPam
->GetNode()->StartOfSectionNode();
538 pPam
->Move( fnMoveForward
, fnGoCntnt
);
540 pPam
->Move( fnMoveBackward
, fnGoCntnt
);
542 ClearFEShellTabCols();
545 // steht im untbl.cxx und darf nur vom Undoobject gerufen werden
546 SwTableNode
* SwNodes::UndoTableToText( ULONG nSttNd
, ULONG nEndNd
,
547 const SwTblToTxtSaves
& rSavedData
)
549 SwNodeIndex
aSttIdx( *this, nSttNd
);
550 SwNodeIndex
aEndIdx( *this, nEndNd
+1 );
552 SwTableNode
* pTblNd
= new SwTableNode( aSttIdx
);
553 SwEndNode
* pEndNd
= new SwEndNode( aEndIdx
, *pTblNd
);
557 /* Set pTblNd as start of section for all nodes in [nSttNd, nEndNd].
558 Delete all Frames attached to the nodes in that range. */
561 ULONG n
, nTmpEnd
= aEndIdx
.GetIndex();
562 for( n
= pTblNd
->GetIndex() + 1; n
< nTmpEnd
; ++n
)
564 if( ( pNd
= (*this)[ n
] )->IsCntntNode() )
565 ((SwCntntNode
*)pNd
)->DelFrms();
566 pNd
->pStartOfSection
= pTblNd
;
570 // dann die Tabellen Struktur teilweise aufbauen. Erstmal eine Line
571 // in der alle Boxen stehen! Die korrekte Struktur kommt dann aus der
573 SwTableBoxFmt
* pBoxFmt
= GetDoc()->MakeTableBoxFmt();
574 SwTableLineFmt
* pLineFmt
= GetDoc()->MakeTableLineFmt();
575 SwTableLine
* pLine
= new SwTableLine( pLineFmt
, rSavedData
.Count(), 0 );
576 pTblNd
->GetTable().GetTabLines().C40_INSERT( SwTableLine
, pLine
, 0 );
578 SvULongs
aBkmkArr( 0, 4 );
579 for( USHORT n
= rSavedData
.Count(); n
; )
581 SwTblToTxtSave
* pSave
= rSavedData
[ --n
];
582 // if the start node was merged with last from prev. cell,
583 // subtract 1 from index to get the merged paragraph, and split that
584 aSttIdx
= pSave
->m_nSttNd
- ( ( USHRT_MAX
!= pSave
->m_nCntnt
) ? 1 : 0);
585 SwTxtNode
* pTxtNd
= aSttIdx
.GetNode().GetTxtNode();
587 if( USHRT_MAX
!= pSave
->m_nCntnt
)
589 // an der ContentPosition splitten, das vorherige Zeichen
590 // loeschen (ist der Trenner!)
591 ASSERT( pTxtNd
, "Wo ist der TextNode geblieben?" );
592 SwIndex
aCntPos( pTxtNd
, pSave
->m_nCntnt
- 1 );
594 pTxtNd
->Erase( aCntPos
, 1 );
595 SwCntntNode
* pNewNd
= pTxtNd
->SplitCntntNode(
596 SwPosition( aSttIdx
, aCntPos
));
597 if( aBkmkArr
.Count() )
598 _RestoreCntntIdx( aBkmkArr
, *pNewNd
, pSave
->m_nCntnt
,
599 pSave
->m_nCntnt
+ 1 );
603 if( aBkmkArr
.Count() )
604 aBkmkArr
.Remove( 0, aBkmkArr
.Count() );
606 _SaveCntntIdx( GetDoc(), aSttIdx
.GetIndex(),
607 pTxtNd
->GetTxt().Len(), aBkmkArr
);
613 pTxtNd
->GetTxtNode()->RestoreMetadata(pSave
->m_pMetadataUndoStart
);
614 if( pTxtNd
->HasSwAttrSet() )
615 pTxtNd
->ResetAllAttr();
617 if( pTxtNd
->GetpSwpHints() )
618 pTxtNd
->ClearSwpHintsArr( false );
621 if( pSave
->m_pHstry
)
623 USHORT nTmpEnd
= pSave
->m_pHstry
->GetTmpEnd();
624 pSave
->m_pHstry
->TmpRollback( GetDoc(), 0 );
625 pSave
->m_pHstry
->SetTmpEnd( nTmpEnd
);
629 // end points to node after cell
630 if ( pSave
->m_nEndNd
- 1 > pSave
->m_nSttNd
)
632 SwTxtNode
* pLastNode
= (*this)[ pSave
->m_nEndNd
- 1 ]->GetTxtNode();
635 pLastNode
->RestoreMetadata(pSave
->m_pMetadataUndoEnd
);
639 aEndIdx
= pSave
->m_nEndNd
;
640 SwStartNode
* pSttNd
= new SwStartNode( aSttIdx
, ND_STARTNODE
,
641 SwTableBoxStartNode
);
642 pSttNd
->pStartOfSection
= pTblNd
;
643 new SwEndNode( aEndIdx
, *pSttNd
);
645 for( ULONG i
= aSttIdx
.GetIndex(); i
< aEndIdx
.GetIndex()-1; ++i
)
648 pNd
->pStartOfSection
= pSttNd
;
649 if( pNd
->IsStartNode() )
650 i
= pNd
->EndOfSectionIndex();
653 SwTableBox
* pBox
= new SwTableBox( pBoxFmt
, *pSttNd
, pLine
);
654 pLine
->GetTabBoxes().C40_INSERT( SwTableBox
, pBox
, 0 );
660 void SwUndoTblToTxt::Redo( SwUndoIter
& rUndoIter
)
662 SwDoc
& rDoc
= rUndoIter
.GetDoc();
663 SwPaM
* pPam
= rUndoIter
.pAktPam
;
666 pPam
->GetPoint()->nNode
= nSttNd
;
667 pPam
->GetPoint()->nContent
.Assign( 0, 0 );
668 SwNodeIndex
aSaveIdx( pPam
->GetPoint()->nNode
, -1 );
670 pPam
->SetMark(); // alle Indizies abmelden
673 SwTableNode
* pTblNd
= pPam
->GetNode()->GetTableNode();
674 ASSERT( pTblNd
, "keinen TableNode gefunden" );
676 if( pTblNd
->GetTable().IsA( TYPE( SwDDETable
)) )
677 pDDEFldType
= (SwDDEFieldType
*)((SwDDETable
&)pTblNd
->GetTable()).
678 GetDDEFldType()->Copy();
680 rDoc
.TableToText( pTblNd
, cTrenner
);
683 SwCntntNode
* pCNd
= aSaveIdx
.GetNode().GetCntntNode();
684 if( !pCNd
&& 0 == ( pCNd
= rDoc
.GetNodes().GoNext( &aSaveIdx
) ) &&
685 0 == ( pCNd
= rDoc
.GetNodes().GoPrevious( &aSaveIdx
)) )
687 ASSERT( FALSE
, "wo steht denn nun der TextNode" );
690 pPam
->GetPoint()->nNode
= aSaveIdx
;
691 pPam
->GetPoint()->nContent
.Assign( pCNd
, 0 );
693 pPam
->SetMark(); // alle Indizies abmelden
698 void SwUndoTblToTxt::Repeat( SwUndoIter
& rUndoIter
)
700 SwTableNode
* pTblNd
= rUndoIter
.pAktPam
->GetNode()->FindTableNode();
703 // bewege den Cursor aus der Tabelle
704 SwPaM
* pPam
= rUndoIter
.pAktPam
;
705 pPam
->GetPoint()->nNode
= *pTblNd
->EndOfSectionNode();
706 pPam
->Move( fnMoveForward
, fnGoCntnt
);
710 rUndoIter
.GetDoc().TableToText( pTblNd
, cTrenner
);
714 void SwUndoTblToTxt::SetRange( const SwNodeRange
& rRg
)
716 nSttNd
= rRg
.aStart
.GetIndex();
717 nEndNd
= rRg
.aEnd
.GetIndex();
720 void SwUndoTblToTxt::AddBoxPos( SwDoc
& rDoc
, ULONG nNdIdx
, ULONG nEndIdx
, xub_StrLen nCntntIdx
)
722 SwTblToTxtSave
* pNew
= new SwTblToTxtSave( rDoc
, nNdIdx
, nEndIdx
, nCntntIdx
);
723 pBoxSaves
->Insert( pNew
, pBoxSaves
->Count() );
726 // -----------------------------------------------------
728 SwUndoTxtToTbl::SwUndoTxtToTbl( const SwPaM
& rRg
,
729 const SwInsertTableOptions
& rInsTblOpts
,
730 sal_Unicode cCh
, USHORT nAdj
,
731 const SwTableAutoFmt
* pAFmt
)
732 : SwUndo( UNDO_TEXTTOTABLE
), SwUndRng( rRg
), aInsTblOpts( rInsTblOpts
),
733 pDelBoxes( 0 ), pAutoFmt( 0 ),
734 pHistory( 0 ), cTrenner( cCh
), nAdjust( nAdj
)
737 pAutoFmt
= new SwTableAutoFmt( *pAFmt
);
739 const SwPosition
* pEnd
= rRg
.End();
740 SwNodes
& rNds
= rRg
.GetDoc()->GetNodes();
741 bSplitEnd
= pEnd
->nContent
.GetIndex() && ( pEnd
->nContent
.GetIndex()
742 != pEnd
->nNode
.GetNode().GetCntntNode()->Len() ||
743 pEnd
->nNode
.GetIndex() >= rNds
.GetEndOfContent().GetIndex()-1 );
746 SwUndoTxtToTbl::~SwUndoTxtToTbl()
752 void SwUndoTxtToTbl::Undo( SwUndoIter
& rUndoIter
)
754 SwDoc
& rDoc
= rUndoIter
.GetDoc();
756 ULONG nTblNd
= nSttNode
;
758 ++nTblNd
; // Node wurde vorher gesplittet
759 SwNodeIndex
aIdx( rDoc
.GetNodes(), nTblNd
);
760 SwTableNode
* pTNd
= rDoc
.GetNodes()[ aIdx
]->GetTableNode();
761 ASSERT( pTNd
, "keinen Tabellen-Node gefunden" );
763 RemoveIdxFromSection( rDoc
, nTblNd
);
765 sTblNm
= pTNd
->GetTable().GetFrmFmt()->GetName();
769 pHistory
->TmpRollback( &rDoc
, 0 );
770 pHistory
->SetTmpEnd( pHistory
->Count() );
775 SwTable
& rTbl
= pTNd
->GetTable();
776 for( USHORT n
= pDelBoxes
->Count(); n
; )
778 SwTableBox
* pBox
= rTbl
.GetTblBox( (*pDelBoxes
)[ --n
] );
780 ::_DeleteBox( rTbl
, pBox
, 0, FALSE
, FALSE
);
782 ASSERT( !this, "Wo ist die Box geblieben?" );
787 SwNodeIndex
aEndIdx( *pTNd
->EndOfSectionNode() );
788 rDoc
.TableToText( pTNd
, 0x0b == cTrenner
? 0x09 : cTrenner
);
790 // am Start wieder zusammenfuegen ?
791 SwPosition
* pPos
= rUndoIter
.pAktPam
->GetPoint();
794 pPos
->nNode
= nTblNd
;
795 pPos
->nContent
.Assign( rDoc
.GetNodes()[ pPos
->nNode
]->GetCntntNode(), 0 );
796 if( rUndoIter
.pAktPam
->Move( fnMoveBackward
, fnGoCntnt
))
798 SwNodeIndex
& rIdx
= rUndoIter
.pAktPam
->GetPoint()->nNode
;
800 // dann die Crsr/etc. nochmal relativ verschieben
801 RemoveIdxRel( rIdx
.GetIndex()+1, *pPos
);
803 rIdx
.GetNode().GetCntntNode()->JoinNext();
807 // am Ende wieder zusammenfuegen ?
810 SwNodeIndex
& rIdx
= pPos
->nNode
;
812 SwTxtNode
* pTxtNd
= rIdx
.GetNode().GetTxtNode();
813 if( pTxtNd
&& pTxtNd
->CanJoinNext() )
815 rUndoIter
.pAktPam
->GetMark()->nContent
.Assign( 0, 0 );
816 rUndoIter
.pAktPam
->GetPoint()->nContent
.Assign( 0, 0 );
818 // dann die Crsr/etc. nochmal relativ verschieben
819 pPos
->nContent
.Assign( pTxtNd
, pTxtNd
->GetTxt().Len() );
820 RemoveIdxRel( nEndNode
+ 1, *pPos
);
826 SetPaM( rUndoIter
); // manipulierten Bereich selectieren
830 void SwUndoTxtToTbl::Redo( SwUndoIter
& rUndoIter
)
833 RemoveIdxFromRange( *rUndoIter
.pAktPam
, FALSE
);
836 const SwTable
* pTable
= rUndoIter
.GetDoc().TextToTable(
837 aInsTblOpts
, *rUndoIter
.pAktPam
, cTrenner
,
839 ((SwFrmFmt
*)pTable
->GetFrmFmt())->SetName( sTblNm
);
843 void SwUndoTxtToTbl::Repeat( SwUndoIter
& rUndoIter
)
845 // keine TABLE IN TABLE
846 if( !rUndoIter
.pAktPam
->GetNode()->FindTableNode() )
847 rUndoIter
.GetDoc().TextToTable( aInsTblOpts
, *rUndoIter
.pAktPam
,
852 void SwUndoTxtToTbl::AddFillBox( const SwTableBox
& rBox
)
855 pDelBoxes
= new SvULongs
;
856 pDelBoxes
->Insert( rBox
.GetSttIdx(), pDelBoxes
->Count() );
859 SwHistory
& SwUndoTxtToTbl::GetHistory()
862 pHistory
= new SwHistory
;
866 // -----------------------------------------------------
868 SwUndoTblHeadline::SwUndoTblHeadline( const SwTable
& rTbl
, USHORT nOldHdl
,
870 : SwUndo( UNDO_TABLEHEADLINE
),
871 nOldHeadline( nOldHdl
),
872 nNewHeadline( nNewHdl
)
874 ASSERT( rTbl
.GetTabSortBoxes().Count(), "Tabelle ohne Inhalt" );
875 const SwStartNode
*pSttNd
= rTbl
.GetTabSortBoxes()[ 0 ]->GetSttNd();
876 ASSERT( pSttNd
, "Box ohne Inhalt" );
878 nTblNd
= pSttNd
->StartOfSectionIndex();
882 void SwUndoTblHeadline::Undo( SwUndoIter
& rUndoIter
)
884 SwDoc
& rDoc
= rUndoIter
.GetDoc();
885 SwTableNode
* pTNd
= rDoc
.GetNodes()[ nTblNd
]->GetTableNode();
886 ASSERT( pTNd
, "keinen Tabellen-Node gefunden" );
888 rDoc
.SetRowsToRepeat( pTNd
->GetTable(), nOldHeadline
);
892 void SwUndoTblHeadline::Redo( SwUndoIter
& rUndoIter
)
894 SwDoc
& rDoc
= rUndoIter
.GetDoc();
896 SwTableNode
* pTNd
= rDoc
.GetNodes()[ nTblNd
]->GetTableNode();
897 ASSERT( pTNd
, "keinen Tabellen-Node gefunden" );
899 rDoc
.SetRowsToRepeat( pTNd
->GetTable(), nNewHeadline
);
903 void SwUndoTblHeadline::Repeat( SwUndoIter
& rUndoIter
)
905 SwTableNode
* pTblNd
= rUndoIter
.pAktPam
->GetNode()->FindTableNode();
907 rUndoIter
.GetDoc().SetRowsToRepeat( pTblNd
->GetTable(), nNewHeadline
);
915 _SaveTable::_SaveTable( const SwTable
& rTbl
, USHORT nLnCnt
, BOOL bSaveFml
)
916 : aTblSet( *rTbl
.GetFrmFmt()->GetAttrSet().GetPool(), aTableSetRange
),
917 pSwTable( &rTbl
), nLineCount( nLnCnt
), bSaveFormula( bSaveFml
)
920 bNewModel
= rTbl
.IsNewModel();
921 aTblSet
.Put( rTbl
.GetFrmFmt()->GetAttrSet() );
922 pLine
= new _SaveLine( 0, *rTbl
.GetTabLines()[ 0 ], *this );
924 _SaveLine
* pLn
= pLine
;
925 if( USHRT_MAX
== nLnCnt
)
926 nLnCnt
= rTbl
.GetTabLines().Count();
927 for( USHORT n
= 1; n
< nLnCnt
; ++n
)
928 pLn
= new _SaveLine( pLn
, *rTbl
.GetTabLines()[ n
], *this );
930 aFrmFmts
.Remove( 0, aFrmFmts
.Count() );
935 _SaveTable::~_SaveTable()
941 USHORT
_SaveTable::AddFmt( SwFrmFmt
* pFmt
, bool bIsLine
)
943 USHORT nRet
= aFrmFmts
.GetPos( pFmt
);
944 if( USHRT_MAX
== nRet
)
946 // Kopie vom ItemSet anlegen
947 SfxItemSet
* pSet
= new SfxItemSet( *pFmt
->GetAttrSet().GetPool(),
948 bIsLine
? aTableLineSetRange
: aTableBoxSetRange
);
949 pSet
->Put( pFmt
->GetAttrSet() );
950 //JP 20.04.98: Bug 49502 - wenn eine Formel gesetzt ist, nie den
951 // Value mit sichern. Der muss gegebenfalls neu
953 //JP 30.07.98: Bug 54295 - Formeln immer im Klartext speichern
954 const SfxPoolItem
* pItem
;
955 if( SFX_ITEM_SET
== pSet
->GetItemState( RES_BOXATR_FORMULA
, TRUE
, &pItem
))
957 pSet
->ClearItem( RES_BOXATR_VALUE
);
958 if( pSwTable
&& bSaveFormula
)
960 SwTableFmlUpdate
aMsgHnt( pSwTable
);
961 aMsgHnt
.eFlags
= TBL_BOXNAME
;
962 ((SwTblBoxFormula
*)pItem
)->ChgDefinedIn( pFmt
);
963 ((SwTblBoxFormula
*)pItem
)->ChangeState( &aMsgHnt
);
964 ((SwTblBoxFormula
*)pItem
)->ChgDefinedIn( 0 );
967 aSets
.Insert( pSet
, (nRet
= aSets
.Count() ) );
968 aFrmFmts
.Insert( pFmt
, nRet
);
974 void _SaveTable::RestoreAttr( SwTable
& rTbl
, BOOL bMdfyBox
)
978 bModifyBox
= bMdfyBox
;
980 // zuerst die Attribute des TabellenFrmFormates zurueck holen
981 SwFrmFmt
* pFmt
= rTbl
.GetFrmFmt();
982 SfxItemSet
& rFmtSet
= (SfxItemSet
&)pFmt
->GetAttrSet();
984 rFmtSet
.Put( aTblSet
);
986 if( pFmt
->IsInCache() )
988 SwFrm::GetCache().Delete( pFmt
);
989 pFmt
->SetInCache( FALSE
);
992 // zur Sicherheit alle Tableframes invalidieren
993 SwClientIter
aIter( *pFmt
);
994 for( SwClient
* pLast
= aIter
.First( TYPE( SwFrm
) ); pLast
; pLast
= aIter
.Next() )
995 if( ((SwTabFrm
*)pLast
)->GetTable() == &rTbl
)
997 ((SwTabFrm
*)pLast
)->InvalidateAll();
998 ((SwTabFrm
*)pLast
)->SetCompletePaint();
1001 // FrmFmts mit Defaults (0) fuellen
1003 for( n
= aSets
.Count(); n
; --n
)
1004 aFrmFmts
.Insert( pFmt
, aFrmFmts
.Count() );
1006 USHORT nLnCnt
= nLineCount
;
1007 if( USHRT_MAX
== nLnCnt
)
1008 nLnCnt
= rTbl
.GetTabLines().Count();
1010 _SaveLine
* pLn
= pLine
;
1011 for( n
= 0; n
< nLnCnt
; ++n
, pLn
= pLn
->pNext
)
1015 ASSERT( !this, "Anzahl der Lines hat sich veraendert" );
1019 pLn
->RestoreAttr( *rTbl
.GetTabLines()[ n
], *this );
1022 aFrmFmts
.Remove( 0, aFrmFmts
.Count() );
1027 void _SaveTable::SaveCntntAttrs( SwDoc
* pDoc
)
1029 pLine
->SaveCntntAttrs( pDoc
);
1033 void _SaveTable::CreateNew( SwTable
& rTbl
, BOOL bCreateFrms
,
1034 BOOL bRestoreChart
)
1038 _FndBox
aTmpBox( 0, 0 );
1039 //if( bRestoreChart )
1040 // // ? TL_CHART2: notification or locking of controller required ?
1041 aTmpBox
.DelFrms( rTbl
);
1043 // zuerst die Attribute des TabellenFrmFormates zurueck holen
1044 SwFrmFmt
* pFmt
= rTbl
.GetFrmFmt();
1045 SfxItemSet
& rFmtSet
= (SfxItemSet
&)pFmt
->GetAttrSet();
1046 rFmtSet
.ClearItem();
1047 rFmtSet
.Put( aTblSet
);
1049 if( pFmt
->IsInCache() )
1051 SwFrm::GetCache().Delete( pFmt
);
1052 pFmt
->SetInCache( FALSE
);
1055 // SwTableBox muss ein Format haben!!
1056 SwTableBox
aParent( (SwTableBoxFmt
*)pFmt
, rTbl
.GetTabLines().Count(), 0 );
1058 // FrmFmts mit Defaults (0) fuellen
1060 for( n
= aSets
.Count(); n
; --n
)
1061 aFrmFmts
.Insert( pFmt
, aFrmFmts
.Count() );
1063 pLine
->CreateNew( rTbl
, aParent
, *this );
1064 aFrmFmts
.Remove( 0, aFrmFmts
.Count() );
1066 // die neuen Lines eintragen, die alten loeschen
1067 USHORT nOldLines
= nLineCount
;
1068 if( USHRT_MAX
== nLineCount
)
1069 nOldLines
= rTbl
.GetTabLines().Count();
1071 SwDoc
*pDoc
= rTbl
.GetFrmFmt()->GetDoc();
1072 SwChartDataProvider
*pPCD
= pDoc
->GetChartDataProvider();
1073 for( n
= 0; n
< aParent
.GetTabLines().Count(); ++n
)
1075 SwTableLine
* pLn
= aParent
.GetTabLines()[ n
];
1079 SwTableLine
* pOld
= rTbl
.GetTabLines()[ n
];
1081 // TL_CHART2: notify chart about boxes to be removed
1082 const SwTableBoxes
&rBoxes
= pOld
->GetTabBoxes();
1083 USHORT nBoxes
= rBoxes
.Count();
1084 for (USHORT k
= 0; k
< nBoxes
; ++k
)
1086 SwTableBox
*pBox
= rBoxes
[k
];
1088 pPCD
->DeleteBox( &rTbl
, *pBox
);
1091 rTbl
.GetTabLines().C40_REPLACE( SwTableLine
, pLn
, n
);
1095 rTbl
.GetTabLines().C40_INSERT( SwTableLine
, pLn
, n
);
1100 // remove remaining lines...
1102 for (USHORT k1
= 0; k1
< nOldLines
- n
; ++k1
)
1104 const SwTableBoxes
&rBoxes
= rTbl
.GetTabLines()[n
+ k1
]->GetTabBoxes();
1105 USHORT nBoxes
= rBoxes
.Count();
1106 for (USHORT k2
= 0; k2
< nBoxes
; ++k2
)
1108 SwTableBox
*pBox
= rBoxes
[k2
];
1109 // TL_CHART2: notify chart about boxes to be removed
1111 pPCD
->DeleteBox( &rTbl
, *pBox
);
1115 rTbl
.GetTabLines().DeleteAndDestroy( n
, nOldLines
- n
);
1118 aParent
.GetTabLines().Remove( 0, n
);
1121 aTmpBox
.MakeFrms( rTbl
);
1124 // TL_CHART2: need to inform chart of probably changed cell names
1125 pDoc
->UpdateCharts( rTbl
.GetFrmFmt()->GetName() );
1130 void _SaveTable::NewFrmFmt( const SwClient
* pLnBx
, BOOL bIsLine
,
1131 USHORT nFmtPos
, SwFrmFmt
* pOldFmt
)
1133 SwDoc
* pDoc
= pOldFmt
->GetDoc();
1135 SwFrmFmt
* pFmt
= aFrmFmts
[ nFmtPos
];
1139 pFmt
= pDoc
->MakeTableLineFmt();
1141 pFmt
= pDoc
->MakeTableBoxFmt();
1142 pFmt
->SetFmtAttr( *aSets
[ nFmtPos
] );
1143 aFrmFmts
.Replace( pFmt
, nFmtPos
);
1146 //Erstmal die Frms ummelden.
1147 SwClientIter
aIter( *pOldFmt
);
1148 for( SwClient
* pLast
= aIter
.First( TYPE( SwFrm
) ); pLast
; pLast
= aIter
.Next() )
1150 if( bIsLine
? pLnBx
== ((SwRowFrm
*)pLast
)->GetTabLine()
1151 : pLnBx
== ((SwCellFrm
*)pLast
)->GetTabBox() )
1154 ((SwFrm
*)pLast
)->InvalidateAll();
1155 ((SwFrm
*)pLast
)->ReinitializeFrmSizeAttrFlags();
1158 ((SwCellFrm
*)pLast
)->SetDerivedVert( FALSE
);
1159 ((SwCellFrm
*)pLast
)->CheckDirChange();
1164 //Jetzt noch mich selbst ummelden.
1165 pFmt
->Add( (SwClient
*)pLnBx
);
1167 if( bModifyBox
&& !bIsLine
)
1169 const SfxPoolItem
& rOld
= pOldFmt
->GetFmtAttr( RES_BOXATR_FORMAT
),
1170 & rNew
= pFmt
->GetFmtAttr( RES_BOXATR_FORMAT
);
1172 pFmt
->Modify( (SfxPoolItem
*)&rOld
, (SfxPoolItem
*)&rNew
);
1175 if( !pOldFmt
->GetDepends() )
1181 _SaveLine::_SaveLine( _SaveLine
* pPrev
, const SwTableLine
& rLine
, _SaveTable
& rSTbl
)
1185 pPrev
->pNext
= this;
1187 nItemSet
= rSTbl
.AddFmt( rLine
.GetFrmFmt(), true );
1189 pBox
= new _SaveBox( 0, *rLine
.GetTabBoxes()[ 0 ], rSTbl
);
1190 _SaveBox
* pBx
= pBox
;
1191 for( USHORT n
= 1; n
< rLine
.GetTabBoxes().Count(); ++n
)
1192 pBx
= new _SaveBox( pBx
, *rLine
.GetTabBoxes()[ n
], rSTbl
);
1196 _SaveLine::~_SaveLine()
1203 void _SaveLine::RestoreAttr( SwTableLine
& rLine
, _SaveTable
& rSTbl
)
1205 rSTbl
.NewFrmFmt( &rLine
, TRUE
, nItemSet
, rLine
.GetFrmFmt() );
1207 _SaveBox
* pBx
= pBox
;
1208 for( USHORT n
= 0; n
< rLine
.GetTabBoxes().Count(); ++n
, pBx
= pBx
->pNext
)
1212 ASSERT( !this, "Anzahl der Boxen hat sich veraendert" );
1215 pBx
->RestoreAttr( *rLine
.GetTabBoxes()[ n
], rSTbl
);
1220 void _SaveLine::SaveCntntAttrs( SwDoc
* pDoc
)
1222 pBox
->SaveCntntAttrs( pDoc
);
1224 pNext
->SaveCntntAttrs( pDoc
);
1228 void _SaveLine::CreateNew( SwTable
& rTbl
, SwTableBox
& rParent
, _SaveTable
& rSTbl
)
1230 SwTableLineFmt
* pFmt
= (SwTableLineFmt
*)rSTbl
.aFrmFmts
[ nItemSet
];
1233 SwDoc
* pDoc
= rTbl
.GetFrmFmt()->GetDoc();
1234 pFmt
= pDoc
->MakeTableLineFmt();
1235 pFmt
->SetFmtAttr( *rSTbl
.aSets
[ nItemSet
] );
1236 rSTbl
.aFrmFmts
.Replace( pFmt
, nItemSet
);
1238 SwTableLine
* pNew
= new SwTableLine( pFmt
, 1, &rParent
);
1240 rParent
.GetTabLines().C40_INSERT( SwTableLine
, pNew
, rParent
.GetTabLines().Count() );
1242 // HB, #127868# robustness: in some cases - which I
1243 // cannot reproduce nor see from the code - pNew seems
1244 // to be set to NULL in C40_INSERT.
1245 ASSERT(pNew
, "Table line just created set to NULL in C40_INSERT");
1249 pBox
->CreateNew( rTbl
, *pNew
, rSTbl
);
1253 pNext
->CreateNew( rTbl
, rParent
, rSTbl
);
1257 _SaveBox::_SaveBox( _SaveBox
* pPrev
, const SwTableBox
& rBox
, _SaveTable
& rSTbl
)
1258 : pNext( 0 ), nSttNode( ULONG_MAX
), nRowSpan(0)
1263 pPrev
->pNext
= this;
1265 nItemSet
= rSTbl
.AddFmt( rBox
.GetFrmFmt(), false );
1267 if( rBox
.GetSttNd() )
1269 nSttNode
= rBox
.GetSttIdx();
1270 nRowSpan
= rBox
.getRowSpan();
1274 Ptrs
.pLine
= new _SaveLine( 0, *rBox
.GetTabLines()[ 0 ], rSTbl
);
1276 _SaveLine
* pLn
= Ptrs
.pLine
;
1277 for( USHORT n
= 1; n
< rBox
.GetTabLines().Count(); ++n
)
1278 pLn
= new _SaveLine( pLn
, *rBox
.GetTabLines()[ n
], rSTbl
);
1283 _SaveBox::~_SaveBox()
1285 if( ULONG_MAX
== nSttNode
) // keine EndBox
1288 delete Ptrs
.pCntntAttrs
;
1293 void _SaveBox::RestoreAttr( SwTableBox
& rBox
, _SaveTable
& rSTbl
)
1295 rSTbl
.NewFrmFmt( &rBox
, FALSE
, nItemSet
, rBox
.GetFrmFmt() );
1297 if( ULONG_MAX
== nSttNode
) // keine EndBox
1299 if( !rBox
.GetTabLines().Count() )
1301 ASSERT( !this, "Anzahl der Lines hat sich veraendert" );
1305 _SaveLine
* pLn
= Ptrs
.pLine
;
1306 for( USHORT n
= 0; n
< rBox
.GetTabLines().Count(); ++n
, pLn
= pLn
->pNext
)
1310 ASSERT( !this, "Anzahl der Lines hat sich veraendert" );
1314 pLn
->RestoreAttr( *rBox
.GetTabLines()[ n
], rSTbl
);
1318 else if( rBox
.GetSttNd() && rBox
.GetSttIdx() == nSttNode
)
1320 if( Ptrs
.pCntntAttrs
)
1322 SwNodes
& rNds
= rBox
.GetFrmFmt()->GetDoc()->GetNodes();
1324 ULONG nEnd
= rBox
.GetSttNd()->EndOfSectionIndex();
1325 for( ULONG n
= nSttNode
+ 1; n
< nEnd
; ++n
)
1327 SwCntntNode
* pCNd
= rNds
[ n
]->GetCntntNode();
1330 SfxItemSet
* pSet
= (*Ptrs
.pCntntAttrs
)[ nSet
++ ];
1333 USHORT
*pRstAttr
= aSave_BoxCntntSet
;
1336 pCNd
->ResetAttr( *pRstAttr
, *(pRstAttr
+1) );
1339 pCNd
->SetAttr( *pSet
);
1342 pCNd
->ResetAllAttr();
1349 ASSERT( !this, "Box nicht mehr am gleichen Node" );
1354 void _SaveBox::SaveCntntAttrs( SwDoc
* pDoc
)
1356 if( ULONG_MAX
== nSttNode
) // keine EndBox
1358 // weiter in der Line
1359 Ptrs
.pLine
->SaveCntntAttrs( pDoc
);
1363 ULONG nEnd
= pDoc
->GetNodes()[ nSttNode
]->EndOfSectionIndex();
1364 Ptrs
.pCntntAttrs
= new SfxItemSets( (BYTE
)(nEnd
- nSttNode
- 1 ), 5 );
1365 for( ULONG n
= nSttNode
+ 1; n
< nEnd
; ++n
)
1367 SwCntntNode
* pCNd
= pDoc
->GetNodes()[ n
]->GetCntntNode();
1370 SfxItemSet
* pSet
= 0;
1371 if( pCNd
->HasSwAttrSet() )
1373 pSet
= new SfxItemSet( pDoc
->GetAttrPool(),
1374 aSave_BoxCntntSet
);
1375 pSet
->Put( *pCNd
->GetpSwAttrSet() );
1378 Ptrs
.pCntntAttrs
->Insert( pSet
, Ptrs
.pCntntAttrs
->Count() );
1383 pNext
->SaveCntntAttrs( pDoc
);
1387 void _SaveBox::CreateNew( SwTable
& rTbl
, SwTableLine
& rParent
, _SaveTable
& rSTbl
)
1389 SwTableBoxFmt
* pFmt
= (SwTableBoxFmt
*)rSTbl
.aFrmFmts
[ nItemSet
];
1392 SwDoc
* pDoc
= rTbl
.GetFrmFmt()->GetDoc();
1393 pFmt
= pDoc
->MakeTableBoxFmt();
1394 pFmt
->SetFmtAttr( *rSTbl
.aSets
[ nItemSet
] );
1395 rSTbl
.aFrmFmts
.Replace( pFmt
, nItemSet
);
1398 if( ULONG_MAX
== nSttNode
) // keine EndBox
1400 SwTableBox
* pNew
= new SwTableBox( pFmt
, 1, &rParent
);
1401 rParent
.GetTabBoxes().C40_INSERT( SwTableBox
, pNew
, rParent
.GetTabBoxes().Count() );
1403 Ptrs
.pLine
->CreateNew( rTbl
, *pNew
, rSTbl
);
1407 // Box zum StartNode in der alten Tabelle suchen
1408 SwTableBox
* pBox
= rTbl
.GetTblBox( nSttNode
);
1409 ASSERT( pBox
, "Wo ist meine TabellenBox geblieben?" );
1411 SwFrmFmt
* pOld
= pBox
->GetFrmFmt();
1413 if( !pOld
->GetDepends() )
1416 pBox
->setRowSpan( nRowSpan
);
1418 SwTableBoxes
* pTBoxes
= &pBox
->GetUpper()->GetTabBoxes();
1419 pTBoxes
->Remove( pTBoxes
->C40_GETPOS( SwTableBox
, pBox
) );
1421 pBox
->SetUpper( &rParent
);
1422 pTBoxes
= &rParent
.GetTabBoxes();
1423 pTBoxes
->C40_INSERT( SwTableBox
, pBox
, pTBoxes
->Count() );
1427 pNext
->CreateNew( rTbl
, rParent
, rSTbl
);
1433 // UndoObject fuer Attribut Aenderung an der Tabelle
1436 SwUndoAttrTbl::SwUndoAttrTbl( const SwTableNode
& rTblNd
, BOOL bClearTabCols
)
1437 : SwUndo( UNDO_TABLE_ATTR
),
1438 nSttNode( rTblNd
.GetIndex() )
1440 bClearTabCol
= bClearTabCols
;
1441 pSaveTbl
= new _SaveTable( rTblNd
.GetTable() );
1445 SwUndoAttrTbl::~SwUndoAttrTbl()
1452 void SwUndoAttrTbl::Undo( SwUndoIter
& rUndoIter
)
1454 SwDoc
& rDoc
= rUndoIter
.GetDoc();
1455 SwTableNode
* pTblNd
= rDoc
.GetNodes()[ nSttNode
]->GetTableNode();
1456 ASSERT( pTblNd
, "kein TabellenNode" );
1460 _SaveTable
* pOrig
= new _SaveTable( pTblNd
->GetTable() );
1461 pSaveTbl
->RestoreAttr( pTblNd
->GetTable() );
1467 ClearFEShellTabCols();
1471 void SwUndoAttrTbl::Redo( SwUndoIter
& rUndoIter
)
1479 // UndoObject fuer AutoFormat an der Tabelle
1482 SwUndoTblAutoFmt::SwUndoTblAutoFmt( const SwTableNode
& rTblNd
,
1483 const SwTableAutoFmt
& rAFmt
)
1484 : SwUndo( UNDO_TABLE_AUTOFMT
),
1485 nSttNode( rTblNd
.GetIndex() ), pUndos( 0 ),
1486 bSaveCntntAttr( FALSE
)
1488 pSaveTbl
= new _SaveTable( rTblNd
.GetTable() );
1490 if( rAFmt
.IsFont() || rAFmt
.IsJustify() )
1492 // dann auch noch ueber die ContentNodes der EndBoxen und
1493 // und alle Absatz-Attribute zusammen sammeln
1494 pSaveTbl
->SaveCntntAttrs( (SwDoc
*)rTblNd
.GetDoc() );
1495 bSaveCntntAttr
= TRUE
;
1500 SwUndoTblAutoFmt::~SwUndoTblAutoFmt()
1506 void SwUndoTblAutoFmt::SaveBoxCntnt( const SwTableBox
& rBox
)
1508 SwUndoTblNumFmt
* p
= new SwUndoTblNumFmt( rBox
);
1510 pUndos
= new SwUndos( 8, 8 );
1511 pUndos
->Insert( p
, pUndos
->Count() );
1515 void SwUndoTblAutoFmt::UndoRedo( BOOL bUndo
, SwUndoIter
& rUndoIter
)
1517 SwDoc
& rDoc
= rUndoIter
.GetDoc();
1518 SwTableNode
* pTblNd
= rDoc
.GetNodes()[ nSttNode
]->GetTableNode();
1519 ASSERT( pTblNd
, "kein TabellenNode" );
1521 _SaveTable
* pOrig
= new _SaveTable( pTblNd
->GetTable() );
1522 // dann auch noch ueber die ContentNodes der EndBoxen und
1523 // und alle Absatz-Attribute zusammen sammeln
1524 if( bSaveCntntAttr
)
1525 pOrig
->SaveCntntAttrs( &rDoc
);
1527 if( pUndos
&& bUndo
)
1528 for( USHORT n
= pUndos
->Count(); n
; )
1529 pUndos
->GetObject( --n
)->Undo( rUndoIter
);
1531 pSaveTbl
->RestoreAttr( pTblNd
->GetTable(), !bUndo
);
1536 void SwUndoTblAutoFmt::Undo( SwUndoIter
& rUndoIter
)
1538 UndoRedo( TRUE
, rUndoIter
);
1542 void SwUndoTblAutoFmt::Redo( SwUndoIter
& rUndoIter
)
1544 UndoRedo( FALSE
, rUndoIter
);
1551 SwUndoTblNdsChg::SwUndoTblNdsChg( SwUndoId nAction
,
1552 const SwSelBoxes
& rBoxes
,
1553 const SwTableNode
& rTblNd
,
1555 USHORT nCnt
, BOOL bFlg
, BOOL bSmHght
)
1556 : SwUndo( nAction
),
1557 aBoxes( rBoxes
.Count() < 255 ? (BYTE
)rBoxes
.Count() : 255, 10 ),
1558 nMin( nMn
), nMax( nMx
),
1559 nSttNode( rTblNd
.GetIndex() ), nCurrBox( 0 ),
1560 nCount( nCnt
), nRelDiff( 0 ), nAbsDiff( 0 ),
1561 nSetColType( USHRT_MAX
),
1563 bSameHeight( bSmHght
)
1565 Ptrs
.pNewSttNds
= 0;
1567 const SwTable
& rTbl
= rTblNd
.GetTable();
1568 pSaveTbl
= new _SaveTable( rTbl
);
1570 // und die Selektion merken
1571 for( USHORT n
= 0; n
< rBoxes
.Count(); ++n
)
1572 aBoxes
.Insert( rBoxes
[n
]->GetSttIdx(), n
);
1576 SwUndoTblNdsChg::SwUndoTblNdsChg( SwUndoId nAction
,
1577 const SwSelBoxes
& rBoxes
,
1578 const SwTableNode
& rTblNd
)
1579 : SwUndo( nAction
),
1580 aBoxes( rBoxes
.Count() < 255 ? (BYTE
)rBoxes
.Count() : 255, 10 ),
1581 nMin( 0 ), nMax( 0 ),
1582 nSttNode( rTblNd
.GetIndex() ), nCurrBox( 0 ),
1583 nCount( 0 ), nRelDiff( 0 ), nAbsDiff( 0 ),
1584 nSetColType( USHRT_MAX
),
1586 bSameHeight( FALSE
)
1588 Ptrs
.pNewSttNds
= 0;
1590 const SwTable
& rTbl
= rTblNd
.GetTable();
1591 pSaveTbl
= new _SaveTable( rTbl
);
1593 // und die Selektion merken
1594 for( USHORT n
= 0; n
< rBoxes
.Count(); ++n
)
1595 aBoxes
.Insert( rBoxes
[n
]->GetSttIdx(), n
);
1598 void SwUndoTblNdsChg::ReNewBoxes( const SwSelBoxes
& rBoxes
)
1600 if( rBoxes
.Count() != aBoxes
.Count() )
1602 aBoxes
.Remove( 0, aBoxes
.Count() );
1603 for( USHORT n
= 0; n
< rBoxes
.Count(); ++n
)
1604 aBoxes
.Insert( rBoxes
[n
]->GetSttIdx(), n
);
1608 SwUndoTblNdsChg::~SwUndoTblNdsChg()
1613 delete Ptrs
.pDelSects
;
1615 delete Ptrs
.pNewSttNds
;
1618 void SwUndoTblNdsChg::SaveNewBoxes( const SwTableNode
& rTblNd
,
1619 const SwTableSortBoxes
& rOld
)
1621 const SwTable
& rTbl
= rTblNd
.GetTable();
1622 const SwTableSortBoxes
& rTblBoxes
= rTbl
.GetTabSortBoxes();
1626 ASSERT( ! IsDelBox(), "falsche Action" );
1627 Ptrs
.pNewSttNds
= new SvULongs( (BYTE
)(rTblBoxes
.Count() - rOld
.Count()), 5 );
1629 for( n
= 0, i
= 0; n
< rOld
.Count(); ++i
)
1631 if( rOld
[ n
] == rTblBoxes
[ i
] )
1634 // neue Box: sortiert einfuegen!!
1635 InsertSort( *Ptrs
.pNewSttNds
, rTblBoxes
[ i
]->GetSttIdx() );
1638 for( ; i
< rTblBoxes
.Count(); ++i
)
1639 // neue Box: sortiert einfuegen!!
1640 InsertSort( *Ptrs
.pNewSttNds
, rTblBoxes
[ i
]->GetSttIdx() );
1644 SwTableLine
* lcl_FindTableLine( const SwTable
& rTable
,
1645 const SwTableBox
& rBox
)
1647 SwTableLine
* pRet
= NULL
;
1648 // i63949: For nested cells we have to take nLineNo - 1, too, not 0!
1649 const SwTableLines
&rTableLines
= ( rBox
.GetUpper()->GetUpper() != NULL
) ?
1650 rBox
.GetUpper()->GetUpper()->GetTabLines()
1651 : rTable
.GetTabLines();
1652 const SwTableLine
* pLine
= rBox
.GetUpper();
1653 USHORT nLineNo
= rTableLines
.C40_GETPOS( SwTableLine
, pLine
);
1654 pRet
= rTableLines
[nLineNo
- 1];
1659 const SwTableLines
& lcl_FindParentLines( const SwTable
& rTable
,
1660 const SwTableBox
& rBox
)
1662 const SwTableLines
& rRet
=
1663 ( rBox
.GetUpper()->GetUpper() != NULL
) ?
1664 rBox
.GetUpper()->GetUpper()->GetTabLines() :
1665 rTable
.GetTabLines();
1671 void SwUndoTblNdsChg::SaveNewBoxes( const SwTableNode
& rTblNd
,
1672 const SwTableSortBoxes
& rOld
,
1673 const SwSelBoxes
& rBoxes
,
1674 const SvULongs
& rNodeCnts
)
1676 const SwTable
& rTbl
= rTblNd
.GetTable();
1677 const SwTableSortBoxes
& rTblBoxes
= rTbl
.GetTabSortBoxes();
1679 ASSERT( ! IsDelBox(), "falsche Action" );
1680 Ptrs
.pNewSttNds
= new SvULongs( (BYTE
)(rTblBoxes
.Count() - rOld
.Count()), 5 );
1682 ASSERT( rTbl
.IsNewModel() || rOld
.Count() + nCount
* rBoxes
.Count() == rTblBoxes
.Count(),
1683 "unexpected boxes" );
1684 ASSERT( rOld
.Count() <= rTblBoxes
.Count(), "more unexpected boxes" );
1685 for( USHORT n
= 0, i
= 0; i
< rTblBoxes
.Count(); ++i
)
1687 if( ( n
< rOld
.Count() ) &&
1688 ( rOld
[ n
] == rTblBoxes
[ i
] ) )
1690 // box already known? Then nothing to be done.
1695 // new box found: insert (obey sort order)
1697 const SwTableBox
* pBox
= rTblBoxes
[ i
];
1698 InsertSort( *Ptrs
.pNewSttNds
, pBox
->GetSttIdx(), &nInsPos
);
1700 // find the source box. It must be one in rBoxes.
1701 // We found the right one if it's in the same column as pBox.
1702 // No, if more than one selected cell in the same column has been splitted,
1703 // we have to look for the nearest one (i65201)!
1704 const SwTableBox
* pSourceBox
= NULL
;
1705 const SwTableBox
* pCheckBox
= NULL
;
1706 const SwTableLine
* pBoxLine
= pBox
->GetUpper();
1707 USHORT nLineDiff
= lcl_FindParentLines(rTbl
,*pBox
).C40_GETPOS(SwTableLine
,pBoxLine
);
1709 for( USHORT j
= 0; j
< rBoxes
.Count(); ++j
)
1711 pCheckBox
= rBoxes
[j
];
1712 if( pCheckBox
->GetUpper()->GetUpper() == pBox
->GetUpper()->GetUpper() )
1714 const SwTableLine
* pCheckLine
= pCheckBox
->GetUpper();
1715 USHORT nCheckLine
= lcl_FindParentLines( rTbl
, *pCheckBox
).
1716 C40_GETPOS( SwTableLine
, pCheckLine
);
1717 if( ( !pSourceBox
|| nCheckLine
> nLineNo
) && nCheckLine
< nLineDiff
)
1719 nLineNo
= nCheckLine
;
1720 pSourceBox
= pCheckBox
;
1725 // find the line number difference
1726 // (to help determine bNodesMoved flag below)
1727 nLineDiff
= nLineDiff
- nLineNo
;
1728 ASSERT( pSourceBox
, "Splitted source box not found!" );
1729 // find out how many nodes the source box used to have
1730 // (to help determine bNodesMoved flag below)
1732 while( rBoxes
[ nNdsPos
] != pSourceBox
)
1734 ULONG nNodes
= rNodeCnts
[ nNdsPos
];
1736 // When a new table cell is created, it either gets a new
1737 // node, or it gets node(s) from elsewhere. The undo must
1738 // know, of course, and thus we must determine here just
1739 // where pBox's nodes are from:
1740 // If 1) the source box has lost nodes, and
1741 // 2) we're in the node range that got nodes
1742 // then pBox received nodes from elsewhere.
1743 // If bNodesMoved is set for pBox the undo must move the
1744 // boxes back, otherwise it must delete them.
1745 // The bNodesMoved flag is stored in a seperate array
1746 // which mirrors Ptrs.pNewSttNds, i.e. Ptrs.pNewSttNds[i]
1747 // and aMvBoxes[i] belong together.
1749 ( nNodes
!= ( pSourceBox
->GetSttNd()->EndOfSectionIndex() -
1750 pSourceBox
->GetSttIdx() ) )
1751 && ( nNodes
- 1 > nLineDiff
);
1752 aMvBoxes
.Insert( bNodesMoved
, nInsPos
);
1758 void SwUndoTblNdsChg::SaveSection( SwStartNode
* pSttNd
)
1760 ASSERT( IsDelBox(), "falsche Action" );
1761 if( !Ptrs
.pDelSects
)
1762 Ptrs
.pDelSects
= new SwUndoSaveSections( 10, 5 );
1764 SwTableNode
* pTblNd
= pSttNd
->FindTableNode();
1765 SwUndoSaveSection
* pSave
= new SwUndoSaveSection
;
1766 pSave
->SaveSection( pSttNd
->GetDoc(), SwNodeIndex( *pSttNd
));
1768 Ptrs
.pDelSects
->Insert( pSave
, Ptrs
.pDelSects
->Count() );
1769 nSttNode
= pTblNd
->GetIndex();
1773 void SwUndoTblNdsChg::Undo( SwUndoIter
& rUndoIter
)
1775 SwDoc
& rDoc
= rUndoIter
.GetDoc();
1776 SwNodeIndex
aIdx( rDoc
.GetNodes(), nSttNode
);
1778 SwTableNode
* pTblNd
= rDoc
.GetNodes()[ aIdx
]->GetTableNode();
1779 ASSERT( pTblNd
, "kein TabellenNode" );
1781 SwTableFmlUpdate
aMsgHnt( &pTblNd
->GetTable() );
1782 aMsgHnt
.eFlags
= TBL_BOXPTR
;
1783 rDoc
.UpdateTblFlds( &aMsgHnt
);
1785 CHECK_TABLE( pTblNd
->GetTable() )
1787 _FndBox
aTmpBox( 0, 0 );
1788 // ? TL_CHART2: notification or locking of controller required ?
1790 SwChartDataProvider
*pPCD
= rDoc
.GetChartDataProvider();
1791 std::vector
< SwTableBox
* > aDelBoxes
;
1794 // Trick: die fehlenden Boxen in irgendeine Line einfuegen, beim
1795 // CreateNew werden sie korrekt verbunden.
1796 SwTableBox
* pCpyBox
= pTblNd
->GetTable().GetTabSortBoxes()[0];
1797 SwTableBoxes
& rLnBoxes
= pCpyBox
->GetUpper()->GetTabBoxes();
1799 // die Sections wieder herstellen
1800 for( USHORT n
= Ptrs
.pDelSects
->Count(); n
; )
1802 SwUndoSaveSection
* pSave
= (*Ptrs
.pDelSects
)[ --n
];
1803 pSave
->RestoreSection( &rDoc
, &aIdx
, SwTableBoxStartNode
);
1804 if( pSave
->GetHistory() )
1805 pSave
->GetHistory()->Rollback( &rDoc
);
1806 SwTableBox
* pBox
= new SwTableBox( (SwTableBoxFmt
*)pCpyBox
->GetFrmFmt(), aIdx
,
1807 pCpyBox
->GetUpper() );
1808 rLnBoxes
.C40_INSERT( SwTableBox
, pBox
, rLnBoxes
.Count() );
1810 Ptrs
.pDelSects
->DeleteAndDestroy( 0, Ptrs
.pDelSects
->Count() );
1812 else if( aMvBoxes
.Count() )
1814 // dann muessen Nodes verschoben und nicht geloescht werden!
1815 // Dafuer brauchen wir aber ein temp Array
1816 SvULongs
aTmp( 0, 5);
1817 aTmp
.Insert( Ptrs
.pNewSttNds
, 0 );
1819 // von hinten anfangen
1820 for( USHORT n
= aTmp
.Count(); n
; )
1822 // Box aus der Tabellen-Struktur entfernen
1823 ULONG nIdx
= aTmp
[ --n
];
1824 SwTableBox
* pBox
= pTblNd
->GetTable().GetTblBox( nIdx
);
1825 ASSERT( pBox
, "Wo ist meine TabellenBox geblieben?" );
1827 // TL_CHART2: notify chart about box to be removed
1829 pPCD
->DeleteBox( &pTblNd
->GetTable(), *pBox
);
1833 SwNodeRange
aRg( *pBox
->GetSttNd(), 1,
1834 *pBox
->GetSttNd()->EndOfSectionNode() );
1836 SwTableLine
* pLine
= lcl_FindTableLine( pTblNd
->GetTable(), *pBox
);
1837 SwNodeIndex
aInsPos( *(pLine
->GetTabBoxes()[0]->GetSttNd()), 2 );
1839 // alle StartNode Indizies anpassen
1841 ULONG nSttIdx
= aInsPos
.GetIndex() - 2,
1842 nNdCnt
= aRg
.aEnd
.GetIndex() - aRg
.aStart
.GetIndex();
1843 while( i
&& aTmp
[ --i
] > nSttIdx
)
1844 aTmp
[ i
] += nNdCnt
;
1846 // erst die Box loeschen
1848 // dann die Nodes verschieben,
1849 rDoc
.GetNodes()._MoveNodes( aRg
, rDoc
.GetNodes(), aInsPos
, FALSE
);
1852 rDoc
.DeleteSection( rDoc
.GetNodes()[ nIdx
] );
1853 aDelBoxes
.insert( aDelBoxes
.end(), pBox
);
1858 // Remove nodes from nodes array (backwards!)
1859 for( USHORT n
= Ptrs
.pNewSttNds
->Count(); n
; )
1861 ULONG nIdx
= (*Ptrs
.pNewSttNds
)[ --n
];
1862 SwTableBox
* pBox
= pTblNd
->GetTable().GetTblBox( nIdx
);
1863 ASSERT( pBox
, "Where's my table box?" );
1864 // TL_CHART2: notify chart about box to be removed
1866 pPCD
->DeleteBox( &pTblNd
->GetTable(), *pBox
);
1867 aDelBoxes
.insert( aDelBoxes
.end(), pBox
);
1868 rDoc
.DeleteSection( rDoc
.GetNodes()[ nIdx
] );
1871 // Remove boxes from table structure
1872 for( USHORT n
= 0; n
< aDelBoxes
.size(); ++n
)
1874 SwTableBox
* pCurrBox
= aDelBoxes
[n
];
1875 SwTableBoxes
* pTBoxes
= &pCurrBox
->GetUpper()->GetTabBoxes();
1876 pTBoxes
->Remove( pTBoxes
->C40_GETPOS( SwTableBox
, pCurrBox
) );
1880 pSaveTbl
->CreateNew( pTblNd
->GetTable(), TRUE
, FALSE
);
1882 // TL_CHART2: need to inform chart of probably changed cell names
1883 rDoc
.UpdateCharts( pTblNd
->GetTable().GetFrmFmt()->GetName() );
1886 nSttNode
= pTblNd
->GetIndex();
1887 ClearFEShellTabCols();
1888 CHECK_TABLE( pTblNd
->GetTable() )
1892 void SwUndoTblNdsChg::Redo( SwUndoIter
& rUndoIter
)
1894 SwDoc
& rDoc
= rUndoIter
.GetDoc();
1896 SwTableNode
* pTblNd
= rDoc
.GetNodes()[ nSttNode
]->GetTableNode();
1897 ASSERT( pTblNd
, "kein TabellenNode" );
1898 CHECK_TABLE( pTblNd
->GetTable() )
1900 SwSelBoxes aSelBoxes
;
1901 for( USHORT n
= 0; n
< aBoxes
.Count(); ++n
)
1903 SwTableBox
* pBox
= pTblNd
->GetTable().GetTblBox( aBoxes
[ n
] );
1904 aSelBoxes
.Insert( pBox
);
1907 // SelBoxes erzeugen und InsertCell/-Row/SplitTbl aufrufen
1910 case UNDO_TABLE_INSCOL
:
1911 if( USHRT_MAX
== nSetColType
)
1912 rDoc
.InsertCol( aSelBoxes
, nCount
, bFlag
);
1915 SwTableBox
* pBox
= pTblNd
->GetTable().GetTblBox( nCurrBox
);
1916 rDoc
.SetColRowWidthHeight( *pBox
, nSetColType
, nAbsDiff
,
1921 case UNDO_TABLE_INSROW
:
1922 if( USHRT_MAX
== nSetColType
)
1923 rDoc
.InsertRow( aSelBoxes
, nCount
, bFlag
);
1926 SwTable
& rTbl
= pTblNd
->GetTable();
1927 SwTableBox
* pBox
= rTbl
.GetTblBox( nCurrBox
);
1928 TblChgMode eOldMode
= rTbl
.GetTblChgMode();
1929 rTbl
.SetTblChgMode( (TblChgMode
)nCount
);
1930 rDoc
.SetColRowWidthHeight( *pBox
, nSetColType
, nAbsDiff
, nRelDiff
);
1931 rTbl
.SetTblChgMode( eOldMode
);
1935 case UNDO_TABLE_SPLIT
:
1936 rDoc
.SplitTbl( aSelBoxes
, bFlag
, nCount
, bSameHeight
);
1938 case UNDO_TABLE_DELBOX
:
1939 case UNDO_ROW_DELETE
:
1940 case UNDO_COL_DELETE
:
1941 if( USHRT_MAX
== nSetColType
)
1943 SwTableFmlUpdate
aMsgHnt( &pTblNd
->GetTable() );
1944 aMsgHnt
.eFlags
= TBL_BOXPTR
;
1945 rDoc
.UpdateTblFlds( &aMsgHnt
);
1946 SwTable
&rTable
= pTblNd
->GetTable();
1947 if( nMax
> nMin
&& rTable
.IsNewModel() )
1948 rTable
.PrepareDeleteCol( nMin
, nMax
);
1949 rTable
.DeleteSel( &rDoc
, aSelBoxes
, 0, this, TRUE
, TRUE
);
1953 SwTable
& rTbl
= pTblNd
->GetTable();
1955 SwTableFmlUpdate
aMsgHnt( &rTbl
);
1956 aMsgHnt
.eFlags
= TBL_BOXPTR
;
1957 rDoc
.UpdateTblFlds( &aMsgHnt
);
1959 SwTableBox
* pBox
= rTbl
.GetTblBox( nCurrBox
);
1960 TblChgMode eOldMode
= rTbl
.GetTblChgMode();
1961 rTbl
.SetTblChgMode( (TblChgMode
)nCount
);
1963 rDoc
.DoUndo( TRUE
); // wir brauchen die SaveSections!
1964 SwUndoTblNdsChg
* pUndo
= 0;
1966 switch( nSetColType
& 0xff )
1968 case nsTblChgWidthHeightType::WH_COL_LEFT
:
1969 case nsTblChgWidthHeightType::WH_COL_RIGHT
:
1970 case nsTblChgWidthHeightType::WH_CELL_LEFT
:
1971 case nsTblChgWidthHeightType::WH_CELL_RIGHT
:
1972 rTbl
.SetColWidth( *pBox
, nSetColType
, nAbsDiff
,
1973 nRelDiff
, (SwUndo
**)&pUndo
);
1975 case nsTblChgWidthHeightType::WH_ROW_TOP
:
1976 case nsTblChgWidthHeightType::WH_ROW_BOTTOM
:
1977 case nsTblChgWidthHeightType::WH_CELL_TOP
:
1978 case nsTblChgWidthHeightType::WH_CELL_BOTTOM
:
1979 rTbl
.SetRowHeight( *pBox
, nSetColType
, nAbsDiff
,
1980 nRelDiff
, (SwUndo
**)&pUndo
);
1986 Ptrs
.pDelSects
->Insert( pUndo
->Ptrs
.pDelSects
, 0 );
1987 pUndo
->Ptrs
.pDelSects
->Remove( 0, pUndo
->Ptrs
.pDelSects
->Count() );
1991 rDoc
.DoUndo( FALSE
);
1993 rTbl
.SetTblChgMode( eOldMode
);
1995 nSttNode
= pTblNd
->GetIndex();
2000 ClearFEShellTabCols();
2001 CHECK_TABLE( pTblNd
->GetTable() )
2008 SwUndoTblMerge::SwUndoTblMerge( const SwPaM
& rTblSel
)
2009 : SwUndo( UNDO_TABLE_MERGE
), SwUndRng( rTblSel
), pHistory( 0 )
2011 const SwTableNode
* pTblNd
= rTblSel
.GetNode()->FindTableNode();
2012 ASSERT( pTblNd
, "Wo ist TabllenNode" )
2013 pSaveTbl
= new _SaveTable( pTblNd
->GetTable() );
2014 pMoves
= new SwUndoMoves
;
2015 nTblNode
= pTblNd
->GetIndex();
2019 SwUndoTblMerge::~SwUndoTblMerge()
2027 void SwUndoTblMerge::Undo( SwUndoIter
& rUndoIter
)
2029 SwDoc
& rDoc
= rUndoIter
.GetDoc();
2030 SwNodeIndex
aIdx( rDoc
.GetNodes(), nTblNode
);
2032 SwTableNode
* pTblNd
= rDoc
.GetNodes()[ aIdx
]->GetTableNode();
2033 ASSERT( pTblNd
, "kein TabellenNode" );
2035 SwTableFmlUpdate
aMsgHnt( &pTblNd
->GetTable() );
2036 aMsgHnt
.eFlags
= TBL_BOXPTR
;
2037 rDoc
.UpdateTblFlds( &aMsgHnt
);
2039 _FndBox
aTmpBox( 0, 0 );
2040 // ? TL_CHART2: notification or locking of controller required ?
2043 // 1. die geloeschten Boxen wiederherstellen:
2045 // Trick: die fehlenden Boxen in irgendeine Line einfuegen, beim
2046 // CreateNew werden sie korrekt verbunden.
2047 SwTableBox
*pBox
, *pCpyBox
= pTblNd
->GetTable().GetTabSortBoxes()[0];
2048 SwTableBoxes
& rLnBoxes
= pCpyBox
->GetUpper()->GetTabBoxes();
2050 DUMPDOC( &rDoc
, "d:\\tmp\\tab_a.db" )
2051 CHECKTABLE(pTblNd
->GetTable())
2053 SwSelBoxes aSelBoxes
;
2054 SwTxtFmtColl
* pColl
= rDoc
.GetTxtCollFromPool( RES_POOLCOLL_STANDARD
);
2057 for( n
= 0; n
< aBoxes
.Count(); ++n
)
2060 SwStartNode
* pSttNd
= rDoc
.GetNodes().MakeTextSection( aIdx
,
2061 SwTableBoxStartNode
, pColl
);
2062 pBox
= new SwTableBox( (SwTableBoxFmt
*)pCpyBox
->GetFrmFmt(), *pSttNd
,
2063 pCpyBox
->GetUpper() );
2064 rLnBoxes
.C40_INSERT( SwTableBox
, pBox
, rLnBoxes
.Count() );
2066 aSelBoxes
.Insert( pBox
);
2069 DUMPDOC( &rDoc
, "d:\\tmp\\tab_b.db" )
2070 CHECKTABLE(pTblNd
->GetTable())
2072 SwChartDataProvider
*pPCD
= rDoc
.GetChartDataProvider();
2073 // 2. die eingefuegten Boxen loeschen
2074 // die Nodes loeschen (von Hinten!!)
2075 for( n
= aNewSttNds
.Count(); n
; )
2077 // Box aus der Tabellen-Struktur entfernen
2078 ULONG nIdx
= aNewSttNds
[ --n
];
2082 nIdx
= aNewSttNds
[ --n
];
2083 pBox
= pTblNd
->GetTable().GetTblBox( nIdx
);
2084 ASSERT( pBox
, "Wo ist meine TabellenBox geblieben?" );
2086 if( !pSaveTbl
->IsNewModel() )
2087 rDoc
.GetNodes().MakeTxtNode( SwNodeIndex(
2088 *pBox
->GetSttNd()->EndOfSectionNode() ), pColl
);
2090 // das war der Trenner, -> die verschobenen herstellen
2091 for( USHORT i
= pMoves
->Count(); i
; )
2093 SwTxtNode
* pTxtNd
= 0;
2095 SwUndoMove
* pUndo
= (*pMoves
)[ --i
];
2096 if( !pUndo
->IsMoveRange() )
2098 pTxtNd
= rDoc
.GetNodes()[ pUndo
->GetDestSttNode() ]->GetTxtNode();
2099 nDelPos
= pUndo
->GetDestSttCntnt() - 1;
2101 pUndo
->Undo( rUndoIter
);
2102 if( pUndo
->IsMoveRange() )
2104 // den ueberfluessigen Node loeschen
2105 aIdx
= pUndo
->GetEndNode();
2106 SwCntntNode
*pCNd
= aIdx
.GetNode().GetCntntNode();
2109 SwNodeIndex
aTmp( aIdx
, -1 );
2110 SwCntntNode
*pMove
= aTmp
.GetNode().GetCntntNode();
2112 pCNd
->MoveTo( *pMove
);
2114 rDoc
.GetNodes().Delete( aIdx
, 1 );
2118 // evt. noch ueberflussige Attribute loeschen
2119 SwIndex
aTmpIdx( pTxtNd
, nDelPos
);
2120 if( pTxtNd
->GetpSwpHints() && pTxtNd
->GetpSwpHints()->Count() )
2121 pTxtNd
->RstAttr( aTmpIdx
, pTxtNd
->GetTxt().Len() -
2123 // das Trennzeichen loeschen
2124 pTxtNd
->Erase( aTmpIdx
, 1 );
2127 DUMPDOC( &rDoc
, String( "d:\\tmp\\tab_") + String( aNewSttNds
.Count() - i
) +
2130 // pMoves->Remove( 0, pMoves->Count() );
2131 nIdx
= pBox
->GetSttIdx();
2134 pBox
= pTblNd
->GetTable().GetTblBox( nIdx
);
2136 if( !pSaveTbl
->IsNewModel() )
2138 // TL_CHART2: notify chart about box to be removed
2140 pPCD
->DeleteBox( &pTblNd
->GetTable(), *pBox
);
2142 SwTableBoxes
* pTBoxes
= &pBox
->GetUpper()->GetTabBoxes();
2143 pTBoxes
->Remove( pTBoxes
->C40_GETPOS( SwTableBox
, pBox
) );
2146 // Indizies aus dem Bereich loeschen
2148 SwNodeIndex
aTmpIdx( *pBox
->GetSttNd() );
2149 rDoc
.CorrAbs( SwNodeIndex( aTmpIdx
, 1 ),
2150 SwNodeIndex( *aTmpIdx
.GetNode().EndOfSectionNode() ),
2151 SwPosition( aTmpIdx
, SwIndex( 0, 0 )), TRUE
);
2155 rDoc
.DeleteSection( rDoc
.GetNodes()[ nIdx
] );
2158 DUMPDOC( &rDoc
, "d:\\tmp\\tab_z.db" )
2159 CHECKTABLE(pTblNd
->GetTable())
2162 pSaveTbl
->CreateNew( pTblNd
->GetTable(), TRUE
, FALSE
);
2164 // TL_CHART2: need to inform chart of probably changed cell names
2165 rDoc
.UpdateCharts( pTblNd
->GetTable().GetFrmFmt()->GetName() );
2169 pHistory
->TmpRollback( &rDoc
, 0 );
2170 pHistory
->SetTmpEnd( pHistory
->Count() );
2172 // nTblNode = pTblNd->GetIndex();
2174 SwPaM
* pPam
= rUndoIter
.pAktPam
;
2176 pPam
->GetPoint()->nNode
= nSttNode
;
2177 pPam
->GetPoint()->nContent
.Assign( pPam
->GetCntntNode(), nSttCntnt
);
2181 CHECKTABLE(pTblNd
->GetTable())
2182 ClearFEShellTabCols();
2186 void SwUndoTblMerge::Redo( SwUndoIter
& rUndoIter
)
2188 SwPaM
* pPam
= rUndoIter
.pAktPam
;
2189 SwDoc
& rDoc
= *pPam
->GetDoc();
2192 rDoc
.MergeTbl( *pPam
);
2195 void SwUndoTblMerge::MoveBoxCntnt( SwDoc
* pDoc
, SwNodeRange
& rRg
, SwNodeIndex
& rPos
)
2197 SwNodeIndex
aTmp( rRg
.aStart
, -1 ), aTmp2( rPos
, -1 );
2198 SwUndoMove
* pUndo
= new SwUndoMove( pDoc
, rRg
, rPos
);
2199 sal_Bool bDoesUndo
= pDoc
->DoesUndo();
2200 pDoc
->DoUndo( sal_False
);
2201 pDoc
->Move( rRg
, rPos
, pSaveTbl
->IsNewModel() ?
2202 IDocumentContentOperations::DOC_NO_DELFRMS
:
2203 IDocumentContentOperations::DOC_MOVEDEFAULT
);
2205 pDoc
->DoUndo( sal_True
);
2208 pUndo
->SetDestRange( aTmp2
, rPos
, aTmp
);
2210 pMoves
->Insert( pUndo
, pMoves
->Count() );
2214 void SwUndoTblMerge::SetSelBoxes( const SwSelBoxes
& rBoxes
)
2216 // die Selektion merken
2217 for( USHORT n
= 0; n
< rBoxes
.Count(); ++n
)
2218 InsertSort( aBoxes
, rBoxes
[n
]->GetSttIdx() );
2220 // als Trennung fuers einfuegen neuer Boxen nach dem Verschieben!
2221 aNewSttNds
.Insert( (ULONG
)0, aNewSttNds
.Count() );
2223 // The new table model does not delete overlapped cells (by row span),
2224 // so the rBoxes array might be empty even some cells have been merged.
2225 if( rBoxes
.Count() )
2226 nTblNode
= rBoxes
[ 0 ]->GetSttNd()->FindTableNode()->GetIndex();
2229 void SwUndoTblMerge::SaveCollection( const SwTableBox
& rBox
)
2232 pHistory
= new SwHistory
;
2234 SwNodeIndex
aIdx( *rBox
.GetSttNd(), 1 );
2235 SwCntntNode
* pCNd
= aIdx
.GetNode().GetCntntNode();
2237 pCNd
= aIdx
.GetNodes().GoNext( &aIdx
);
2239 pHistory
->Add( pCNd
->GetFmtColl(), aIdx
.GetIndex(), pCNd
->GetNodeType());
2240 if( pCNd
->HasSwAttrSet() )
2241 pHistory
->CopyFmtAttr( *pCNd
->GetpSwAttrSet(), aIdx
.GetIndex() );
2247 SwUndoTblNumFmt::SwUndoTblNumFmt( const SwTableBox
& rBox
,
2248 const SfxItemSet
* pNewSet
)
2249 : SwUndo( UNDO_TBLNUMFMT
),
2250 pBoxSet( 0 ), pHistory( 0 ), nFmtIdx( NUMBERFORMAT_TEXT
)
2252 bNewFmt
= bNewFml
= bNewValue
= FALSE
;
2253 nNode
= rBox
.GetSttIdx();
2255 nNdPos
= rBox
.IsValidNumTxtNd( 0 == pNewSet
);
2256 SwDoc
* pDoc
= rBox
.GetFrmFmt()->GetDoc();
2258 if( ULONG_MAX
!= nNdPos
)
2260 SwTxtNode
* pTNd
= pDoc
->GetNodes()[ nNdPos
]->GetTxtNode();
2262 pHistory
= new SwHistory
;
2263 SwRegHistory
aRHst( *rBox
.GetSttNd(), pHistory
);
2264 // always save all text atttibutes because of possibly overlapping
2266 pHistory
->CopyAttr( pTNd
->GetpSwpHints(), nNdPos
, 0,
2267 pTNd
->GetTxt().Len(), true );
2269 if( pTNd
->HasSwAttrSet() )
2270 pHistory
->CopyFmtAttr( *pTNd
->GetpSwAttrSet(), nNdPos
);
2272 aStr
= pTNd
->GetTxt();
2273 if( pTNd
->GetpSwpHints() )
2274 pTNd
->GetpSwpHints()->DeRegister();
2277 pBoxSet
= new SfxItemSet( pDoc
->GetAttrPool(), aTableBoxSetRange
);
2278 pBoxSet
->Put( rBox
.GetFrmFmt()->GetAttrSet() );
2282 const SfxPoolItem
* pItem
;
2283 if( SFX_ITEM_SET
== pNewSet
->GetItemState( RES_BOXATR_FORMAT
,
2287 nNewFmtIdx
= ((SwTblBoxNumFormat
*)pItem
)->GetValue();
2289 if( SFX_ITEM_SET
== pNewSet
->GetItemState( RES_BOXATR_FORMULA
,
2293 aNewFml
= ((SwTblBoxFormula
*)pItem
)->GetFormula();
2295 if( SFX_ITEM_SET
== pNewSet
->GetItemState( RES_BOXATR_VALUE
,
2299 fNewNum
= ((SwTblBoxValue
*)pItem
)->GetValue();
2303 // wird die History ueberhaupt benoetigt ??
2304 if( pHistory
&& !pHistory
->Count() )
2305 DELETEZ( pHistory
);
2309 SwUndoTblNumFmt::~SwUndoTblNumFmt()
2315 void SwUndoTblNumFmt::Undo( SwUndoIter
& rIter
)
2317 ASSERT( pBoxSet
, "Where's the stored item set?" )
2319 SwDoc
& rDoc
= rIter
.GetDoc();
2320 SwStartNode
* pSttNd
= rDoc
.GetNodes()[ nNode
]->
2321 FindSttNodeByType( SwTableBoxStartNode
);
2322 ASSERT( pSttNd
, "ohne StartNode kein TabellenBox" );
2323 SwTableBox
* pBox
= pSttNd
->FindTableNode()->GetTable().GetTblBox(
2324 pSttNd
->GetIndex() );
2325 ASSERT( pBox
, "keine TabellenBox gefunden" );
2327 SwTableBoxFmt
* pFmt
= rDoc
.MakeTableBoxFmt();
2328 pFmt
->SetFmtAttr( *pBoxSet
);
2329 pBox
->ChgFrmFmt( pFmt
);
2331 if( ULONG_MAX
== nNdPos
)
2334 SwTxtNode
* pTxtNd
= rDoc
.GetNodes()[ nNdPos
]->GetTxtNode();
2335 // wenn mehr als ein Node geloescht wurde, dann wurden auch
2336 // alle "Node"-Attribute gespeichert
2337 if( pTxtNd
->HasSwAttrSet() )
2338 pTxtNd
->ResetAllAttr();
2340 if( pTxtNd
->GetpSwpHints() && aStr
.Len() )
2341 pTxtNd
->ClearSwpHintsArr( true );
2343 // ChgTextToNum(..) only acts when the strings are different. We
2344 // need to do the same here.
2345 if( pTxtNd
->GetTxt() != aStr
)
2347 rDoc
.DeleteRedline( *( pBox
->GetSttNd() ), false, USHRT_MAX
);
2349 SwIndex
aIdx( pTxtNd
, 0 );
2352 pTxtNd
->Erase( aIdx
);
2353 pTxtNd
->Insert( aStr
, aIdx
, INS_NOHINTEXPAND
);
2359 USHORT nTmpEnd
= pHistory
->GetTmpEnd();
2360 pHistory
->TmpRollback( &rDoc
, 0 );
2361 pHistory
->SetTmpEnd( nTmpEnd
);
2364 SwPaM
* pPam
= rIter
.pAktPam
;
2366 pPam
->GetPoint()->nNode
= nNode
+ 1;
2367 pPam
->GetPoint()->nContent
.Assign( pTxtNd
, 0 );
2370 /** switch the RedlineMode on the given document, using
2371 * SetRedlineMode_intern. This class set the mode in the constructor,
2372 * and changes it back in the destructor, i.e. it uses the
2373 * initialization-is-resource-acquisition idiom.
2375 class RedlineModeInternGuard
2378 RedlineMode_t meOldRedlineMode
;
2381 RedlineModeInternGuard(
2382 SwDoc
& rDoc
, /// change mode of this document
2383 RedlineMode_t eNewRedlineMode
, /// new redline mode
2384 RedlineMode_t eRedlineModeMask
= (RedlineMode_t
)(nsRedlineMode_t::REDLINE_ON
| nsRedlineMode_t::REDLINE_IGNORE
/*change only bits set in this mask*/));
2386 ~RedlineModeInternGuard();
2389 RedlineModeInternGuard::RedlineModeInternGuard(
2391 RedlineMode_t eNewRedlineMode
,
2392 RedlineMode_t eRedlineModeMask
)
2394 meOldRedlineMode( rDoc
.GetRedlineMode() )
2396 mrDoc
.SetRedlineMode_intern((RedlineMode_t
)( ( meOldRedlineMode
& ~eRedlineModeMask
) |
2397 ( eNewRedlineMode
& eRedlineModeMask
) ));
2400 RedlineModeInternGuard::~RedlineModeInternGuard()
2402 mrDoc
.SetRedlineMode_intern( meOldRedlineMode
);
2407 void SwUndoTblNumFmt::Redo( SwUndoIter
& rIter
)
2409 // konnte die Box veraendert werden ?
2413 SwDoc
& rDoc
= rIter
.GetDoc();
2415 SwPaM
* pPam
= rIter
.pAktPam
;
2417 pPam
->GetPoint()->nNode
= nNode
;
2419 SwNode
* pNd
= rDoc
.GetNodes()[ pPam
->GetPoint()->nNode
];
2420 SwStartNode
* pSttNd
= pNd
->FindSttNodeByType( SwTableBoxStartNode
);
2421 ASSERT( pSttNd
, "ohne StartNode kein TabellenBox" );
2422 SwTableBox
* pBox
= pSttNd
->FindTableNode()->GetTable().GetTblBox(
2423 pSttNd
->GetIndex() );
2424 ASSERT( pBox
, "keine TabellenBox gefunden" );
2426 SwFrmFmt
* pBoxFmt
= pBox
->ClaimFrmFmt();
2427 if( bNewFmt
|| bNewFml
|| bNewValue
)
2429 SfxItemSet
aBoxSet( rDoc
.GetAttrPool(),
2430 RES_BOXATR_FORMAT
, RES_BOXATR_VALUE
);
2432 // JP 15.01.99: Nur Attribute zuruecksetzen reicht nicht.
2433 // Sorge dafuer, das der Text auch entsprechend
2435 pBoxFmt
->LockModify();
2438 aBoxSet
.Put( SwTblBoxFormula( aNewFml
));
2440 pBoxFmt
->ResetFmtAttr( RES_BOXATR_FORMULA
);
2442 aBoxSet
.Put( SwTblBoxNumFormat( nNewFmtIdx
));
2444 pBoxFmt
->ResetFmtAttr( RES_BOXATR_FORMAT
);
2446 aBoxSet
.Put( SwTblBoxValue( fNewNum
));
2448 pBoxFmt
->ResetFmtAttr( RES_BOXATR_VALUE
);
2449 pBoxFmt
->UnlockModify();
2451 // dvo: When redlining is (was) enabled, setting the attribute
2452 // will also change the cell content. To allow this, the
2453 // REDLINE_IGNORE flag must be removed during Redo. #108450#
2454 RedlineModeInternGuard
aGuard( rDoc
, nsRedlineMode_t::REDLINE_NONE
, nsRedlineMode_t::REDLINE_IGNORE
);
2455 pBoxFmt
->SetFmtAttr( aBoxSet
);
2457 else if( NUMBERFORMAT_TEXT
!= nFmtIdx
)
2459 SfxItemSet
aBoxSet( rDoc
.GetAttrPool(),
2460 RES_BOXATR_FORMAT
, RES_BOXATR_VALUE
);
2462 aBoxSet
.Put( SwTblBoxNumFormat( nFmtIdx
));
2463 aBoxSet
.Put( SwTblBoxValue( fNum
));
2465 // JP 15.01.99: Nur Attribute zuruecksetzen reicht nicht.
2466 // Sorge dafuer, das der Text auch entsprechend
2468 pBoxFmt
->LockModify();
2469 pBoxFmt
->ResetFmtAttr( RES_BOXATR_FORMULA
);
2470 pBoxFmt
->UnlockModify();
2472 // dvo: When redlining is (was) enabled, setting the attribute
2473 // will also change the cell content. To allow this, the
2474 // REDLINE_IGNORE flag must be removed during Redo. #108450#
2475 RedlineModeInternGuard
aGuard( rDoc
, nsRedlineMode_t::REDLINE_NONE
, nsRedlineMode_t::REDLINE_IGNORE
);
2476 pBoxFmt
->SetFmtAttr( aBoxSet
);
2480 // es ist keine Zahl
2482 // JP 15.01.99: Nur Attribute zuruecksetzen reicht nicht.
2483 // Sorge dafuer, das der Text auch entsprechend
2485 pBoxFmt
->SetFmtAttr( *GetDfltAttr( RES_BOXATR_FORMAT
));
2487 pBoxFmt
->ResetFmtAttr( RES_BOXATR_FORMAT
, RES_BOXATR_VALUE
);
2492 // egal was gesetzt wurde, ein Update der Tabelle macht sich immer gut
2493 SwTableFmlUpdate
aTblUpdate( &pSttNd
->FindTableNode()->GetTable() );
2494 rDoc
.UpdateTblFlds( &aTblUpdate
);
2497 if( !pNd
->IsCntntNode() )
2498 pNd
= rDoc
.GetNodes().GoNext( &pPam
->GetPoint()->nNode
);
2499 pPam
->GetPoint()->nContent
.Assign( (SwCntntNode
*)pNd
, 0 );
2502 void SwUndoTblNumFmt::SetBox( const SwTableBox
& rBox
)
2504 nNode
= rBox
.GetSttIdx();
2509 _UndoTblCpyTbl_Entry::_UndoTblCpyTbl_Entry( const SwTableBox
& rBox
)
2510 : nBoxIdx( rBox
.GetSttIdx() ), nOffset( 0 ),
2511 pBoxNumAttr( 0 ), pUndo( 0 ), bJoin( false )
2515 _UndoTblCpyTbl_Entry::~_UndoTblCpyTbl_Entry()
2522 SwUndoTblCpyTbl::SwUndoTblCpyTbl()
2523 : SwUndo( UNDO_TBLCPYTBL
), pInsRowUndo( 0 )
2525 pArr
= new _UndoTblCpyTbl_Entries
;
2528 SwUndoTblCpyTbl::~SwUndoTblCpyTbl()
2534 void SwUndoTblCpyTbl::Undo( SwUndoIter
& rIter
)
2536 SwDoc
& rDoc
= rIter
.GetDoc();
2537 _DEBUG_REDLINE( &rDoc
)
2539 SwTableNode
* pTblNd
= 0;
2540 for( USHORT n
= pArr
->Count(); n
; )
2542 _UndoTblCpyTbl_Entry
* pEntry
= (*pArr
)[ --n
];
2543 ULONG nSttPos
= pEntry
->nBoxIdx
+ pEntry
->nOffset
;
2544 SwStartNode
* pSNd
= rDoc
.GetNodes()[ nSttPos
]->StartOfSectionNode();
2546 pTblNd
= pSNd
->FindTableNode();
2548 SwTableBox
& rBox
= *pTblNd
->GetTable().GetTblBox( nSttPos
);
2550 SwNodeIndex
aInsIdx( *rBox
.GetSttNd(), 1 );
2551 rDoc
.GetNodes().MakeTxtNode( aInsIdx
, (SwTxtFmtColl
*)rDoc
.GetDfltTxtFmtColl() );
2553 // b62341295: Redline for copying tables
2554 const SwNode
*pEndNode
= rBox
.GetSttNd()->EndOfSectionNode();
2555 SwPaM
aPam( aInsIdx
.GetNode(), *pEndNode
);
2556 SwUndoDelete
* pUndo
= 0;
2558 if( IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ) )
2560 bool bDeleteCompleteParagraph
= false;
2561 bool bShiftPam
= false;
2562 // There are a couple of different situations to consider during redlining
2565 SwUndoDelete
*pUnDel
= (SwUndoDelete
*)pEntry
->pUndo
;
2566 if( UNDO_REDLINE
== pUnDel
->GetId() )
2568 // The old content was not empty or he has been merged with the new content
2569 bDeleteCompleteParagraph
= !pEntry
->bJoin
; // bJoin is set when merged
2570 // Set aTmpIdx to the beginning fo the old content
2571 SwNodeIndex
aTmpIdx( *pEndNode
, pUnDel
->NodeDiff()-1 );
2572 SwTxtNode
*pTxt
= aTmpIdx
.GetNode().GetTxtNode();
2575 aPam
.GetPoint()->nNode
= *pTxt
;
2576 aPam
.GetPoint()->nContent
.Assign( pTxt
, pUnDel
->ContentStart() );
2579 *aPam
.GetPoint() = SwPosition( aTmpIdx
);
2581 else if( pUnDel
->IsDelFullPara() )
2583 // When the old content was an empty paragraph, but could not be joined
2584 // with the new content (e.g. because of a section or table)
2585 // We "save" the aPam.Point, we go one step backwards (because later on the
2586 // empty paragraph will be inserted by the undo) and set the "ShiftPam-flag
2587 // for step forward later on.
2588 bDeleteCompleteParagraph
= true;
2590 SwNodeIndex
aTmpIdx( *pEndNode
, -1 );
2591 SwTxtNode
*pTxt
= aTmpIdx
.GetNode().GetTxtNode();
2594 aPam
.GetPoint()->nNode
= *pTxt
;
2595 aPam
.GetPoint()->nContent
.Assign( pTxt
, 0 );
2598 *aPam
.GetPoint() = SwPosition( aTmpIdx
);
2601 rDoc
.DeleteRedline( aPam
, true, USHRT_MAX
);
2605 pEntry
->pUndo
->Undo( rIter
);
2606 delete pEntry
->pUndo
;
2610 // The aPam.Point is at the moment at the last position of the new content and has to be
2611 // moved to the first postion of the old content for the SwUndoDelete operation
2612 SwNodeIndex
aTmpIdx( aPam
.GetPoint()->nNode
, 1 );
2613 SwTxtNode
*pTxt
= aTmpIdx
.GetNode().GetTxtNode();
2616 aPam
.GetPoint()->nNode
= *pTxt
;
2617 aPam
.GetPoint()->nContent
.Assign( pTxt
, 0 );
2620 *aPam
.GetPoint() = SwPosition( aTmpIdx
);
2622 pUndo
= new SwUndoDelete( aPam
, bDeleteCompleteParagraph
, TRUE
);
2626 pUndo
= new SwUndoDelete( aPam
, true );
2629 pEntry
->pUndo
->Undo( rIter
);
2630 delete pEntry
->pUndo
;
2633 pEntry
->pUndo
= pUndo
;
2635 aInsIdx
= rBox
.GetSttIdx() + 1;
2636 rDoc
.GetNodes().Delete( aInsIdx
, 1 );
2638 SfxItemSet
aTmpSet( rDoc
.GetAttrPool(), RES_BOXATR_FORMAT
, RES_BOXATR_VALUE
,
2639 RES_VERT_ORIENT
, RES_VERT_ORIENT
, 0 );
2640 aTmpSet
.Put( rBox
.GetFrmFmt()->GetAttrSet() );
2641 if( aTmpSet
.Count() )
2643 SwFrmFmt
* pBoxFmt
= rBox
.ClaimFrmFmt();
2644 pBoxFmt
->ResetFmtAttr( RES_BOXATR_FORMAT
, RES_BOXATR_VALUE
);
2645 pBoxFmt
->ResetFmtAttr( RES_VERT_ORIENT
);
2648 if( pEntry
->pBoxNumAttr
)
2650 rBox
.ClaimFrmFmt()->SetFmtAttr( *pEntry
->pBoxNumAttr
);
2651 delete pEntry
->pBoxNumAttr
, pEntry
->pBoxNumAttr
= 0;
2654 if( aTmpSet
.Count() )
2656 pEntry
->pBoxNumAttr
= new SfxItemSet( rDoc
.GetAttrPool(),
2657 RES_BOXATR_FORMAT
, RES_BOXATR_VALUE
,
2658 RES_VERT_ORIENT
, RES_VERT_ORIENT
, 0 );
2659 pEntry
->pBoxNumAttr
->Put( aTmpSet
);
2662 pEntry
->nOffset
= rBox
.GetSttIdx() - pEntry
->nBoxIdx
;
2666 pInsRowUndo
->Undo( rIter
);
2667 _DEBUG_REDLINE( &rDoc
)
2670 void SwUndoTblCpyTbl::Redo( SwUndoIter
& rIter
)
2672 SwDoc
& rDoc
= rIter
.GetDoc();
2673 _DEBUG_REDLINE( &rDoc
)
2676 pInsRowUndo
->Redo( rIter
);
2678 SwTableNode
* pTblNd
= 0;
2679 for( USHORT n
= 0; n
< pArr
->Count(); ++n
)
2681 _UndoTblCpyTbl_Entry
* pEntry
= (*pArr
)[ n
];
2682 ULONG nSttPos
= pEntry
->nBoxIdx
+ pEntry
->nOffset
;
2683 SwStartNode
* pSNd
= rDoc
.GetNodes()[ nSttPos
]->StartOfSectionNode();
2685 pTblNd
= pSNd
->FindTableNode();
2687 SwTableBox
& rBox
= *pTblNd
->GetTable().GetTblBox( nSttPos
);
2689 SwNodeIndex
aInsIdx( *rBox
.GetSttNd(), 1 );
2691 // b62341295: Redline for copying tables - Start.
2692 rDoc
.GetNodes().MakeTxtNode( aInsIdx
, (SwTxtFmtColl
*)rDoc
.GetDfltTxtFmtColl() );
2693 SwPaM
aPam( aInsIdx
.GetNode(), *rBox
.GetSttNd()->EndOfSectionNode());
2694 SwUndo
* pUndo
= IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ) ? 0 : new SwUndoDelete( aPam
, TRUE
);
2697 pEntry
->pUndo
->Undo( rIter
);
2698 if( IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ) )
2700 // PrepareRedline has to be called with the beginning of the old content
2701 // When new and old content has been joined, the rIter.pAktPam has been set
2702 // by the Undo operation to this point.
2703 // Otherwise aInsIdx has been moved during the Undo operation
2705 pUndo
= PrepareRedline( &rDoc
, rBox
, *rIter
.pAktPam
->GetPoint(),
2706 pEntry
->bJoin
, true );
2709 SwPosition
aTmpPos( aInsIdx
);
2710 pUndo
= PrepareRedline( &rDoc
, rBox
, aTmpPos
, pEntry
->bJoin
, true );
2713 delete pEntry
->pUndo
;
2715 pEntry
->pUndo
= pUndo
;
2716 // b62341295: Redline for copying tables - End.
2718 aInsIdx
= rBox
.GetSttIdx() + 1;
2719 rDoc
.GetNodes().Delete( aInsIdx
, 1 );
2721 SfxItemSet
aTmpSet( rDoc
.GetAttrPool(), RES_BOXATR_FORMAT
, RES_BOXATR_VALUE
,
2722 RES_VERT_ORIENT
, RES_VERT_ORIENT
, 0 );
2723 aTmpSet
.Put( rBox
.GetFrmFmt()->GetAttrSet() );
2724 if( aTmpSet
.Count() )
2726 SwFrmFmt
* pBoxFmt
= rBox
.ClaimFrmFmt();
2727 pBoxFmt
->ResetFmtAttr( RES_BOXATR_FORMAT
, RES_BOXATR_VALUE
);
2728 pBoxFmt
->ResetFmtAttr( RES_VERT_ORIENT
);
2730 if( pEntry
->pBoxNumAttr
)
2732 rBox
.ClaimFrmFmt()->SetFmtAttr( *pEntry
->pBoxNumAttr
);
2733 delete pEntry
->pBoxNumAttr
, pEntry
->pBoxNumAttr
= 0;
2736 if( aTmpSet
.Count() )
2738 pEntry
->pBoxNumAttr
= new SfxItemSet( rDoc
.GetAttrPool(),
2739 RES_BOXATR_FORMAT
, RES_BOXATR_VALUE
,
2740 RES_VERT_ORIENT
, RES_VERT_ORIENT
, 0 );
2741 pEntry
->pBoxNumAttr
->Put( aTmpSet
);
2744 pEntry
->nOffset
= rBox
.GetSttIdx() - pEntry
->nBoxIdx
;
2746 _DEBUG_REDLINE( &rDoc
)
2749 void SwUndoTblCpyTbl::AddBoxBefore( const SwTableBox
& rBox
, BOOL bDelCntnt
)
2751 if( pArr
->Count() && !bDelCntnt
)
2754 _UndoTblCpyTbl_Entry
* pEntry
= new _UndoTblCpyTbl_Entry( rBox
);
2755 pArr
->Insert( pEntry
, pArr
->Count() );
2757 SwDoc
* pDoc
= rBox
.GetFrmFmt()->GetDoc();
2758 _DEBUG_REDLINE( pDoc
)
2761 SwNodeIndex
aInsIdx( *rBox
.GetSttNd(), 1 );
2762 pDoc
->GetNodes().MakeTxtNode( aInsIdx
, (SwTxtFmtColl
*)pDoc
->GetDfltTxtFmtColl() );
2763 SwPaM
aPam( aInsIdx
.GetNode(), *rBox
.GetSttNd()->EndOfSectionNode() );
2765 if( !pDoc
->IsRedlineOn() )
2766 pEntry
->pUndo
= new SwUndoDelete( aPam
, TRUE
);
2769 pEntry
->pBoxNumAttr
= new SfxItemSet( pDoc
->GetAttrPool(),
2770 RES_BOXATR_FORMAT
, RES_BOXATR_VALUE
,
2771 RES_VERT_ORIENT
, RES_VERT_ORIENT
, 0 );
2772 pEntry
->pBoxNumAttr
->Put( rBox
.GetFrmFmt()->GetAttrSet() );
2773 if( !pEntry
->pBoxNumAttr
->Count() )
2774 delete pEntry
->pBoxNumAttr
, pEntry
->pBoxNumAttr
= 0;
2775 _DEBUG_REDLINE( pDoc
)
2778 void SwUndoTblCpyTbl::AddBoxAfter( const SwTableBox
& rBox
, const SwNodeIndex
& rIdx
, BOOL bDelCntnt
)
2780 _UndoTblCpyTbl_Entry
* pEntry
= (*pArr
)[ pArr
->Count() - 1 ];
2782 // wurde der Inhalt geloescht, so loesche jetzt auch noch den temp.
2786 SwDoc
* pDoc
= rBox
.GetFrmFmt()->GetDoc();
2787 _DEBUG_REDLINE( pDoc
)
2789 if( pDoc
->IsRedlineOn() )
2791 SwPosition
aTmpPos( rIdx
);
2792 pEntry
->pUndo
= PrepareRedline( pDoc
, rBox
, aTmpPos
, pEntry
->bJoin
, false );
2794 SwNodeIndex
aDelIdx( *rBox
.GetSttNd(), 1 );
2795 rBox
.GetFrmFmt()->GetDoc()->GetNodes().Delete( aDelIdx
, 1 );
2796 _DEBUG_REDLINE( pDoc
)
2799 pEntry
->nOffset
= rBox
.GetSttIdx() - pEntry
->nBoxIdx
;
2802 // PrepareRedline is called from AddBoxAfter() and from Redo() in slightly different situations.
2803 // bRedo is set by calling from Redo()
2804 // rJoin is false by calling from AddBoxAfter() and will be set if the old and new content has
2806 // rJoin is true if Redo() is calling and the content has already been merged
2808 SwUndo
* SwUndoTblCpyTbl::PrepareRedline( SwDoc
* pDoc
, const SwTableBox
& rBox
,
2809 const SwPosition
& rPos
, bool& rJoin
, bool bRedo
)
2812 // b62341295: Redline for copying tables
2814 // Mark the cell content before rIdx as insertion,
2815 // mark the cell content behind rIdx as deletion
2816 // merge text nodes at rIdx if possible
2817 RedlineMode_t eOld
= pDoc
->GetRedlineMode();
2818 pDoc
->SetRedlineMode_intern((RedlineMode_t
)( ( eOld
| nsRedlineMode_t::REDLINE_DONTCOMBINE_REDLINES
) &
2819 ~nsRedlineMode_t::REDLINE_IGNORE
));
2820 SwPosition
aInsertEnd( rPos
);
2824 // If the content is not merged, the end of the insertion is at the end of the node
2825 // _before_ the given position rPos
2827 pTxt
= aInsertEnd
.nNode
.GetNode().GetTxtNode();
2830 aInsertEnd
.nContent
.Assign( pTxt
, pTxt
->GetTxt().Len() );
2831 if( !bRedo
&& rPos
.nNode
.GetNode().GetTxtNode() )
2832 { // Try to merge, if not called by Redo()
2838 aInsertEnd
.nContent
= SwIndex( 0 );
2840 // For joined (merged) contents the start of deletionm and end of insertion are identical
2841 // otherwise adjacent nodes.
2842 SwPosition
aDeleteStart( rJoin
? aInsertEnd
: rPos
);
2845 pTxt
= aDeleteStart
.nNode
.GetNode().GetTxtNode();
2847 aDeleteStart
.nContent
.Assign( pTxt
, 0 );
2849 SwPosition
aCellEnd( SwNodeIndex( *rBox
.GetSttNd()->EndOfSectionNode(), -1 ) );
2850 pTxt
= aCellEnd
.nNode
.GetNode().GetTxtNode();
2852 aCellEnd
.nContent
.Assign( pTxt
, pTxt
->GetTxt().Len() );
2853 if( aDeleteStart
!= aCellEnd
)
2854 { // If the old (deleted) part is not empty, here we are...
2855 SwPaM
aDeletePam( aDeleteStart
, aCellEnd
);
2856 pUndo
= new SwUndoRedlineDelete( aDeletePam
, UNDO_DELETE
);
2857 pDoc
->AppendRedline( new SwRedline( nsRedlineType_t::REDLINE_DELETE
, aDeletePam
), true );
2859 else if( !rJoin
) // If the old part is empty and joined, we are finished
2860 { // if it is not joined, we have to delete this empty paragraph
2861 aCellEnd
= SwPosition(
2862 SwNodeIndex( *rBox
.GetSttNd()->EndOfSectionNode() ));
2863 SwPaM
aTmpPam( aDeleteStart
, aCellEnd
);
2864 pUndo
= new SwUndoDelete( aTmpPam
, TRUE
);
2866 SwPosition
aCellStart( SwNodeIndex( *rBox
.GetSttNd(), 2 ) );
2867 pTxt
= aCellStart
.nNode
.GetNode().GetTxtNode();
2869 aCellStart
.nContent
.Assign( pTxt
, 0 );
2870 if( aCellStart
!= aInsertEnd
) // An empty insertion will not been marked
2872 SwPaM
aTmpPam( aCellStart
, aInsertEnd
);
2873 pDoc
->AppendRedline( new SwRedline( nsRedlineType_t::REDLINE_INSERT
, aTmpPam
), true );
2876 pDoc
->SetRedlineMode_intern( eOld
);
2881 BOOL
SwUndoTblCpyTbl::InsertRow( SwTable
& rTbl
, const SwSelBoxes
& rBoxes
,
2884 SwTableNode
* pTblNd
= (SwTableNode
*)rTbl
.GetTabSortBoxes()[0]->
2885 GetSttNd()->FindTableNode();
2887 SwTableSortBoxes
aTmpLst( 0, 5 );
2888 pInsRowUndo
= new SwUndoTblNdsChg( UNDO_TABLE_INSROW
, rBoxes
, *pTblNd
,
2889 0, 0, nCnt
, TRUE
, FALSE
);
2890 aTmpLst
.Insert( &rTbl
.GetTabSortBoxes(), 0, rTbl
.GetTabSortBoxes().Count() );
2892 BOOL bRet
= rTbl
.InsertRow( rTbl
.GetFrmFmt()->GetDoc(), rBoxes
, nCnt
, TRUE
);
2894 pInsRowUndo
->SaveNewBoxes( *pTblNd
, aTmpLst
);
2896 delete pInsRowUndo
, pInsRowUndo
= 0;
2900 BOOL
SwUndoTblCpyTbl::IsEmpty() const
2902 return !pInsRowUndo
&& !pArr
->Count();
2907 SwUndoCpyTbl::SwUndoCpyTbl()
2908 : SwUndo( UNDO_CPYTBL
), pDel( 0 ), nTblNode( 0 )
2912 SwUndoCpyTbl::~SwUndoCpyTbl()
2917 void SwUndoCpyTbl::Undo( SwUndoIter
& rIter
)
2919 SwDoc
& rDoc
= rIter
.GetDoc();
2920 SwTableNode
* pTNd
= rDoc
.GetNodes()[ nTblNode
]->GetTableNode();
2922 // harte SeitenUmbrueche am nachfolgenden Node verschieben
2923 SwCntntNode
* pNextNd
= rDoc
.GetNodes()[ pTNd
->EndOfSectionIndex()+1 ]->GetCntntNode();
2926 SwFrmFmt
* pTableFmt
= pTNd
->GetTable().GetFrmFmt();
2927 const SfxPoolItem
*pItem
;
2929 if( SFX_ITEM_SET
== pTableFmt
->GetItemState( RES_PAGEDESC
,
2931 pNextNd
->SetAttr( *pItem
);
2933 if( SFX_ITEM_SET
== pTableFmt
->GetItemState( RES_BREAK
,
2935 pNextNd
->SetAttr( *pItem
);
2938 SwPaM
aPam( *pTNd
, *pTNd
->EndOfSectionNode(), 0 , 1 );
2939 pDel
= new SwUndoDelete( aPam
, TRUE
);
2942 void SwUndoCpyTbl::Redo( SwUndoIter
& rIter
)
2944 pDel
->Undo( rIter
);
2945 delete pDel
, pDel
= 0;
2951 SwUndoSplitTbl::SwUndoSplitTbl( const SwTableNode
& rTblNd
,
2952 SwSaveRowSpan
* pRowSp
, USHORT eMode
, BOOL bNewSize
)
2953 : SwUndo( UNDO_SPLIT_TABLE
),
2954 nTblNode( rTblNd
.GetIndex() ), nOffset( 0 ), mpSaveRowSpan( pRowSp
), pSavTbl( 0 ),
2955 pHistory( 0 ), nMode( eMode
), nFmlEnd( 0 ), bCalcNewSize( bNewSize
)
2959 case HEADLINE_BOXATRCOLLCOPY
:
2960 pHistory
= new SwHistory
;
2962 case HEADLINE_BORDERCOPY
:
2963 case HEADLINE_BOXATTRCOPY
:
2964 pSavTbl
= new _SaveTable( rTblNd
.GetTable(), 1, FALSE
);
2969 SwUndoSplitTbl::~SwUndoSplitTbl()
2973 delete mpSaveRowSpan
;
2976 void SwUndoSplitTbl::Undo( SwUndoIter
& rIter
)
2978 SwPaM
* pPam
= rIter
.pAktPam
;
2979 SwDoc
* pDoc
= pPam
->GetDoc();
2982 SwNodeIndex
& rIdx
= pPam
->GetPoint()->nNode
;
2983 rIdx
= nTblNode
+ nOffset
;
2985 //Den implizit erzeugten Absatz wieder entfernen.
2986 pDoc
->GetNodes().Delete( rIdx
, 1 );
2988 rIdx
= nTblNode
+ nOffset
;
2989 SwTableNode
* pTblNd
= rIdx
.GetNode().GetTableNode();
2990 SwTable
& rTbl
= pTblNd
->GetTable();
2992 SwTableFmlUpdate
aMsgHnt( &rTbl
);
2993 aMsgHnt
.eFlags
= TBL_BOXPTR
;
2994 pDoc
->UpdateTblFlds( &aMsgHnt
);
2998 case HEADLINE_BOXATRCOLLCOPY
:
3000 pHistory
->TmpRollback( pDoc
, nFmlEnd
);
3003 case HEADLINE_BOXATTRCOPY
:
3004 case HEADLINE_BORDERCOPY
:
3006 pSavTbl
->CreateNew( rTbl
, FALSE
);
3007 pSavTbl
->RestoreAttr( rTbl
);
3011 case HEADLINE_CNTNTCOPY
:
3012 // die erzeugte 1. Line muss wieder entfernt werden
3014 SwSelBoxes aSelBoxes
;
3015 SwTableBox
* pBox
= rTbl
.GetTblBox( nTblNode
+ nOffset
+ 1 );
3016 rTbl
.SelLineFromBox( pBox
, aSelBoxes
, TRUE
);
3017 _FndBox
aTmpBox( 0, 0 );
3018 aTmpBox
.SetTableLines( aSelBoxes
, rTbl
);
3019 aTmpBox
.DelFrms( rTbl
);
3020 rTbl
.DeleteSel( pDoc
, aSelBoxes
, 0, 0, FALSE
, FALSE
);
3025 pDoc
->GetNodes().MergeTable( rIdx
);
3029 pHistory
->TmpRollback( pDoc
, 0 );
3030 pHistory
->SetTmpEnd( pHistory
->Count() );
3034 pTblNd
= rIdx
.GetNode().FindTableNode();
3036 pTblNd
->GetTable().RestoreRowSpan( *mpSaveRowSpan
);
3038 ClearFEShellTabCols();
3041 void SwUndoSplitTbl::Redo( SwUndoIter
& rIter
)
3043 SwPaM
* pPam
= rIter
.pAktPam
;
3044 SwDoc
* pDoc
= pPam
->GetDoc();
3047 pPam
->GetPoint()->nNode
= nTblNode
;
3048 pDoc
->SplitTable( *pPam
->GetPoint(), nMode
, bCalcNewSize
);
3050 ClearFEShellTabCols();
3053 void SwUndoSplitTbl::Repeat( SwUndoIter
& rIter
)
3055 SwPaM
* pPam
= rIter
.pAktPam
;
3056 SwDoc
* pDoc
= pPam
->GetDoc();
3058 pDoc
->SplitTable( *pPam
->GetPoint(), nMode
, bCalcNewSize
);
3059 ClearFEShellTabCols();
3062 void SwUndoSplitTbl::SaveFormula( SwHistory
& rHistory
)
3065 pHistory
= new SwHistory
;
3067 nFmlEnd
= rHistory
.Count();
3068 pHistory
->Move( 0, &rHistory
);
3073 SwUndoMergeTbl::SwUndoMergeTbl( const SwTableNode
& rTblNd
,
3074 const SwTableNode
& rDelTblNd
,
3075 BOOL bWithPrv
, USHORT nMd
)
3076 : SwUndo( UNDO_MERGE_TABLE
), pSavTbl( 0 ),
3077 pHistory( 0 ), nMode( nMd
), bWithPrev( bWithPrv
)
3079 // Endnode der letzen Tabellenzelle merken, die auf der Position verbleibt
3081 nTblNode
= rDelTblNd
.EndOfSectionIndex() - 1;
3083 nTblNode
= rTblNd
.EndOfSectionIndex() - 1;
3085 aName
= rDelTblNd
.GetTable().GetFrmFmt()->GetName();
3086 pSavTbl
= new _SaveTable( rDelTblNd
.GetTable() );
3088 pSavHdl
= bWithPrev
? new _SaveTable( rTblNd
.GetTable(), 1 ) : 0;
3091 SwUndoMergeTbl::~SwUndoMergeTbl()
3098 void SwUndoMergeTbl::Undo( SwUndoIter
& rIter
)
3100 SwPaM
* pPam
= rIter
.pAktPam
;
3101 SwDoc
* pDoc
= pPam
->GetDoc();
3104 SwNodeIndex
& rIdx
= pPam
->GetPoint()->nNode
;
3107 SwTableNode
* pTblNd
= rIdx
.GetNode().FindTableNode();
3108 SwTable
* pTbl
= &pTblNd
->GetTable();
3110 SwTableFmlUpdate
aMsgHnt( pTbl
);
3111 aMsgHnt
.eFlags
= TBL_BOXPTR
;
3112 pDoc
->UpdateTblFlds( &aMsgHnt
);
3114 //Lines fuer das Layout-Update herausuchen.
3115 _FndBox
aFndBox( 0, 0 );
3116 aFndBox
.SetTableLines( *pTbl
);
3117 aFndBox
.DelFrms( *pTbl
);
3118 // ? TL_CHART2: notification or locking of controller required ?
3120 SwTableNode
* pNew
= pDoc
->GetNodes().SplitTable( rIdx
, TRUE
, FALSE
);
3123 aFndBox
.MakeFrms( *pTbl
);
3124 // ? TL_CHART2: notification or locking of controller required ?
3128 // den Namen umsetzen
3129 pNew
->GetTable().GetFrmFmt()->SetName( pTbl
->GetFrmFmt()->GetName() );
3130 pSavHdl
->RestoreAttr( pNew
->GetTable() );
3133 pTbl
= &pNew
->GetTable();
3134 pTbl
->GetFrmFmt()->SetName( aName
);
3136 // pSavTbl->CreateNew( *pTbl, FALSE );
3137 pSavTbl
->RestoreAttr( *pTbl
);
3142 pHistory
->TmpRollback( pDoc
, 0 );
3143 pHistory
->SetTmpEnd( pHistory
->Count() );
3146 // fuer die neue Tabelle die Frames anlegen
3147 SwNodeIndex
aTmpIdx( *pNew
);
3148 pNew
->MakeFrms( &aTmpIdx
);
3150 // Cursor irgendwo in den Content stellen
3151 SwCntntNode
* pCNd
= pDoc
->GetNodes().GoNext( &rIdx
);
3152 pPam
->GetPoint()->nContent
.Assign( pCNd
, 0 );
3154 ClearFEShellTabCols();
3156 // TL_CHART2: need to inform chart of probably changed cell names
3157 SwChartDataProvider
*pPCD
= pDoc
->GetChartDataProvider();
3160 pDoc
->UpdateCharts( pTbl
->GetFrmFmt()->GetName() );
3161 pDoc
->UpdateCharts( pNew
->GetTable().GetFrmFmt()->GetName() );
3165 void SwUndoMergeTbl::Redo( SwUndoIter
& rIter
)
3167 SwPaM
* pPam
= rIter
.pAktPam
;
3168 SwDoc
* pDoc
= pPam
->GetDoc();
3171 pPam
->GetPoint()->nNode
= nTblNode
;
3173 pPam
->GetPoint()->nNode
= nTblNode
+ 3;
3175 pPam
->GetPoint()->nNode
= nTblNode
;
3177 pDoc
->MergeTable( *pPam
->GetPoint(), bWithPrev
, nMode
);
3179 ClearFEShellTabCols();
3182 void SwUndoMergeTbl::Repeat( SwUndoIter
& rIter
)
3184 SwPaM
* pPam
= rIter
.pAktPam
;
3185 SwDoc
* pDoc
= pPam
->GetDoc();
3187 pDoc
->MergeTable( *pPam
->GetPoint(), bWithPrev
, nMode
);
3188 ClearFEShellTabCols();
3191 void SwUndoMergeTbl::SaveFormula( SwHistory
& rHistory
)
3194 pHistory
= new SwHistory
;
3195 pHistory
->Move( 0, &rHistory
);
3201 void InsertSort( SvUShorts
& rArr
, USHORT nIdx
, USHORT
* pInsPos
)
3203 USHORT nO
= rArr
.Count(), nM
, nU
= 0;
3209 nM
= nU
+ ( nO
- nU
) / 2;
3210 if( *(rArr
.GetData() + nM
) == nIdx
)
3212 ASSERT( FALSE
, "Index ist schon vorhanden, darf nie sein!" );
3215 if( *(rArr
.GetData() + nM
) < nIdx
)
3223 rArr
.Insert( nIdx
, nU
);
3228 void InsertSort( SvULongs
& rArr
, ULONG nIdx
, USHORT
* pInsPos
)
3230 USHORT nO
= rArr
.Count(), nM
, nU
= 0;
3236 nM
= nU
+ ( nO
- nU
) / 2;
3237 if( *(rArr
.GetData() + nM
) == nIdx
)
3239 ASSERT( FALSE
, "Index ist schon vorhanden, darf nie sein!" );
3242 if( *(rArr
.GetData() + nM
) < nIdx
)
3250 rArr
.Insert( nIdx
, nU
);
3255 #if defined( JP_DEBUG ) && !defined( PRODUCT )
3258 void DumpDoc( SwDoc
* pDoc
, const String
& rFileNm
)
3260 Writer
* pWrt
= SwIoSystem::GetWriter( "DEBUG" );
3263 SvFileStream
aStream( rFileNm
, STREAM_STD_WRITE
);
3264 SwPaM
* pPam
= new SwPaM( pDoc
, SwPosition( pDoc
->GetNodes().EndOfContent
,
3265 pDoc
->GetNodes().EndOfContent
));
3266 pPam
->Move( fnMoveBackward
, fnGoDoc
);
3268 pPam
->Move( fnMoveForward
, fnGoDoc
);
3270 pWrt
->Write( pPam
, *pDoc
, aStream
, rFileNm
.GetStr() );
3275 void CheckTable( const SwTable
& rTbl
)
3277 const SwNodes
& rNds
= rTbl
.GetFrmFmt()->GetDoc()->GetNodes();
3278 const SwTableSortBoxes
& rSrtArr
= pTblNd
->GetTable().GetTabSortBoxes();
3279 for( USHORT n
= 0; n
< rSrtArr
.Count(); ++n
)
3281 const SwTableBox
* pBox
= rSrtArr
[ n
];
3282 const SwNode
* pNd
= pBox
->GetSttNd();
3283 ASSERT( rNds
[ *pBox
->GetSttIdx() ] == pNd
, "Box mit falchem StartNode" );