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: unsect.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 <svx/linkmgr.hxx>
36 #include <fmtcntnt.hxx>
39 #include <swundo.hxx> // fuer die UndoIds
43 #include <section.hxx>
45 #include <redline.hxx>
49 /// OD 04.10.2002 #102894#
50 /// class Calc needed for calculation of the hidden condition of a section.
54 inline SwDoc
& SwUndoIter::GetDoc() const { return *pAktPam
->GetDoc(); }
56 SfxItemSet
* lcl_GetAttrSet( const SwSection
& rSect
)
58 // Attribute des Formate sichern (Spalten, Farbe, ... )
59 // Cntnt- und Protect- Items interessieren nicht (stehen schon in der
60 // Section), muessen also entfernen werden
61 SfxItemSet
* pAttr
= 0;
65 if( rSect
.IsProtect() )
68 if( nCnt
< rSect
.GetFmt()->GetAttrSet().Count() )
70 pAttr
= new SfxItemSet( rSect
.GetFmt()->GetAttrSet() );
71 pAttr
->ClearItem( RES_PROTECT
);
72 pAttr
->ClearItem( RES_CNTNT
);
74 delete pAttr
, pAttr
= 0;
80 SwUndoInsSection::SwUndoInsSection( const SwPaM
& rPam
, const SwSection
& rNew
,
81 const SfxItemSet
* pSet
)
82 : SwUndo( UNDO_INSSECTION
), SwUndRng( rPam
),
83 pHistory( 0 ), pRedlData( 0 ), pAttr( 0 ), nSectNodePos( 0 )
85 if( rNew
.ISA( SwTOXBaseSection
))
87 const SwTOXBase
& rBase
= (SwTOXBaseSection
&)rNew
;
88 pSection
= new SwTOXBaseSection( rBase
);
91 pSection
= new SwSection( rNew
.GetType(), rNew
.GetName() );
94 SwDoc
& rDoc
= *(SwDoc
*)rPam
.GetDoc();
95 if( rDoc
.IsRedlineOn() )
97 pRedlData
= new SwRedlineData( nsRedlineType_t::REDLINE_INSERT
,
98 rDoc
.GetRedlineAuthor() );
99 SetRedlineMode( rDoc
.GetRedlineMode() );
106 if( pSet
&& pSet
->Count() )
107 pAttr
= new SfxItemSet( *pSet
);
109 if( !rPam
.HasMark() )
111 const SwCntntNode
* pCNd
= rPam
.GetPoint()->nNode
.GetNode().GetCntntNode();
112 if( pCNd
&& pCNd
->HasSwAttrSet() && (
113 !rPam
.GetPoint()->nContent
.GetIndex() ||
114 rPam
.GetPoint()->nContent
.GetIndex() == pCNd
->Len() ))
116 SfxItemSet
aBrkSet( rDoc
.GetAttrPool(), aBreakSetRange
);
117 aBrkSet
.Put( *pCNd
->GetpSwAttrSet() );
118 if( aBrkSet
.Count() )
120 pHistory
= new SwHistory
;
121 pHistory
->CopyFmtAttr( aBrkSet
, pCNd
->GetIndex() );
128 SwUndoInsSection::~SwUndoInsSection()
140 void SwUndoInsSection::Undo( SwUndoIter
& rUndoIter
)
142 SwDoc
& rDoc
= rUndoIter
.GetDoc();
144 RemoveIdxFromSection( rDoc
, nSectNodePos
);
146 SwSectionNode
* pNd
= rDoc
.GetNodes()[ nSectNodePos
]->GetSectionNode();
147 ASSERT( pNd
, "wo ist mein SectionNode?" );
149 if( IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ))
150 rDoc
.DeleteRedline( *pNd
, true, USHRT_MAX
);
152 // lag keine Selektion vor ??
153 SwNodeIndex
aIdx( *pNd
);
154 if( ( !nEndNode
&& STRING_MAXLEN
== nEndCntnt
) ||
155 ( nSttNode
== nEndNode
&& nSttCntnt
== nEndCntnt
))
156 // loesche einfach alle Nodes
157 rDoc
.GetNodes().Delete( aIdx
, pNd
->EndOfSectionIndex() -
160 // einfach das Format loeschen, der Rest erfolgt automatisch
161 rDoc
.DelSectionFmt( pNd
->GetSection().GetFmt() );
163 // muessen wir noch zusammenfassen ?
165 Join( rDoc
, nSttNode
);
168 Join( rDoc
, nEndNode
);
172 pHistory
->TmpRollback( &rDoc
, 0, false );
176 rDoc
.GetFtnIdxs().UpdateFtn( aIdx
);
182 void SwUndoInsSection::Redo( SwUndoIter
& rUndoIter
)
184 SwDoc
& rDoc
= rUndoIter
.GetDoc();
187 const SwTOXBaseSection
* pUpdateTOX
= 0;
188 if( pSection
->ISA( SwTOXBaseSection
))
190 const SwTOXBase
& rBase
= *(SwTOXBaseSection
*)pSection
;
191 pUpdateTOX
= rDoc
.InsertTableOf( *rUndoIter
.pAktPam
->GetPoint(),
192 rBase
, pAttr
, TRUE
);
195 rDoc
.Insert( *rUndoIter
.pAktPam
, *pSection
, pAttr
, TRUE
);
198 pHistory
->SetTmpEnd( pHistory
->Count() );
200 SwSectionNode
* pSectNd
= rDoc
.GetNodes()[ nSectNodePos
]->GetSectionNode();
201 if( pRedlData
&& IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ))
203 RedlineMode_t eOld
= rDoc
.GetRedlineMode();
204 rDoc
.SetRedlineMode_intern((RedlineMode_t
)(eOld
& ~nsRedlineMode_t::REDLINE_IGNORE
));
206 SwPaM
aPam( *pSectNd
->EndOfSectionNode(), *pSectNd
, 1 );
207 rDoc
.AppendRedline( new SwRedline( *pRedlData
, aPam
), true);
208 rDoc
.SetRedlineMode_intern( eOld
);
210 else if( !( nsRedlineMode_t::REDLINE_IGNORE
& GetRedlineMode() ) &&
211 rDoc
.GetRedlineTbl().Count() )
213 SwPaM
aPam( *pSectNd
->EndOfSectionNode(), *pSectNd
, 1 );
214 rDoc
.SplitRedline( aPam
);
219 // Formatierung anstossen
220 SwEditShell
* pESh
= rDoc
.GetEditShell();
224 // Seitennummern eintragen
225 ((SwTOXBaseSection
*)pUpdateTOX
)->UpdatePageNum();
230 void SwUndoInsSection::Repeat( SwUndoIter
& rUndoIter
)
232 if( pSection
->ISA( SwTOXBaseSection
))
234 const SwTOXBase
& rBase
= *(SwTOXBaseSection
*)pSection
;
235 rUndoIter
.GetDoc().InsertTableOf( *rUndoIter
.pAktPam
->GetPoint(),
236 rBase
, pAttr
, TRUE
);
239 rUndoIter
.GetDoc().Insert( *rUndoIter
.pAktPam
, *pSection
, pAttr
);
243 void SwUndoInsSection::Join( SwDoc
& rDoc
, ULONG nNode
)
245 SwNodeIndex
aIdx( rDoc
.GetNodes(), nNode
);
246 SwTxtNode
* pTxtNd
= aIdx
.GetNode().GetTxtNode();
247 ASSERT( pTxtNd
, "wo ist mein TextNode?" );
250 RemoveIdxRel( nNode
+ 1, SwPosition( aIdx
,
251 SwIndex( pTxtNd
, pTxtNd
->GetTxt().Len() )));
257 SwIndex
aCntIdx( pTxtNd
, 0 );
258 pTxtNd
->RstAttr( aCntIdx
, pTxtNd
->GetTxt().Len() );
263 void SwUndoInsSection::SaveSplitNode( SwTxtNode
* pTxtNd
, BOOL bAtStt
)
265 if( pTxtNd
->GetpSwpHints() )
268 pHistory
= new SwHistory
;
269 pHistory
->CopyAttr( pTxtNd
->GetpSwpHints(), pTxtNd
->GetIndex(), 0,
270 pTxtNd
->GetTxt().Len(), false );
280 // -----------------------------
282 SwUndoDelSection::SwUndoDelSection( const SwSectionFmt
& rFmt
)
283 : SwUndo( UNDO_DELSECTION
)
285 const SwSection
& rSect
= *rFmt
.GetSection();
286 if( rSect
.ISA( SwTOXBaseSection
))
288 const SwTOXBase
& rBase
= (SwTOXBaseSection
&)rSect
;
289 pSection
= new SwTOXBaseSection( rBase
);
292 pSection
= new SwSection( rSect
.GetType(), rSect
.GetName() );
295 pAttr
= ::lcl_GetAttrSet( rSect
);
297 const SwNodeIndex
* pIdx
= rFmt
.GetCntnt().GetCntntIdx();
298 nSttNd
= pIdx
->GetIndex();
299 nEndNd
= pIdx
->GetNode().EndOfSectionIndex();
303 SwUndoDelSection::~SwUndoDelSection()
310 void SwUndoDelSection::Undo( SwUndoIter
& rUndoIter
)
312 SwDoc
& rDoc
= rUndoIter
.GetDoc();
314 if( pSection
->ISA( SwTOXBaseSection
))
316 const SwTOXBase
& rBase
= *(SwTOXBaseSection
*)pSection
;
317 rDoc
.InsertTableOf( nSttNd
, nEndNd
-2, rBase
, pAttr
);
321 SwNodeIndex
aStt( rDoc
.GetNodes(), nSttNd
);
322 SwNodeIndex
aEnd( rDoc
.GetNodes(), nEndNd
-2 );
323 SwSectionFmt
* pFmt
= rDoc
.MakeSectionFmt( 0 );
325 pFmt
->SetFmtAttr( *pAttr
);
327 /// OD 04.10.2002 #102894#
328 /// remember inserted section node for further calculations
329 SwSectionNode
* pInsertedSectNd
=
330 rDoc
.GetNodes().InsertSection( aStt
, *pFmt
, *pSection
, &aEnd
);
332 if( SFX_ITEM_SET
== pFmt
->GetItemState( RES_FTN_AT_TXTEND
) ||
333 SFX_ITEM_SET
== pFmt
->GetItemState( RES_END_AT_TXTEND
))
335 rDoc
.GetFtnIdxs().UpdateFtn( aStt
);
338 /// OD 04.10.2002 #102894#
339 /// consider that section is hidden by condition.
340 /// If section is hidden by condition,
341 /// recalculate condition and update hidden condition flag.
342 /// Recalculation is necessary, because fields, on which the hide
343 /// condition depends, can be changed - fields changes aren't undoable.
344 /// NOTE: setting hidden condition flag also creates/deletes corresponding
345 /// frames, if the hidden condition flag changes.
346 SwSection
& aInsertedSect
= pInsertedSectNd
->GetSection();
347 if ( aInsertedSect
.IsHidden() &&
348 aInsertedSect
.GetCondition().Len() > 0 )
350 SwCalc
aCalc( rDoc
);
351 rDoc
.FldsToCalc(aCalc
, pInsertedSectNd
->GetIndex(), USHRT_MAX
);
352 bool bRecalcCondHidden
=
353 aCalc
.Calculate( aInsertedSect
.GetCondition() ).GetBool() ? true : false;
354 aInsertedSect
.SetCondHidden( bRecalcCondHidden
);
361 void SwUndoDelSection::Redo( SwUndoIter
& rUndoIter
)
363 SwDoc
& rDoc
= rUndoIter
.GetDoc();
365 SwSectionNode
* pNd
= rDoc
.GetNodes()[ nSttNd
]->GetSectionNode();
366 ASSERT( pNd
, "wo ist mein SectionNode?" );
367 // einfach das Format loeschen, der Rest erfolgt automatisch
368 rDoc
.DelSectionFmt( pNd
->GetSection().GetFmt() );
373 SwUndoChgSection::SwUndoChgSection( const SwSectionFmt
& rFmt
, BOOL bOnlyAttr
)
374 : SwUndo( UNDO_CHGSECTION
), bOnlyAttrChgd( bOnlyAttr
)
376 const SwSection
& rSect
= *rFmt
.GetSection();
377 pSection
= new SwSection( rSect
.GetType(), rSect
.GetName() );
380 pAttr
= ::lcl_GetAttrSet( rSect
);
382 nSttNd
= rFmt
.GetCntnt().GetCntntIdx()->GetIndex();
386 SwUndoChgSection::~SwUndoChgSection()
393 void SwUndoChgSection::Undo( SwUndoIter
& rUndoIter
)
395 SwDoc
& rDoc
= rUndoIter
.GetDoc();
396 SwSectionNode
* pSectNd
= rDoc
.GetNodes()[ nSttNd
]->GetSectionNode();
397 ASSERT( pSectNd
, "wo ist mein SectionNode?" );
399 SwSection
& rNdSect
= pSectNd
->GetSection();
400 SwFmt
* pFmt
= rNdSect
.GetFmt();
402 SfxItemSet
* pCur
= ::lcl_GetAttrSet( rNdSect
);
405 // das Content- und Protect-Item muss bestehen bleiben
406 const SfxPoolItem
* pItem
;
407 pAttr
->Put( pFmt
->GetFmtAttr( RES_CNTNT
));
408 if( SFX_ITEM_SET
== pFmt
->GetItemState( RES_PROTECT
, TRUE
, &pItem
))
409 pAttr
->Put( *pItem
);
410 pFmt
->DelDiffs( *pAttr
);
411 pAttr
->ClearItem( RES_CNTNT
);
412 pFmt
->SetFmtAttr( *pAttr
);
417 // dann muessen die alten entfernt werden
418 pFmt
->ResetFmtAttr( RES_FRMATR_BEGIN
, RES_BREAK
);
419 pFmt
->ResetFmtAttr( RES_HEADER
, RES_OPAQUE
);
420 pFmt
->ResetFmtAttr( RES_SURROUND
, RES_FRMATR_END
-1 );
426 BOOL bUpdate
= (!rNdSect
.IsLinkType() && pSection
->IsLinkType() ) ||
427 ( pSection
->GetLinkFileName().Len() &&
428 pSection
->GetLinkFileName() !=
429 rNdSect
.GetLinkFileName());
431 SwSection
* pTmp
= new SwSection( CONTENT_SECTION
, aEmptyStr
);
432 *pTmp
= rNdSect
; // das aktuelle sichern
434 rNdSect
= *pSection
; // das alte setzen
437 pSection
= pTmp
; // das aktuelle ist jetzt das alte
440 rNdSect
.CreateLink( CREATE_UPDATE
);
441 else if( CONTENT_SECTION
== rNdSect
.GetType() && rNdSect
.IsConnected() )
443 rNdSect
.Disconnect();
444 rDoc
.GetLinkManager().Remove( &rNdSect
.GetBaseLink() );
450 void SwUndoChgSection::Redo( SwUndoIter
& rUndoIter
)