Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <rolbck.hxx>
21 : #include <tools/resid.hxx>
22 : #include <svl/itemiter.hxx>
23 : #include <editeng/formatbreakitem.hxx>
24 : #include <hints.hxx>
25 : #include <hintids.hxx>
26 : #include <fmtftn.hxx>
27 : #include <fchrfmt.hxx>
28 : #include <fmtflcnt.hxx>
29 : #include <fmtrfmrk.hxx>
30 : #include <fmtfld.hxx>
31 : #include <fmtpdsc.hxx>
32 : #include <txtfld.hxx>
33 : #include <txtrfmrk.hxx>
34 : #include <txttxmrk.hxx>
35 : #include <txtftn.hxx>
36 : #include <txtflcnt.hxx>
37 : #include <fmtanchr.hxx>
38 : #include <fmtcnct.hxx>
39 : #include <frmfmt.hxx>
40 : #include <ftnidx.hxx>
41 : #include <doc.hxx>
42 : #include <IDocumentUndoRedo.hxx>
43 : #include <IDocumentFieldsAccess.hxx>
44 : #include <IDocumentLayoutAccess.hxx>
45 : #include <docary.hxx>
46 : #include <ndtxt.hxx>
47 : #include <paratr.hxx>
48 : #include <cellatr.hxx>
49 : #include <fldbas.hxx>
50 : #include <pam.hxx>
51 : #include <swtable.hxx>
52 : #include <ndgrf.hxx>
53 : #include <UndoCore.hxx>
54 : #include <IMark.hxx>
55 : #include <charfmt.hxx>
56 : #include <comcore.hrc>
57 : #include <undo.hrc>
58 : #include <bookmrk.hxx>
59 : #include <boost/scoped_ptr.hpp>
60 :
61 1144 : OUString SwHistoryHint::GetDescription() const
62 : {
63 1144 : return OUString();
64 : }
65 :
66 3558 : SwHistorySetFmt::SwHistorySetFmt( const SfxPoolItem* pFmtHt, sal_uLong nNd )
67 : : SwHistoryHint( HSTRY_SETFMTHNT )
68 3558 : , m_pAttr( pFmtHt->Clone() )
69 7116 : , m_nNodeIndex( nNd )
70 : {
71 3558 : switch ( m_pAttr->Which() )
72 : {
73 : case RES_PAGEDESC:
74 6 : static_cast<SwFmtPageDesc&>(*m_pAttr).ChgDefinedIn( 0 );
75 6 : break;
76 : case RES_PARATR_DROP:
77 0 : static_cast<SwFmtDrop&>(*m_pAttr).ChgDefinedIn( 0 );
78 0 : break;
79 : case RES_BOXATR_FORMULA:
80 : {
81 : // save formulas always in plain text
82 0 : SwTblBoxFormula& rNew = static_cast<SwTblBoxFormula&>(*m_pAttr);
83 0 : if ( rNew.IsIntrnlName() )
84 : {
85 : const SwTblBoxFormula& rOld =
86 0 : *static_cast<const SwTblBoxFormula*>(pFmtHt);
87 0 : const SwNode* pNd = rOld.GetNodeOfFormula();
88 0 : if ( pNd )
89 : {
90 0 : const SwTableNode* pTableNode = pNd->FindTableNode();
91 0 : if (pTableNode)
92 : {
93 0 : SwTableFmlUpdate aMsgHnt( &pTableNode->GetTable() );
94 0 : aMsgHnt.eFlags = TBL_BOXNAME;
95 0 : rNew.ChgDefinedIn( rOld.GetDefinedIn() );
96 0 : rNew.ChangeState( &aMsgHnt );
97 : }
98 : }
99 : }
100 0 : rNew.ChgDefinedIn( 0 );
101 : }
102 0 : break;
103 : }
104 3558 : }
105 :
106 60 : OUString SwHistorySetFmt::GetDescription() const
107 : {
108 60 : OUString aResult;
109 :
110 60 : switch (m_pAttr->Which())
111 : {
112 : case RES_BREAK:
113 0 : switch ((static_cast<SvxFmtBreakItem &>(*m_pAttr)).GetBreak())
114 : {
115 : case SVX_BREAK_PAGE_BEFORE:
116 : case SVX_BREAK_PAGE_AFTER:
117 : case SVX_BREAK_PAGE_BOTH:
118 0 : aResult = SW_RESSTR(STR_UNDO_PAGEBREAKS);
119 :
120 0 : break;
121 : case SVX_BREAK_COLUMN_BEFORE:
122 : case SVX_BREAK_COLUMN_AFTER:
123 : case SVX_BREAK_COLUMN_BOTH:
124 0 : aResult = SW_RESSTR(STR_UNDO_COLBRKS);
125 :
126 0 : break;
127 : default:
128 0 : break;
129 : }
130 0 : break;
131 : default:
132 60 : break;
133 : }
134 :
135 60 : return aResult;
136 : }
137 :
138 0 : void SwHistorySetFmt::SetInDoc( SwDoc* pDoc, bool bTmpSet )
139 : {
140 0 : SwNode * pNode = pDoc->GetNodes()[ m_nNodeIndex ];
141 0 : if ( pNode->IsCntntNode() )
142 : {
143 0 : static_cast<SwCntntNode*>(pNode)->SetAttr( *m_pAttr );
144 : }
145 0 : else if ( pNode->IsTableNode() )
146 : {
147 0 : static_cast<SwTableNode*>(pNode)->GetTable().GetFrmFmt()->SetFmtAttr(
148 0 : *m_pAttr );
149 : }
150 0 : else if ( pNode->IsStartNode() && (SwTableBoxStartNode ==
151 0 : static_cast<SwStartNode*>(pNode)->GetStartNodeType()) )
152 : {
153 0 : SwTableNode* pTNd = pNode->FindTableNode();
154 0 : if ( pTNd )
155 : {
156 0 : SwTableBox* pBox = pTNd->GetTable().GetTblBox( m_nNodeIndex );
157 0 : if (pBox)
158 : {
159 0 : pBox->ClaimFrmFmt()->SetFmtAttr( *m_pAttr );
160 : }
161 : }
162 : }
163 :
164 0 : if ( !bTmpSet )
165 : {
166 0 : m_pAttr.reset();
167 : }
168 0 : }
169 :
170 7110 : SwHistorySetFmt::~SwHistorySetFmt()
171 : {
172 7110 : }
173 :
174 2074 : SwHistoryResetFmt::SwHistoryResetFmt(const SfxPoolItem* pFmtHt, sal_uLong nNodeIdx)
175 : : SwHistoryHint( HSTRY_RESETFMTHNT )
176 : , m_nNodeIndex( nNodeIdx )
177 2074 : , m_nWhich( pFmtHt->Which() )
178 : {
179 2074 : }
180 :
181 0 : void SwHistoryResetFmt::SetInDoc( SwDoc* pDoc, bool )
182 : {
183 0 : SwNode * pNode = pDoc->GetNodes()[ m_nNodeIndex ];
184 0 : if ( pNode->IsCntntNode() )
185 : {
186 0 : static_cast<SwCntntNode*>(pNode)->ResetAttr( m_nWhich );
187 : }
188 0 : else if ( pNode->IsTableNode() )
189 : {
190 0 : static_cast<SwTableNode*>(pNode)->GetTable().GetFrmFmt()->
191 0 : ResetFmtAttr( m_nWhich );
192 : }
193 0 : }
194 :
195 522 : SwHistorySetTxt::SwHistorySetTxt( SwTxtAttr* pTxtHt, sal_uLong nNodePos )
196 : : SwHistoryHint( HSTRY_SETTXTHNT )
197 : , m_nNodeIndex( nNodePos )
198 522 : , m_nStart( pTxtHt->GetStart() )
199 522 : , m_nEnd( *pTxtHt->GetAnyEnd() )
200 522 : , m_bFormatIgnoreStart(pTxtHt->IsFormatIgnoreStart())
201 2088 : , m_bFormatIgnoreEnd (pTxtHt->IsFormatIgnoreEnd ())
202 : {
203 : // Caution: the following attributes generate no format attributes:
204 : // - NoLineBreak, NoHypen, Inserted, Deleted
205 : // These cases must be handled separately !!!
206 :
207 : // a little bit complicated but works: first assign a copy of the
208 : // default value and afterwards the values from text attribute
209 522 : if ( RES_TXTATR_CHARFMT == pTxtHt->Which() )
210 : {
211 4 : m_pAttr.reset( new SwFmtCharFmt( pTxtHt->GetCharFmt().GetCharFmt() ) );
212 : }
213 : else
214 : {
215 518 : m_pAttr.reset( pTxtHt->GetAttr().Clone() );
216 : }
217 522 : }
218 :
219 1044 : SwHistorySetTxt::~SwHistorySetTxt()
220 : {
221 1044 : }
222 :
223 0 : void SwHistorySetTxt::SetInDoc( SwDoc* pDoc, bool )
224 : {
225 0 : if ( !m_pAttr.get() )
226 0 : return;
227 :
228 0 : if ( RES_TXTATR_CHARFMT == m_pAttr->Which() )
229 : {
230 : // ask the Doc if the CharFmt still exists
231 0 : if ( !pDoc->GetCharFmts()->Contains( (static_cast<SwFmtCharFmt&>(*m_pAttr)).GetCharFmt() ) )
232 0 : return; // do not set, format does not exist
233 : }
234 :
235 0 : SwTxtNode * pTxtNd = pDoc->GetNodes()[ m_nNodeIndex ]->GetTxtNode();
236 : OSL_ENSURE( pTxtNd, "SwHistorySetTxt::SetInDoc: not a TextNode" );
237 :
238 0 : if ( pTxtNd )
239 : {
240 0 : SwTxtAttr *const pAttr = pTxtNd->InsertItem(*m_pAttr, m_nStart, m_nEnd,
241 : nsSetAttrMode::SETATTR_NOTXTATRCHR |
242 0 : nsSetAttrMode::SETATTR_NOHINTADJUST );
243 : // shouldn't be possible to hit any error/merging path from here
244 : assert(pAttr);
245 0 : if (m_bFormatIgnoreStart)
246 : {
247 0 : pAttr->SetFormatIgnoreStart(true);
248 : }
249 0 : if (m_bFormatIgnoreEnd)
250 : {
251 0 : pAttr->SetFormatIgnoreEnd(true);
252 : }
253 : }
254 : }
255 :
256 86 : SwHistorySetTxtFld::SwHistorySetTxtFld( SwTxtFld* pTxtFld, sal_uLong nNodePos )
257 : : SwHistoryHint( HSTRY_SETTXTFLDHNT )
258 86 : , m_pFld( new SwFmtFld( *pTxtFld->GetFmtFld().GetField() ) )
259 : {
260 : // only copy if not Sys-FieldType
261 86 : SwDoc* pDoc = pTxtFld->GetTxtNode().GetDoc();
262 :
263 86 : m_nFldWhich = m_pFld->GetField()->GetTyp()->Which();
264 232 : if (m_nFldWhich == RES_DBFLD ||
265 120 : m_nFldWhich == RES_USERFLD ||
266 120 : m_nFldWhich == RES_SETEXPFLD ||
267 206 : m_nFldWhich == RES_DDEFLD ||
268 60 : !pDoc->getIDocumentFieldsAccess().GetSysFldType( m_nFldWhich ))
269 : {
270 26 : m_pFldType.reset( m_pFld->GetField()->GetTyp()->Copy() );
271 26 : m_pFld->GetField()->ChgTyp( m_pFldType.get() ); // change field type
272 : }
273 86 : m_nNodeIndex = nNodePos;
274 86 : m_nPos = pTxtFld->GetStart();
275 86 : }
276 :
277 48 : OUString SwHistorySetTxtFld::GetDescription() const
278 : {
279 48 : return m_pFld->GetField()->GetDescription();
280 : }
281 :
282 170 : SwHistorySetTxtFld::~SwHistorySetTxtFld()
283 : {
284 170 : }
285 :
286 0 : void SwHistorySetTxtFld::SetInDoc( SwDoc* pDoc, bool )
287 : {
288 0 : if ( !m_pFld.get() )
289 0 : return;
290 :
291 0 : SwFieldType* pNewFldType = m_pFldType.get();
292 0 : if ( !pNewFldType )
293 : {
294 0 : pNewFldType = pDoc->getIDocumentFieldsAccess().GetSysFldType( m_nFldWhich );
295 : }
296 : else
297 : {
298 : // register type with the document
299 0 : pNewFldType = pDoc->getIDocumentFieldsAccess().InsertFldType( *m_pFldType );
300 : }
301 :
302 0 : m_pFld->GetField()->ChgTyp( pNewFldType ); // change field type
303 :
304 0 : SwTxtNode * pTxtNd = pDoc->GetNodes()[ m_nNodeIndex ]->GetTxtNode();
305 : OSL_ENSURE( pTxtNd, "SwHistorySetTxtFld: no TextNode" );
306 :
307 0 : if ( pTxtNd )
308 : {
309 0 : pTxtNd->InsertItem( *m_pFld, m_nPos, m_nPos,
310 0 : nsSetAttrMode::SETATTR_NOTXTATRCHR );
311 : }
312 : }
313 :
314 24 : SwHistorySetRefMark::SwHistorySetRefMark( SwTxtRefMark* pTxtHt, sal_uLong nNodePos )
315 : : SwHistoryHint( HSTRY_SETREFMARKHNT )
316 24 : , m_RefName( pTxtHt->GetRefMark().GetRefName() )
317 : , m_nNodeIndex( nNodePos )
318 24 : , m_nStart( pTxtHt->GetStart() )
319 72 : , m_nEnd( *pTxtHt->GetAnyEnd() )
320 : {
321 24 : }
322 :
323 0 : void SwHistorySetRefMark::SetInDoc( SwDoc* pDoc, bool )
324 : {
325 0 : SwTxtNode * pTxtNd = pDoc->GetNodes()[ m_nNodeIndex ]->GetTxtNode();
326 : OSL_ENSURE( pTxtNd, "SwHistorySetRefMark: no TextNode" );
327 0 : if ( !pTxtNd )
328 0 : return;
329 :
330 0 : SwFmtRefMark aRefMark( m_RefName );
331 :
332 : // if a reference mark without an end already exists here: must not insert!
333 0 : if ( m_nStart != m_nEnd ||
334 0 : !pTxtNd->GetTxtAttrForCharAt( m_nStart, RES_TXTATR_REFMARK ) )
335 : {
336 : pTxtNd->InsertItem( aRefMark, m_nStart, m_nEnd,
337 0 : nsSetAttrMode::SETATTR_NOTXTATRCHR );
338 0 : }
339 : }
340 :
341 26 : SwHistorySetTOXMark::SwHistorySetTOXMark( SwTxtTOXMark* pTxtHt, sal_uLong nNodePos )
342 : : SwHistoryHint( HSTRY_SETTOXMARKHNT )
343 26 : , m_TOXMark( pTxtHt->GetTOXMark() )
344 : , m_TOXName( m_TOXMark.GetTOXType()->GetTypeName() )
345 26 : , m_eTOXTypes( m_TOXMark.GetTOXType()->GetType() )
346 : , m_nNodeIndex( nNodePos )
347 26 : , m_nStart( pTxtHt->GetStart() )
348 104 : , m_nEnd( *pTxtHt->GetAnyEnd() )
349 : {
350 26 : m_TOXMark.DeRegister();
351 26 : }
352 :
353 0 : void SwHistorySetTOXMark::SetInDoc( SwDoc* pDoc, bool )
354 : {
355 0 : SwTxtNode * pTxtNd = pDoc->GetNodes()[ m_nNodeIndex ]->GetTxtNode();
356 : OSL_ENSURE( pTxtNd, "SwHistorySetTOXMark: no TextNode" );
357 0 : if ( !pTxtNd )
358 0 : return;
359 :
360 : // search for respective TOX type
361 0 : const sal_uInt16 nCnt = pDoc->GetTOXTypeCount( m_eTOXTypes );
362 0 : SwTOXType* pToxType = 0;
363 0 : for ( sal_uInt16 n = 0; n < nCnt; ++n )
364 : {
365 0 : pToxType = const_cast<SwTOXType*>(pDoc->GetTOXType( m_eTOXTypes, n ));
366 0 : if ( pToxType->GetTypeName() == m_TOXName )
367 0 : break;
368 0 : pToxType = 0;
369 : }
370 :
371 0 : if ( !pToxType ) // TOX type not found, create new
372 : {
373 : pToxType = const_cast<SwTOXType*>(
374 0 : pDoc->InsertTOXType( SwTOXType( m_eTOXTypes, m_TOXName )));
375 : }
376 :
377 0 : SwTOXMark aNew( m_TOXMark );
378 0 : aNew.RegisterToTOXType( *pToxType );
379 :
380 : pTxtNd->InsertItem( aNew, m_nStart, m_nEnd,
381 0 : nsSetAttrMode::SETATTR_NOTXTATRCHR );
382 : }
383 :
384 0 : bool SwHistorySetTOXMark::IsEqual( const SwTOXMark& rCmp ) const
385 : {
386 0 : return m_TOXName == rCmp.GetTOXType()->GetTypeName() &&
387 0 : m_eTOXTypes == rCmp.GetTOXType()->GetType() &&
388 0 : m_TOXMark.GetAlternativeText() == rCmp.GetAlternativeText() &&
389 0 : ( (TOX_INDEX == m_eTOXTypes)
390 0 : ? ( m_TOXMark.GetPrimaryKey() == rCmp.GetPrimaryKey() &&
391 0 : m_TOXMark.GetSecondaryKey() == rCmp.GetSecondaryKey() )
392 0 : : m_TOXMark.GetLevel() == rCmp.GetLevel()
393 0 : );
394 : }
395 :
396 3554 : SwHistoryResetTxt::SwHistoryResetTxt( sal_uInt16 nWhich,
397 : sal_Int32 nAttrStart, sal_Int32 nAttrEnd, sal_uLong nNodePos )
398 : : SwHistoryHint( HSTRY_RESETTXTHNT )
399 : , m_nNodeIndex( nNodePos ), m_nStart( nAttrStart ), m_nEnd( nAttrEnd )
400 3554 : , m_nAttr( nWhich )
401 : {
402 3554 : }
403 :
404 0 : void SwHistoryResetTxt::SetInDoc( SwDoc* pDoc, bool )
405 : {
406 0 : SwTxtNode * pTxtNd = pDoc->GetNodes()[ m_nNodeIndex ]->GetTxtNode();
407 : OSL_ENSURE( pTxtNd, "SwHistoryResetTxt: no TextNode" );
408 0 : if ( pTxtNd )
409 : {
410 0 : pTxtNd->DeleteAttributes( m_nAttr, m_nStart, m_nEnd );
411 : }
412 0 : }
413 :
414 26 : SwHistorySetFootnote::SwHistorySetFootnote( SwTxtFtn* pTxtFtn, sal_uLong nNodePos )
415 : : SwHistoryHint( HSTRY_SETFTNHNT )
416 26 : , m_pUndo( new SwUndoSaveSection )
417 26 : , m_FootnoteNumber( pTxtFtn->GetFtn().GetNumStr() )
418 : , m_nNodeIndex( nNodePos )
419 26 : , m_nStart( pTxtFtn->GetStart() )
420 104 : , m_bEndNote( pTxtFtn->GetFtn().IsEndNote() )
421 : {
422 : OSL_ENSURE( pTxtFtn->GetStartNode(),
423 : "SwHistorySetFootnote: Footnote without Section" );
424 :
425 : // keep the old NodePos (because who knows what later will be saved/deleted
426 : // in SaveSection)
427 26 : SwDoc* pDoc = const_cast<SwDoc*>(pTxtFtn->GetTxtNode().GetDoc());
428 26 : SwNode* pSaveNd = pDoc->GetNodes()[ m_nNodeIndex ];
429 :
430 : // keep pointer to StartNode of FtnSection and reset its attribute for now
431 : // (as a result, its/all Frms will be deleted automatically)
432 26 : SwNodeIndex aSttIdx( *pTxtFtn->GetStartNode() );
433 26 : pTxtFtn->SetStartNode( 0, false );
434 :
435 26 : m_pUndo->SaveSection( pDoc, aSttIdx );
436 26 : m_nNodeIndex = pSaveNd->GetIndex();
437 26 : }
438 :
439 4 : SwHistorySetFootnote::SwHistorySetFootnote( const SwTxtFtn &rTxtFtn )
440 : : SwHistoryHint( HSTRY_SETFTNHNT )
441 4 : , m_FootnoteNumber( rTxtFtn.GetFtn().GetNumStr() )
442 4 : , m_nNodeIndex( _SwTxtFtn_GetIndex( (&rTxtFtn) ) )
443 4 : , m_nStart( rTxtFtn.GetStart() )
444 16 : , m_bEndNote( rTxtFtn.GetFtn().IsEndNote() )
445 : {
446 : OSL_ENSURE( rTxtFtn.GetStartNode(),
447 : "SwHistorySetFootnote: Footnote without Section" );
448 4 : }
449 :
450 20 : OUString SwHistorySetFootnote::GetDescription() const
451 : {
452 20 : return SW_RES(STR_FOOTNOTE);
453 : }
454 :
455 60 : SwHistorySetFootnote::~SwHistorySetFootnote()
456 : {
457 60 : }
458 :
459 0 : void SwHistorySetFootnote::SetInDoc( SwDoc* pDoc, bool )
460 : {
461 0 : SwTxtNode * pTxtNd = pDoc->GetNodes()[ m_nNodeIndex ]->GetTxtNode();
462 : OSL_ENSURE( pTxtNd, "SwHistorySetFootnote: no TextNode" );
463 0 : if ( !pTxtNd )
464 0 : return;
465 :
466 0 : if ( m_pUndo.get() )
467 : {
468 : // set the footnote in the TextNode
469 0 : SwFmtFtn aTemp( m_bEndNote );
470 : SwFmtFtn& rNew = const_cast<SwFmtFtn&>(
471 0 : static_cast<const SwFmtFtn&>(pDoc->GetAttrPool().Put(aTemp)) );
472 0 : if ( !m_FootnoteNumber.isEmpty() )
473 : {
474 0 : rNew.SetNumStr( m_FootnoteNumber );
475 : }
476 0 : SwTxtFtn* pTxtFtn = new SwTxtFtn( rNew, m_nStart );
477 :
478 : // create the section of the Footnote
479 0 : SwNodeIndex aIdx( *pTxtNd );
480 0 : m_pUndo->RestoreSection( pDoc, &aIdx, SwFootnoteStartNode );
481 0 : pTxtFtn->SetStartNode( &aIdx );
482 0 : if ( m_pUndo->GetHistory() )
483 : {
484 : // create frames only now
485 0 : m_pUndo->GetHistory()->Rollback( pDoc );
486 : }
487 :
488 0 : pTxtNd->InsertHint( pTxtFtn );
489 : }
490 : else
491 : {
492 : SwTxtFtn * const pFtn =
493 : const_cast<SwTxtFtn*>( static_cast<const SwTxtFtn*>(
494 0 : pTxtNd->GetTxtAttrForCharAt( m_nStart )));
495 0 : SwFmtFtn &rFtn = const_cast<SwFmtFtn&>(pFtn->GetFtn());
496 0 : rFtn.SetNumStr( m_FootnoteNumber );
497 0 : if ( rFtn.IsEndNote() != m_bEndNote )
498 : {
499 0 : rFtn.SetEndNote( m_bEndNote );
500 0 : pFtn->CheckCondColl();
501 : }
502 : }
503 : }
504 :
505 4058 : SwHistoryChangeFmtColl::SwHistoryChangeFmtColl( SwFmtColl* pFmtColl, sal_uLong nNd,
506 : sal_uInt8 nNodeWhich )
507 : : SwHistoryHint( HSTRY_CHGFMTCOLL )
508 : , m_pColl( pFmtColl )
509 : , m_nNodeIndex( nNd )
510 4058 : , m_nNodeType( nNodeWhich )
511 : {
512 4058 : }
513 :
514 0 : void SwHistoryChangeFmtColl::SetInDoc( SwDoc* pDoc, bool )
515 : {
516 0 : SwCntntNode * pCntntNd = pDoc->GetNodes()[ m_nNodeIndex ]->GetCntntNode();
517 : OSL_ENSURE( pCntntNd, "SwHistoryChangeFmtColl: no ContentNode" );
518 :
519 : // before setting the format, check if it is still available in the
520 : // document. if it has been deleted, there is no undo!
521 0 : if ( pCntntNd && m_nNodeType == pCntntNd->GetNodeType() )
522 : {
523 0 : if ( ND_TEXTNODE == m_nNodeType )
524 : {
525 0 : if ( USHRT_MAX != pDoc->GetTxtFmtColls()->GetPos(
526 0 : static_cast<SwTxtFmtColl * const>(m_pColl) ))
527 : {
528 0 : pCntntNd->ChgFmtColl( m_pColl );
529 : }
530 : }
531 0 : else if ( USHRT_MAX != pDoc->GetGrfFmtColls()->GetPos(
532 0 : static_cast<SwGrfFmtColl * const>(m_pColl) ))
533 : {
534 0 : pCntntNd->ChgFmtColl( m_pColl );
535 : }
536 : }
537 0 : }
538 :
539 2 : SwHistoryTxtFlyCnt::SwHistoryTxtFlyCnt( SwFrmFmt* const pFlyFmt )
540 : : SwHistoryHint( HSTRY_FLYCNT )
541 2 : , m_pUndo( new SwUndoDelLayFmt( pFlyFmt ) )
542 : {
543 : OSL_ENSURE( pFlyFmt, "SwHistoryTxtFlyCnt: no Format" );
544 2 : m_pUndo->ChgShowSel( false );
545 2 : }
546 :
547 4 : SwHistoryTxtFlyCnt::~SwHistoryTxtFlyCnt()
548 : {
549 4 : }
550 :
551 2 : void SwHistoryTxtFlyCnt::SetInDoc( SwDoc* pDoc, bool )
552 : {
553 2 : ::sw::IShellCursorSupplier *const pISCS(pDoc->GetIShellCursorSupplier());
554 : OSL_ASSERT(pISCS);
555 2 : ::sw::UndoRedoContext context(*pDoc, *pISCS);
556 2 : m_pUndo->UndoImpl(context);
557 2 : }
558 :
559 3108 : SwHistoryBookmark::SwHistoryBookmark(
560 : const ::sw::mark::IMark& rBkmk,
561 : bool bSavePos,
562 : bool bSaveOtherPos)
563 : : SwHistoryHint(HSTRY_BOOKMARK)
564 3108 : , m_aName(rBkmk.GetName())
565 : , m_aShortName()
566 : , m_aKeycode()
567 : , m_nNode(bSavePos ?
568 2764 : rBkmk.GetMarkPos().nNode.GetIndex() : 0)
569 : , m_nOtherNode(bSaveOtherPos ?
570 2649 : rBkmk.GetOtherMarkPos().nNode.GetIndex() : 0)
571 : , m_nCntnt(bSavePos ?
572 2764 : rBkmk.GetMarkPos().nContent.GetIndex() : 0)
573 : , m_nOtherCntnt(bSaveOtherPos ?
574 2649 : rBkmk.GetOtherMarkPos().nContent.GetIndex() :0)
575 : , m_bSavePos(bSavePos)
576 : , m_bSaveOtherPos(bSaveOtherPos)
577 3108 : , m_bHadOtherPos(rBkmk.IsExpanded())
578 20150 : , m_eBkmkType(IDocumentMarkAccess::GetType(rBkmk))
579 : {
580 3108 : const ::sw::mark::IBookmark* const pBookmark = dynamic_cast< const ::sw::mark::IBookmark* >(&rBkmk);
581 3108 : if(pBookmark)
582 : {
583 2542 : m_aKeycode = pBookmark->GetKeyCode();
584 2542 : m_aShortName = pBookmark->GetShortName();
585 :
586 : ::sfx2::Metadatable const*const pMetadatable(
587 2542 : dynamic_cast< ::sfx2::Metadatable const* >(pBookmark));
588 2542 : if (pMetadatable)
589 : {
590 2542 : m_pMetadataUndo = pMetadatable->CreateUndo();
591 : }
592 : }
593 3108 : }
594 :
595 0 : void SwHistoryBookmark::SetInDoc( SwDoc* pDoc, bool )
596 : {
597 0 : ::sw::UndoGuard const undoGuard(pDoc->GetIDocumentUndoRedo());
598 :
599 0 : SwNodes& rNds = pDoc->GetNodes();
600 0 : IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess();
601 0 : boost::scoped_ptr<SwPaM> pPam;
602 0 : ::sw::mark::IMark* pMark = NULL;
603 :
604 0 : if(m_bSavePos)
605 : {
606 0 : SwCntntNode* const pCntntNd = rNds[m_nNode]->GetCntntNode();
607 : OSL_ENSURE(pCntntNd,
608 : "<SwHistoryBookmark::SetInDoc(..)>"
609 : " - wrong node for a mark");
610 :
611 : // #111660# don't crash when nNode1 doesn't point to content node.
612 0 : if(pCntntNd)
613 0 : pPam.reset(new SwPaM(*pCntntNd, m_nCntnt));
614 : }
615 : else
616 : {
617 0 : pMark = pMarkAccess->findMark(m_aName)->get();
618 0 : pPam.reset(new SwPaM(pMark->GetMarkPos()));
619 : }
620 :
621 0 : if(m_bSaveOtherPos)
622 : {
623 0 : SwCntntNode* const pCntntNd = rNds[m_nOtherNode]->GetCntntNode();
624 : OSL_ENSURE(pCntntNd,
625 : "<SwHistoryBookmark::SetInDoc(..)>"
626 : " - wrong node for a mark");
627 :
628 0 : if(pPam.get() != NULL && pCntntNd)
629 : {
630 0 : pPam->SetMark();
631 0 : pPam->GetMark()->nNode = m_nOtherNode;
632 0 : pPam->GetMark()->nContent.Assign(pCntntNd, m_nOtherCntnt);
633 : }
634 : }
635 0 : else if(m_bHadOtherPos)
636 : {
637 0 : if(!pMark)
638 0 : pMark = pMarkAccess->findMark(m_aName)->get();
639 : OSL_ENSURE(pMark->IsExpanded(),
640 : "<SwHistoryBookmark::SetInDoc(..)>"
641 : " - missing pos on old mark");
642 0 : pPam->SetMark();
643 0 : *pPam->GetMark() = pMark->GetOtherMarkPos();
644 : }
645 :
646 0 : if(pPam.get())
647 : {
648 0 : if ( pMark != NULL )
649 : {
650 0 : pMarkAccess->deleteMark( pMark );
651 : }
652 : ::sw::mark::IBookmark* const pBookmark =
653 0 : dynamic_cast< ::sw::mark::IBookmark* >( pMarkAccess->makeMark(*pPam, m_aName, m_eBkmkType) );
654 0 : if ( pBookmark != NULL )
655 : {
656 0 : pBookmark->SetKeyCode(m_aKeycode);
657 0 : pBookmark->SetShortName(m_aShortName);
658 0 : if (m_pMetadataUndo)
659 : {
660 : ::sfx2::Metadatable * const pMeta(
661 0 : dynamic_cast< ::sfx2::Metadatable* >(pBookmark));
662 : OSL_ENSURE(pMeta, "metadata undo, but not metadatable?");
663 0 : if (pMeta)
664 : {
665 0 : pMeta->RestoreMetadata(m_pMetadataUndo);
666 : }
667 : }
668 : }
669 0 : }
670 0 : }
671 :
672 0 : bool SwHistoryBookmark::IsEqualBookmark(const ::sw::mark::IMark& rBkmk)
673 : {
674 0 : return m_nNode == rBkmk.GetMarkPos().nNode.GetIndex()
675 0 : && m_nCntnt == rBkmk.GetMarkPos().nContent.GetIndex()
676 0 : && m_aName == rBkmk.GetName();
677 : }
678 :
679 :
680 2956 : SwHistorySetAttrSet::SwHistorySetAttrSet( const SfxItemSet& rSet,
681 : sal_uLong nNodePos, const std::set<sal_uInt16> &rSetArr )
682 : : SwHistoryHint( HSTRY_SETATTRSET )
683 : , m_OldSet( rSet )
684 : , m_ResetArray( 0, 4 )
685 2956 : , m_nNodeIndex( nNodePos )
686 : {
687 5912 : SfxItemIter aIter( m_OldSet ), aOrigIter( rSet );
688 2956 : const SfxPoolItem* pItem = aIter.FirstItem(),
689 2956 : * pOrigItem = aOrigIter.FirstItem();
690 : do {
691 20948 : if( !rSetArr.count( pOrigItem->Which() ))
692 : {
693 20858 : m_ResetArray.push_back( pOrigItem->Which() );
694 20858 : m_OldSet.ClearItem( pOrigItem->Which() );
695 : }
696 : else
697 : {
698 90 : switch ( pItem->Which() )
699 : {
700 : case RES_PAGEDESC:
701 : static_cast<SwFmtPageDesc*>(
702 0 : const_cast<SfxPoolItem*>(pItem))->ChgDefinedIn( 0 );
703 0 : break;
704 :
705 : case RES_PARATR_DROP:
706 : static_cast<SwFmtDrop*>(
707 0 : const_cast<SfxPoolItem*>(pItem))->ChgDefinedIn( 0 );
708 0 : break;
709 :
710 : case RES_BOXATR_FORMULA:
711 : {
712 : // When a formula is set, never save the value. It
713 : // possibly must be recalculated!
714 : // Save formulas always in plain text
715 0 : m_OldSet.ClearItem( RES_BOXATR_VALUE );
716 :
717 : SwTblBoxFormula& rNew =
718 : *static_cast<SwTblBoxFormula*>(
719 0 : const_cast<SfxPoolItem*>(pItem));
720 0 : if ( rNew.IsIntrnlName() )
721 : {
722 : const SwTblBoxFormula& rOld =
723 : static_cast<const SwTblBoxFormula&>(
724 0 : rSet.Get( RES_BOXATR_FORMULA ));
725 0 : const SwNode* pNd = rOld.GetNodeOfFormula();
726 0 : if ( pNd )
727 : {
728 : const SwTableNode* pTableNode
729 0 : = pNd->FindTableNode();
730 0 : if (pTableNode)
731 : {
732 : SwTableFmlUpdate aMsgHnt(
733 0 : &pTableNode->GetTable() );
734 0 : aMsgHnt.eFlags = TBL_BOXNAME;
735 0 : rNew.ChgDefinedIn( rOld.GetDefinedIn() );
736 0 : rNew.ChangeState( &aMsgHnt );
737 : }
738 : }
739 : }
740 0 : rNew.ChgDefinedIn( 0 );
741 : }
742 0 : break;
743 : }
744 : }
745 :
746 20948 : if( aIter.IsAtEnd() )
747 2956 : break;
748 17992 : pItem = aIter.NextItem();
749 17992 : pOrigItem = aOrigIter.NextItem();
750 2956 : } while( true );
751 2956 : }
752 :
753 0 : void SwHistorySetAttrSet::SetInDoc( SwDoc* pDoc, bool )
754 : {
755 0 : ::sw::UndoGuard const undoGuard(pDoc->GetIDocumentUndoRedo());
756 :
757 0 : SwNode * pNode = pDoc->GetNodes()[ m_nNodeIndex ];
758 0 : if ( pNode->IsCntntNode() )
759 : {
760 0 : static_cast<SwCntntNode*>(pNode)->SetAttr( m_OldSet );
761 0 : if ( !m_ResetArray.empty() )
762 : {
763 0 : static_cast<SwCntntNode*>(pNode)->ResetAttr( m_ResetArray );
764 : }
765 : }
766 0 : else if ( pNode->IsTableNode() )
767 : {
768 : SwFmt& rFmt =
769 0 : *static_cast<SwTableNode*>(pNode)->GetTable().GetFrmFmt();
770 0 : rFmt.SetFmtAttr( m_OldSet );
771 0 : if ( !m_ResetArray.empty() )
772 : {
773 0 : rFmt.ResetFmtAttr( m_ResetArray.front() );
774 : }
775 0 : }
776 0 : }
777 :
778 4430 : SwHistoryResetAttrSet::SwHistoryResetAttrSet( const SfxItemSet& rSet,
779 : sal_uLong nNodePos, sal_Int32 nAttrStt, sal_Int32 nAttrEnd )
780 : : SwHistoryHint( HSTRY_RESETATTRSET )
781 : , m_nNodeIndex( nNodePos ), m_nStart( nAttrStt ), m_nEnd( nAttrEnd )
782 4430 : , m_Array( (sal_uInt8)rSet.Count() )
783 : {
784 4430 : SfxItemIter aIter( rSet );
785 4430 : bool bAutoStyle = false;
786 :
787 : while( true )
788 : {
789 4494 : const sal_uInt16 nWhich = aIter.GetCurItem()->Which();
790 :
791 : #ifdef DBG_UTIL
792 : switch (nWhich)
793 : {
794 : case RES_TXTATR_REFMARK:
795 : case RES_TXTATR_TOXMARK:
796 : if (m_nStart != m_nEnd) break; // else: fall through!
797 : case RES_TXTATR_FIELD:
798 : case RES_TXTATR_ANNOTATION:
799 : case RES_TXTATR_FLYCNT:
800 : case RES_TXTATR_FTN:
801 : case RES_TXTATR_META:
802 : case RES_TXTATR_METAFIELD:
803 : OSL_ENSURE(rSet.Count() == 1,
804 : "text attribute with CH_TXTATR, but not the only one:"
805 : "\nnot such a good idea");
806 : break;
807 : }
808 : #endif // DBG_UTIL
809 :
810 : // Character attribute cannot be inserted into the hints array
811 : // anymore. Therefore we have to treat them as one RES_TXTATR_AUTOFMT:
812 4494 : if (isCHRATR(nWhich))
813 : {
814 204 : bAutoStyle = true;
815 : }
816 : else
817 : {
818 4290 : m_Array.push_back( aIter.GetCurItem()->Which() );
819 : }
820 :
821 4494 : if( aIter.IsAtEnd() )
822 4430 : break;
823 :
824 64 : aIter.NextItem();
825 : }
826 :
827 4430 : if ( bAutoStyle )
828 : {
829 140 : m_Array.push_back( RES_TXTATR_AUTOFMT );
830 4430 : }
831 4430 : }
832 :
833 0 : void SwHistoryResetAttrSet::SetInDoc( SwDoc* pDoc, bool )
834 : {
835 0 : ::sw::UndoGuard const undoGuard(pDoc->GetIDocumentUndoRedo());
836 :
837 0 : SwCntntNode * pCntntNd = pDoc->GetNodes()[ m_nNodeIndex ]->GetCntntNode();
838 : OSL_ENSURE( pCntntNd, "SwHistoryResetAttrSet: no CntntNode" );
839 :
840 0 : if (pCntntNd)
841 : {
842 0 : std::vector<sal_uInt16>::iterator it;
843 0 : if ( USHRT_MAX == m_nEnd && USHRT_MAX == m_nStart )
844 : {
845 : // no area: use ContentNode
846 0 : for ( it = m_Array.begin(); it != m_Array.end(); ++it )
847 : {
848 0 : pCntntNd->ResetAttr( *it );
849 : }
850 : }
851 : else
852 : {
853 : // area: use TextNode
854 0 : for ( it = m_Array.begin(); it != m_Array.end(); ++it )
855 : {
856 : static_cast<SwTxtNode*>(pCntntNd)->
857 0 : DeleteAttributes( *it, m_nStart, m_nEnd );
858 : }
859 : }
860 0 : }
861 0 : }
862 :
863 0 : SwHistoryChangeFlyAnchor::SwHistoryChangeFlyAnchor( SwFrmFmt& rFmt )
864 : : SwHistoryHint( HSTRY_CHGFLYANCHOR )
865 : , m_rFmt( rFmt )
866 0 : , m_nOldNodeIndex( rFmt.GetAnchor().GetCntntAnchor()->nNode.GetIndex() )
867 0 : , m_nOldContentIndex( (FLY_AT_CHAR == rFmt.GetAnchor().GetAnchorId())
868 0 : ? rFmt.GetAnchor().GetCntntAnchor()->nContent.GetIndex()
869 0 : : COMPLETE_STRING )
870 : {
871 0 : }
872 :
873 0 : void SwHistoryChangeFlyAnchor::SetInDoc( SwDoc* pDoc, bool )
874 : {
875 0 : ::sw::UndoGuard const undoGuard(pDoc->GetIDocumentUndoRedo());
876 :
877 0 : const sal_uInt16 nPos = pDoc->GetSpzFrmFmts()->GetPos( &m_rFmt );
878 0 : if ( USHRT_MAX != nPos ) // Format does still exist
879 : {
880 0 : SwFmtAnchor aTmp( m_rFmt.GetAnchor() );
881 :
882 0 : SwNode* pNd = pDoc->GetNodes()[ m_nOldNodeIndex ];
883 0 : SwCntntNode* pCNd = pNd->GetCntntNode();
884 0 : SwPosition aPos( *pNd );
885 0 : if ( COMPLETE_STRING != m_nOldContentIndex )
886 : {
887 : OSL_ENSURE(pCNd, "SwHistoryChangeFlyAnchor: no ContentNode");
888 0 : if (pCNd)
889 : {
890 0 : aPos.nContent.Assign( pCNd, m_nOldContentIndex );
891 : }
892 : }
893 0 : aTmp.SetAnchor( &aPos );
894 :
895 : // so the Layout does not get confused
896 0 : if ( !pCNd || !pCNd->getLayoutFrm( pDoc->getIDocumentLayoutAccess().GetCurrentLayout(), 0, 0, false ) )
897 : {
898 0 : m_rFmt.DelFrms();
899 : }
900 :
901 0 : m_rFmt.SetFmtAttr( aTmp );
902 0 : }
903 0 : }
904 :
905 0 : SwHistoryChangeFlyChain::SwHistoryChangeFlyChain( SwFlyFrmFmt& rFmt,
906 : const SwFmtChain& rAttr )
907 : : SwHistoryHint( HSTRY_CHGFLYCHAIN )
908 0 : , m_pPrevFmt( rAttr.GetPrev() )
909 0 : , m_pNextFmt( rAttr.GetNext() )
910 0 : , m_pFlyFmt( &rFmt )
911 : {
912 0 : }
913 :
914 0 : void SwHistoryChangeFlyChain::SetInDoc( SwDoc* pDoc, bool )
915 : {
916 0 : if ( USHRT_MAX != pDoc->GetSpzFrmFmts()->GetPos( m_pFlyFmt ) )
917 : {
918 0 : SwFmtChain aChain;
919 :
920 0 : if ( m_pPrevFmt &&
921 0 : USHRT_MAX != pDoc->GetSpzFrmFmts()->GetPos( m_pPrevFmt ) )
922 : {
923 0 : aChain.SetPrev( m_pPrevFmt );
924 0 : SwFmtChain aTmp( m_pPrevFmt->GetChain() );
925 0 : aTmp.SetNext( m_pFlyFmt );
926 0 : m_pPrevFmt->SetFmtAttr( aTmp );
927 : }
928 :
929 0 : if ( m_pNextFmt &&
930 0 : USHRT_MAX != pDoc->GetSpzFrmFmts()->GetPos( m_pNextFmt ) )
931 : {
932 0 : aChain.SetNext( m_pNextFmt );
933 0 : SwFmtChain aTmp( m_pNextFmt->GetChain() );
934 0 : aTmp.SetPrev( m_pFlyFmt );
935 0 : m_pNextFmt->SetFmtAttr( aTmp );
936 : }
937 :
938 0 : if ( aChain.GetNext() || aChain.GetPrev() )
939 : {
940 0 : m_pFlyFmt->SetFmtAttr( aChain );
941 0 : }
942 : }
943 0 : }
944 :
945 : // -> #i27615#
946 0 : SwHistoryChangeCharFmt::SwHistoryChangeCharFmt(const SfxItemSet & rSet,
947 : const OUString & sFmt)
948 : : SwHistoryHint(HSTRY_CHGCHARFMT)
949 0 : , m_OldSet(rSet), m_Fmt(sFmt)
950 : {
951 0 : }
952 :
953 0 : void SwHistoryChangeCharFmt::SetInDoc(SwDoc * pDoc, bool )
954 : {
955 0 : SwCharFmt * pCharFmt = pDoc->FindCharFmtByName(m_Fmt);
956 :
957 0 : if (pCharFmt)
958 : {
959 0 : pCharFmt->SetFmtAttr(m_OldSet);
960 : }
961 0 : }
962 : // <- #i27615#
963 :
964 24206 : SwHistory::SwHistory( sal_uInt16 nInitSz )
965 : : m_SwpHstry()
966 24206 : , m_nEndDiff( 0 )
967 : {
968 24206 : m_SwpHstry.reserve( (sal_uInt8)nInitSz );
969 24206 : }
970 :
971 48406 : SwHistory::~SwHistory()
972 : {
973 24203 : Delete( 0 );
974 24203 : std::vector<SwHistoryHint*>::const_iterator it;
975 24203 : for(it = m_SwpHstry.begin(); it != m_SwpHstry.end(); ++it)
976 0 : delete *it;
977 24203 : }
978 :
979 2416 : void SwHistory::Add(
980 : const SfxPoolItem* pOldValue,
981 : const SfxPoolItem* pNewValue,
982 : sal_uLong nNodeIdx)
983 : {
984 : OSL_ENSURE( !m_nEndDiff, "History was not deleted after REDO" );
985 2416 : const sal_uInt16 nWhich(pNewValue->Which());
986 :
987 : // excluded values
988 2416 : if(nWhich == RES_TXTATR_FIELD || nWhich == RES_TXTATR_ANNOTATION)
989 : {
990 2416 : return;
991 : }
992 :
993 : // no default Attribute?
994 2416 : SwHistoryHint* pHt = 0;
995 :
996 : //UUUU To be able to include the DrawingLayer FillItems something more
997 : // general has to be done to check if an Item is default than to check
998 : // if it's pointzer equals that in Writer's global PoolDefaults (held in
999 : // aAttrTab and used to fill the pool defaults in Writer - looks as if
1000 : // Writer is *older* than the SfxItemPool ?). I checked the possibility to
1001 : // get the SfxItemPool here (works), but decided to use the SfxPoolItem's
1002 : // global tooling aka IsDefaultItem(const SfxPoolItem*) for now
1003 2416 : if(pOldValue && !IsDefaultItem(pOldValue))
1004 : {
1005 2416 : pHt = new SwHistorySetFmt( pOldValue, nNodeIdx );
1006 : }
1007 : else
1008 : {
1009 0 : pHt = new SwHistoryResetFmt( pNewValue, nNodeIdx );
1010 : }
1011 :
1012 2416 : m_SwpHstry.push_back( pHt );
1013 : }
1014 :
1015 : // FIXME: refactor the following "Add" methods (DRY)?
1016 4240 : void SwHistory::Add( SwTxtAttr* pHint, sal_uLong nNodeIdx, bool bNewAttr )
1017 : {
1018 : OSL_ENSURE( !m_nEndDiff, "History was not deleted after REDO" );
1019 :
1020 4240 : SwHistoryHint * pHt = 0;
1021 4240 : if( !bNewAttr )
1022 : {
1023 686 : switch ( pHint->Which() )
1024 : {
1025 : case RES_TXTATR_FTN:
1026 : pHt = new SwHistorySetFootnote(
1027 26 : static_cast<SwTxtFtn*>(pHint), nNodeIdx );
1028 26 : break;
1029 : case RES_TXTATR_FLYCNT:
1030 : pHt = new SwHistoryTxtFlyCnt( static_cast<SwTxtFlyCnt*>(pHint)
1031 2 : ->GetFlyCnt().GetFrmFmt() );
1032 2 : break;
1033 : case RES_TXTATR_FIELD:
1034 : case RES_TXTATR_ANNOTATION:
1035 : pHt = new SwHistorySetTxtFld(
1036 86 : static_txtattr_cast<SwTxtFld*>(pHint), nNodeIdx);
1037 86 : break;
1038 : case RES_TXTATR_TOXMARK:
1039 : pHt = new SwHistorySetTOXMark(
1040 26 : static_txtattr_cast<SwTxtTOXMark*>(pHint), nNodeIdx);
1041 26 : break;
1042 : case RES_TXTATR_REFMARK:
1043 : pHt = new SwHistorySetRefMark(
1044 24 : static_txtattr_cast<SwTxtRefMark*>(pHint), nNodeIdx);
1045 24 : break;
1046 : default:
1047 : pHt = new SwHistorySetTxt(
1048 522 : static_cast<SwTxtAttr*>(pHint), nNodeIdx );
1049 : }
1050 : }
1051 : else
1052 : {
1053 7108 : pHt = new SwHistoryResetTxt( pHint->Which(), pHint->GetStart(),
1054 7108 : *pHint->GetAnyEnd(), nNodeIdx );
1055 : }
1056 4240 : m_SwpHstry.push_back( pHt );
1057 4240 : }
1058 :
1059 4058 : void SwHistory::Add( SwFmtColl* pColl, sal_uLong nNodeIdx, sal_uInt8 nWhichNd )
1060 : {
1061 : OSL_ENSURE( !m_nEndDiff, "History was not deleted after REDO" );
1062 :
1063 : SwHistoryHint * pHt =
1064 4058 : new SwHistoryChangeFmtColl( pColl, nNodeIdx, nWhichNd );
1065 4058 : m_SwpHstry.push_back( pHt );
1066 4058 : }
1067 :
1068 1028 : void SwHistory::Add(const ::sw::mark::IMark& rBkmk, bool bSavePos, bool bSaveOtherPos)
1069 : {
1070 : OSL_ENSURE( !m_nEndDiff, "History was not deleted after REDO" );
1071 :
1072 1028 : SwHistoryHint * pHt = new SwHistoryBookmark(rBkmk, bSavePos, bSaveOtherPos);
1073 1028 : m_SwpHstry.push_back( pHt );
1074 1028 : }
1075 :
1076 0 : void SwHistory::Add( SwFrmFmt& rFmt )
1077 : {
1078 0 : SwHistoryHint * pHt = new SwHistoryChangeFlyAnchor( rFmt );
1079 0 : m_SwpHstry.push_back( pHt );
1080 0 : }
1081 :
1082 0 : void SwHistory::Add( SwFlyFrmFmt& rFmt, sal_uInt16& rSetPos )
1083 : {
1084 : OSL_ENSURE( !m_nEndDiff, "History was not deleted after REDO" );
1085 :
1086 0 : const sal_uInt16 nWh = rFmt.Which();
1087 0 : if( RES_FLYFRMFMT == nWh || RES_DRAWFRMFMT == nWh )
1088 : {
1089 0 : SwHistoryHint * pHint = new SwHistoryTxtFlyCnt( &rFmt );
1090 0 : m_SwpHstry.push_back( pHint );
1091 :
1092 : const SwFmtChain* pChainItem;
1093 0 : if( SfxItemState::SET == rFmt.GetItemState( RES_CHAIN, false,
1094 0 : (const SfxPoolItem**)&pChainItem ))
1095 : {
1096 0 : if( pChainItem->GetNext() || pChainItem->GetPrev() )
1097 : {
1098 : SwHistoryHint * pHt =
1099 0 : new SwHistoryChangeFlyChain( rFmt, *pChainItem );
1100 0 : m_SwpHstry.insert( m_SwpHstry.begin() + rSetPos++, pHt );
1101 0 : if ( pChainItem->GetNext() )
1102 : {
1103 0 : SwFmtChain aTmp( pChainItem->GetNext()->GetChain() );
1104 0 : aTmp.SetPrev( 0 );
1105 0 : pChainItem->GetNext()->SetFmtAttr( aTmp );
1106 : }
1107 0 : if ( pChainItem->GetPrev() )
1108 : {
1109 0 : SwFmtChain aTmp( pChainItem->GetPrev()->GetChain() );
1110 0 : aTmp.SetNext( 0 );
1111 0 : pChainItem->GetPrev()->SetFmtAttr( aTmp );
1112 : }
1113 : }
1114 0 : rFmt.ResetFmtAttr( RES_CHAIN );
1115 : }
1116 : }
1117 0 : }
1118 :
1119 4 : void SwHistory::Add( const SwTxtFtn& rFtn )
1120 : {
1121 4 : SwHistoryHint *pHt = new SwHistorySetFootnote( rFtn );
1122 4 : m_SwpHstry.push_back( pHt );
1123 4 : }
1124 :
1125 : // #i27615#
1126 0 : void SwHistory::Add(const SfxItemSet & rSet, const SwCharFmt & rFmt)
1127 : {
1128 0 : SwHistoryHint * pHt = new SwHistoryChangeCharFmt(rSet, rFmt.GetName());
1129 0 : m_SwpHstry.push_back( pHt );
1130 0 : }
1131 :
1132 2 : bool SwHistory::Rollback( SwDoc* pDoc, sal_uInt16 nStart )
1133 : {
1134 2 : if ( !Count() )
1135 0 : return false;
1136 :
1137 : SwHistoryHint * pHHt;
1138 6 : for ( sal_uInt16 i = Count(); i > nStart ; )
1139 : {
1140 2 : pHHt = m_SwpHstry[ --i ];
1141 2 : pHHt->SetInDoc( pDoc, false );
1142 2 : delete pHHt;
1143 : }
1144 2 : m_SwpHstry.erase( m_SwpHstry.begin() + nStart, m_SwpHstry.end() );
1145 2 : m_nEndDiff = 0;
1146 2 : return true;
1147 : }
1148 :
1149 2 : bool SwHistory::TmpRollback( SwDoc* pDoc, sal_uInt16 nStart, bool bToFirst )
1150 : {
1151 2 : sal_uInt16 nEnd = Count() - m_nEndDiff;
1152 2 : if ( !Count() || !nEnd || nStart >= nEnd )
1153 2 : return false;
1154 :
1155 : SwHistoryHint * pHHt;
1156 0 : if ( bToFirst )
1157 : {
1158 0 : for ( ; nEnd > nStart; ++m_nEndDiff )
1159 : {
1160 0 : pHHt = m_SwpHstry[ --nEnd ];
1161 0 : pHHt->SetInDoc( pDoc, true );
1162 : }
1163 : }
1164 : else
1165 : {
1166 0 : for ( ; nStart < nEnd; ++m_nEndDiff, ++nStart )
1167 : {
1168 0 : pHHt = m_SwpHstry[ nStart ];
1169 0 : pHHt->SetInDoc( pDoc, true );
1170 : }
1171 : }
1172 0 : return true;
1173 : }
1174 :
1175 24203 : void SwHistory::Delete( sal_uInt16 nStart )
1176 : {
1177 70745 : for ( sal_uInt16 n = Count(); n > nStart; )
1178 : {
1179 22339 : delete m_SwpHstry[ --n ];
1180 22339 : m_SwpHstry.erase( m_SwpHstry.begin() + n );
1181 : }
1182 24203 : m_nEndDiff = 0;
1183 24203 : }
1184 :
1185 0 : sal_uInt16 SwHistory::SetTmpEnd( sal_uInt16 nNewTmpEnd )
1186 : {
1187 : OSL_ENSURE( nNewTmpEnd <= Count(), "SwHistory::SetTmpEnd: out of bounds" );
1188 :
1189 0 : const sal_uInt16 nOld = Count() - m_nEndDiff;
1190 0 : m_nEndDiff = Count() - nNewTmpEnd;
1191 :
1192 : // for every SwHistoryFlyCnt, call the Redo of its UndoObject.
1193 : // this saves the formats of the flys!
1194 0 : for ( sal_uInt16 n = nOld; n < nNewTmpEnd; n++ )
1195 : {
1196 0 : if ( HSTRY_FLYCNT == (*this)[ n ]->Which() )
1197 : {
1198 0 : static_cast<SwHistoryTxtFlyCnt*>((*this)[ n ])
1199 0 : ->GetUDelLFmt()->RedoForRollback();
1200 : }
1201 : }
1202 :
1203 0 : return nOld;
1204 : }
1205 :
1206 108 : void SwHistory::CopyFmtAttr(
1207 : const SfxItemSet& rSet,
1208 : sal_uLong nNodeIdx)
1209 : {
1210 108 : if(rSet.Count())
1211 : {
1212 108 : SfxItemIter aIter(rSet);
1213 :
1214 : do
1215 : {
1216 2416 : if(!IsInvalidItem(aIter.GetCurItem()))
1217 : {
1218 2416 : const SfxPoolItem* pNew = aIter.GetCurItem();
1219 :
1220 : Add(
1221 : pNew,
1222 : pNew,
1223 2416 : nNodeIdx);
1224 : }
1225 :
1226 2416 : if(aIter.IsAtEnd())
1227 : {
1228 108 : break;
1229 : }
1230 :
1231 2308 : aIter.NextItem();
1232 :
1233 108 : } while(true);
1234 : }
1235 108 : }
1236 :
1237 1244 : void SwHistory::CopyAttr(
1238 : SwpHints* pHts,
1239 : const sal_uLong nNodeIdx,
1240 : const sal_Int32 nStart,
1241 : const sal_Int32 nEnd,
1242 : const bool bCopyFields )
1243 : {
1244 1244 : if( !pHts )
1245 2338 : return;
1246 :
1247 : // copy all attributes of the TextNode in the area from nStart to nEnd
1248 : SwTxtAttr* pHt;
1249 : const sal_Int32 * pEndIdx;
1250 452 : for( size_t n = 0; n < pHts->Count(); ++n )
1251 : {
1252 : // nAttrStt must even be set when !pEndIdx
1253 302 : pHt = pHts->GetTextHint(n);
1254 302 : const sal_Int32 nAttrStt = pHt->GetStart();
1255 302 : if( 0 != ( pEndIdx = pHt->GetEnd() ) && nAttrStt > nEnd )
1256 0 : break;
1257 :
1258 : // never copy Flys and Ftn !!
1259 302 : bool bNextAttr = false;
1260 302 : switch( pHt->Which() )
1261 : {
1262 : case RES_TXTATR_FIELD:
1263 : case RES_TXTATR_ANNOTATION:
1264 : case RES_TXTATR_INPUTFIELD:
1265 100 : if( !bCopyFields )
1266 4 : bNextAttr = true;
1267 100 : break;
1268 : case RES_TXTATR_FLYCNT:
1269 : case RES_TXTATR_FTN:
1270 0 : bNextAttr = true;
1271 0 : break;
1272 : }
1273 :
1274 302 : if( bNextAttr )
1275 4 : continue;
1276 :
1277 : // save all attributes that are somehow in this area
1278 298 : if ( nStart <= nAttrStt )
1279 : {
1280 298 : if ( nEnd > nAttrStt )
1281 : {
1282 218 : Add( pHt, nNodeIdx, false );
1283 : }
1284 : }
1285 0 : else if ( pEndIdx && nStart < *pEndIdx )
1286 : {
1287 0 : Add( pHt, nNodeIdx, false );
1288 : }
1289 : }
1290 : }
1291 :
1292 : // Class to register the history at a Node, Format, HintsArray, ...
1293 0 : SwRegHistory::SwRegHistory( SwHistory* pHst )
1294 : : SwClient( 0 )
1295 : , m_pHistory( pHst )
1296 0 : , m_nNodeIndex( ULONG_MAX )
1297 : {
1298 0 : _MakeSetWhichIds();
1299 0 : }
1300 :
1301 203638 : SwRegHistory::SwRegHistory( SwModify* pRegIn, const SwNode& rNd,
1302 : SwHistory* pHst )
1303 : : SwClient( pRegIn )
1304 : , m_pHistory( pHst )
1305 203638 : , m_nNodeIndex( rNd.GetIndex() )
1306 : {
1307 203638 : _MakeSetWhichIds();
1308 203638 : }
1309 :
1310 2248 : SwRegHistory::SwRegHistory( const SwNode& rNd, SwHistory* pHst )
1311 : : SwClient( 0 )
1312 : , m_pHistory( pHst )
1313 2248 : , m_nNodeIndex( rNd.GetIndex() )
1314 : {
1315 2248 : _MakeSetWhichIds();
1316 2248 : }
1317 :
1318 199492 : void SwRegHistory::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew )
1319 : {
1320 199492 : if ( m_pHistory && ( pOld || pNew ) && pOld != pNew )
1321 : {
1322 11172 : if ( pNew->Which() < POOLATTR_END )
1323 : {
1324 58 : if(RES_UPDATE_ATTR == pNew->Which())
1325 : {
1326 : // const SfxItemPool& rPool = static_cast< const SwUpdateAttr* >(pNew)->GetSfxItemPool();
1327 :
1328 : m_pHistory->Add(
1329 : // rPool,
1330 : pOld,
1331 : pNew,
1332 0 : m_nNodeIndex);
1333 : }
1334 : else
1335 : {
1336 : OSL_ENSURE(false, "Unexpected update attribute (!)");
1337 : }
1338 : }
1339 11114 : else if (pOld && RES_ATTRSET_CHG == pNew->Which())
1340 : {
1341 : SwHistoryHint* pNewHstr;
1342 6172 : const SfxItemSet& rSet = *static_cast< const SwAttrSetChg* >(pOld)->GetChgSet();
1343 :
1344 6172 : if ( 1 < rSet.Count() )
1345 : {
1346 2956 : pNewHstr = new SwHistorySetAttrSet( rSet, m_nNodeIndex, m_WhichIdSet );
1347 : }
1348 : else
1349 : {
1350 3216 : const SfxPoolItem* pItem = SfxItemIter( rSet ).FirstItem();
1351 :
1352 3216 : if ( m_WhichIdSet.count( pItem->Which() ) )
1353 : {
1354 1142 : pNewHstr = new SwHistorySetFmt( pItem, m_nNodeIndex );
1355 : }
1356 : else
1357 : {
1358 2074 : pNewHstr = new SwHistoryResetFmt( pItem, m_nNodeIndex );
1359 : }
1360 : }
1361 :
1362 6172 : m_pHistory->m_SwpHstry.push_back( pNewHstr );
1363 : }
1364 : }
1365 199492 : }
1366 :
1367 3994 : void SwRegHistory::AddHint( SwTxtAttr* pHt, const bool bNew )
1368 : {
1369 3994 : m_pHistory->Add( pHt, m_nNodeIndex, bNew );
1370 3994 : }
1371 :
1372 133044 : bool SwRegHistory::InsertItems( const SfxItemSet& rSet,
1373 : sal_Int32 const nStart, sal_Int32 const nEnd, SetAttrMode const nFlags )
1374 : {
1375 133044 : if( !rSet.Count() )
1376 0 : return false;
1377 :
1378 : SwTxtNode * const pTxtNode =
1379 133044 : dynamic_cast<SwTxtNode *>(const_cast<SwModify *>(GetRegisteredIn()));
1380 :
1381 : OSL_ENSURE(pTxtNode, "SwRegHistory not registered at text node?");
1382 133044 : if (!pTxtNode)
1383 0 : return false;
1384 :
1385 133044 : if ( pTxtNode->GetpSwpHints() && m_pHistory )
1386 : {
1387 3380 : pTxtNode->GetpSwpHints()->Register( this );
1388 : }
1389 :
1390 133044 : const bool bInserted = pTxtNode->SetAttr( rSet, nStart, nEnd, nFlags );
1391 :
1392 : // Caution: The array can be deleted when inserting an attribute!
1393 : // This can happen when the value that should be added first deletes
1394 : // an existing attribute but does not need to be added itself because
1395 : // the paragraph attributes are identical
1396 : // ( -> bForgetAttr in SwpHints::Insert )
1397 133044 : if ( pTxtNode->GetpSwpHints() && m_pHistory )
1398 : {
1399 4360 : pTxtNode->GetpSwpHints()->DeRegister();
1400 : }
1401 :
1402 133044 : if ( m_pHistory && bInserted )
1403 : {
1404 : SwHistoryHint* pNewHstr = new SwHistoryResetAttrSet( rSet,
1405 4430 : pTxtNode->GetIndex(), nStart, nEnd );
1406 : // the NodeIndex might be moved!
1407 :
1408 4430 : m_pHistory->m_SwpHstry.push_back( pNewHstr );
1409 : }
1410 :
1411 133044 : return bInserted;
1412 : }
1413 :
1414 0 : void SwRegHistory::RegisterInModify( SwModify* pRegIn, const SwNode& rNd )
1415 : {
1416 0 : if ( m_pHistory && pRegIn )
1417 : {
1418 0 : pRegIn->Add( this );
1419 0 : m_nNodeIndex = rNd.GetIndex();
1420 0 : _MakeSetWhichIds();
1421 : }
1422 : else
1423 : {
1424 0 : m_WhichIdSet.clear();
1425 : }
1426 0 : }
1427 :
1428 205886 : void SwRegHistory::_MakeSetWhichIds()
1429 : {
1430 411772 : if (!m_pHistory) return;
1431 :
1432 21036 : m_WhichIdSet.clear();
1433 :
1434 21036 : if( GetRegisteredIn() )
1435 : {
1436 18788 : const SfxItemSet* pSet = 0;
1437 18788 : if( GetRegisteredIn()->ISA( SwCntntNode ) )
1438 : {
1439 : pSet = static_cast<SwCntntNode*>(
1440 18788 : const_cast<SwModify*>(GetRegisteredIn()))->GetpSwAttrSet();
1441 : }
1442 0 : else if ( GetRegisteredIn()->ISA( SwFmt ) )
1443 : {
1444 : pSet = &static_cast<SwFmt*>(
1445 0 : const_cast<SwModify*>(GetRegisteredIn()))->GetAttrSet();
1446 : }
1447 18788 : if( pSet && pSet->Count() )
1448 : {
1449 10598 : SfxItemIter aIter( *pSet );
1450 10598 : sal_uInt16 nW = aIter.FirstItem()->Which();
1451 : while( true )
1452 : {
1453 100008 : m_WhichIdSet.insert( nW );
1454 100008 : if( aIter.IsAtEnd() )
1455 10598 : break;
1456 89410 : nW = aIter.NextItem()->Which();
1457 10598 : }
1458 : }
1459 : }
1460 270 : }
1461 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|