1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <UndoInsert.hxx>
23 #include <hintids.hxx>
24 #include <unotools/charclass.hxx>
25 #include <sot/storage.hxx>
26 #include <editeng/keepitem.hxx>
27 #include <svx/svdobj.hxx>
28 #include <xmloff/odffields.hxx>
31 #include <fmtcntnt.hxx>
32 #include <fmtanchr.hxx>
35 #include <IDocumentUndoRedo.hxx>
39 #include <UndoCore.hxx>
40 #include <UndoDelete.hxx>
41 #include <UndoAttribute.hxx>
49 #include <swtable.hxx>
50 #include <redline.hxx>
52 #include <acorrect.hxx>
53 #include <dcontact.hxx>
55 #include <comcore.hrc> // #111827#
58 using namespace ::com::sun::star
;
61 //------------------------------------------------------------
65 String
* SwUndoInsert::GetTxtFromDoc() const
67 String
* pResult
= NULL
;
69 SwNodeIndex
aNd( pDoc
->GetNodes(), nNode
);
70 SwCntntNode
* pCNd
= aNd
.GetNode().GetCntntNode();
71 SwPaM
aPaM( *pCNd
, nCntnt
);
75 if( pCNd
->IsTxtNode() )
77 pResult
= new String( ((SwTxtNode
*)pCNd
)->GetTxt().Copy(nCntnt
-nLen
,
85 void SwUndoInsert::Init(const SwNodeIndex
& rNd
)
88 pDoc
= rNd
.GetNode().GetDoc();
89 if( pDoc
->IsRedlineOn() )
91 pRedlData
= new SwRedlineData( nsRedlineType_t::REDLINE_INSERT
,
92 pDoc
->GetRedlineAuthor() );
93 SetRedlineMode( pDoc
->GetRedlineMode() );
96 pUndoTxt
= GetTxtFromDoc();
98 bCacheComment
= false;
102 SwUndoInsert::SwUndoInsert( const SwNodeIndex
& rNd
, xub_StrLen nCnt
,
104 const IDocumentContentOperations::InsertFlags nInsertFlags
,
106 : SwUndo(UNDO_TYPING
), pPos( 0 ), pTxt( 0 ), pRedlData( 0 ),
107 nNode( rNd
.GetIndex() ), nCntnt(nCnt
), nLen(nL
),
108 bIsWordDelim( bWDelim
), bIsAppend( sal_False
)
109 , m_nInsertFlags(nInsertFlags
)
115 SwUndoInsert::SwUndoInsert( const SwNodeIndex
& rNd
)
116 : SwUndo(UNDO_SPLITNODE
), pPos( 0 ), pTxt( 0 ),
117 pRedlData( 0 ), nNode( rNd
.GetIndex() ), nCntnt(0), nLen(1),
118 bIsWordDelim( sal_False
), bIsAppend( sal_True
)
119 , m_nInsertFlags(IDocumentContentOperations::INS_EMPTYEXPAND
)
124 // Check if the next Insert can be combined with the current one. If so
125 // change the length and InsPos. As a result, SwDoc::Inser will not add a
126 // new object into the Undo list.
128 sal_Bool
SwUndoInsert::CanGrouping( sal_Unicode cIns
)
130 if( !bIsAppend
&& bIsWordDelim
==
131 !GetAppCharClass().isLetterNumeric( rtl::OUString( cIns
)) )
137 pUndoTxt
->Insert(cIns
);
144 sal_Bool
SwUndoInsert::CanGrouping( const SwPosition
& rPos
)
146 sal_Bool bRet
= sal_False
;
147 if( nNode
== rPos
.nNode
.GetIndex() &&
148 nCntnt
== rPos
.nContent
.GetIndex() )
151 SwDoc
& rDoc
= *rPos
.nNode
.GetNode().GetDoc();
152 if( ( ~nsRedlineMode_t::REDLINE_SHOW_MASK
& rDoc
.GetRedlineMode() ) ==
153 ( ~nsRedlineMode_t::REDLINE_SHOW_MASK
& GetRedlineMode() ) )
157 // than there is or was still an active Redline:
158 // Check if there is another Redline at the InsPosition. If the
159 // same exists only once, it can be combined.
160 const SwRedlineTbl
& rTbl
= rDoc
.GetRedlineTbl();
163 SwRedlineData
aRData( nsRedlineType_t::REDLINE_INSERT
, rDoc
.GetRedlineAuthor() );
164 const SwIndexReg
* pIReg
= rPos
.nContent
.GetIdxReg();
166 for( sal_uInt16 i
= 0; i
< rTbl
.size(); ++i
)
168 SwRedline
* pRedl
= rTbl
[ i
];
169 if( pIReg
== (pIdx
= &pRedl
->End()->nContent
)->GetIdxReg() &&
170 nCntnt
== pIdx
->GetIndex() )
172 if( !pRedl
->HasMark() || !pRedlData
||
173 *pRedl
!= *pRedlData
|| *pRedl
!= aRData
)
186 SwUndoInsert::~SwUndoInsert()
188 if( pPos
) // delete the section from UndoNodes array
190 // Insert saves the content in IconSection
191 SwNodes
& rUNds
= pPos
->nNode
.GetNode().GetNodes();
192 if( pPos
->nContent
.GetIndex() ) // do not delete the whole node
194 SwTxtNode
* pTxtNd
= pPos
->nNode
.GetNode().GetTxtNode();
195 OSL_ENSURE( pTxtNd
, "no TextNode to delete from" );
196 pTxtNd
->EraseText( pPos
->nContent
);
199 pPos
->nContent
.Assign( 0, 0 );
200 rUNds
.Delete( pPos
->nNode
, rUNds
.GetEndOfExtras().GetIndex() -
201 pPos
->nNode
.GetIndex() );
204 else if( pTxt
) // the inserted text
212 void SwUndoInsert::UndoImpl(::sw::UndoRedoContext
& rContext
)
214 SwDoc
*const pTmpDoc
= & rContext
.GetDoc();
215 SwPaM
*const pPam(& rContext
.GetCursorSupplier().CreateNewShellCursor());
219 pPam
->GetPoint()->nNode
= nNode
;
221 if( IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ))
223 pPam
->GetPoint()->nContent
.Assign( pPam
->GetCntntNode(), 0 );
225 pPam
->Move( fnMoveBackward
);
227 pTmpDoc
->DeleteRedline( *pPam
, true, USHRT_MAX
);
230 pTmpDoc
->DelFullPara( *pPam
);
231 pPam
->GetPoint()->nContent
.Assign( pPam
->GetCntntNode(), 0 );
235 sal_uLong nNd
= nNode
;
236 xub_StrLen nCnt
= nCntnt
;
239 SwNodeIndex
aNd( pTmpDoc
->GetNodes(), nNode
);
240 SwCntntNode
* pCNd
= aNd
.GetNode().GetCntntNode();
241 SwPaM
aPaM( *pCNd
, nCntnt
);
245 SwTxtNode
* const pTxtNode( pCNd
->GetTxtNode() );
248 aPaM
.GetPoint()->nContent
-= nLen
;
249 if( IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ))
250 pTmpDoc
->DeleteRedline( aPaM
, true, USHRT_MAX
);
251 RemoveIdxFromRange( aPaM
, sal_False
);
252 pTxt
= new String( pTxtNode
->GetTxt().Copy(nCntnt
-nLen
, nLen
) );
253 pTxtNode
->EraseText( aPaM
.GetPoint()->nContent
, nLen
);
255 // Undo deletes fieldmarks in two step: first the end then the start position.
256 // Once the start position is deleted, make sure the fieldmark itself is deleted as well.
259 IDocumentMarkAccess
* const pMarkAccess
= pTmpDoc
->getIDocumentMarkAccess();
260 for ( IDocumentMarkAccess::const_iterator_t i
= pMarkAccess
->getMarksBegin(); i
!= pMarkAccess
->getMarksEnd(); ++i
)
262 sw::mark::IMark
* pMark
= i
->get();
263 if (pMark
->GetMarkStart() == *aPaM
.GetPoint() && pMark
->GetMarkStart().nContent
== aPaM
.GetPoint()->nContent
)
265 sw::mark::IFieldmark
* pFieldmark
= dynamic_cast<sw::mark::IFieldmark
*>(pMark
);
266 if (pFieldmark
&& pFieldmark
->GetFieldname() == ODF_COMMENTRANGE
)
268 pTmpDoc
->getIDocumentMarkAccess()->deleteMark(pMark
);
275 else // otherwise Graphics/OLE/Text/...
277 aPaM
.Move(fnMoveBackward
);
278 if( IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ))
279 pTmpDoc
->DeleteRedline( aPaM
, true, USHRT_MAX
);
280 RemoveIdxFromRange( aPaM
, sal_False
);
283 nNd
= aPaM
.GetPoint()->nNode
.GetIndex();
284 nCnt
= aPaM
.GetPoint()->nContent
.GetIndex();
288 pPos
= new SwPosition( *aPaM
.GetPoint() );
289 MoveToUndoNds( aPaM
, &pPos
->nNode
, &pPos
->nContent
);
291 nNode
= aPaM
.GetPoint()->nNode
.GetIndex();
292 nCntnt
= aPaM
.GetPoint()->nContent
.GetIndex();
295 // set cursor to Undo range
298 pPam
->GetPoint()->nNode
= nNd
;
299 pPam
->GetPoint()->nContent
.Assign(
300 pPam
->GetPoint()->nNode
.GetNode().GetCntntNode(), nCnt
);
307 void SwUndoInsert::RedoImpl(::sw::UndoRedoContext
& rContext
)
309 SwDoc
*const pTmpDoc
= & rContext
.GetDoc();
310 SwPaM
*const pPam(& rContext
.GetCursorSupplier().CreateNewShellCursor());
315 pPam
->GetPoint()->nNode
= nNode
- 1;
316 pTmpDoc
->AppendTxtNode( *pPam
->GetPoint() );
319 pPam
->Move( fnMoveBackward
);
322 if( pRedlData
&& IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ))
324 RedlineMode_t eOld
= pTmpDoc
->GetRedlineMode();
325 pTmpDoc
->SetRedlineMode_intern((RedlineMode_t
)(eOld
& ~nsRedlineMode_t::REDLINE_IGNORE
));
326 pTmpDoc
->AppendRedline( new SwRedline( *pRedlData
, *pPam
), true);
327 pTmpDoc
->SetRedlineMode_intern( eOld
);
329 else if( !( nsRedlineMode_t::REDLINE_IGNORE
& GetRedlineMode() ) &&
330 !pTmpDoc
->GetRedlineTbl().empty() )
331 pTmpDoc
->SplitRedline( *pPam
);
337 pPam
->GetPoint()->nNode
= nNode
;
338 SwCntntNode
*const pCNd
=
339 pPam
->GetPoint()->nNode
.GetNode().GetCntntNode();
340 pPam
->GetPoint()->nContent
.Assign( pCNd
, nCntnt
);
344 sal_Bool bMvBkwrd
= MovePtBackward( *pPam
);
348 SwTxtNode
*const pTxtNode
= pCNd
->GetTxtNode();
349 OSL_ENSURE( pTxtNode
, "where is my textnode ?" );
351 pTxtNode
->InsertText( *pTxt
, pPam
->GetMark()->nContent
,
353 assert(ins
.getLength() == pTxt
->Len()); // must succeed
358 // re-insert content (log out pPos before!)
359 sal_uLong nMvNd
= pPos
->nNode
.GetIndex();
360 xub_StrLen nMvCnt
= pPos
->nContent
.GetIndex();
362 MoveFromUndoNds( *pTmpDoc
, nMvNd
, nMvCnt
, *pPam
->GetMark() );
364 nNode
= pPam
->GetMark()->nNode
.GetIndex();
365 nCntnt
= pPam
->GetMark()->nContent
.GetIndex();
367 MovePtForward( *pPam
, bMvBkwrd
);
369 if( pRedlData
&& IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ))
371 RedlineMode_t eOld
= pTmpDoc
->GetRedlineMode();
372 pTmpDoc
->SetRedlineMode_intern((RedlineMode_t
)(eOld
& ~nsRedlineMode_t::REDLINE_IGNORE
));
373 pTmpDoc
->AppendRedline( new SwRedline( *pRedlData
,
375 pTmpDoc
->SetRedlineMode_intern( eOld
);
377 else if( !( nsRedlineMode_t::REDLINE_IGNORE
& GetRedlineMode() ) &&
378 !pTmpDoc
->GetRedlineTbl().empty() )
379 pTmpDoc
->SplitRedline(*pPam
);
383 pUndoTxt
= GetTxtFromDoc();
387 void SwUndoInsert::RepeatImpl(::sw::RepeatContext
& rContext
)
392 SwDoc
& rDoc
= rContext
.GetDoc();
393 SwNodeIndex
aNd( rDoc
.GetNodes(), nNode
);
394 SwCntntNode
* pCNd
= aNd
.GetNode().GetCntntNode();
396 if( !bIsAppend
&& 1 == nLen
) // >1 than always Text, otherwise Graphics/OLE/Text/...
398 SwPaM
aPaM( *pCNd
, nCntnt
);
400 aPaM
.Move(fnMoveBackward
);
401 pCNd
= aPaM
.GetCntntNode();
404 // What happens with the possible selected range ???
406 switch( pCNd
->GetNodeType() )
411 rDoc
.AppendTxtNode( *rContext
.GetRepeatPaM().GetPoint() );
415 String
aTxt( ((SwTxtNode
*)pCNd
)->GetTxt() );
416 ::sw::GroupUndoGuard
const undoGuard(rDoc
.GetIDocumentUndoRedo());
417 rDoc
.InsertString( rContext
.GetRepeatPaM(),
418 aTxt
.Copy( nCntnt
- nLen
, nLen
) );
423 SwGrfNode
* pGrfNd
= (SwGrfNode
*)pCNd
;
424 String sFile
, sFilter
;
425 if( pGrfNd
->IsGrfLink() )
426 pGrfNd
->GetFileFilterNms( &sFile
, &sFilter
);
428 rDoc
.Insert( rContext
.GetRepeatPaM(), sFile
, sFilter
,
430 0/* Graphics collection*/, NULL
, NULL
);
436 // StarView does not yet provide an option to copy a StarOBJ
437 SvStorageRef aRef
= new SvStorage( aEmptyStr
);
438 SwOLEObj
& rSwOLE
= (SwOLEObj
&)((SwOLENode
*)pCNd
)->GetOLEObj();
440 // temporary storage until object is inserted
441 // TODO/MBA: seems that here a physical copy is done - not as in drawing layer! Testing!
442 // TODO/LATER: Copying through the container would copy the replacement image as well
443 comphelper::EmbeddedObjectContainer aCnt
;
444 ::rtl::OUString aName
= aCnt
.CreateUniqueObjectName();
445 if ( aCnt
.StoreEmbeddedObject( rSwOLE
.GetOleRef(), aName
, sal_True
) )
447 uno::Reference
< embed::XEmbeddedObject
> aNew
= aCnt
.GetEmbeddedObject( aName
);
448 rDoc
.Insert( rContext
.GetRepeatPaM(),
449 svt::EmbeddedObjectRef( aNew
,
450 static_cast<SwOLENode
*>(pCNd
)->GetAspect() ),
460 SwRewriter
SwUndoInsert::GetRewriter() const
463 String
* pStr
= NULL
;
473 String aString
= ShortenString(DenoteSpecialCharacters(*pStr
),
475 String(SW_RES(STR_LDOTS
)));
477 aResult
.AddRule(UndoArg1
, aString
);
484 aResult
.AddRule(UndoArg1
, String("??", RTL_TEXTENCODING_ASCII_US
));
491 // SwUndoReplace /////////////////////////////////////////////////////////
494 class SwUndoReplace::Impl
495 : private SwUndoSaveCntnt
497 ::rtl::OUString m_sOld
;
498 ::rtl::OUString m_sIns
;
499 sal_uLong m_nSttNd
, m_nEndNd
, m_nOffset
;
500 xub_StrLen m_nSttCnt
, m_nEndCnt
, m_nSetPos
, m_nSelEnd
;
501 bool m_bSplitNext
: 1;
503 // metadata references for paragraph and following para (if m_bSplitNext)
504 ::boost::shared_ptr
< ::sfx2::MetadatableUndo
> m_pMetadataUndoStart
;
505 ::boost::shared_ptr
< ::sfx2::MetadatableUndo
> m_pMetadataUndoEnd
;
508 Impl(SwPaM
const& rPam
, ::rtl::OUString
const& rIns
, bool const bRegExp
);
513 virtual void UndoImpl( ::sw::UndoRedoContext
& );
514 virtual void RedoImpl( ::sw::UndoRedoContext
& );
516 void SetEnd(SwPaM
const& rPam
);
518 ::rtl::OUString
const& GetOld() const { return m_sOld
; }
519 ::rtl::OUString
const& GetIns() const { return m_sIns
; }
523 SwUndoReplace::SwUndoReplace(SwPaM
const& rPam
,
524 ::rtl::OUString
const& rIns
, bool const bRegExp
)
525 : SwUndo( UNDO_REPLACE
)
526 , m_pImpl(new Impl(rPam
, rIns
, bRegExp
))
530 SwUndoReplace::~SwUndoReplace()
534 void SwUndoReplace::UndoImpl(::sw::UndoRedoContext
& rContext
)
536 m_pImpl
->UndoImpl(rContext
);
539 void SwUndoReplace::RedoImpl(::sw::UndoRedoContext
& rContext
)
541 m_pImpl
->RedoImpl(rContext
);
545 MakeUndoReplaceRewriter(sal_uLong
const occurrences
,
546 ::rtl::OUString
const& sOld
, ::rtl::OUString
const& sNew
)
552 aResult
.AddRule(UndoArg1
, String::CreateFromInt32(occurrences
));
553 aResult
.AddRule(UndoArg2
, String(SW_RES(STR_OCCURRENCES_OF
)));
556 aTmpStr
+= String(SW_RES(STR_START_QUOTE
));
557 aTmpStr
+= ShortenString(sOld
, nUndoStringLength
,
559 aTmpStr
+= String(SW_RES(STR_END_QUOTE
));
560 aResult
.AddRule(UndoArg3
, aTmpStr
);
562 else if (1 == occurrences
)
567 aTmpStr
+= String(SW_RES(STR_START_QUOTE
));
569 aTmpStr
+= ShortenString(sOld
, nUndoStringLength
,
571 aTmpStr
+= String(SW_RES(STR_END_QUOTE
));
572 aResult
.AddRule(UndoArg1
, aTmpStr
);
575 aResult
.AddRule(UndoArg2
, String(SW_RES(STR_YIELDS
)));
580 aTmpStr
+= String(SW_RES(STR_START_QUOTE
));
582 aTmpStr
+= ShortenString(sNew
, nUndoStringLength
,
584 aTmpStr
+= String(SW_RES(STR_END_QUOTE
));
585 aResult
.AddRule(UndoArg3
, aTmpStr
);
593 SwRewriter
SwUndoReplace::GetRewriter() const
595 return MakeUndoReplaceRewriter(1, m_pImpl
->GetOld(), m_pImpl
->GetIns());
598 void SwUndoReplace::SetEnd(SwPaM
const& rPam
)
600 m_pImpl
->SetEnd(rPam
);
603 SwUndoReplace::Impl::Impl(
604 SwPaM
const& rPam
, ::rtl::OUString
const& rIns
, bool const bRegExp
)
610 const SwPosition
* pStt( rPam
.Start() );
611 const SwPosition
* pEnd( rPam
.End() );
613 m_nSttNd
= m_nEndNd
= pStt
->nNode
.GetIndex();
614 m_nSttCnt
= pStt
->nContent
.GetIndex();
615 m_nSelEnd
= m_nEndCnt
= pEnd
->nContent
.GetIndex();
617 m_bSplitNext
= m_nSttNd
!= pEnd
->nNode
.GetIndex();
619 SwTxtNode
* pNd
= pStt
->nNode
.GetNode().GetTxtNode();
620 OSL_ENSURE( pNd
, "Dude, where's my TextNode?" );
622 pHistory
= new SwHistory
;
623 DelCntntIndex( *rPam
.GetMark(), *rPam
.GetPoint() );
625 m_nSetPos
= pHistory
->Count();
627 sal_uLong nNewPos
= pStt
->nNode
.GetIndex();
628 m_nOffset
= m_nSttNd
- nNewPos
;
630 if ( pNd
->GetpSwpHints() )
632 pHistory
->CopyAttr( pNd
->GetpSwpHints(), nNewPos
, 0,
633 pNd
->GetTxt().Len(), true );
638 if( pNd
->HasSwAttrSet() )
639 pHistory
->CopyFmtAttr( *pNd
->GetpSwAttrSet(), nNewPos
);
640 pHistory
->Add( pNd
->GetTxtColl(), nNewPos
, ND_TEXTNODE
);
642 SwTxtNode
* pNext
= pEnd
->nNode
.GetNode().GetTxtNode();
643 sal_uLong nTmp
= pNext
->GetIndex();
644 pHistory
->CopyAttr( pNext
->GetpSwpHints(), nTmp
, 0,
645 pNext
->GetTxt().Len(), true );
646 if( pNext
->HasSwAttrSet() )
647 pHistory
->CopyFmtAttr( *pNext
->GetpSwAttrSet(), nTmp
);
648 pHistory
->Add( pNext
->GetTxtColl(),nTmp
, ND_TEXTNODE
);
650 m_pMetadataUndoStart
= pNd
->CreateUndo();
651 m_pMetadataUndoEnd
= pNext
->CreateUndo();
654 if( !pHistory
->Count() )
655 delete pHistory
, pHistory
= 0;
657 xub_StrLen nECnt
= m_bSplitNext
? pNd
->GetTxt().Len()
658 : pEnd
->nContent
.GetIndex();
659 m_sOld
= pNd
->GetTxt().Copy( m_nSttCnt
, nECnt
- m_nSttCnt
);
662 void SwUndoReplace::Impl::UndoImpl(::sw::UndoRedoContext
& rContext
)
664 SwDoc
*const pDoc
= & rContext
.GetDoc();
665 SwPaM
& rPam(rContext
.GetCursorSupplier().CreateNewShellCursor());
668 SwTxtNode
* pNd
= pDoc
->GetNodes()[ m_nSttNd
- m_nOffset
]->GetTxtNode();
669 OSL_ENSURE( pNd
, "Dude, where's my TextNode?" );
671 SwAutoCorrExceptWord
* pACEWord
= pDoc
->GetAutoCorrExceptWord();
674 if ((1 == m_sIns
.getLength()) && (1 == m_sOld
.getLength()))
676 SwPosition
aPos( *pNd
); aPos
.nContent
.Assign( pNd
, m_nSttCnt
);
677 pACEWord
->CheckChar( aPos
, m_sOld
[ 0 ] );
679 pDoc
->SetAutoCorrExceptWord( 0 );
682 SwIndex
aIdx( pNd
, m_nSttCnt
);
683 // don't look at m_sIns for deletion, maybe it was not completely inserted
685 rPam
.GetPoint()->nNode
= *pNd
;
686 rPam
.GetPoint()->nContent
.Assign( pNd
, m_nSttCnt
);
688 rPam
.GetPoint()->nNode
= m_nEndNd
- m_nOffset
;
689 rPam
.GetPoint()->nContent
.Assign( rPam
.GetCntntNode(), m_nEndCnt
);
690 // move it out of the way so it is not registered at deleted node
693 pDoc
->DeleteAndJoin( rPam
);
695 pNd
= rPam
.GetNode()->GetTxtNode();
696 OSL_ENSURE( pNd
, "Dude, where's my TextNode?" );
697 aIdx
.Assign( pNd
, m_nSttCnt
);
702 SwPosition
aPos( *pNd
, aIdx
);
703 pDoc
->SplitNode( aPos
, false );
704 pNd
->RestoreMetadata(m_pMetadataUndoEnd
);
705 pNd
= pDoc
->GetNodes()[ m_nSttNd
- m_nOffset
]->GetTxtNode();
706 aIdx
.Assign( pNd
, m_nSttCnt
);
708 pNd
->RestoreMetadata(m_pMetadataUndoStart
);
711 if (!m_sOld
.isEmpty())
713 OUString
const ins( pNd
->InsertText( m_sOld
, aIdx
) );
714 assert(ins
.getLength() == m_sOld
.getLength()); // must succeed
719 if( pNd
->GetpSwpHints() )
720 pNd
->ClearSwpHintsArr( true );
722 pHistory
->TmpRollback( pDoc
, m_nSetPos
, false );
723 if ( m_nSetPos
) // there were footnotes/FlyFrames
725 // are there others than these?
726 if( m_nSetPos
< pHistory
->Count() )
728 // than save those attributes as well
730 aHstr
.Move( 0, pHistory
, m_nSetPos
);
731 pHistory
->Rollback( pDoc
);
732 pHistory
->Move( 0, &aHstr
);
736 pHistory
->Rollback( pDoc
);
742 rPam
.GetPoint()->nNode
= m_nSttNd
;
743 rPam
.GetPoint()->nContent
= aIdx
;
746 void SwUndoReplace::Impl::RedoImpl(::sw::UndoRedoContext
& rContext
)
748 SwDoc
& rDoc
= rContext
.GetDoc();
749 SwPaM
& rPam(rContext
.GetCursorSupplier().CreateNewShellCursor());
751 rPam
.GetPoint()->nNode
= m_nSttNd
;
753 SwTxtNode
* pNd
= rPam
.GetPoint()->nNode
.GetNode().GetTxtNode();
754 OSL_ENSURE( pNd
, "Dude, where's my TextNode?" );
755 rPam
.GetPoint()->nContent
.Assign( pNd
, m_nSttCnt
);
759 rPam
.GetPoint()->nNode
= m_nSttNd
+ 1;
760 pNd
= rPam
.GetPoint()->nNode
.GetNode().GetTxtNode();
762 rPam
.GetPoint()->nContent
.Assign( pNd
, m_nSelEnd
);
766 SwHistory
* pSave
= pHistory
;
769 DelCntntIndex( *rPam
.GetMark(), *rPam
.GetPoint() );
770 m_nSetPos
= pHistory
->Count();
773 pHistory
->Move( 0, &aHst
);
777 pHistory
= new SwHistory
;
778 DelCntntIndex( *rPam
.GetMark(), *rPam
.GetPoint() );
779 m_nSetPos
= pHistory
->Count();
781 delete pHistory
, pHistory
= 0;
784 rDoc
.ReplaceRange( rPam
, m_sIns
, m_bRegExp
);
788 void SwUndoReplace::Impl::SetEnd(SwPaM
const& rPam
)
790 const SwPosition
* pEnd
= rPam
.End();
791 m_nEndNd
= m_nOffset
+ pEnd
->nNode
.GetIndex();
792 m_nEndCnt
= pEnd
->nContent
.GetIndex();
796 // SwUndoReRead //////////////////////////////////////////////////////////
799 SwUndoReRead::SwUndoReRead( const SwPaM
& rPam
, const SwGrfNode
& rGrfNd
)
800 : SwUndo( UNDO_REREAD
), nPos( rPam
.GetPoint()->nNode
.GetIndex() )
802 SaveGraphicData( rGrfNd
);
806 SwUndoReRead::~SwUndoReRead()
814 void SwUndoReRead::SetAndSave(::sw::UndoRedoContext
& rContext
)
816 SwDoc
& rDoc
= rContext
.GetDoc();
817 SwGrfNode
* pGrfNd
= rDoc
.GetNodes()[ nPos
]->GetGrfNode();
822 // cache the old values
823 Graphic
* pOldGrf
= pGrf
;
824 String
* pOldNm
= pNm
;
825 String
* pOldFltr
= pFltr
;
826 sal_uInt16 nOldMirr
= nMirr
;
828 SaveGraphicData( *pGrfNd
);
831 pGrfNd
->ReRead( *pOldNm
, pFltr
? *pFltr
: aEmptyStr
, 0, 0, sal_True
);
837 pGrfNd
->ReRead( aEmptyStr
, aEmptyStr
, pOldGrf
, 0, sal_True
);
841 if( RES_MIRROR_GRAPH_DONT
!= nOldMirr
)
842 pGrfNd
->SetAttr( SwMirrorGrf() );
844 rContext
.SetSelections(pGrfNd
->GetFlyFmt(), 0);
848 void SwUndoReRead::UndoImpl(::sw::UndoRedoContext
& rContext
)
850 SetAndSave(rContext
);
854 void SwUndoReRead::RedoImpl(::sw::UndoRedoContext
& rContext
)
856 SetAndSave(rContext
);
860 void SwUndoReRead::SaveGraphicData( const SwGrfNode
& rGrfNd
)
862 if( rGrfNd
.IsGrfLink() )
866 rGrfNd
.GetFileFilterNms( pNm
, pFltr
);
871 ((SwGrfNode
&)rGrfNd
).SwapIn( sal_True
);
872 pGrf
= new Graphic( rGrfNd
.GetGrf() );
875 nMirr
= rGrfNd
.GetSwAttrSet().GetMirrorGrf().GetValue();
879 SwUndoInsertLabel::SwUndoInsertLabel( const SwLabelType eTyp
,
881 const String
& rSeparator
,
882 const String
& rNumberSeparator
,
884 const sal_uInt16 nInitId
,
885 const String
& rCharacterStyle
,
886 const sal_Bool bCpyBorder
)
887 : SwUndo( UNDO_INSERTLABEL
),
889 sSeparator( rSeparator
),
890 sNumberSeparator( rNumberSeparator
),//#i61007# order of captions
891 sCharacterStyle( rCharacterStyle
),
896 bCpyBrd( bCpyBorder
)
898 bUndoKeep
= sal_False
;
900 OBJECT
.pUndoAttr
= 0;
903 SwUndoInsertLabel::~SwUndoInsertLabel()
905 if( LTYPE_OBJECT
== eType
|| LTYPE_DRAW
== eType
)
907 delete OBJECT
.pUndoFly
;
908 delete OBJECT
.pUndoAttr
;
911 delete NODE
.pUndoInsNd
;
914 void SwUndoInsertLabel::UndoImpl(::sw::UndoRedoContext
& rContext
)
916 SwDoc
& rDoc
= rContext
.GetDoc();
918 if( LTYPE_OBJECT
== eType
|| LTYPE_DRAW
== eType
)
920 OSL_ENSURE( OBJECT
.pUndoAttr
&& OBJECT
.pUndoFly
, "Pointer not initialized" );
922 SdrObject
*pSdrObj
= 0;
923 if( OBJECT
.pUndoAttr
&&
924 0 != (pFmt
= (SwFrmFmt
*)OBJECT
.pUndoAttr
->GetFmt( rDoc
)) &&
925 ( LTYPE_DRAW
!= eType
||
926 0 != (pSdrObj
= pFmt
->FindSdrObject()) ) )
928 OBJECT
.pUndoAttr
->UndoImpl(rContext
);
929 OBJECT
.pUndoFly
->UndoImpl(rContext
);
930 if( LTYPE_DRAW
== eType
)
932 pSdrObj
->SetLayer( nLayerId
);
936 else if( NODE
.nNode
)
938 if ( eType
== LTYPE_TABLE
&& bUndoKeep
)
940 SwTableNode
*pNd
= rDoc
.GetNodes()[
941 rDoc
.GetNodes()[NODE
.nNode
-1]->StartOfSectionIndex()]->GetTableNode();
943 pNd
->GetTable().GetFrmFmt()->ResetFmtAttr( RES_KEEP
);
945 SwPaM
aPam( rDoc
.GetNodes().GetEndOfContent() );
946 aPam
.GetPoint()->nNode
= NODE
.nNode
;
948 aPam
.GetPoint()->nNode
= NODE
.nNode
+ 1;
949 NODE
.pUndoInsNd
= new SwUndoDelete( aPam
, sal_True
);
954 void SwUndoInsertLabel::RedoImpl(::sw::UndoRedoContext
& rContext
)
956 SwDoc
& rDoc
= rContext
.GetDoc();
958 if( LTYPE_OBJECT
== eType
|| LTYPE_DRAW
== eType
)
960 OSL_ENSURE( OBJECT
.pUndoAttr
&& OBJECT
.pUndoFly
, "Pointer not initialized" );
962 SdrObject
*pSdrObj
= 0;
963 if( OBJECT
.pUndoAttr
&&
964 0 != (pFmt
= (SwFrmFmt
*)OBJECT
.pUndoAttr
->GetFmt( rDoc
)) &&
965 ( LTYPE_DRAW
!= eType
||
966 0 != (pSdrObj
= pFmt
->FindSdrObject()) ) )
968 OBJECT
.pUndoFly
->RedoImpl(rContext
);
969 OBJECT
.pUndoAttr
->RedoImpl(rContext
);
970 if( LTYPE_DRAW
== eType
)
972 pSdrObj
->SetLayer( nLayerId
);
973 if( pSdrObj
->GetLayer() == rDoc
.GetHellId() )
974 pSdrObj
->SetLayer( rDoc
.GetHeavenId() );
975 // OD 02.07.2003 #108784#
976 else if( pSdrObj
->GetLayer() == rDoc
.GetInvisibleHellId() )
977 pSdrObj
->SetLayer( rDoc
.GetInvisibleHeavenId() );
981 else if( NODE
.pUndoInsNd
)
983 if ( eType
== LTYPE_TABLE
&& bUndoKeep
)
985 SwTableNode
*pNd
= rDoc
.GetNodes()[
986 rDoc
.GetNodes()[NODE
.nNode
-1]->StartOfSectionIndex()]->GetTableNode();
988 pNd
->GetTable().GetFrmFmt()->SetFmtAttr( SvxFmtKeepItem(sal_True
, RES_KEEP
) );
990 NODE
.pUndoInsNd
->UndoImpl(rContext
);
991 delete NODE
.pUndoInsNd
, NODE
.pUndoInsNd
= 0;
995 void SwUndoInsertLabel::RepeatImpl(::sw::RepeatContext
& rContext
)
997 SwDoc
& rDoc
= rContext
.GetDoc();
998 const SwPosition
& rPos
= *rContext
.GetRepeatPaM().GetPoint();
1002 SwCntntNode
* pCNd
= rPos
.nNode
.GetNode().GetCntntNode();
1008 const SwTableNode
* pTNd
= pCNd
->FindTableNode();
1010 nIdx
= pTNd
->GetIndex();
1018 SwCntntFrm
*pCnt
= pCNd
->getLayoutFrm( rDoc
.GetCurrentLayout() );
1019 if( pCnt
&& 0 != ( pFly
= pCnt
->FindFlyFrm() ) )
1020 nIdx
= pFly
->GetFmt()->GetCntnt().GetCntntIdx()->GetIndex();
1029 rDoc
.InsertLabel( eType
, sText
, sSeparator
, sNumberSeparator
, bBefore
,
1030 nFldId
, nIdx
, sCharacterStyle
, bCpyBrd
);
1035 SwRewriter
SwUndoInsertLabel::GetRewriter() const
1037 SwRewriter aRewriter
;
1041 aTmpStr
+= String(SW_RES(STR_START_QUOTE
));
1042 aTmpStr
+= ShortenString(sText
, nUndoStringLength
,
1043 String(SW_RES(STR_LDOTS
)));
1044 aTmpStr
+= String(SW_RES(STR_END_QUOTE
));
1046 aRewriter
.AddRule(UndoArg1
, aTmpStr
);
1051 void SwUndoInsertLabel::SetFlys( SwFrmFmt
& rOldFly
, SfxItemSet
& rChgSet
,
1054 if( LTYPE_OBJECT
== eType
|| LTYPE_DRAW
== eType
)
1056 SwUndoFmtAttrHelper
aTmp( rOldFly
, false );
1057 rOldFly
.SetFmtAttr( rChgSet
);
1058 if ( aTmp
.GetUndo() )
1060 OBJECT
.pUndoAttr
= aTmp
.ReleaseUndo();
1062 OBJECT
.pUndoFly
= new SwUndoInsLayFmt( &rNewFly
,0,0 );
1066 void SwUndoInsertLabel::SetDrawObj( sal_uInt8 nLId
)
1068 if( LTYPE_DRAW
== eType
)
1074 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */