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: unins.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"
33 #include <hintids.hxx>
34 #include <unotools/charclass.hxx>
35 #include <sot/storage.hxx>
36 #include <svx/keepitem.hxx>
37 #include <svx/svdobj.hxx>
40 #include <fmtcntnt.hxx>
41 #include <fmtanchr.hxx>
44 #include <swundo.hxx> // fuer die UndoIds
55 #include <swtable.hxx>
56 #include <redline.hxx>
58 #include <acorrect.hxx>
59 #include <dcontact.hxx>
61 #include <comcore.hrc> // #111827#
64 using namespace ::com::sun::star
;
67 class _UnReplaceData
: private SwUndoSaveCntnt
69 String m_sOld
, m_sIns
;
70 ULONG m_nSttNd
, m_nEndNd
, m_nOffset
;
71 xub_StrLen m_nSttCnt
, m_nEndCnt
, m_nSetPos
, m_nSelEnd
;
72 BOOL m_bSplitNext
: 1;
74 // metadata references for paragraph and following para (if m_bSplitNext)
75 ::boost::shared_ptr
< ::sfx2::MetadatableUndo
> m_pMetadataUndoStart
;
76 ::boost::shared_ptr
< ::sfx2::MetadatableUndo
> m_pMetadataUndoEnd
;
79 _UnReplaceData( const SwPaM
& rPam
, const String
& rIns
, BOOL bRegExp
);
82 void Undo( SwUndoIter
& rIter
);
83 void Redo( SwUndoIter
& rIter
);
84 void SetEnd( const SwPaM
& rPam
);
86 const String
& GetOld() const { return m_sOld
; }
87 const String
& GetIns() const { return m_sIns
; }
91 SV_IMPL_PTRARR( _UnReplaceDatas
, _UnReplaceData
* )
93 //------------------------------------------------------------------
95 inline SwDoc
& SwUndoIter::GetDoc() const { return *pAktPam
->GetDoc(); }
97 // zwei Zugriffs-Funktionen
98 inline SwPosition
* IterPt( SwUndoIter
& rUIter
)
99 { return rUIter
.pAktPam
->GetPoint(); }
100 inline SwPosition
* IterMk( SwUndoIter
& rUIter
)
101 { return rUIter
.pAktPam
->GetMark(); }
103 //------------------------------------------------------------
107 String
* SwUndoInsert::GetTxtFromDoc() const
109 String
* pResult
= NULL
;
111 SwNodeIndex
aNd( pDoc
->GetNodes(), nNode
);
112 SwCntntNode
* pCNd
= aNd
.GetNode().GetCntntNode();
113 SwPaM
aPaM( *pCNd
, nCntnt
);
117 if( pCNd
->IsTxtNode() )
119 pResult
= new String( ((SwTxtNode
*)pCNd
)->GetTxt().Copy(nCntnt
-nLen
,
127 void SwUndoInsert::Init(const SwNodeIndex
& rNd
)
130 pDoc
= rNd
.GetNode().GetDoc();
131 if( pDoc
->IsRedlineOn() )
133 pRedlData
= new SwRedlineData( nsRedlineType_t::REDLINE_INSERT
,
134 pDoc
->GetRedlineAuthor() );
135 SetRedlineMode( pDoc
->GetRedlineMode() );
138 pUndoTxt
= GetTxtFromDoc();
140 bCacheComment
= false;
144 SwUndoInsert::SwUndoInsert( const SwNodeIndex
& rNd
, xub_StrLen nCnt
,
145 xub_StrLen nL
, BOOL bWDelim
)
146 : SwUndo(UNDO_TYPING
), pPos( 0 ), pTxt( 0 ), pRedlData( 0 ),
147 nNode( rNd
.GetIndex() ), nCntnt(nCnt
), nLen(nL
),
148 bIsWordDelim( bWDelim
), bIsAppend( FALSE
)
154 SwUndoInsert::SwUndoInsert( const SwNodeIndex
& rNd
)
155 : SwUndo(UNDO_SPLITNODE
), pPos( 0 ), pTxt( 0 ),
156 pRedlData( 0 ), nNode( rNd
.GetIndex() ), nCntnt(0), nLen(1),
157 bIsWordDelim( FALSE
), bIsAppend( TRUE
)
162 // stelle fest, ob das naechste Insert mit dem aktuellen zusammengefasst
163 // werden kann. Wenn ja, dann aender die Laenge und die InsPos.
164 // Dann wird von SwDoc::Insert kein neues Object in die Undoliste gestellt.
166 BOOL
SwUndoInsert::CanGrouping( const SwPosition
& rInsPos
, sal_Unicode cIns
)
172 bRet
= CanGrouping( rInsPos
);
175 bRet
= CanGrouping( cIns
);
181 BOOL
SwUndoInsert::CanGrouping( sal_Unicode cIns
)
183 if( !bIsAppend
&& bIsWordDelim
==
184 !GetAppCharClass().isLetterNumeric( String( cIns
)) )
190 pUndoTxt
->Insert(cIns
);
197 BOOL
SwUndoInsert::CanGrouping( const SwPosition
& rPos
)
200 if( nNode
== rPos
.nNode
.GetIndex() &&
201 nCntnt
== rPos
.nContent
.GetIndex() )
204 SwDoc
& rDoc
= *rPos
.nNode
.GetNode().GetDoc();
205 if( ( ~nsRedlineMode_t::REDLINE_SHOW_MASK
& rDoc
.GetRedlineMode() ) ==
206 ( ~nsRedlineMode_t::REDLINE_SHOW_MASK
& GetRedlineMode() ) )
210 // dann war oder ist noch Redline an:
211 // pruefe, ob an der InsPosition ein anderer Redline
212 // rumsteht. Wenn der gleiche nur einmalig vorhanden ist,
213 // kann zusammen gefasst werden.
214 const SwRedlineTbl
& rTbl
= rDoc
.GetRedlineTbl();
217 SwRedlineData
aRData( nsRedlineType_t::REDLINE_INSERT
, rDoc
.GetRedlineAuthor() );
218 const SwIndexReg
* pIReg
= rPos
.nContent
.GetIdxReg();
220 for( USHORT i
= 0; i
< rTbl
.Count(); ++i
)
222 SwRedline
* pRedl
= rTbl
[ i
];
223 if( pIReg
== (pIdx
= &pRedl
->End()->nContent
)->GetIdxReg() &&
224 nCntnt
== pIdx
->GetIndex() )
226 if( !pRedl
->HasMark() || !pRedlData
||
227 *pRedl
!= *pRedlData
|| *pRedl
!= aRData
)
240 SwUndoInsert::~SwUndoInsert()
242 if( pPos
) // loesche noch den Bereich aus dem UndoNodes Array
244 // Insert speichert den Inhalt in der IconSection
245 SwNodes
& rUNds
= pPos
->nNode
.GetNode().GetNodes();
246 if( pPos
->nContent
.GetIndex() ) // nicht den gesamten Node loeschen
248 SwTxtNode
* pTxtNd
= pPos
->nNode
.GetNode().GetTxtNode();
249 ASSERT( pTxtNd
, "kein TextNode, aus dem geloescht werden soll" );
250 pTxtNd
->Erase( pPos
->nContent
);
253 pPos
->nContent
.Assign( 0, 0 );
254 rUNds
.Delete( pPos
->nNode
, rUNds
.GetEndOfExtras().GetIndex() -
255 pPos
->nNode
.GetIndex() );
258 else if( pTxt
) // der eingefuegte Text
265 void SwUndoInsert::Undo( SwUndoIter
& rUndoIter
)
267 SwDoc
* pTmpDoc
= &rUndoIter
.GetDoc();
271 SwPaM
* pPam
= rUndoIter
.pAktPam
;
272 pPam
->GetPoint()->nNode
= nNode
;
274 if( IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ))
276 pPam
->GetPoint()->nContent
.Assign( pPam
->GetCntntNode(), 0 );
278 pPam
->Move( fnMoveBackward
);
280 pTmpDoc
->DeleteRedline( *pPam
, true, USHRT_MAX
);
283 pTmpDoc
->DelFullPara( *pPam
);
284 pPam
->GetPoint()->nContent
.Assign( pPam
->GetCntntNode(), 0 );
289 xub_StrLen nCnt
= nCntnt
;
292 SwNodeIndex
aNd( pTmpDoc
->GetNodes(), nNode
);
293 SwCntntNode
* pCNd
= aNd
.GetNode().GetCntntNode();
294 SwPaM
aPaM( *pCNd
, nCntnt
);
298 if( pCNd
->IsTxtNode() ) // Text !!
300 aPaM
.GetPoint()->nContent
-= nLen
;
301 if( IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ))
302 pTmpDoc
->DeleteRedline( aPaM
, true, USHRT_MAX
);
303 RemoveIdxFromRange( aPaM
, FALSE
);
304 pTxt
= new String( ((SwTxtNode
*)pCNd
)->GetTxt().Copy(
305 nCntnt
-nLen
, nLen
) );
306 ((SwTxtNode
*)pCNd
)->Erase( aPaM
.GetPoint()->nContent
, nLen
);
308 else // ansonsten Grafik/OLE/Text/...
310 aPaM
.Move(fnMoveBackward
);
311 if( IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ))
312 pTmpDoc
->DeleteRedline( aPaM
, true, USHRT_MAX
);
313 RemoveIdxFromRange( aPaM
, FALSE
);
316 nNd
= aPaM
.GetPoint()->nNode
.GetIndex();
317 nCnt
= aPaM
.GetPoint()->nContent
.GetIndex();
321 pPos
= new SwPosition( *aPaM
.GetPoint() );
322 MoveToUndoNds( aPaM
, &pPos
->nNode
, &pPos
->nContent
);
324 nNode
= aPaM
.GetPoint()->nNode
.GetIndex();
325 nCntnt
= aPaM
.GetPoint()->nContent
.GetIndex();
328 // setze noch den Cursor auf den Undo-Bereich
329 rUndoIter
.pAktPam
->DeleteMark();
331 IterPt(rUndoIter
)->nNode
= nNd
;
332 IterPt(rUndoIter
)->nContent
.Assign( pTmpDoc
->GetNodes()[
333 IterPt(rUndoIter
)->nNode
]->GetCntntNode(), nCnt
);
334 // SPoint und GetMark auf der gleichen Position
341 void SwUndoInsert::Redo( SwUndoIter
& rUndoIter
)
343 // setze noch den Cursor auf den Redo-Bereich
344 SwPaM
* pPam
= rUndoIter
.pAktPam
;
345 SwDoc
* pTmpDoc
= pPam
->GetDoc();
350 pPam
->GetPoint()->nNode
= nNode
- 1;
351 pTmpDoc
->AppendTxtNode( *pPam
->GetPoint() );
354 pPam
->Move( fnMoveBackward
);
357 if( pRedlData
&& IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ))
359 RedlineMode_t eOld
= pTmpDoc
->GetRedlineMode();
360 pTmpDoc
->SetRedlineMode_intern((RedlineMode_t
)(eOld
& ~nsRedlineMode_t::REDLINE_IGNORE
));
361 pTmpDoc
->AppendRedline( new SwRedline( *pRedlData
, *pPam
), true);
362 pTmpDoc
->SetRedlineMode_intern( eOld
);
364 else if( !( nsRedlineMode_t::REDLINE_IGNORE
& GetRedlineMode() ) &&
365 pTmpDoc
->GetRedlineTbl().Count() )
366 pTmpDoc
->SplitRedline( *pPam
);
372 pPam
->GetPoint()->nNode
= nNode
;
373 SwCntntNode
* pCNd
= pTmpDoc
->GetNodes()[ pPam
->GetPoint()->nNode
]->GetCntntNode();
374 pPam
->GetPoint()->nContent
.Assign( pCNd
, nCntnt
);
378 BOOL bMvBkwrd
= MovePtBackward( *pPam
);
382 ASSERT( pCNd
->IsTxtNode(), "wo ist mein Textnode ??" );
383 ((SwTxtNode
*)pCNd
)->Insert( *pTxt
, pPam
->GetMark()->nContent
,
389 // Inhalt wieder einfuegen. (erst pPos abmelden !!)
390 ULONG nMvNd
= pPos
->nNode
.GetIndex();
391 xub_StrLen nMvCnt
= pPos
->nContent
.GetIndex();
393 MoveFromUndoNds( *pTmpDoc
, nMvNd
, nMvCnt
, *pPam
->GetMark() );
395 nNode
= pPam
->GetMark()->nNode
.GetIndex();
396 nCntnt
= pPam
->GetMark()->nContent
.GetIndex();
398 MovePtForward( *pPam
, bMvBkwrd
);
399 rUndoIter
.pAktPam
->Exchange();
400 if( pRedlData
&& IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ))
402 RedlineMode_t eOld
= pTmpDoc
->GetRedlineMode();
403 pTmpDoc
->SetRedlineMode_intern((RedlineMode_t
)(eOld
& ~nsRedlineMode_t::REDLINE_IGNORE
));
404 pTmpDoc
->AppendRedline( new SwRedline( *pRedlData
,
405 *rUndoIter
.pAktPam
), true);
406 pTmpDoc
->SetRedlineMode_intern( eOld
);
408 else if( !( nsRedlineMode_t::REDLINE_IGNORE
& GetRedlineMode() ) &&
409 pTmpDoc
->GetRedlineTbl().Count() )
410 pTmpDoc
->SplitRedline( *rUndoIter
.pAktPam
);
414 pUndoTxt
= GetTxtFromDoc();
418 void SwUndoInsert::Repeat( SwUndoIter
& rUndoIter
)
420 rUndoIter
.pLastUndoObj
= this;
424 SwDoc
& rDoc
= rUndoIter
.GetDoc();
425 SwNodeIndex
aNd( rDoc
.GetNodes(), nNode
);
426 SwCntntNode
* pCNd
= aNd
.GetNode().GetCntntNode();;
428 if( !bIsAppend
&& 1 == nLen
) // >1 dann immer nur Text, ansonsten Grafik/OLE/Text/...
430 SwPaM
aPaM( *pCNd
, nCntnt
);
432 aPaM
.Move(fnMoveBackward
);
433 pCNd
= aPaM
.GetCntntNode();
436 // Was passiert mit dem evt. selektierten Bereich ???
438 switch( pCNd
->GetNodeType() )
442 rDoc
.AppendTxtNode( *rUndoIter
.pAktPam
->GetPoint() );
445 String
aTxt( ((SwTxtNode
*)pCNd
)->GetTxt() );
446 BOOL bGroupUndo
= rDoc
.DoesGroupUndo();
447 rDoc
.DoGroupUndo( FALSE
);
448 rDoc
.Insert( *rUndoIter
.pAktPam
, aTxt
.Copy( nCntnt
- nLen
, nLen
), true);
449 rDoc
.DoGroupUndo( bGroupUndo
);
454 SwGrfNode
* pGrfNd
= (SwGrfNode
*)pCNd
;
455 String sFile
, sFilter
;
456 if( pGrfNd
->IsGrfLink() )
457 pGrfNd
->GetFileFilterNms( &sFile
, &sFilter
);
459 rDoc
.Insert( *rUndoIter
.pAktPam
, sFile
, sFilter
,
461 0/* Grafik-Collection*/, NULL
, NULL
);
467 // StarView bietet noch nicht die Moeglichkeit ein StarOBJ zu kopieren
468 SvStorageRef aRef
= new SvStorage( aEmptyStr
);
469 SwOLEObj
& rSwOLE
= (SwOLEObj
&)((SwOLENode
*)pCNd
)->GetOLEObj();
471 // temporary storage until object is inserted
472 // TODO/MBA: seems that here a physical copy is done - not as in drawing layer! Testing!
473 // TODO/LATER: Copying through the container would copy the replacement image as well
474 comphelper::EmbeddedObjectContainer aCnt
;
475 ::rtl::OUString aName
= aCnt
.CreateUniqueObjectName();
476 if ( aCnt
.StoreEmbeddedObject( rSwOLE
.GetOleRef(), aName
, sal_True
) )
478 uno::Reference
< embed::XEmbeddedObject
> aNew
= aCnt
.GetEmbeddedObject( aName
);
479 rDoc
.Insert( *rUndoIter
.pAktPam
, svt::EmbeddedObjectRef( aNew
, ((SwOLENode
*)pCNd
)->GetAspect() ), NULL
, NULL
, NULL
);
488 SwRewriter
SwUndoInsert::GetRewriter() const
491 String
* pStr
= NULL
;
501 String aString
= ShortenString(DenoteSpecialCharacters(*pStr
),
503 String(SW_RES(STR_LDOTS
)));
505 aResult
.AddRule(UNDO_ARG1
, aString
);
512 aResult
.AddRule(UNDO_ARG1
, String("??", RTL_TEXTENCODING_ASCII_US
));
521 SwUndoReplace::SwUndoReplace()
522 : SwUndo( UNDO_REPLACE
), nAktPos( USHRT_MAX
)
526 SwUndoReplace::~SwUndoReplace()
530 void SwUndoReplace::Undo( SwUndoIter
& rUndoIter
)
532 // war dieses nicht die letze Undo-Aktion, dann setze den
534 if( rUndoIter
.pLastUndoObj
!= this )
536 nAktPos
= aArr
.Count();
537 rUndoIter
.pLastUndoObj
= this;
538 bOldIterFlag
= rUndoIter
.bWeiter
;
539 rUndoIter
.bWeiter
= TRUE
;
542 aArr
[ --nAktPos
]->Undo( rUndoIter
);
544 if( !nAktPos
) // alten Status wieder zurueck
545 rUndoIter
.bWeiter
= bOldIterFlag
;
549 void SwUndoReplace::Redo( SwUndoIter
& rUndoIter
)
551 // war dieses nicht die letze Undo-Aktion, dann setze den
553 if( rUndoIter
.pLastUndoObj
!= this )
555 ASSERT( !nAktPos
, "Redo ohne vorheriges Undo??" );
556 rUndoIter
.pLastUndoObj
= this;
557 bOldIterFlag
= rUndoIter
.bWeiter
;
558 rUndoIter
.bWeiter
= TRUE
;
561 aArr
[ nAktPos
]->Redo( rUndoIter
);
563 if( ++nAktPos
>= aArr
.Count() ) // alten Status wieder zurueck
566 rUndoIter
.bWeiter
= bOldIterFlag
;
571 SwRewriter
SwUndoReplace::GetRewriter() const
575 if (aArr
.Count() > 1)
577 aResult
.AddRule(UNDO_ARG1
, String::CreateFromInt32(aArr
.Count()));
578 aResult
.AddRule(UNDO_ARG2
, String(SW_RES(STR_OCCURRENCES_OF
)));
581 aTmpStr
+= String(SW_RES(STR_START_QUOTE
));
582 aTmpStr
+= ShortenString(aArr
[0]->GetOld(), nUndoStringLength
,
584 aTmpStr
+= String(SW_RES(STR_END_QUOTE
));
585 aResult
.AddRule(UNDO_ARG3
, aTmpStr
);
587 else if (aArr
.Count() == 1)
592 aTmpStr
+= String(SW_RES(STR_START_QUOTE
));
594 aTmpStr
+= ShortenString(aArr
[0]->GetOld(), nUndoStringLength
,
596 aTmpStr
+= String(SW_RES(STR_END_QUOTE
));
597 aResult
.AddRule(UNDO_ARG1
, aTmpStr
);
600 aResult
.AddRule(UNDO_ARG2
, String(SW_RES(STR_YIELDS
)));
605 aTmpStr
+= String(SW_RES(STR_START_QUOTE
));
607 aTmpStr
+= ShortenString(aArr
[0]->GetIns(), nUndoStringLength
,
609 aTmpStr
+= String(SW_RES(STR_END_QUOTE
));
610 aResult
.AddRule(UNDO_ARG3
, aTmpStr
);
617 void SwUndoReplace::AddEntry( const SwPaM
& rPam
, const String
& rInsert
,
620 _UnReplaceData
* pNew
= new _UnReplaceData( rPam
, rInsert
, bRegExp
);
621 aArr
.C40_INSERT(_UnReplaceData
, pNew
, aArr
.Count() );
624 void SwUndoReplace::SetEntryEnd( const SwPaM
& rPam
)
626 _UnReplaceData
* pEntry
= aArr
[ aArr
.Count()-1 ];
627 pEntry
->SetEnd( rPam
);
630 _UnReplaceData::_UnReplaceData( const SwPaM
& rPam
, const String
& rIns
,
632 : m_sIns( rIns
), m_nOffset( 0 )
636 const SwPosition
* pStt( rPam
.Start() );
637 const SwPosition
* pEnd( rPam
.End() );
639 m_nSttNd
= m_nEndNd
= pStt
->nNode
.GetIndex();
640 m_nSttCnt
= pStt
->nContent
.GetIndex();
641 m_nSelEnd
= m_nEndCnt
= pEnd
->nContent
.GetIndex();
643 m_bSplitNext
= m_nSttNd
!= pEnd
->nNode
.GetIndex();
645 SwTxtNode
* pNd
= pStt
->nNode
.GetNode().GetTxtNode();
646 ASSERT( pNd
, "wo ist der TextNode" );
648 pHistory
= new SwHistory
;
649 DelCntntIndex( *rPam
.GetMark(), *rPam
.GetPoint() );
651 m_nSetPos
= pHistory
->Count();
653 ULONG nNewPos
= pStt
->nNode
.GetIndex();
654 m_nOffset
= m_nSttNd
- nNewPos
;
656 if ( pNd
->GetpSwpHints() )
658 pHistory
->CopyAttr( pNd
->GetpSwpHints(), nNewPos
, 0,
659 pNd
->GetTxt().Len(), true );
664 if( pNd
->HasSwAttrSet() )
665 pHistory
->CopyFmtAttr( *pNd
->GetpSwAttrSet(), nNewPos
);
666 pHistory
->Add( pNd
->GetTxtColl(), nNewPos
, ND_TEXTNODE
);
668 SwTxtNode
* pNext
= pEnd
->nNode
.GetNode().GetTxtNode();
669 ULONG nTmp
= pNext
->GetIndex();
670 pHistory
->CopyAttr( pNext
->GetpSwpHints(), nTmp
, 0,
671 pNext
->GetTxt().Len(), true );
672 if( pNext
->HasSwAttrSet() )
673 pHistory
->CopyFmtAttr( *pNext
->GetpSwAttrSet(), nTmp
);
674 pHistory
->Add( pNext
->GetTxtColl(),nTmp
, ND_TEXTNODE
);
676 m_pMetadataUndoStart
= pNd
->CreateUndo();
677 m_pMetadataUndoEnd
= pNext
->CreateUndo();
680 if( !pHistory
->Count() )
681 delete pHistory
, pHistory
= 0;
683 xub_StrLen nECnt
= m_bSplitNext
? pNd
->GetTxt().Len()
684 : pEnd
->nContent
.GetIndex();
685 m_sOld
= pNd
->GetTxt().Copy( m_nSttCnt
, nECnt
- m_nSttCnt
);
688 _UnReplaceData::~_UnReplaceData()
692 void _UnReplaceData::Undo( SwUndoIter
& rIter
)
694 SwDoc
* pDoc
= &rIter
.GetDoc();
695 SwPaM
& rPam
= *rIter
.pAktPam
;
698 SwTxtNode
* pNd
= pDoc
->GetNodes()[ m_nSttNd
- m_nOffset
]->GetTxtNode();
699 ASSERT( pNd
, "Wo ist der TextNode geblieben?" )
701 SwAutoCorrExceptWord
* pACEWord
= pDoc
->GetAutoCorrExceptWord();
704 if( 1 == m_sIns
.Len() && 1 == m_sOld
.Len() )
706 SwPosition
aPos( *pNd
); aPos
.nContent
.Assign( pNd
, m_nSttCnt
);
707 pACEWord
->CheckChar( aPos
, m_sOld
.GetChar( 0 ) );
709 pDoc
->SetAutoCorrExceptWord( 0 );
712 SwIndex
aIdx( pNd
, m_nSttCnt
);
713 if( m_nSttNd
== m_nEndNd
)
715 pNd
->Erase( aIdx
, m_sIns
.Len() );
719 rPam
.GetPoint()->nNode
= *pNd
;
720 rPam
.GetPoint()->nContent
.Assign( pNd
, m_nSttCnt
);
722 rPam
.GetPoint()->nNode
= m_nEndNd
- m_nOffset
;
723 rPam
.GetPoint()->nContent
.Assign( rPam
.GetCntntNode(), m_nEndCnt
);
725 pDoc
->DeleteAndJoin( rPam
);
727 pNd
= rPam
.GetNode()->GetTxtNode();
728 ASSERT( pNd
, "Wo ist der TextNode geblieben?" );
729 aIdx
.Assign( pNd
, m_nSttCnt
);
734 SwPosition
aPos( *pNd
, aIdx
);
735 pDoc
->SplitNode( aPos
, false );
736 pNd
->RestoreMetadata(m_pMetadataUndoEnd
);
737 pNd
= pDoc
->GetNodes()[ m_nSttNd
- m_nOffset
]->GetTxtNode();
738 aIdx
.Assign( pNd
, m_nSttCnt
);
740 pNd
->RestoreMetadata(m_pMetadataUndoStart
);
744 pNd
->Insert( m_sOld
, aIdx
);
748 if( pNd
->GetpSwpHints() )
749 pNd
->ClearSwpHintsArr( true );
751 pHistory
->TmpRollback( pDoc
, m_nSetPos
, false );
752 if ( m_nSetPos
) // there were footnotes/FlyFrames
754 // gibts ausser diesen noch andere ?
755 if( m_nSetPos
< pHistory
->Count() )
757 // dann sicher die Attribute anderen Attribute
759 aHstr
.Move( 0, pHistory
, m_nSetPos
);
760 pHistory
->Rollback( pDoc
);
761 pHistory
->Move( 0, &aHstr
);
765 pHistory
->Rollback( pDoc
);
771 rPam
.GetPoint()->nNode
= m_nSttNd
;
772 rPam
.GetPoint()->nContent
= aIdx
;
775 void _UnReplaceData::Redo( SwUndoIter
& rIter
)
777 SwDoc
& rDoc
= rIter
.GetDoc();
778 BOOL bUndo
= rDoc
.DoesUndo();
779 rDoc
.DoUndo( FALSE
);
781 SwPaM
& rPam
= *rIter
.pAktPam
;
783 rPam
.GetPoint()->nNode
= m_nSttNd
;
785 SwTxtNode
* pNd
= rPam
.GetPoint()->nNode
.GetNode().GetTxtNode();
786 ASSERT( pNd
, "Wo ist der TextNode geblieben?" )
787 rPam
.GetPoint()->nContent
.Assign( pNd
, m_nSttCnt
);
791 rPam
.GetPoint()->nNode
= m_nSttNd
+ 1;
792 pNd
= rPam
.GetPoint()->nNode
.GetNode().GetTxtNode();
794 rPam
.GetPoint()->nContent
.Assign( pNd
, m_nSelEnd
);
798 SwHistory
* pSave
= pHistory
;
801 DelCntntIndex( *rPam
.GetMark(), *rPam
.GetPoint() );
802 m_nSetPos
= pHistory
->Count();
805 pHistory
->Move( 0, &aHst
);
809 pHistory
= new SwHistory
;
810 DelCntntIndex( *rPam
.GetMark(), *rPam
.GetPoint() );
811 m_nSetPos
= pHistory
->Count();
813 delete pHistory
, pHistory
= 0;
816 rDoc
.Replace( rPam
, m_sIns
, m_bRegExp
);
818 rDoc
.DoUndo( bUndo
);
821 void _UnReplaceData::SetEnd( const SwPaM
& rPam
)
823 if( rPam
.GetPoint()->nNode
!= rPam
.GetMark()->nNode
)
825 // es wurden mehrere Absaetze eingefuegt
826 const SwPosition
* pEnd
= rPam
.End();
827 m_nEndNd
= m_nOffset
+ pEnd
->nNode
.GetIndex();
828 m_nEndCnt
= pEnd
->nContent
.GetIndex();
835 SwUndoReRead::SwUndoReRead( const SwPaM
& rPam
, const SwGrfNode
& rGrfNd
)
836 : SwUndo( UNDO_REREAD
), nPos( rPam
.GetPoint()->nNode
.GetIndex() )
838 SaveGraphicData( rGrfNd
);
842 SwUndoReRead::~SwUndoReRead()
850 void SwUndoReRead::SetAndSave( SwUndoIter
& rIter
)
852 SwDoc
& rDoc
= rIter
.GetDoc();
853 SwGrfNode
* pGrfNd
= rDoc
.GetNodes()[ nPos
]->GetGrfNode();
858 // die alten Werte zwischen speichern
859 Graphic
* pOldGrf
= pGrf
;
860 String
* pOldNm
= pNm
;
861 String
* pOldFltr
= pFltr
;
862 USHORT nOldMirr
= nMirr
;
864 SaveGraphicData( *pGrfNd
);
867 pGrfNd
->ReRead( *pOldNm
, pFltr
? *pFltr
: aEmptyStr
, 0, 0, TRUE
);
873 pGrfNd
->ReRead( aEmptyStr
, aEmptyStr
, pOldGrf
, 0, TRUE
);
877 if( RES_MIRROR_GRAPH_DONT
!= nOldMirr
)
878 pGrfNd
->SetAttr( SwMirrorGrf() );
880 rIter
.pSelFmt
= pGrfNd
->GetFlyFmt();
884 void SwUndoReRead::Undo( SwUndoIter
& rIter
)
890 void SwUndoReRead::Redo( SwUndoIter
& rIter
)
896 void SwUndoReRead::SaveGraphicData( const SwGrfNode
& rGrfNd
)
898 if( rGrfNd
.IsGrfLink() )
902 rGrfNd
.GetFileFilterNms( pNm
, pFltr
);
907 ((SwGrfNode
&)rGrfNd
).SwapIn( TRUE
);
908 pGrf
= new Graphic( rGrfNd
.GetGrf() );
911 nMirr
= rGrfNd
.GetSwAttrSet().GetMirrorGrf().GetValue();
916 SwUndoInsertLabel::SwUndoInsertLabel( const SwLabelType eTyp
,
918 const String
& rSeparator
,
919 const String
& rNumberSeparator
,
921 const USHORT nInitId
,
922 const String
& rCharacterStyle
,
923 const BOOL bCpyBorder
)
924 : SwUndo( UNDO_INSERTLABEL
),
926 sSeparator( rSeparator
),
927 sNumberSeparator( rNumberSeparator
),//#i61007# order of captions
928 sCharacterStyle( rCharacterStyle
),
933 bCpyBrd( bCpyBorder
)
937 OBJECT
.pUndoAttr
= 0;
940 SwUndoInsertLabel::~SwUndoInsertLabel()
942 if( LTYPE_OBJECT
== eType
|| LTYPE_DRAW
== eType
)
944 delete OBJECT
.pUndoFly
;
945 delete OBJECT
.pUndoAttr
;
948 delete NODE
.pUndoInsNd
;
951 void SwUndoInsertLabel::Undo( SwUndoIter
& rIter
)
953 SwDoc
& rDoc
= rIter
.GetDoc();
955 if( LTYPE_OBJECT
== eType
|| LTYPE_DRAW
== eType
)
957 ASSERT( OBJECT
.pUndoAttr
&& OBJECT
.pUndoFly
, "Pointer nicht initialisiert" )
959 SdrObject
*pSdrObj
= 0;
960 if( OBJECT
.pUndoAttr
&&
961 0 != (pFmt
= (SwFrmFmt
*)OBJECT
.pUndoAttr
->GetFmt( rDoc
)) &&
962 ( LTYPE_DRAW
!= eType
||
963 0 != (pSdrObj
= pFmt
->FindSdrObject()) ) )
965 OBJECT
.pUndoAttr
->Undo( rIter
);
966 OBJECT
.pUndoFly
->Undo( rIter
);
967 if( LTYPE_DRAW
== eType
)
969 pSdrObj
->SetLayer( nLayerId
);
973 else if( NODE
.nNode
)
975 if ( eType
== LTYPE_TABLE
&& bUndoKeep
)
977 SwTableNode
*pNd
= rDoc
.GetNodes()[
978 rDoc
.GetNodes()[NODE
.nNode
-1]->StartOfSectionIndex()]->GetTableNode();
980 pNd
->GetTable().GetFrmFmt()->ResetFmtAttr( RES_KEEP
);
982 SwPaM
aPam( *rIter
.pAktPam
->GetPoint() );
983 aPam
.GetPoint()->nNode
= NODE
.nNode
;
985 aPam
.GetPoint()->nNode
= NODE
.nNode
+ 1;
986 NODE
.pUndoInsNd
= new SwUndoDelete( aPam
, TRUE
);
991 void SwUndoInsertLabel::Redo( SwUndoIter
& rIter
)
993 SwDoc
& rDoc
= rIter
.GetDoc();
995 if( LTYPE_OBJECT
== eType
|| LTYPE_DRAW
== eType
)
997 ASSERT( OBJECT
.pUndoAttr
&& OBJECT
.pUndoFly
, "Pointer nicht initialisiert" )
999 SdrObject
*pSdrObj
= 0;
1000 if( OBJECT
.pUndoAttr
&&
1001 0 != (pFmt
= (SwFrmFmt
*)OBJECT
.pUndoAttr
->GetFmt( rDoc
)) &&
1002 ( LTYPE_DRAW
!= eType
||
1003 0 != (pSdrObj
= pFmt
->FindSdrObject()) ) )
1005 OBJECT
.pUndoFly
->Redo( rIter
);
1006 OBJECT
.pUndoAttr
->Redo( rIter
);
1007 if( LTYPE_DRAW
== eType
)
1009 pSdrObj
->SetLayer( nLayerId
);
1010 if( pSdrObj
->GetLayer() == rDoc
.GetHellId() )
1011 pSdrObj
->SetLayer( rDoc
.GetHeavenId() );
1012 // OD 02.07.2003 #108784#
1013 else if( pSdrObj
->GetLayer() == rDoc
.GetInvisibleHellId() )
1014 pSdrObj
->SetLayer( rDoc
.GetInvisibleHeavenId() );
1018 else if( NODE
.pUndoInsNd
)
1020 if ( eType
== LTYPE_TABLE
&& bUndoKeep
)
1022 SwTableNode
*pNd
= rDoc
.GetNodes()[
1023 rDoc
.GetNodes()[NODE
.nNode
-1]->StartOfSectionIndex()]->GetTableNode();
1025 pNd
->GetTable().GetFrmFmt()->SetFmtAttr( SvxFmtKeepItem(TRUE
, RES_KEEP
) );
1027 NODE
.pUndoInsNd
->Undo( rIter
);
1028 delete NODE
.pUndoInsNd
, NODE
.pUndoInsNd
= 0;
1032 void SwUndoInsertLabel::Repeat( SwUndoIter
& rIter
)
1034 SwDoc
& rDoc
= rIter
.GetDoc();
1035 const SwPosition
& rPos
= *rIter
.pAktPam
->GetPoint();
1039 SwCntntNode
* pCNd
= rPos
.nNode
.GetNode().GetCntntNode();
1045 const SwTableNode
* pTNd
= pCNd
->FindTableNode();
1047 nIdx
= pTNd
->GetIndex();
1055 SwCntntFrm
*pCnt
= pCNd
->GetFrm();
1056 if( pCnt
&& 0 != ( pFly
= pCnt
->FindFlyFrm() ) )
1057 nIdx
= pFly
->GetFmt()->GetCntnt().GetCntntIdx()->GetIndex();
1066 rDoc
.InsertLabel( eType
, sText
, sSeparator
, sNumberSeparator
, bBefore
,
1067 nFldId
, nIdx
, sCharacterStyle
, bCpyBrd
);
1072 SwRewriter
SwUndoInsertLabel::GetRewriter() const
1074 SwRewriter aRewriter
;
1078 aTmpStr
+= String(SW_RES(STR_START_QUOTE
));
1079 aTmpStr
+= ShortenString(sText
, nUndoStringLength
,
1080 String(SW_RES(STR_LDOTS
)));
1081 aTmpStr
+= String(SW_RES(STR_END_QUOTE
));
1083 aRewriter
.AddRule(UNDO_ARG1
, aTmpStr
);
1088 void SwUndoInsertLabel::SetFlys( SwFrmFmt
& rOldFly
, SfxItemSet
& rChgSet
,
1091 if( LTYPE_OBJECT
== eType
|| LTYPE_DRAW
== eType
)
1093 SwUndoFmtAttrHelper
aTmp( rOldFly
, false );
1094 rOldFly
.SetFmtAttr( rChgSet
);
1095 if ( aTmp
.GetUndo() )
1097 OBJECT
.pUndoAttr
= aTmp
.ReleaseUndo();
1099 OBJECT
.pUndoFly
= new SwUndoInsLayFmt( &rNewFly
,0,0 );
1103 void SwUndoInsertLabel::SetDrawObj( BYTE nLId
)
1105 if( LTYPE_DRAW
== eType
)