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
);
196 rDoc
.InsertSwSection( *rUndoIter
.pAktPam
, *pSection
, pAttr
, true );
200 pHistory
->SetTmpEnd( pHistory
->Count() );
202 SwSectionNode
* pSectNd
= rDoc
.GetNodes()[ nSectNodePos
]->GetSectionNode();
203 if( pRedlData
&& IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ))
205 RedlineMode_t eOld
= rDoc
.GetRedlineMode();
206 rDoc
.SetRedlineMode_intern((RedlineMode_t
)(eOld
& ~nsRedlineMode_t::REDLINE_IGNORE
));
208 SwPaM
aPam( *pSectNd
->EndOfSectionNode(), *pSectNd
, 1 );
209 rDoc
.AppendRedline( new SwRedline( *pRedlData
, aPam
), true);
210 rDoc
.SetRedlineMode_intern( eOld
);
212 else if( !( nsRedlineMode_t::REDLINE_IGNORE
& GetRedlineMode() ) &&
213 rDoc
.GetRedlineTbl().Count() )
215 SwPaM
aPam( *pSectNd
->EndOfSectionNode(), *pSectNd
, 1 );
216 rDoc
.SplitRedline( aPam
);
221 // Formatierung anstossen
222 SwEditShell
* pESh
= rDoc
.GetEditShell();
226 // Seitennummern eintragen
227 ((SwTOXBaseSection
*)pUpdateTOX
)->UpdatePageNum();
232 void SwUndoInsSection::Repeat( SwUndoIter
& rUndoIter
)
234 if( pSection
->ISA( SwTOXBaseSection
))
236 const SwTOXBase
& rBase
= *(SwTOXBaseSection
*)pSection
;
237 rUndoIter
.GetDoc().InsertTableOf( *rUndoIter
.pAktPam
->GetPoint(),
238 rBase
, pAttr
, TRUE
);
242 rUndoIter
.GetDoc().InsertSwSection( *rUndoIter
.pAktPam
,
248 void SwUndoInsSection::Join( SwDoc
& rDoc
, ULONG nNode
)
250 SwNodeIndex
aIdx( rDoc
.GetNodes(), nNode
);
251 SwTxtNode
* pTxtNd
= aIdx
.GetNode().GetTxtNode();
252 ASSERT( pTxtNd
, "wo ist mein TextNode?" );
255 RemoveIdxRel( nNode
+ 1, SwPosition( aIdx
,
256 SwIndex( pTxtNd
, pTxtNd
->GetTxt().Len() )));
262 SwIndex
aCntIdx( pTxtNd
, 0 );
263 pTxtNd
->RstAttr( aCntIdx
, pTxtNd
->Len(), 0, 0, true );
268 void SwUndoInsSection::SaveSplitNode( SwTxtNode
* pTxtNd
, BOOL bAtStt
)
270 if( pTxtNd
->GetpSwpHints() )
273 pHistory
= new SwHistory
;
274 pHistory
->CopyAttr( pTxtNd
->GetpSwpHints(), pTxtNd
->GetIndex(), 0,
275 pTxtNd
->GetTxt().Len(), false );
285 // -----------------------------
287 SwUndoDelSection::SwUndoDelSection( const SwSectionFmt
& rFmt
)
288 : SwUndo( UNDO_DELSECTION
)
290 const SwSection
& rSect
= *rFmt
.GetSection();
291 if( rSect
.ISA( SwTOXBaseSection
))
293 const SwTOXBase
& rBase
= (SwTOXBaseSection
&)rSect
;
294 pSection
= new SwTOXBaseSection( rBase
);
297 pSection
= new SwSection( rSect
.GetType(), rSect
.GetName() );
300 pAttr
= ::lcl_GetAttrSet( rSect
);
302 const SwNodeIndex
* pIdx
= rFmt
.GetCntnt().GetCntntIdx();
303 nSttNd
= pIdx
->GetIndex();
304 nEndNd
= pIdx
->GetNode().EndOfSectionIndex();
308 SwUndoDelSection::~SwUndoDelSection()
315 void SwUndoDelSection::Undo( SwUndoIter
& rUndoIter
)
317 SwDoc
& rDoc
= rUndoIter
.GetDoc();
319 if( pSection
->ISA( SwTOXBaseSection
))
321 const SwTOXBase
& rBase
= *(SwTOXBaseSection
*)pSection
;
322 rDoc
.InsertTableOf( nSttNd
, nEndNd
-2, rBase
, pAttr
);
326 SwNodeIndex
aStt( rDoc
.GetNodes(), nSttNd
);
327 SwNodeIndex
aEnd( rDoc
.GetNodes(), nEndNd
-2 );
328 SwSectionFmt
* pFmt
= rDoc
.MakeSectionFmt( 0 );
330 pFmt
->SetFmtAttr( *pAttr
);
332 /// OD 04.10.2002 #102894#
333 /// remember inserted section node for further calculations
334 SwSectionNode
* pInsertedSectNd
=
335 rDoc
.GetNodes().InsertSection( aStt
, *pFmt
, *pSection
, &aEnd
);
337 if( SFX_ITEM_SET
== pFmt
->GetItemState( RES_FTN_AT_TXTEND
) ||
338 SFX_ITEM_SET
== pFmt
->GetItemState( RES_END_AT_TXTEND
))
340 rDoc
.GetFtnIdxs().UpdateFtn( aStt
);
343 /// OD 04.10.2002 #102894#
344 /// consider that section is hidden by condition.
345 /// If section is hidden by condition,
346 /// recalculate condition and update hidden condition flag.
347 /// Recalculation is necessary, because fields, on which the hide
348 /// condition depends, can be changed - fields changes aren't undoable.
349 /// NOTE: setting hidden condition flag also creates/deletes corresponding
350 /// frames, if the hidden condition flag changes.
351 SwSection
& aInsertedSect
= pInsertedSectNd
->GetSection();
352 if ( aInsertedSect
.IsHidden() &&
353 aInsertedSect
.GetCondition().Len() > 0 )
355 SwCalc
aCalc( rDoc
);
356 rDoc
.FldsToCalc(aCalc
, pInsertedSectNd
->GetIndex(), USHRT_MAX
);
357 bool bRecalcCondHidden
=
358 aCalc
.Calculate( aInsertedSect
.GetCondition() ).GetBool() ? true : false;
359 aInsertedSect
.SetCondHidden( bRecalcCondHidden
);
366 void SwUndoDelSection::Redo( SwUndoIter
& rUndoIter
)
368 SwDoc
& rDoc
= rUndoIter
.GetDoc();
370 SwSectionNode
* pNd
= rDoc
.GetNodes()[ nSttNd
]->GetSectionNode();
371 ASSERT( pNd
, "wo ist mein SectionNode?" );
372 // einfach das Format loeschen, der Rest erfolgt automatisch
373 rDoc
.DelSectionFmt( pNd
->GetSection().GetFmt() );
378 SwUndoChgSection::SwUndoChgSection( const SwSectionFmt
& rFmt
, BOOL bOnlyAttr
)
379 : SwUndo( UNDO_CHGSECTION
), bOnlyAttrChgd( bOnlyAttr
)
381 const SwSection
& rSect
= *rFmt
.GetSection();
382 pSection
= new SwSection( rSect
.GetType(), rSect
.GetName() );
385 pAttr
= ::lcl_GetAttrSet( rSect
);
387 nSttNd
= rFmt
.GetCntnt().GetCntntIdx()->GetIndex();
391 SwUndoChgSection::~SwUndoChgSection()
398 void SwUndoChgSection::Undo( SwUndoIter
& rUndoIter
)
400 SwDoc
& rDoc
= rUndoIter
.GetDoc();
401 SwSectionNode
* pSectNd
= rDoc
.GetNodes()[ nSttNd
]->GetSectionNode();
402 ASSERT( pSectNd
, "wo ist mein SectionNode?" );
404 SwSection
& rNdSect
= pSectNd
->GetSection();
405 SwFmt
* pFmt
= rNdSect
.GetFmt();
407 SfxItemSet
* pCur
= ::lcl_GetAttrSet( rNdSect
);
410 // das Content- und Protect-Item muss bestehen bleiben
411 const SfxPoolItem
* pItem
;
412 pAttr
->Put( pFmt
->GetFmtAttr( RES_CNTNT
));
413 if( SFX_ITEM_SET
== pFmt
->GetItemState( RES_PROTECT
, TRUE
, &pItem
))
414 pAttr
->Put( *pItem
);
415 pFmt
->DelDiffs( *pAttr
);
416 pAttr
->ClearItem( RES_CNTNT
);
417 pFmt
->SetFmtAttr( *pAttr
);
422 // dann muessen die alten entfernt werden
423 pFmt
->ResetFmtAttr( RES_FRMATR_BEGIN
, RES_BREAK
);
424 pFmt
->ResetFmtAttr( RES_HEADER
, RES_OPAQUE
);
425 pFmt
->ResetFmtAttr( RES_SURROUND
, RES_FRMATR_END
-1 );
431 BOOL bUpdate
= (!rNdSect
.IsLinkType() && pSection
->IsLinkType() ) ||
432 ( pSection
->GetLinkFileName().Len() &&
433 pSection
->GetLinkFileName() !=
434 rNdSect
.GetLinkFileName());
436 SwSection
* pTmp
= new SwSection( CONTENT_SECTION
, aEmptyStr
);
437 *pTmp
= rNdSect
; // das aktuelle sichern
439 rNdSect
= *pSection
; // das alte setzen
442 pSection
= pTmp
; // das aktuelle ist jetzt das alte
445 rNdSect
.CreateLink( CREATE_UPDATE
);
446 else if( CONTENT_SECTION
== rNdSect
.GetType() && rNdSect
.IsConnected() )
448 rNdSect
.Disconnect();
449 rDoc
.GetLinkManager().Remove( &rNdSect
.GetBaseLink() );
455 void SwUndoChgSection::Redo( SwUndoIter
& rUndoIter
)