xref: /aoo41x/main/sw/source/core/undo/undobj.cxx (revision bdf72556)
1efeef26fSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3efeef26fSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4efeef26fSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5efeef26fSAndrew Rist  * distributed with this work for additional information
6efeef26fSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7efeef26fSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8efeef26fSAndrew Rist  * "License"); you may not use this file except in compliance
9efeef26fSAndrew Rist  * with the License.  You may obtain a copy of the License at
10efeef26fSAndrew Rist  *
11efeef26fSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12efeef26fSAndrew Rist  *
13efeef26fSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14efeef26fSAndrew Rist  * software distributed under the License is distributed on an
15efeef26fSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16efeef26fSAndrew Rist  * KIND, either express or implied.  See the License for the
17efeef26fSAndrew Rist  * specific language governing permissions and limitations
18efeef26fSAndrew Rist  * under the License.
19efeef26fSAndrew Rist  *
20efeef26fSAndrew Rist  *************************************************************/
21efeef26fSAndrew Rist 
22efeef26fSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sw.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir 
28cdf0e10cSrcweir #include <IShellCursorSupplier.hxx>
29cdf0e10cSrcweir #include <txtftn.hxx>
30cdf0e10cSrcweir #include <fmtanchr.hxx>
31cdf0e10cSrcweir #include <ftnidx.hxx>
32cdf0e10cSrcweir #include <frmfmt.hxx>
33cdf0e10cSrcweir #include <doc.hxx>
34cdf0e10cSrcweir #include <UndoManager.hxx>
35cdf0e10cSrcweir #include <docary.hxx>
36cdf0e10cSrcweir #include <swundo.hxx>			// fuer die UndoIds
37cdf0e10cSrcweir #include <pam.hxx>
38cdf0e10cSrcweir #include <ndtxt.hxx>
39cdf0e10cSrcweir #include <UndoCore.hxx>
40cdf0e10cSrcweir #include <rolbck.hxx>
41cdf0e10cSrcweir #include <ndnotxt.hxx>
42cdf0e10cSrcweir #include <IMark.hxx>
43cdf0e10cSrcweir #include <mvsave.hxx>
44cdf0e10cSrcweir #include <redline.hxx>
45cdf0e10cSrcweir #include <crossrefbookmark.hxx>
46cdf0e10cSrcweir #include <undo.hrc>
47cdf0e10cSrcweir #include <comcore.hrc>
48cdf0e10cSrcweir #include <docsh.hxx>
49cdf0e10cSrcweir 
50641de097SOliver-Rainer Wittmann class SwRedlineSaveData: public SwUndRng, public SwRedlineData, private SwUndoSaveSection
51cdf0e10cSrcweir {
52cdf0e10cSrcweir public:
53641de097SOliver-Rainer Wittmann     SwRedlineSaveData(
54641de097SOliver-Rainer Wittmann         SwComparePosition eCmpPos,
55641de097SOliver-Rainer Wittmann         const SwPosition& rSttPos,
56641de097SOliver-Rainer Wittmann         const SwPosition& rEndPos,
57*bdf72556SOliver-Rainer Wittmann         SwRedline& rRedl,
58*bdf72556SOliver-Rainer Wittmann         sal_Bool bCopyNext );
59641de097SOliver-Rainer Wittmann 
60641de097SOliver-Rainer Wittmann     ~SwRedlineSaveData();
61641de097SOliver-Rainer Wittmann 
62641de097SOliver-Rainer Wittmann     void RedlineToDoc( SwPaM& rPam );
63641de097SOliver-Rainer Wittmann 
GetMvSttIdx() const64641de097SOliver-Rainer Wittmann     SwNodeIndex* GetMvSttIdx() const
65641de097SOliver-Rainer Wittmann     {
66641de097SOliver-Rainer Wittmann         return SwUndoSaveSection::GetMvSttIdx();
67641de097SOliver-Rainer Wittmann     }
68cdf0e10cSrcweir 
69cdf0e10cSrcweir #ifdef DBG_UTIL
70cdf0e10cSrcweir     sal_uInt16 nRedlineCount;
71cdf0e10cSrcweir #endif
72cdf0e10cSrcweir };
73cdf0e10cSrcweir 
SV_IMPL_PTRARR(SwRedlineSaveDatas,SwRedlineSaveDataPtr)74cdf0e10cSrcweir SV_IMPL_PTRARR( SwRedlineSaveDatas, SwRedlineSaveDataPtr )
75cdf0e10cSrcweir 
76cdf0e10cSrcweir 
77cdf0e10cSrcweir //------------------------------------------------------------
78cdf0e10cSrcweir 
79cdf0e10cSrcweir // Diese Klasse speichert den Pam als sal_uInt16's und kann diese wieder zu
80cdf0e10cSrcweir 
81cdf0e10cSrcweir // einem PaM zusammensetzen
82cdf0e10cSrcweir SwUndRng::SwUndRng()
83cdf0e10cSrcweir 	: nSttNode( 0 ), nEndNode( 0 ), nSttCntnt( 0 ), nEndCntnt( 0 )
84cdf0e10cSrcweir {
85cdf0e10cSrcweir }
86cdf0e10cSrcweir 
SwUndRng(const SwPaM & rPam)87cdf0e10cSrcweir SwUndRng::SwUndRng( const SwPaM& rPam )
88cdf0e10cSrcweir {
89cdf0e10cSrcweir 	SetValues( rPam );
90cdf0e10cSrcweir }
91cdf0e10cSrcweir 
SetValues(const SwPaM & rPam)92cdf0e10cSrcweir void SwUndRng::SetValues( const SwPaM& rPam )
93cdf0e10cSrcweir {
94cdf0e10cSrcweir 	const SwPosition *pStt = rPam.Start();
95cdf0e10cSrcweir 	if( rPam.HasMark() )
96cdf0e10cSrcweir 	{
97cdf0e10cSrcweir 		const SwPosition *pEnd = rPam.GetPoint() == pStt
98cdf0e10cSrcweir 						? rPam.GetMark()
99cdf0e10cSrcweir 						: rPam.GetPoint();
100cdf0e10cSrcweir 		nEndNode = pEnd->nNode.GetIndex();
101cdf0e10cSrcweir 		nEndCntnt = pEnd->nContent.GetIndex();
102cdf0e10cSrcweir 	}
103cdf0e10cSrcweir 	else
104cdf0e10cSrcweir 		// keine Selektion !!
105cdf0e10cSrcweir 		nEndNode = 0, nEndCntnt = STRING_MAXLEN;
106cdf0e10cSrcweir 
107cdf0e10cSrcweir 	nSttNode = pStt->nNode.GetIndex();
108cdf0e10cSrcweir 	nSttCntnt = pStt->nContent.GetIndex();
109cdf0e10cSrcweir }
110cdf0e10cSrcweir 
SetPaM(SwPaM & rPam,sal_Bool bCorrToCntnt) const111cdf0e10cSrcweir void SwUndRng::SetPaM( SwPaM & rPam, sal_Bool bCorrToCntnt ) const
112cdf0e10cSrcweir {
113cdf0e10cSrcweir 	rPam.DeleteMark();
114cdf0e10cSrcweir 	rPam.GetPoint()->nNode = nSttNode;
115cdf0e10cSrcweir 	SwNode* pNd = rPam.GetNode();
116cdf0e10cSrcweir 	if( pNd->IsCntntNode() )
117cdf0e10cSrcweir 		rPam.GetPoint()->nContent.Assign( pNd->GetCntntNode(), nSttCntnt );
118cdf0e10cSrcweir 	else if( bCorrToCntnt )
119cdf0e10cSrcweir 		rPam.Move( fnMoveForward, fnGoCntnt );
120cdf0e10cSrcweir 	else
121cdf0e10cSrcweir 		rPam.GetPoint()->nContent.Assign( 0, 0 );
122cdf0e10cSrcweir 
123cdf0e10cSrcweir 	if( !nEndNode && STRING_MAXLEN == nEndCntnt )		// keine Selection
124cdf0e10cSrcweir 		return ;
125cdf0e10cSrcweir 
126cdf0e10cSrcweir 	rPam.SetMark();
127cdf0e10cSrcweir 	if( nSttNode == nEndNode && nSttCntnt == nEndCntnt )
128cdf0e10cSrcweir 		return;								// nichts mehr zu tun
129cdf0e10cSrcweir 
130cdf0e10cSrcweir 	rPam.GetPoint()->nNode = nEndNode;
131cdf0e10cSrcweir 	if( (pNd = rPam.GetNode())->IsCntntNode() )
132cdf0e10cSrcweir 		rPam.GetPoint()->nContent.Assign( pNd->GetCntntNode(), nEndCntnt );
133cdf0e10cSrcweir 	else if( bCorrToCntnt )
134cdf0e10cSrcweir 		rPam.Move( fnMoveBackward, fnGoCntnt );
135cdf0e10cSrcweir 	else
136cdf0e10cSrcweir 		rPam.GetPoint()->nContent.Assign( 0, 0 );
137cdf0e10cSrcweir }
138cdf0e10cSrcweir 
AddUndoRedoPaM(::sw::UndoRedoContext & rContext,bool const bCorrToCntnt) const139cdf0e10cSrcweir SwPaM & SwUndRng::AddUndoRedoPaM(
140cdf0e10cSrcweir         ::sw::UndoRedoContext & rContext, bool const bCorrToCntnt) const
141cdf0e10cSrcweir {
142cdf0e10cSrcweir     SwPaM & rPaM( rContext.GetCursorSupplier().CreateNewShellCursor() );
143cdf0e10cSrcweir     SetPaM( rPaM, bCorrToCntnt );
144cdf0e10cSrcweir     return rPaM;
145cdf0e10cSrcweir }
146cdf0e10cSrcweir 
147cdf0e10cSrcweir 
148cdf0e10cSrcweir //------------------------------------------------------------
149cdf0e10cSrcweir 
150cdf0e10cSrcweir 
RemoveIdxFromSection(SwDoc & rDoc,sal_uLong nSttIdx,sal_uLong * pEndIdx)151cdf0e10cSrcweir void SwUndo::RemoveIdxFromSection( SwDoc& rDoc, sal_uLong nSttIdx,
152cdf0e10cSrcweir 									sal_uLong* pEndIdx )
153cdf0e10cSrcweir {
154cdf0e10cSrcweir 	SwNodeIndex aIdx( rDoc.GetNodes(), nSttIdx );
155cdf0e10cSrcweir 	SwNodeIndex aEndIdx( rDoc.GetNodes(), pEndIdx ? *pEndIdx
156cdf0e10cSrcweir 									: aIdx.GetNode().EndOfSectionIndex() );
157cdf0e10cSrcweir 	SwPosition aPos( rDoc.GetNodes().GetEndOfPostIts() );
158cdf0e10cSrcweir 	rDoc.CorrAbs( aIdx, aEndIdx, aPos, sal_True );
159cdf0e10cSrcweir }
160cdf0e10cSrcweir 
RemoveIdxFromRange(SwPaM & rPam,sal_Bool bMoveNext)161cdf0e10cSrcweir void SwUndo::RemoveIdxFromRange( SwPaM& rPam, sal_Bool bMoveNext )
162cdf0e10cSrcweir {
163cdf0e10cSrcweir 	const SwPosition* pEnd = rPam.End();
164cdf0e10cSrcweir 	if( bMoveNext )
165cdf0e10cSrcweir 	{
166cdf0e10cSrcweir 		if( pEnd != rPam.GetPoint() )
167cdf0e10cSrcweir 			rPam.Exchange();
168cdf0e10cSrcweir 
169cdf0e10cSrcweir 		SwNodeIndex aStt( rPam.GetMark()->nNode );
170cdf0e10cSrcweir 		SwNodeIndex aEnd( rPam.GetPoint()->nNode );
171cdf0e10cSrcweir 
172cdf0e10cSrcweir 		if( !rPam.Move( fnMoveForward ) )
173cdf0e10cSrcweir 		{
174cdf0e10cSrcweir 			rPam.Exchange();
175cdf0e10cSrcweir 			if( !rPam.Move( fnMoveBackward ) )
176cdf0e10cSrcweir 			{
177cdf0e10cSrcweir 				rPam.GetPoint()->nNode = rPam.GetDoc()->GetNodes().GetEndOfPostIts();
178cdf0e10cSrcweir 				rPam.GetPoint()->nContent.Assign( 0, 0 );
179cdf0e10cSrcweir 			}
180cdf0e10cSrcweir 		}
181cdf0e10cSrcweir 
182cdf0e10cSrcweir 		rPam.GetDoc()->CorrAbs( aStt, aEnd, *rPam.GetPoint(), sal_True );
183cdf0e10cSrcweir 	}
184cdf0e10cSrcweir 	else
185cdf0e10cSrcweir 		rPam.GetDoc()->CorrAbs( rPam, *pEnd, sal_True );
186cdf0e10cSrcweir }
187cdf0e10cSrcweir 
RemoveIdxRel(sal_uLong nIdx,const SwPosition & rPos)188cdf0e10cSrcweir void SwUndo::RemoveIdxRel( sal_uLong nIdx, const SwPosition& rPos )
189cdf0e10cSrcweir {
190cdf0e10cSrcweir 	// nur die Crsr verschieben; die Bookmarks/TOXMarks/.. werden vom
191cdf0e10cSrcweir 	// entsp. JoinNext/JoinPrev erledigt!
192cdf0e10cSrcweir 	SwNodeIndex aIdx( rPos.nNode.GetNode().GetNodes(), nIdx );
193cdf0e10cSrcweir 	::PaMCorrRel( aIdx, rPos );
194cdf0e10cSrcweir }
195cdf0e10cSrcweir 
SwUndo(SwUndoId const nId)196cdf0e10cSrcweir SwUndo::SwUndo(SwUndoId const nId)
197cdf0e10cSrcweir     : m_nId(nId), nOrigRedlineMode(nsRedlineMode_t::REDLINE_NONE),
198cdf0e10cSrcweir       bCacheComment(true), pComment(NULL)
199cdf0e10cSrcweir {
200cdf0e10cSrcweir }
201cdf0e10cSrcweir 
IsDelBox() const202cdf0e10cSrcweir bool SwUndo::IsDelBox() const
203cdf0e10cSrcweir {
204cdf0e10cSrcweir     return GetId() == UNDO_COL_DELETE || GetId() == UNDO_ROW_DELETE ||
205cdf0e10cSrcweir         GetId() == UNDO_TABLE_DELBOX;
206cdf0e10cSrcweir }
207cdf0e10cSrcweir 
~SwUndo()208cdf0e10cSrcweir SwUndo::~SwUndo()
209cdf0e10cSrcweir {
210cdf0e10cSrcweir     delete pComment;
211cdf0e10cSrcweir }
212cdf0e10cSrcweir 
213cdf0e10cSrcweir 
214cdf0e10cSrcweir class UndoRedoRedlineGuard
215cdf0e10cSrcweir {
216cdf0e10cSrcweir public:
UndoRedoRedlineGuard(::sw::UndoRedoContext & rContext,SwUndo & rUndo)217cdf0e10cSrcweir     UndoRedoRedlineGuard(::sw::UndoRedoContext & rContext, SwUndo & rUndo)
218cdf0e10cSrcweir         : m_rRedlineAccess(rContext.GetDoc())
219cdf0e10cSrcweir         , m_eMode(m_rRedlineAccess.GetRedlineMode())
220cdf0e10cSrcweir     {
221cdf0e10cSrcweir         RedlineMode_t const eTmpMode =
222cdf0e10cSrcweir             static_cast<RedlineMode_t>(rUndo.GetRedlineMode());
223cdf0e10cSrcweir         if ((nsRedlineMode_t::REDLINE_SHOW_MASK & eTmpMode) !=
224cdf0e10cSrcweir             (nsRedlineMode_t::REDLINE_SHOW_MASK & m_eMode))
225cdf0e10cSrcweir         {
226cdf0e10cSrcweir             m_rRedlineAccess.SetRedlineMode( eTmpMode );
227cdf0e10cSrcweir         }
228cdf0e10cSrcweir         m_rRedlineAccess.SetRedlineMode_intern( static_cast<RedlineMode_t>(
229cdf0e10cSrcweir                 eTmpMode | nsRedlineMode_t::REDLINE_IGNORE) );
230cdf0e10cSrcweir     }
~UndoRedoRedlineGuard()231cdf0e10cSrcweir     ~UndoRedoRedlineGuard()
232cdf0e10cSrcweir     {
233cdf0e10cSrcweir         m_rRedlineAccess.SetRedlineMode(m_eMode);
234cdf0e10cSrcweir     }
235cdf0e10cSrcweir private:
236cdf0e10cSrcweir     IDocumentRedlineAccess & m_rRedlineAccess;
237cdf0e10cSrcweir     RedlineMode_t const m_eMode;
238cdf0e10cSrcweir };
239cdf0e10cSrcweir 
Undo()240cdf0e10cSrcweir void SwUndo::Undo()
241cdf0e10cSrcweir {
242cdf0e10cSrcweir     OSL_ENSURE(false, "SwUndo::Undo(): ERROR: must call Undo(context) instead");
243cdf0e10cSrcweir }
244cdf0e10cSrcweir 
Redo()245cdf0e10cSrcweir void SwUndo::Redo()
246cdf0e10cSrcweir {
247cdf0e10cSrcweir     OSL_ENSURE(false, "SwUndo::Redo(): ERROR: must call Redo(context) instead");
248cdf0e10cSrcweir }
249cdf0e10cSrcweir 
UndoWithContext(SfxUndoContext & rContext)250cdf0e10cSrcweir void SwUndo::UndoWithContext(SfxUndoContext & rContext)
251cdf0e10cSrcweir {
252cdf0e10cSrcweir     ::sw::UndoRedoContext *const pContext(
253cdf0e10cSrcweir             dynamic_cast< ::sw::UndoRedoContext * >(& rContext));
254cdf0e10cSrcweir     OSL_ASSERT(pContext);
255cdf0e10cSrcweir     if (!pContext) { return; }
256641de097SOliver-Rainer Wittmann     const UndoRedoRedlineGuard aUndoRedoRedlineGuard(*pContext, *this);
257cdf0e10cSrcweir     UndoImpl(*pContext);
258cdf0e10cSrcweir }
259cdf0e10cSrcweir 
RedoWithContext(SfxUndoContext & rContext)260cdf0e10cSrcweir void SwUndo::RedoWithContext(SfxUndoContext & rContext)
261cdf0e10cSrcweir {
262cdf0e10cSrcweir     ::sw::UndoRedoContext *const pContext(
263cdf0e10cSrcweir             dynamic_cast< ::sw::UndoRedoContext * >(& rContext));
264cdf0e10cSrcweir     OSL_ASSERT(pContext);
265cdf0e10cSrcweir     if (!pContext) { return; }
266641de097SOliver-Rainer Wittmann     const UndoRedoRedlineGuard aUndoRedoRedlineGuard(*pContext, *this);
267cdf0e10cSrcweir     RedoImpl(*pContext);
268cdf0e10cSrcweir }
269cdf0e10cSrcweir 
Repeat(SfxRepeatTarget & rContext)270cdf0e10cSrcweir void SwUndo::Repeat(SfxRepeatTarget & rContext)
271cdf0e10cSrcweir {
272cdf0e10cSrcweir     ::sw::RepeatContext *const pRepeatContext(
273cdf0e10cSrcweir             dynamic_cast< ::sw::RepeatContext * >(& rContext));
274cdf0e10cSrcweir     OSL_ASSERT(pRepeatContext);
275cdf0e10cSrcweir     if (!pRepeatContext) { return; }
276cdf0e10cSrcweir     RepeatImpl(*pRepeatContext);
277cdf0e10cSrcweir }
278cdf0e10cSrcweir 
CanRepeat(SfxRepeatTarget & rContext) const279cdf0e10cSrcweir sal_Bool SwUndo::CanRepeat(SfxRepeatTarget & rContext) const
280cdf0e10cSrcweir {
281cdf0e10cSrcweir     ::sw::RepeatContext *const pRepeatContext(
282cdf0e10cSrcweir             dynamic_cast< ::sw::RepeatContext * >(& rContext));
283cdf0e10cSrcweir     OSL_ASSERT(pRepeatContext);
284cdf0e10cSrcweir     if (!pRepeatContext) { return false; }
285cdf0e10cSrcweir     return CanRepeatImpl(*pRepeatContext);
286cdf0e10cSrcweir }
287cdf0e10cSrcweir 
RepeatImpl(::sw::RepeatContext &)288cdf0e10cSrcweir void SwUndo::RepeatImpl( ::sw::RepeatContext & )
289cdf0e10cSrcweir {
290cdf0e10cSrcweir }
291cdf0e10cSrcweir 
CanRepeatImpl(::sw::RepeatContext &) const292cdf0e10cSrcweir bool SwUndo::CanRepeatImpl( ::sw::RepeatContext & ) const
293cdf0e10cSrcweir {
294cdf0e10cSrcweir //    return false;
295cdf0e10cSrcweir     return ((REPEAT_START <= GetId()) && (GetId() < REPEAT_END));
296cdf0e10cSrcweir }
297cdf0e10cSrcweir 
GetComment() const298cdf0e10cSrcweir String SwUndo::GetComment() const
299cdf0e10cSrcweir {
300cdf0e10cSrcweir     String aResult;
301cdf0e10cSrcweir 
302cdf0e10cSrcweir     if (bCacheComment)
303cdf0e10cSrcweir     {
304cdf0e10cSrcweir         if (! pComment)
305cdf0e10cSrcweir         {
306cdf0e10cSrcweir             pComment = new String(SW_RES(UNDO_BASE + GetId()));
307cdf0e10cSrcweir 
308cdf0e10cSrcweir             SwRewriter aRewriter = GetRewriter();
309cdf0e10cSrcweir 
310cdf0e10cSrcweir             *pComment = aRewriter.Apply(*pComment);
311cdf0e10cSrcweir         }
312cdf0e10cSrcweir 
313cdf0e10cSrcweir         aResult = *pComment;
314cdf0e10cSrcweir     }
315cdf0e10cSrcweir     else
316cdf0e10cSrcweir     {
317cdf0e10cSrcweir         aResult = String(SW_RES(UNDO_BASE + GetId()));
318cdf0e10cSrcweir 
319cdf0e10cSrcweir         SwRewriter aRewriter = GetRewriter();
320cdf0e10cSrcweir 
321cdf0e10cSrcweir         aResult = aRewriter.Apply(aResult);
322cdf0e10cSrcweir     }
323cdf0e10cSrcweir 
324cdf0e10cSrcweir     return aResult;
325cdf0e10cSrcweir }
326cdf0e10cSrcweir 
GetRewriter() const327cdf0e10cSrcweir SwRewriter SwUndo::GetRewriter() const
328cdf0e10cSrcweir {
329cdf0e10cSrcweir     SwRewriter aResult;
330cdf0e10cSrcweir 
331cdf0e10cSrcweir     return aResult;
332cdf0e10cSrcweir }
333cdf0e10cSrcweir 
334cdf0e10cSrcweir 
335cdf0e10cSrcweir //------------------------------------------------------------
336cdf0e10cSrcweir 
SwUndoSaveCntnt()337cdf0e10cSrcweir SwUndoSaveCntnt::SwUndoSaveCntnt()
338cdf0e10cSrcweir 	: pHistory( 0 )
339cdf0e10cSrcweir {}
340cdf0e10cSrcweir 
~SwUndoSaveCntnt()341cdf0e10cSrcweir SwUndoSaveCntnt::~SwUndoSaveCntnt()
342cdf0e10cSrcweir {
343cdf0e10cSrcweir 	delete pHistory;
344cdf0e10cSrcweir }
345cdf0e10cSrcweir 
346cdf0e10cSrcweir 	// wird fuer das Loeschen von Inhalt benoetigt. Fuer das ReDo werden
347cdf0e10cSrcweir 	// Inhalte in das UndoNodesArray verschoben. Diese Methoden fuegen
348cdf0e10cSrcweir 	// am Ende eines TextNodes fuer die Attribute einen Trenner ein.
349cdf0e10cSrcweir 	// Dadurch werden die Attribute nicht expandiert.
350cdf0e10cSrcweir 	// MoveTo.. 	verschiebt aus dem NodesArray in das UndoNodesArray
351cdf0e10cSrcweir 	// MoveFrom..	verschiebt aus dem UndoNodesArray in das NodesArray
352cdf0e10cSrcweir 
353cdf0e10cSrcweir 	// 2.8.93:	ist pEndNdIdx angebenen, wird vom Undo/Redo -Ins/DelFly
354cdf0e10cSrcweir 	//			aufgerufen. Dann soll die gesamte Section verschoben werden.
355cdf0e10cSrcweir 
MoveToUndoNds(SwPaM & rPaM,SwNodeIndex * pNodeIdx,SwIndex * pCntIdx,sal_uLong * pEndNdIdx,xub_StrLen * pEndCntIdx)356cdf0e10cSrcweir void SwUndoSaveCntnt::MoveToUndoNds( SwPaM& rPaM, SwNodeIndex* pNodeIdx,
357cdf0e10cSrcweir 					SwIndex* pCntIdx, sal_uLong* pEndNdIdx, xub_StrLen* pEndCntIdx )
358cdf0e10cSrcweir {
359cdf0e10cSrcweir 	SwDoc& rDoc = *rPaM.GetDoc();
360cdf0e10cSrcweir     ::sw::UndoGuard const undoGuard(rDoc.GetIDocumentUndoRedo());
361cdf0e10cSrcweir 
362cdf0e10cSrcweir 	SwNoTxtNode* pCpyNd = rPaM.GetNode()->GetNoTxtNode();
363cdf0e10cSrcweir 
364cdf0e10cSrcweir 	// jetzt kommt das eigentliche Loeschen(Verschieben)
365cdf0e10cSrcweir     SwNodes & rNds = rDoc.GetUndoManager().GetUndoNodes();
366cdf0e10cSrcweir 	SwPosition aPos( pEndNdIdx ? rNds.GetEndOfPostIts()
367cdf0e10cSrcweir 							   : rNds.GetEndOfExtras() );
368cdf0e10cSrcweir 	aPos.nNode--;
369cdf0e10cSrcweir 
370cdf0e10cSrcweir 	const SwPosition* pStt = rPaM.Start(), *pEnd = rPaM.End();
371cdf0e10cSrcweir 
372cdf0e10cSrcweir 	if( pCpyNd || pEndNdIdx || !aPos.nNode.GetNode().GetCntntNode() ||
373cdf0e10cSrcweir 		(!pStt->nContent.GetIndex() && (pStt->nNode != pEnd->nNode ||
374cdf0e10cSrcweir 				(!pStt->nNode.GetNode().GetCntntNode() ||
375cdf0e10cSrcweir 					pStt->nNode.GetNode().GetCntntNode()->Len() ==
376cdf0e10cSrcweir 						pEnd->nContent.GetIndex() ) ) ) )
377cdf0e10cSrcweir 	{
378cdf0e10cSrcweir 		aPos.nNode++;
379cdf0e10cSrcweir 		aPos.nContent = 0;
380cdf0e10cSrcweir 	}
381cdf0e10cSrcweir 	else
382cdf0e10cSrcweir 		aPos.nNode.GetNode().GetCntntNode()->MakeEndIndex( &aPos.nContent );
383cdf0e10cSrcweir 
384cdf0e10cSrcweir 	// als sal_uInt16 merken; die Indizies verschieben sich !!
385cdf0e10cSrcweir 	sal_uLong nTmpMvNode = aPos.nNode.GetIndex();
386cdf0e10cSrcweir 	xub_StrLen nTmpMvCntnt = aPos.nContent.GetIndex();
387cdf0e10cSrcweir 
388cdf0e10cSrcweir 	if( pCpyNd || pEndNdIdx )
389cdf0e10cSrcweir 	{
390cdf0e10cSrcweir 		SwNodeRange aRg( pStt->nNode, 0, pEnd->nNode, 1 );
391cdf0e10cSrcweir 		rDoc.GetNodes()._MoveNodes( aRg, rNds, aPos.nNode, sal_False );
392cdf0e10cSrcweir 		aPos.nContent = 0;
393cdf0e10cSrcweir 		aPos.nNode--;
394cdf0e10cSrcweir 	}
395cdf0e10cSrcweir 	else
396cdf0e10cSrcweir     {
397cdf0e10cSrcweir         rDoc.GetNodes().MoveRange( rPaM, aPos, rNds );
398cdf0e10cSrcweir 
399cdf0e10cSrcweir 		SwTxtNode* pTxtNd = aPos.nNode.GetNode().GetTxtNode();
400cdf0e10cSrcweir 		if( pTxtNd )		// fuege einen Trenner fuer die Attribute ein !
401cdf0e10cSrcweir 		{
402cdf0e10cSrcweir 			// weil aber beim Insert die Attribute angefasst/sprich
403cdf0e10cSrcweir 			// aus dem Array geloescht und wieder eingefuegt werden, koennen
404cdf0e10cSrcweir 			// dadurch Attribute verschwinden (z.B "Fett aus" von 10-20,
405cdf0e10cSrcweir 			// "Fett an" von 12-15, dann wird durchs Insert/Delete das
406cdf0e10cSrcweir 			// "Fett an" geloescht !! Ist hier aber nicht erwuenscht !!)
407cdf0e10cSrcweir 			// DARUM: nicht die Hints anfassen, direct den String manipulieren
408cdf0e10cSrcweir 
409cdf0e10cSrcweir 			String& rStr = (String&)pTxtNd->GetTxt();
410cdf0e10cSrcweir 			// Zur Sicherheit lieber nur wenn wirklich am Ende steht
411cdf0e10cSrcweir 			if( rStr.Len() == aPos.nContent.GetIndex() )
412cdf0e10cSrcweir 			{
413cdf0e10cSrcweir 				rStr.Insert( ' ' );
414cdf0e10cSrcweir 				++aPos.nContent;
415cdf0e10cSrcweir 			}
416cdf0e10cSrcweir 			else
417cdf0e10cSrcweir             {
418cdf0e10cSrcweir                 pTxtNd->InsertText( sal_Unicode(' '), aPos.nContent,
419cdf0e10cSrcweir                         IDocumentContentOperations::INS_NOHINTEXPAND );
420cdf0e10cSrcweir             }
421cdf0e10cSrcweir 		}
422cdf0e10cSrcweir 	}
423cdf0e10cSrcweir 	if( pEndNdIdx )
424cdf0e10cSrcweir 		*pEndNdIdx = aPos.nNode.GetIndex();
425cdf0e10cSrcweir 	if( pEndCntIdx )
426cdf0e10cSrcweir 		*pEndCntIdx = aPos.nContent.GetIndex();
427cdf0e10cSrcweir 
428cdf0e10cSrcweir 	// alte Position
429cdf0e10cSrcweir 	aPos.nNode = nTmpMvNode;
430cdf0e10cSrcweir 	if( pNodeIdx )
431cdf0e10cSrcweir 		*pNodeIdx = aPos.nNode;
432cdf0e10cSrcweir 
433cdf0e10cSrcweir 	if( pCntIdx )
434cdf0e10cSrcweir 	{
435cdf0e10cSrcweir 		SwCntntNode* pCNd = aPos.nNode.GetNode().GetCntntNode();
436cdf0e10cSrcweir 		if( pCNd )
437cdf0e10cSrcweir 			pCntIdx->Assign( pCNd, nTmpMvCntnt );
438cdf0e10cSrcweir 		else
439cdf0e10cSrcweir 			pCntIdx->Assign( 0, 0 );
440cdf0e10cSrcweir 	}
441cdf0e10cSrcweir }
442cdf0e10cSrcweir 
MoveFromUndoNds(SwDoc & rDoc,sal_uLong nNodeIdx,xub_StrLen nCntIdx,SwPosition & rInsPos,sal_uLong * pEndNdIdx,xub_StrLen * pEndCntIdx)443cdf0e10cSrcweir void SwUndoSaveCntnt::MoveFromUndoNds( SwDoc& rDoc, sal_uLong nNodeIdx,
444cdf0e10cSrcweir 							xub_StrLen nCntIdx, SwPosition& rInsPos,
445cdf0e10cSrcweir 							sal_uLong* pEndNdIdx, xub_StrLen* pEndCntIdx )
446cdf0e10cSrcweir {
447cdf0e10cSrcweir 	// jetzt kommt das wiederherstellen
448cdf0e10cSrcweir     SwNodes & rNds = rDoc.GetUndoManager().GetUndoNodes();
449cdf0e10cSrcweir 	if( nNodeIdx == rNds.GetEndOfPostIts().GetIndex() )
450cdf0e10cSrcweir 		return;		// nichts gespeichert
451cdf0e10cSrcweir 
452cdf0e10cSrcweir     ::sw::UndoGuard const undoGuard(rDoc.GetIDocumentUndoRedo());
453cdf0e10cSrcweir 
454cdf0e10cSrcweir 	SwPaM aPaM( rInsPos );
455cdf0e10cSrcweir 	if( pEndNdIdx )			// dann hole aus diesem den Bereich
456cdf0e10cSrcweir 		aPaM.GetPoint()->nNode.Assign( rNds, *pEndNdIdx );
457cdf0e10cSrcweir 	else
458cdf0e10cSrcweir 	{
459cdf0e10cSrcweir 		aPaM.GetPoint()->nNode = rNds.GetEndOfExtras();
460cdf0e10cSrcweir 		GoInCntnt( aPaM, fnMoveBackward );
461cdf0e10cSrcweir 	}
462cdf0e10cSrcweir 
463cdf0e10cSrcweir 	SwTxtNode* pTxtNd = aPaM.GetNode()->GetTxtNode();
464cdf0e10cSrcweir 	if( !pEndNdIdx && pTxtNd )	// loesche den Trenner wieder
465cdf0e10cSrcweir 	{
466cdf0e10cSrcweir 		if( pEndCntIdx )
467cdf0e10cSrcweir 			aPaM.GetPoint()->nContent.Assign( pTxtNd, *pEndCntIdx );
468cdf0e10cSrcweir 		if( pTxtNd->GetTxt().Len() )
469cdf0e10cSrcweir 		{
470cdf0e10cSrcweir 			GoInCntnt( aPaM, fnMoveBackward );
471cdf0e10cSrcweir             pTxtNd->EraseText( aPaM.GetPoint()->nContent, 1 );
472cdf0e10cSrcweir         }
473cdf0e10cSrcweir 
474cdf0e10cSrcweir 		aPaM.SetMark();
475cdf0e10cSrcweir 		aPaM.GetPoint()->nNode = nNodeIdx;
476cdf0e10cSrcweir 		aPaM.GetPoint()->nContent.Assign( aPaM.GetCntntNode(), nCntIdx );
477cdf0e10cSrcweir 
478cdf0e10cSrcweir 		_SaveRedlEndPosForRestore aRedlRest( rInsPos.nNode, rInsPos.nContent.GetIndex() );
479cdf0e10cSrcweir 
480cdf0e10cSrcweir         rNds.MoveRange( aPaM, rInsPos, rDoc.GetNodes() );
481cdf0e10cSrcweir 
482cdf0e10cSrcweir 		// noch den letzen Node loeschen.
483cdf0e10cSrcweir 		if( !aPaM.GetPoint()->nContent.GetIndex() ||
484cdf0e10cSrcweir 			( aPaM.GetPoint()->nNode++ && 		// noch leere Nodes am Ende ??
485cdf0e10cSrcweir 			&rNds.GetEndOfExtras() != &aPaM.GetPoint()->nNode.GetNode() ))
486cdf0e10cSrcweir 		{
487cdf0e10cSrcweir 			aPaM.GetPoint()->nContent.Assign( 0, 0 );
488cdf0e10cSrcweir 			aPaM.SetMark();
489cdf0e10cSrcweir 			rNds.Delete( aPaM.GetPoint()->nNode,
490cdf0e10cSrcweir 						rNds.GetEndOfExtras().GetIndex() -
491cdf0e10cSrcweir 						aPaM.GetPoint()->nNode.GetIndex() );
492cdf0e10cSrcweir 		}
493cdf0e10cSrcweir 
494cdf0e10cSrcweir 		aRedlRest.Restore();
495cdf0e10cSrcweir 	}
496cdf0e10cSrcweir 	else if( pEndNdIdx || !pTxtNd )
497cdf0e10cSrcweir 	{
498cdf0e10cSrcweir 		SwNodeRange aRg( rNds, nNodeIdx, rNds, (pEndNdIdx
499cdf0e10cSrcweir 						? ((*pEndNdIdx) + 1)
500cdf0e10cSrcweir 						: rNds.GetEndOfExtras().GetIndex() ) );
501cdf0e10cSrcweir 		rNds._MoveNodes( aRg, rDoc.GetNodes(), rInsPos.nNode, 0 == pEndNdIdx );
502cdf0e10cSrcweir 
503cdf0e10cSrcweir 	}
504cdf0e10cSrcweir 	else {
505cdf0e10cSrcweir 		ASSERT( sal_False, "was ist es denn nun?" );
506cdf0e10cSrcweir     }
507cdf0e10cSrcweir }
508cdf0e10cSrcweir 
509cdf0e10cSrcweir // diese beiden Methoden bewegen den Point vom Pam zurueck/vor. Damit
510cdf0e10cSrcweir // kann fuer ein Undo/Redo ein Bereich aufgespannt werden. (Der
511cdf0e10cSrcweir // Point liegt dann vor dem manipuliertem Bereich !!)
512cdf0e10cSrcweir // Das Flag gibt an, ob noch vorm Point Inhalt steht.
513cdf0e10cSrcweir 
MovePtBackward(SwPaM & rPam)514cdf0e10cSrcweir sal_Bool SwUndoSaveCntnt::MovePtBackward( SwPaM& rPam )
515cdf0e10cSrcweir {
516cdf0e10cSrcweir 	rPam.SetMark();
517cdf0e10cSrcweir 	if( rPam.Move( fnMoveBackward ))
518cdf0e10cSrcweir 		return sal_True;
519cdf0e10cSrcweir 
520cdf0e10cSrcweir 	// gibt es nach vorne keinen Inhalt mehr, so setze den Point einfach
521cdf0e10cSrcweir 	// auf die vorherige Position (Node und Content, damit der Content
522cdf0e10cSrcweir 	// abgemeldet wird !!)
523cdf0e10cSrcweir 	rPam.GetPoint()->nNode--;
524cdf0e10cSrcweir 	rPam.GetPoint()->nContent.Assign( 0, 0 );
525cdf0e10cSrcweir 	return sal_False;
526cdf0e10cSrcweir }
527cdf0e10cSrcweir 
MovePtForward(SwPaM & rPam,sal_Bool bMvBkwrd)528cdf0e10cSrcweir void SwUndoSaveCntnt::MovePtForward( SwPaM& rPam, sal_Bool bMvBkwrd )
529cdf0e10cSrcweir {
530cdf0e10cSrcweir 	// gab es noch Inhalt vor der Position ?
531cdf0e10cSrcweir 	if( bMvBkwrd )
532cdf0e10cSrcweir 		rPam.Move( fnMoveForward );
533cdf0e10cSrcweir 	else
534cdf0e10cSrcweir 	{                       // setzen Point auf die naechste Position
535cdf0e10cSrcweir 		rPam.GetPoint()->nNode++;
536cdf0e10cSrcweir 		SwCntntNode* pCNd = rPam.GetCntntNode();
537cdf0e10cSrcweir 		if( pCNd )
538cdf0e10cSrcweir 			pCNd->MakeStartIndex( &rPam.GetPoint()->nContent );
539cdf0e10cSrcweir 		else
540cdf0e10cSrcweir 			rPam.Move( fnMoveForward );
541cdf0e10cSrcweir 	}
542cdf0e10cSrcweir }
543cdf0e10cSrcweir 
544cdf0e10cSrcweir 
545cdf0e10cSrcweir /*
546cdf0e10cSrcweir    JP 21.03.94: loesche alle Objecte, die ContentIndizies auf den ang.
547cdf0e10cSrcweir 				Bereich besitzen.
548cdf0e10cSrcweir 				Zur Zeit gibts folgende Objecte
549cdf0e10cSrcweir 					- Fussnoten
550cdf0e10cSrcweir 					- Flys
551cdf0e10cSrcweir 					- Bookmarks
552cdf0e10cSrcweir 					- Verzeichnisse
553cdf0e10cSrcweir */
554cdf0e10cSrcweir // --> OD 2007-10-17 #i81002# - extending method:
555cdf0e10cSrcweir // delete certain (not all) cross-reference bookmarks at text node of <rMark>
556cdf0e10cSrcweir // and at text node of <rPoint>, if these text nodes aren't the same.
DelCntntIndex(const SwPosition & rMark,const SwPosition & rPoint,DelCntntType nDelCntntType)557cdf0e10cSrcweir void SwUndoSaveCntnt::DelCntntIndex( const SwPosition& rMark,
558cdf0e10cSrcweir 								     const SwPosition& rPoint,
559cdf0e10cSrcweir 									 DelCntntType nDelCntntType )
560cdf0e10cSrcweir {
561cdf0e10cSrcweir 	const SwPosition *pStt = rMark < rPoint ? &rMark : &rPoint,
562cdf0e10cSrcweir 					*pEnd = &rMark == pStt ? &rPoint : &rMark;
563cdf0e10cSrcweir 
564cdf0e10cSrcweir 	SwDoc* pDoc = rMark.nNode.GetNode().GetDoc();
565cdf0e10cSrcweir 
566cdf0e10cSrcweir     ::sw::UndoGuard const undoGuard(pDoc->GetIDocumentUndoRedo());
567cdf0e10cSrcweir 
568cdf0e10cSrcweir 	// 1. Fussnoten
569cdf0e10cSrcweir     if( nsDelCntntType::DELCNT_FTN & nDelCntntType )
570cdf0e10cSrcweir 	{
571cdf0e10cSrcweir 		SwFtnIdxs& rFtnArr = pDoc->GetFtnIdxs();
572cdf0e10cSrcweir 		if( rFtnArr.Count() )
573cdf0e10cSrcweir 		{
574cdf0e10cSrcweir 			const SwNode* pFtnNd;
575cdf0e10cSrcweir 			sal_uInt16 nPos;
576cdf0e10cSrcweir 			rFtnArr.SeekEntry( pStt->nNode, &nPos );
577cdf0e10cSrcweir 			SwTxtFtn* pSrch;
578cdf0e10cSrcweir 
579cdf0e10cSrcweir 			// loesche erstmal alle, die dahinter stehen
580cdf0e10cSrcweir 			while( nPos < rFtnArr.Count() && ( pFtnNd =
581cdf0e10cSrcweir 				&( pSrch = rFtnArr[ nPos ] )->GetTxtNode())->GetIndex()
582cdf0e10cSrcweir 						<= pEnd->nNode.GetIndex() )
583cdf0e10cSrcweir 			{
584cdf0e10cSrcweir 				xub_StrLen nFtnSttIdx = *pSrch->GetStart();
585cdf0e10cSrcweir                 if( (nsDelCntntType::DELCNT_CHKNOCNTNT & nDelCntntType )
586cdf0e10cSrcweir 					? (&pEnd->nNode.GetNode() == pFtnNd )
587cdf0e10cSrcweir 					: (( &pStt->nNode.GetNode() == pFtnNd &&
588cdf0e10cSrcweir 					pStt->nContent.GetIndex() > nFtnSttIdx) ||
589cdf0e10cSrcweir 					( &pEnd->nNode.GetNode() == pFtnNd &&
590cdf0e10cSrcweir 					nFtnSttIdx >= pEnd->nContent.GetIndex() )) )
591cdf0e10cSrcweir 				{
592cdf0e10cSrcweir 					++nPos;		// weiter suchen
593cdf0e10cSrcweir 					continue;
594cdf0e10cSrcweir 				}
595cdf0e10cSrcweir 
596cdf0e10cSrcweir 				// es muss leider ein Index angelegt werden. Sonst knallts im
597cdf0e10cSrcweir 				// TextNode, weil im DTOR der SwFtn dieser geloescht wird !!
598cdf0e10cSrcweir 				SwTxtNode* pTxtNd = (SwTxtNode*)pFtnNd;
599cdf0e10cSrcweir 				if( !pHistory )
600cdf0e10cSrcweir 					pHistory = new SwHistory;
601cdf0e10cSrcweir                 SwTxtAttr* const pFtnHnt =
602cdf0e10cSrcweir                     pTxtNd->GetTxtAttrForCharAt( nFtnSttIdx );
603cdf0e10cSrcweir 				ASSERT( pFtnHnt, "kein FtnAttribut" );
604cdf0e10cSrcweir 				SwIndex aIdx( pTxtNd, nFtnSttIdx );
605cdf0e10cSrcweir                 pHistory->Add( pFtnHnt, pTxtNd->GetIndex(), false );
606cdf0e10cSrcweir                 pTxtNd->EraseText( aIdx, 1 );
607cdf0e10cSrcweir             }
608cdf0e10cSrcweir 
609cdf0e10cSrcweir 			while( nPos-- && ( pFtnNd = &( pSrch = rFtnArr[ nPos ] )->
610cdf0e10cSrcweir 					GetTxtNode())->GetIndex() >= pStt->nNode.GetIndex() )
611cdf0e10cSrcweir 			{
612cdf0e10cSrcweir 				xub_StrLen nFtnSttIdx = *pSrch->GetStart();
613cdf0e10cSrcweir                 if( !(nsDelCntntType::DELCNT_CHKNOCNTNT & nDelCntntType) && (
614cdf0e10cSrcweir 					( &pStt->nNode.GetNode() == pFtnNd &&
615cdf0e10cSrcweir 					pStt->nContent.GetIndex() > nFtnSttIdx ) ||
616cdf0e10cSrcweir 					( &pEnd->nNode.GetNode() == pFtnNd &&
617cdf0e10cSrcweir 					nFtnSttIdx >= pEnd->nContent.GetIndex() )))
618cdf0e10cSrcweir 					continue;				// weiter suchen
619cdf0e10cSrcweir 
620cdf0e10cSrcweir 				// es muss leider ein Index angelegt werden. Sonst knallts im
621cdf0e10cSrcweir 				// TextNode, weil im DTOR der SwFtn dieser geloescht wird !!
622cdf0e10cSrcweir 				SwTxtNode* pTxtNd = (SwTxtNode*)pFtnNd;
623cdf0e10cSrcweir 				if( !pHistory )
624cdf0e10cSrcweir 					pHistory = new SwHistory;
625cdf0e10cSrcweir                 SwTxtAttr* const pFtnHnt =
626cdf0e10cSrcweir                     pTxtNd->GetTxtAttrForCharAt( nFtnSttIdx );
627cdf0e10cSrcweir 				ASSERT( pFtnHnt, "kein FtnAttribut" );
628cdf0e10cSrcweir 				SwIndex aIdx( pTxtNd, nFtnSttIdx );
629cdf0e10cSrcweir                 pHistory->Add( pFtnHnt, pTxtNd->GetIndex(), false );
630cdf0e10cSrcweir                 pTxtNd->EraseText( aIdx, 1 );
631cdf0e10cSrcweir             }
632cdf0e10cSrcweir         }
633cdf0e10cSrcweir     }
634cdf0e10cSrcweir 
635cdf0e10cSrcweir 	// 2. Flys
636cdf0e10cSrcweir     if( nsDelCntntType::DELCNT_FLY & nDelCntntType )
637cdf0e10cSrcweir 	{
638cdf0e10cSrcweir 		sal_uInt16 nChainInsPos = pHistory ? pHistory->Count() : 0;
639cdf0e10cSrcweir 		const SwSpzFrmFmts& rSpzArr = *pDoc->GetSpzFrmFmts();
640cdf0e10cSrcweir 		if( rSpzArr.Count() )
641cdf0e10cSrcweir 		{
642cdf0e10cSrcweir 			const sal_Bool bDelFwrd = rMark.nNode.GetIndex() <= rPoint.nNode.GetIndex();
643cdf0e10cSrcweir 			SwFlyFrmFmt* pFmt;
644cdf0e10cSrcweir 			const SwFmtAnchor* pAnchor;
645cdf0e10cSrcweir 			sal_uInt16 n = rSpzArr.Count();
646cdf0e10cSrcweir 			const SwPosition* pAPos;
647cdf0e10cSrcweir 
648cdf0e10cSrcweir 			while( n && rSpzArr.Count() )
649cdf0e10cSrcweir 			{
650cdf0e10cSrcweir 				pFmt = (SwFlyFrmFmt*)rSpzArr[--n];
651cdf0e10cSrcweir 				pAnchor = &pFmt->GetAnchor();
652cdf0e10cSrcweir 				switch( pAnchor->GetAnchorId() )
653cdf0e10cSrcweir 				{
654cdf0e10cSrcweir                 case FLY_AS_CHAR:
655cdf0e10cSrcweir 					if( 0 != (pAPos = pAnchor->GetCntntAnchor() ) &&
656cdf0e10cSrcweir                         (( nsDelCntntType::DELCNT_CHKNOCNTNT & nDelCntntType )
657cdf0e10cSrcweir 						? ( pStt->nNode <= pAPos->nNode &&
658cdf0e10cSrcweir 							pAPos->nNode < pEnd->nNode )
659cdf0e10cSrcweir 						: ( *pStt <= *pAPos && *pAPos < *pEnd )) )
660cdf0e10cSrcweir 					{
661cdf0e10cSrcweir 						if( !pHistory )
662cdf0e10cSrcweir 							pHistory = new SwHistory;
663cdf0e10cSrcweir                         SwTxtNode *const pTxtNd =
664cdf0e10cSrcweir                             pAPos->nNode.GetNode().GetTxtNode();
665cdf0e10cSrcweir                         SwTxtAttr* const pFlyHnt = pTxtNd->GetTxtAttrForCharAt(
666cdf0e10cSrcweir                             pAPos->nContent.GetIndex());
667cdf0e10cSrcweir 						ASSERT( pFlyHnt, "kein FlyAttribut" );
668cdf0e10cSrcweir                         pHistory->Add( pFlyHnt, 0, false );
669cdf0e10cSrcweir 						// n wieder zurueck, damit nicht ein Format uebesprungen wird !
670cdf0e10cSrcweir 						n = n >= rSpzArr.Count() ? rSpzArr.Count() : n+1;
671cdf0e10cSrcweir 					}
672cdf0e10cSrcweir 					break;
673cdf0e10cSrcweir                 case FLY_AT_PARA:
674cdf0e10cSrcweir                     {
675cdf0e10cSrcweir                         pAPos =  pAnchor->GetCntntAnchor();
676cdf0e10cSrcweir                         if( pAPos )
677cdf0e10cSrcweir                         {
678cdf0e10cSrcweir                             bool bTmp;
679cdf0e10cSrcweir                             if( nsDelCntntType::DELCNT_CHKNOCNTNT & nDelCntntType )
680cdf0e10cSrcweir                                 bTmp = pStt->nNode <= pAPos->nNode && pAPos->nNode < pEnd->nNode;
681cdf0e10cSrcweir                             else
682cdf0e10cSrcweir                             {
683cdf0e10cSrcweir                                 if (bDelFwrd)
684cdf0e10cSrcweir                                     bTmp = rMark.nNode < pAPos->nNode &&
685cdf0e10cSrcweir                                         pAPos->nNode <= rPoint.nNode;
686cdf0e10cSrcweir                                 else
687cdf0e10cSrcweir                                     bTmp = rPoint.nNode <= pAPos->nNode &&
688cdf0e10cSrcweir                                         pAPos->nNode < rMark.nNode;
689cdf0e10cSrcweir                             }
690cdf0e10cSrcweir 
691cdf0e10cSrcweir                             if (bTmp)
692cdf0e10cSrcweir                             {
693cdf0e10cSrcweir                                 if( !pHistory )
694cdf0e10cSrcweir                                     pHistory = new SwHistory;
695cdf0e10cSrcweir 
696cdf0e10cSrcweir                                 // Moving the anchor?
697cdf0e10cSrcweir                                 if( !( nsDelCntntType::DELCNT_CHKNOCNTNT & nDelCntntType ) &&
698cdf0e10cSrcweir                                     ( rPoint.nNode.GetIndex() == pAPos->nNode.GetIndex() ) )
699cdf0e10cSrcweir                                 {
700cdf0e10cSrcweir                                     // Do not try to move the anchor to a table!
701cdf0e10cSrcweir                                     if( rMark.nNode.GetNode().GetTxtNode() )
702cdf0e10cSrcweir                                     {
703cdf0e10cSrcweir                                         pHistory->Add( *pFmt );
704cdf0e10cSrcweir                                         SwFmtAnchor aAnch( *pAnchor );
705cdf0e10cSrcweir                                         SwPosition aPos( rMark.nNode );
706cdf0e10cSrcweir                                         aAnch.SetAnchor( &aPos );
707cdf0e10cSrcweir                                         pFmt->SetFmtAttr( aAnch );
708cdf0e10cSrcweir                                     }
709cdf0e10cSrcweir                                 }
710cdf0e10cSrcweir                                 else
711cdf0e10cSrcweir                                 {
712cdf0e10cSrcweir                                     pHistory->Add( *pFmt, nChainInsPos );
713cdf0e10cSrcweir                                     // n wieder zurueck, damit nicht ein
714cdf0e10cSrcweir                                     // Format uebesprungen wird !
715cdf0e10cSrcweir                                     n = n >= rSpzArr.Count() ?
716cdf0e10cSrcweir                                         rSpzArr.Count() : n+1;
717cdf0e10cSrcweir                                 }
718cdf0e10cSrcweir                             }
719cdf0e10cSrcweir                         }
720cdf0e10cSrcweir                     }
721cdf0e10cSrcweir 					break;
722cdf0e10cSrcweir                 case FLY_AT_CHAR:
723cdf0e10cSrcweir 					if( 0 != (pAPos = pAnchor->GetCntntAnchor() ) &&
724cdf0e10cSrcweir 						( pStt->nNode <= pAPos->nNode && pAPos->nNode <= pEnd->nNode ) )
725cdf0e10cSrcweir 					{
726cdf0e10cSrcweir 						if( !pHistory )
727cdf0e10cSrcweir 							pHistory = new SwHistory;
728cdf0e10cSrcweir                         if (IsDestroyFrameAnchoredAtChar(
729cdf0e10cSrcweir                                 *pAPos, *pStt, *pEnd, nDelCntntType))
730cdf0e10cSrcweir                         {
731cdf0e10cSrcweir 							pHistory->Add( *pFmt, nChainInsPos );
732cdf0e10cSrcweir 							n = n >= rSpzArr.Count() ? rSpzArr.Count() : n+1;
733cdf0e10cSrcweir 						}
734cdf0e10cSrcweir                         else if( !( nsDelCntntType::DELCNT_CHKNOCNTNT & nDelCntntType ) )
735cdf0e10cSrcweir                         {
736cdf0e10cSrcweir                             if( *pStt <= *pAPos && *pAPos < *pEnd )
737cdf0e10cSrcweir                             {
738cdf0e10cSrcweir                                 // These are the objects anchored
739cdf0e10cSrcweir                                 // between section start and end position
740cdf0e10cSrcweir                                 // Do not try to move the anchor to a table!
741cdf0e10cSrcweir                                 if( rMark.nNode.GetNode().GetTxtNode() )
742cdf0e10cSrcweir                                 {
743cdf0e10cSrcweir                                     pHistory->Add( *pFmt );
744cdf0e10cSrcweir                                     SwFmtAnchor aAnch( *pAnchor );
745cdf0e10cSrcweir                                     aAnch.SetAnchor( &rMark );
746cdf0e10cSrcweir                                     pFmt->SetFmtAttr( aAnch );
747cdf0e10cSrcweir                                 }
748cdf0e10cSrcweir                             }
749cdf0e10cSrcweir                         }
750cdf0e10cSrcweir 					}
751cdf0e10cSrcweir 					break;
752cdf0e10cSrcweir 				case FLY_AT_FLY:
753cdf0e10cSrcweir 
754cdf0e10cSrcweir 					if( 0 != (pAPos = pAnchor->GetCntntAnchor() ) &&
755cdf0e10cSrcweir 						pStt->nNode == pAPos->nNode )
756cdf0e10cSrcweir 					{
757cdf0e10cSrcweir 						if( !pHistory )
758cdf0e10cSrcweir 							pHistory = new SwHistory;
759cdf0e10cSrcweir 
760cdf0e10cSrcweir 						pHistory->Add( *pFmt, nChainInsPos );
761cdf0e10cSrcweir 
762cdf0e10cSrcweir 						// n wieder zurueck, damit nicht ein Format uebesprungen wird !
763cdf0e10cSrcweir 						n = n >= rSpzArr.Count() ? rSpzArr.Count() : n+1;
764cdf0e10cSrcweir 					}
765cdf0e10cSrcweir 					break;
766cdf0e10cSrcweir 				default: break;
767cdf0e10cSrcweir 				}
768cdf0e10cSrcweir 			}
769cdf0e10cSrcweir 		}
770cdf0e10cSrcweir 	}
771cdf0e10cSrcweir 
772dec99bbdSOliver-Rainer Wittmann     // 3. Bookmarks
773cdf0e10cSrcweir     if( nsDelCntntType::DELCNT_BKM & nDelCntntType )
774dec99bbdSOliver-Rainer Wittmann     {
775cdf0e10cSrcweir         IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
776dec99bbdSOliver-Rainer Wittmann         if( pMarkAccess->getAllMarksCount() )
777dec99bbdSOliver-Rainer Wittmann         {
778cdf0e10cSrcweir 
779dec99bbdSOliver-Rainer Wittmann             for( sal_uInt16 n = 0; n < pMarkAccess->getAllMarksCount(); ++n )
780dec99bbdSOliver-Rainer Wittmann             {
781cdf0e10cSrcweir                 bool bSavePos = false;
782cdf0e10cSrcweir                 bool bSaveOtherPos = false;
783dec99bbdSOliver-Rainer Wittmann                 const ::sw::mark::IMark* pBkmk = (pMarkAccess->getAllMarksBegin() + n)->get();
784dec99bbdSOliver-Rainer Wittmann 
785cdf0e10cSrcweir                 if( nsDelCntntType::DELCNT_CHKNOCNTNT & nDelCntntType )
786cdf0e10cSrcweir                 {
787dec99bbdSOliver-Rainer Wittmann                     if ( pStt->nNode <= pBkmk->GetMarkPos().nNode
788dec99bbdSOliver-Rainer Wittmann                          && pBkmk->GetMarkPos().nNode < pEnd->nNode )
789dec99bbdSOliver-Rainer Wittmann                     {
790cdf0e10cSrcweir                         bSavePos = true;
791dec99bbdSOliver-Rainer Wittmann                     }
792dec99bbdSOliver-Rainer Wittmann                     if ( pBkmk->IsExpanded()
793dec99bbdSOliver-Rainer Wittmann                          && pStt->nNode <= pBkmk->GetOtherMarkPos().nNode
794dec99bbdSOliver-Rainer Wittmann                          && pBkmk->GetOtherMarkPos().nNode < pEnd->nNode )
795dec99bbdSOliver-Rainer Wittmann                     {
796cdf0e10cSrcweir                         bSaveOtherPos = true;
797dec99bbdSOliver-Rainer Wittmann                     }
798cdf0e10cSrcweir                 }
799cdf0e10cSrcweir                 else
800cdf0e10cSrcweir                 {
801dec99bbdSOliver-Rainer Wittmann                     // keep cross-reference bookmarks, if content inside one paragraph is deleted.
802dec99bbdSOliver-Rainer Wittmann                     if ( rMark.nNode == rPoint.nNode
803dec99bbdSOliver-Rainer Wittmann                          && ( IDocumentMarkAccess::GetType(*pBkmk) == IDocumentMarkAccess::CROSSREF_HEADING_BOOKMARK
804dec99bbdSOliver-Rainer Wittmann                               || IDocumentMarkAccess::GetType(*pBkmk) == IDocumentMarkAccess::CROSSREF_NUMITEM_BOOKMARK ) )
805cdf0e10cSrcweir                     {
806dec99bbdSOliver-Rainer Wittmann                         continue;
807dec99bbdSOliver-Rainer Wittmann                     }
808dec99bbdSOliver-Rainer Wittmann 
809dec99bbdSOliver-Rainer Wittmann                     bool bMaybe = false;
810dec99bbdSOliver-Rainer Wittmann                     if ( *pStt <= pBkmk->GetMarkPos() && pBkmk->GetMarkPos() <= *pEnd )
811dec99bbdSOliver-Rainer Wittmann                     {
812dec99bbdSOliver-Rainer Wittmann                         if ( pBkmk->GetMarkPos() == *pEnd
813dec99bbdSOliver-Rainer Wittmann                              || ( *pStt == pBkmk->GetMarkPos() && pBkmk->IsExpanded() ) )
814dec99bbdSOliver-Rainer Wittmann                             bMaybe = true;
815dec99bbdSOliver-Rainer Wittmann                         else
816dec99bbdSOliver-Rainer Wittmann                             bSavePos = true;
817cdf0e10cSrcweir                     }
818dec99bbdSOliver-Rainer Wittmann                     if( pBkmk->IsExpanded() &&
819dec99bbdSOliver-Rainer Wittmann                         *pStt <= pBkmk->GetOtherMarkPos() && pBkmk->GetOtherMarkPos() <= *pEnd )
820cdf0e10cSrcweir                     {
821dec99bbdSOliver-Rainer Wittmann                         if ( bSavePos || bSaveOtherPos
822dec99bbdSOliver-Rainer Wittmann                              || ( pBkmk->GetOtherMarkPos() < *pEnd && pBkmk->GetOtherMarkPos() > *pStt ) )
823cdf0e10cSrcweir                         {
824dec99bbdSOliver-Rainer Wittmann                             if( bMaybe )
825cdf0e10cSrcweir                                 bSavePos = true;
826dec99bbdSOliver-Rainer Wittmann                             bSaveOtherPos = true;
827cdf0e10cSrcweir                         }
828dec99bbdSOliver-Rainer Wittmann                     }
829dec99bbdSOliver-Rainer Wittmann 
830dec99bbdSOliver-Rainer Wittmann                     if ( !bSavePos && !bSaveOtherPos
831dec99bbdSOliver-Rainer Wittmann                          && dynamic_cast< const ::sw::mark::CrossRefBookmark* >(pBkmk) )
832dec99bbdSOliver-Rainer Wittmann                     {
833dec99bbdSOliver-Rainer Wittmann                         // certain special handling for cross-reference bookmarks
834dec99bbdSOliver-Rainer Wittmann                         const bool bDifferentTxtNodesAtMarkAndPoint =
835dec99bbdSOliver-Rainer Wittmann                             rMark.nNode != rPoint.nNode
836dec99bbdSOliver-Rainer Wittmann                             && rMark.nNode.GetNode().GetTxtNode()
837dec99bbdSOliver-Rainer Wittmann                             && rPoint.nNode.GetNode().GetTxtNode();
838dec99bbdSOliver-Rainer Wittmann                         if ( bDifferentTxtNodesAtMarkAndPoint )
839cdf0e10cSrcweir                         {
840dec99bbdSOliver-Rainer Wittmann                             // delete cross-reference bookmark at <pStt>, if only part of
841dec99bbdSOliver-Rainer Wittmann                             // <pEnd> text node content is deleted.
842dec99bbdSOliver-Rainer Wittmann                             if( pStt->nNode == pBkmk->GetMarkPos().nNode
843dec99bbdSOliver-Rainer Wittmann                                 && pEnd->nContent.GetIndex() != pEnd->nNode.GetNode().GetTxtNode()->Len() )
844dec99bbdSOliver-Rainer Wittmann                             {
845dec99bbdSOliver-Rainer Wittmann                                 bSavePos = true;
846dec99bbdSOliver-Rainer Wittmann                                 bSaveOtherPos = false; // cross-reference bookmarks are not expanded
847dec99bbdSOliver-Rainer Wittmann                             }
848dec99bbdSOliver-Rainer Wittmann                             // delete cross-reference bookmark at <pEnd>, if only part of
849dec99bbdSOliver-Rainer Wittmann                             // <pStt> text node content is deleted.
850dec99bbdSOliver-Rainer Wittmann                             else if( pEnd->nNode == pBkmk->GetMarkPos().nNode &&
851dec99bbdSOliver-Rainer Wittmann                                 pStt->nContent.GetIndex() != 0 )
852cdf0e10cSrcweir                             {
853dec99bbdSOliver-Rainer Wittmann                                 bSavePos = true;
854dec99bbdSOliver-Rainer Wittmann                                 bSaveOtherPos = false; // cross-reference bookmarks are not expanded
855cdf0e10cSrcweir                             }
856cdf0e10cSrcweir                         }
857cdf0e10cSrcweir                     }
858dec99bbdSOliver-Rainer Wittmann                     else if ( IDocumentMarkAccess::GetType(*pBkmk) == IDocumentMarkAccess::ANNOTATIONMARK )
859cdf0e10cSrcweir                     {
860dec99bbdSOliver-Rainer Wittmann                         // delete annotation marks, if its end position is covered by the deletion
861dec99bbdSOliver-Rainer Wittmann                         const SwPosition& rAnnotationEndPos = pBkmk->GetMarkEnd();
862dec99bbdSOliver-Rainer Wittmann                         if ( *pStt < rAnnotationEndPos && rAnnotationEndPos <= *pEnd )
863cdf0e10cSrcweir                         {
864cdf0e10cSrcweir                             bSavePos = true;
865dec99bbdSOliver-Rainer Wittmann                             bSaveOtherPos = true;
866cdf0e10cSrcweir                         }
867cdf0e10cSrcweir                     }
868cdf0e10cSrcweir                 }
869cdf0e10cSrcweir 
870dec99bbdSOliver-Rainer Wittmann                 if ( bSavePos || bSaveOtherPos )
871dec99bbdSOliver-Rainer Wittmann                 {
872dec99bbdSOliver-Rainer Wittmann                     if( !pHistory )
873dec99bbdSOliver-Rainer Wittmann                         pHistory = new SwHistory;
874dec99bbdSOliver-Rainer Wittmann 
875dec99bbdSOliver-Rainer Wittmann                     pHistory->Add( *pBkmk, bSavePos, bSaveOtherPos );
876dec99bbdSOliver-Rainer Wittmann                     if ( bSavePos
877dec99bbdSOliver-Rainer Wittmann                          && ( bSaveOtherPos
878dec99bbdSOliver-Rainer Wittmann                               || !pBkmk->IsExpanded() ) )
879cdf0e10cSrcweir                     {
880dec99bbdSOliver-Rainer Wittmann                         pMarkAccess->deleteMark(pMarkAccess->getAllMarksBegin()+n);
881cdf0e10cSrcweir                         n--;
882cdf0e10cSrcweir                     }
883dec99bbdSOliver-Rainer Wittmann                 }
884dec99bbdSOliver-Rainer Wittmann             }
885dec99bbdSOliver-Rainer Wittmann         }
886dec99bbdSOliver-Rainer Wittmann     }
887cdf0e10cSrcweir }
888cdf0e10cSrcweir 
889cdf0e10cSrcweir 
890cdf0e10cSrcweir // sicher eine vollstaendige Section im Undo-Nodes-Array
891cdf0e10cSrcweir 
SwUndoSaveSection()892cdf0e10cSrcweir SwUndoSaveSection::SwUndoSaveSection()
893cdf0e10cSrcweir 	: pMvStt( 0 ), pRedlSaveData( 0 ), nMvLen( 0 ), nStartPos( ULONG_MAX )
894cdf0e10cSrcweir {
895cdf0e10cSrcweir }
896cdf0e10cSrcweir 
~SwUndoSaveSection()897cdf0e10cSrcweir SwUndoSaveSection::~SwUndoSaveSection()
898cdf0e10cSrcweir {
899cdf0e10cSrcweir 	if( pMvStt )		// loesche noch den Bereich aus dem UndoNodes Array
900cdf0e10cSrcweir 	{
901cdf0e10cSrcweir 		// SaveSection speichert den Inhalt in der PostIt-Section
902cdf0e10cSrcweir 		SwNodes& rUNds = pMvStt->GetNode().GetNodes();
903cdf0e10cSrcweir 		rUNds.Delete( *pMvStt, nMvLen );
904cdf0e10cSrcweir 
905cdf0e10cSrcweir 		delete pMvStt;
906cdf0e10cSrcweir 	}
907cdf0e10cSrcweir 	delete pRedlSaveData;
908cdf0e10cSrcweir }
909cdf0e10cSrcweir 
SaveSection(SwDoc * pDoc,const SwNodeIndex & rSttIdx)910cdf0e10cSrcweir void SwUndoSaveSection::SaveSection( SwDoc* pDoc, const SwNodeIndex& rSttIdx )
911cdf0e10cSrcweir {
912cdf0e10cSrcweir 	SwNodeRange aRg( rSttIdx.GetNode(), *rSttIdx.GetNode().EndOfSectionNode() );
913cdf0e10cSrcweir 	SaveSection( pDoc, aRg );
914cdf0e10cSrcweir }
915cdf0e10cSrcweir 
916cdf0e10cSrcweir 
SaveSection(SwDoc * pDoc,const SwNodeRange & rRange)917332f371aSOliver-Rainer Wittmann void SwUndoSaveSection::SaveSection(
918332f371aSOliver-Rainer Wittmann     SwDoc* pDoc,
919332f371aSOliver-Rainer Wittmann     const SwNodeRange& rRange )
920cdf0e10cSrcweir {
921332f371aSOliver-Rainer Wittmann     SwPaM aPam( rRange.aStart, rRange.aEnd );
922cdf0e10cSrcweir 
923332f371aSOliver-Rainer Wittmann     // delete all footnotes, fly frames, bookmarks and indexes
924332f371aSOliver-Rainer Wittmann     DelCntntIndex( *aPam.GetMark(), *aPam.GetPoint() );
925332f371aSOliver-Rainer Wittmann     {
926332f371aSOliver-Rainer Wittmann         // move certain indexes out of deleted range
927332f371aSOliver-Rainer Wittmann         SwNodeIndex aSttIdx( aPam.Start()->nNode.GetNode() );
928332f371aSOliver-Rainer Wittmann         SwNodeIndex aEndIdx( aPam.End()->nNode.GetNode() );
929332f371aSOliver-Rainer Wittmann         SwNodeIndex aMvStt( aEndIdx, 1 );
930332f371aSOliver-Rainer Wittmann         pDoc->CorrAbs( aSttIdx, aEndIdx, SwPosition( aMvStt ), sal_True );
931332f371aSOliver-Rainer Wittmann     }
932cdf0e10cSrcweir 
933cdf0e10cSrcweir 	pRedlSaveData = new SwRedlineSaveDatas;
934cdf0e10cSrcweir 	if( !SwUndo::FillSaveData( aPam, *pRedlSaveData, sal_True, sal_True ))
935cdf0e10cSrcweir 		delete pRedlSaveData, pRedlSaveData = 0;
936cdf0e10cSrcweir 
937cdf0e10cSrcweir 	nStartPos = rRange.aStart.GetIndex();
938cdf0e10cSrcweir 
939cdf0e10cSrcweir 	aPam.GetPoint()->nNode--;
940cdf0e10cSrcweir 	aPam.GetMark()->nNode++;
941cdf0e10cSrcweir 
942cdf0e10cSrcweir 	SwCntntNode* pCNd = aPam.GetCntntNode( sal_False );
943cdf0e10cSrcweir 	if( pCNd )
944cdf0e10cSrcweir 		aPam.GetMark()->nContent.Assign( pCNd, 0 );
945cdf0e10cSrcweir 	if( 0 != ( pCNd = aPam.GetCntntNode( sal_True )) )
946cdf0e10cSrcweir 		aPam.GetPoint()->nContent.Assign( pCNd, pCNd->Len() );
947cdf0e10cSrcweir 
948cdf0e10cSrcweir 	// Positionen als SwIndex merken, damit im DTOR dieser Bereich
949cdf0e10cSrcweir 	// entfernt werden kann !!
950cdf0e10cSrcweir 	sal_uLong nEnd;
951cdf0e10cSrcweir 	pMvStt = new SwNodeIndex( rRange.aStart );
952cdf0e10cSrcweir 	MoveToUndoNds( aPam, pMvStt, 0, &nEnd, 0 );
953cdf0e10cSrcweir 	nMvLen = nEnd - pMvStt->GetIndex() + 1;
954cdf0e10cSrcweir }
955cdf0e10cSrcweir 
RestoreSection(SwDoc * pDoc,SwNodeIndex * pIdx,sal_uInt16 nSectType)956cdf0e10cSrcweir void SwUndoSaveSection::RestoreSection( SwDoc* pDoc, SwNodeIndex* pIdx,
957cdf0e10cSrcweir 										sal_uInt16 nSectType )
958cdf0e10cSrcweir {
959cdf0e10cSrcweir 	if( ULONG_MAX != nStartPos )		// gab es ueberhaupt Inhalt ?
960cdf0e10cSrcweir 	{
961cdf0e10cSrcweir 		// ueberpruefe, ob der Inhalt an der alten Position steht
962cdf0e10cSrcweir 		SwNodeIndex aSttIdx( pDoc->GetNodes(), nStartPos );
963cdf0e10cSrcweir         OSL_ENSURE(!aSttIdx.GetNode().GetCntntNode(),
964cdf0e10cSrcweir                 "RestoreSection(): Position on content node");
965cdf0e10cSrcweir 
966cdf0e10cSrcweir 		// move den Inhalt aus dem UndoNodes-Array in den Fly
967cdf0e10cSrcweir 		SwStartNode* pSttNd = pDoc->GetNodes().MakeEmptySection( aSttIdx,
968cdf0e10cSrcweir 												(SwStartNodeType)nSectType );
969cdf0e10cSrcweir 
970cdf0e10cSrcweir 		RestoreSection( pDoc, SwNodeIndex( *pSttNd->EndOfSectionNode() ));
971cdf0e10cSrcweir 
972cdf0e10cSrcweir 		if( pIdx )
973cdf0e10cSrcweir 			*pIdx = *pSttNd;
974cdf0e10cSrcweir 	}
975cdf0e10cSrcweir }
976cdf0e10cSrcweir 
RestoreSection(SwDoc * pDoc,const SwNodeIndex & rInsPos)977cdf0e10cSrcweir void SwUndoSaveSection::RestoreSection( SwDoc* pDoc, const SwNodeIndex& rInsPos )
978cdf0e10cSrcweir {
979cdf0e10cSrcweir 	if( ULONG_MAX != nStartPos )		// gab es ueberhaupt Inhalt ?
980cdf0e10cSrcweir 	{
981cdf0e10cSrcweir 		SwPosition aInsPos( rInsPos );
982cdf0e10cSrcweir 		sal_uLong nEnd = pMvStt->GetIndex() + nMvLen - 1;
983cdf0e10cSrcweir 		MoveFromUndoNds( *pDoc, pMvStt->GetIndex(), 0, aInsPos, &nEnd, 0 );
984cdf0e10cSrcweir 
985cdf0e10cSrcweir 		// Indizies wieder zerstoren, Inhalt ist aus dem UndoNodes-Array
986cdf0e10cSrcweir 		// entfernt worden.
987cdf0e10cSrcweir 		DELETEZ( pMvStt );
988cdf0e10cSrcweir 		nMvLen = 0;
989cdf0e10cSrcweir 
990cdf0e10cSrcweir 		if( pRedlSaveData )
991cdf0e10cSrcweir 		{
992cdf0e10cSrcweir 			SwUndo::SetSaveData( *pDoc, *pRedlSaveData );
993cdf0e10cSrcweir 			delete pRedlSaveData, pRedlSaveData = 0;
994cdf0e10cSrcweir 		}
995cdf0e10cSrcweir 	}
996cdf0e10cSrcweir }
997cdf0e10cSrcweir 
998cdf0e10cSrcweir 		// sicher und setze die RedlineDaten
999cdf0e10cSrcweir 
SwRedlineSaveData(SwComparePosition eCmpPos,const SwPosition & rSttPos,const SwPosition & rEndPos,SwRedline & rRedl,sal_Bool bCopyNext)1000641de097SOliver-Rainer Wittmann SwRedlineSaveData::SwRedlineSaveData(
1001641de097SOliver-Rainer Wittmann     SwComparePosition eCmpPos,
1002641de097SOliver-Rainer Wittmann     const SwPosition& rSttPos,
1003641de097SOliver-Rainer Wittmann     const SwPosition& rEndPos,
1004*bdf72556SOliver-Rainer Wittmann     SwRedline& rRedl,
1005*bdf72556SOliver-Rainer Wittmann     sal_Bool bCopyNext )
1006641de097SOliver-Rainer Wittmann     : SwUndRng( rRedl )
1007*bdf72556SOliver-Rainer Wittmann     , SwRedlineData( rRedl.GetRedlineData(), bCopyNext )
1008cdf0e10cSrcweir {
1009641de097SOliver-Rainer Wittmann     ASSERT( POS_OUTSIDE == eCmpPos || !rRedl.GetContentIdx(), "Redline mit Content" );
1010cdf0e10cSrcweir 
1011641de097SOliver-Rainer Wittmann     switch (eCmpPos)
1012641de097SOliver-Rainer Wittmann     {
1013641de097SOliver-Rainer Wittmann     case POS_OVERLAP_BEFORE:		// Pos1 ueberlappt Pos2 am Anfang
1014641de097SOliver-Rainer Wittmann         nEndNode = rEndPos.nNode.GetIndex();
1015641de097SOliver-Rainer Wittmann         nEndCntnt = rEndPos.nContent.GetIndex();
1016641de097SOliver-Rainer Wittmann         break;
1017*bdf72556SOliver-Rainer Wittmann 
1018641de097SOliver-Rainer Wittmann     case POS_OVERLAP_BEHIND: 		// Pos1 ueberlappt Pos2 am Ende
1019641de097SOliver-Rainer Wittmann         nSttNode = rSttPos.nNode.GetIndex();
1020641de097SOliver-Rainer Wittmann         nSttCntnt = rSttPos.nContent.GetIndex();
1021641de097SOliver-Rainer Wittmann         break;
1022641de097SOliver-Rainer Wittmann 
1023641de097SOliver-Rainer Wittmann     case POS_INSIDE:				// Pos1 liegt vollstaendig in Pos2
1024641de097SOliver-Rainer Wittmann         nSttNode = rSttPos.nNode.GetIndex();
1025641de097SOliver-Rainer Wittmann         nSttCntnt = rSttPos.nContent.GetIndex();
1026641de097SOliver-Rainer Wittmann         nEndNode = rEndPos.nNode.GetIndex();
1027641de097SOliver-Rainer Wittmann         nEndCntnt = rEndPos.nContent.GetIndex();
1028641de097SOliver-Rainer Wittmann         break;
1029641de097SOliver-Rainer Wittmann 
1030641de097SOliver-Rainer Wittmann     case POS_OUTSIDE:				// Pos2 liegt vollstaendig in Pos1
1031641de097SOliver-Rainer Wittmann         if ( rRedl.GetContentIdx() )
1032641de097SOliver-Rainer Wittmann         {
1033641de097SOliver-Rainer Wittmann             // dann den Bereich ins UndoArray verschieben und merken
1034641de097SOliver-Rainer Wittmann             SaveSection( rRedl.GetDoc(), *rRedl.GetContentIdx() );
1035641de097SOliver-Rainer Wittmann             rRedl.SetContentIdx( 0 );
1036641de097SOliver-Rainer Wittmann         }
1037641de097SOliver-Rainer Wittmann         break;
1038cdf0e10cSrcweir 
1039641de097SOliver-Rainer Wittmann     case POS_EQUAL:					// Pos1 ist genauso gross wie Pos2
1040641de097SOliver-Rainer Wittmann         break;
1041cdf0e10cSrcweir 
1042641de097SOliver-Rainer Wittmann     default:
1043641de097SOliver-Rainer Wittmann         ASSERT( !this, "keine gueltigen Daten!" )
1044641de097SOliver-Rainer Wittmann     }
1045cdf0e10cSrcweir 
1046cdf0e10cSrcweir #ifdef DBG_UTIL
1047cdf0e10cSrcweir     nRedlineCount = rSttPos.nNode.GetNode().GetDoc()->GetRedlineTbl().Count();
1048cdf0e10cSrcweir #endif
1049cdf0e10cSrcweir }
1050cdf0e10cSrcweir 
~SwRedlineSaveData()1051cdf0e10cSrcweir SwRedlineSaveData::~SwRedlineSaveData()
1052cdf0e10cSrcweir {
1053cdf0e10cSrcweir }
1054cdf0e10cSrcweir 
RedlineToDoc(SwPaM & rPam)1055cdf0e10cSrcweir void SwRedlineSaveData::RedlineToDoc( SwPaM& rPam )
1056cdf0e10cSrcweir {
1057cdf0e10cSrcweir 	SwDoc& rDoc = *rPam.GetDoc();
1058cdf0e10cSrcweir 	SwRedline* pRedl = new SwRedline( *this, rPam );
1059cdf0e10cSrcweir 
1060cdf0e10cSrcweir 	if( GetMvSttIdx() )
1061cdf0e10cSrcweir 	{
1062cdf0e10cSrcweir 		SwNodeIndex aIdx( rDoc.GetNodes() );
1063cdf0e10cSrcweir 		RestoreSection( &rDoc, &aIdx, SwNormalStartNode );
1064cdf0e10cSrcweir 		if( GetHistory() )
1065cdf0e10cSrcweir 			GetHistory()->Rollback( &rDoc );
1066cdf0e10cSrcweir 		pRedl->SetContentIdx( &aIdx );
1067cdf0e10cSrcweir 	}
1068cdf0e10cSrcweir 	SetPaM( *pRedl );
1069cdf0e10cSrcweir 	// erstmal die "alten" entfernen, damit im Append keine unerwarteten
1070cdf0e10cSrcweir 	// Dinge passieren, wie z.B. eine Delete in eigenen Insert. Dann wird
1071cdf0e10cSrcweir 	// naehmlich das gerade restaurierte wieder geloescht - nicht das gewollte
1072cdf0e10cSrcweir     rDoc.DeleteRedline( *pRedl, false, USHRT_MAX );
1073cdf0e10cSrcweir 
1074cdf0e10cSrcweir     RedlineMode_t eOld = rDoc.GetRedlineMode();
1075cdf0e10cSrcweir     rDoc.SetRedlineMode_intern((RedlineMode_t)(eOld | nsRedlineMode_t::REDLINE_DONTCOMBINE_REDLINES));
1076cdf0e10cSrcweir 	//#i92154# let UI know about a new redline with comment
1077cdf0e10cSrcweir 	if (rDoc.GetDocShell() && (pRedl->GetComment() != String(::rtl::OUString::createFromAscii(""))) )
1078cdf0e10cSrcweir 		rDoc.GetDocShell()->Broadcast(SwRedlineHint(pRedl,SWREDLINE_INSERTED));
1079cdf0e10cSrcweir 	//
1080cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0
1081cdf0e10cSrcweir     bool const bSuccess =
1082cdf0e10cSrcweir #endif
1083cdf0e10cSrcweir         rDoc.AppendRedline( pRedl, true );
1084cdf0e10cSrcweir     OSL_ENSURE(bSuccess,
1085cdf0e10cSrcweir         "SwRedlineSaveData::RedlineToDoc: insert redline failed");
1086cdf0e10cSrcweir 	rDoc.SetRedlineMode_intern( eOld );
1087cdf0e10cSrcweir }
1088cdf0e10cSrcweir 
1089*bdf72556SOliver-Rainer Wittmann 
FillSaveData(const SwPaM & rRange,SwRedlineSaveDatas & rSData,sal_Bool bDelRange,sal_Bool bCopyNext)1090641de097SOliver-Rainer Wittmann sal_Bool SwUndo::FillSaveData(
1091641de097SOliver-Rainer Wittmann     const SwPaM& rRange,
1092641de097SOliver-Rainer Wittmann     SwRedlineSaveDatas& rSData,
1093641de097SOliver-Rainer Wittmann     sal_Bool bDelRange,
1094641de097SOliver-Rainer Wittmann     sal_Bool bCopyNext )
1095cdf0e10cSrcweir {
1096641de097SOliver-Rainer Wittmann     if ( rSData.Count() )
1097641de097SOliver-Rainer Wittmann     {
1098641de097SOliver-Rainer Wittmann         rSData.DeleteAndDestroy( 0, rSData.Count() );
1099641de097SOliver-Rainer Wittmann     }
1100cdf0e10cSrcweir 
1101641de097SOliver-Rainer Wittmann     SwRedlineSaveData* pNewData;
1102641de097SOliver-Rainer Wittmann     const SwPosition* pStt = rRange.Start();
1103641de097SOliver-Rainer Wittmann     const SwPosition* pEnd = rRange.End();
1104641de097SOliver-Rainer Wittmann     const SwRedlineTbl& rTbl = rRange.GetDoc()->GetRedlineTbl();
1105641de097SOliver-Rainer Wittmann     sal_uInt16 n = 0;
1106641de097SOliver-Rainer Wittmann     rRange.GetDoc()->GetRedline( *pStt, &n );
1107641de097SOliver-Rainer Wittmann     for ( ; n < rTbl.Count(); ++n )
1108641de097SOliver-Rainer Wittmann     {
1109641de097SOliver-Rainer Wittmann         SwRedline* pRedl = rTbl[n];
1110*bdf72556SOliver-Rainer Wittmann 
1111641de097SOliver-Rainer Wittmann         const SwComparePosition eCmpPos =
1112641de097SOliver-Rainer Wittmann             ComparePosition( *pStt, *pEnd, *pRedl->Start(), *pRedl->End() );
1113641de097SOliver-Rainer Wittmann         if ( eCmpPos != POS_BEFORE
1114641de097SOliver-Rainer Wittmann              && eCmpPos != POS_BEHIND
1115641de097SOliver-Rainer Wittmann              && eCmpPos != POS_COLLIDE_END
1116641de097SOliver-Rainer Wittmann              && eCmpPos != POS_COLLIDE_START )
1117641de097SOliver-Rainer Wittmann         {
1118*bdf72556SOliver-Rainer Wittmann             pNewData = new SwRedlineSaveData( eCmpPos, *pStt, *pEnd, *pRedl, bCopyNext );
1119641de097SOliver-Rainer Wittmann             rSData.Insert( pNewData, rSData.Count() );
1120641de097SOliver-Rainer Wittmann         }
1121641de097SOliver-Rainer Wittmann     }
1122641de097SOliver-Rainer Wittmann     if ( rSData.Count() && bDelRange )
1123*bdf72556SOliver-Rainer Wittmann     {
1124cdf0e10cSrcweir         rRange.GetDoc()->DeleteRedline( rRange, false, USHRT_MAX );
1125*bdf72556SOliver-Rainer Wittmann     }
1126641de097SOliver-Rainer Wittmann     return 0 != rSData.Count();
1127cdf0e10cSrcweir }
1128cdf0e10cSrcweir 
1129*bdf72556SOliver-Rainer Wittmann 
FillSaveDataForFmt(const SwPaM & rRange,SwRedlineSaveDatas & rSData)1130641de097SOliver-Rainer Wittmann sal_Bool SwUndo::FillSaveDataForFmt(
1131641de097SOliver-Rainer Wittmann     const SwPaM& rRange,
1132641de097SOliver-Rainer Wittmann     SwRedlineSaveDatas& rSData )
1133cdf0e10cSrcweir {
1134641de097SOliver-Rainer Wittmann     if ( rSData.Count() )
1135*bdf72556SOliver-Rainer Wittmann     {
1136641de097SOliver-Rainer Wittmann         rSData.DeleteAndDestroy( 0, rSData.Count() );
1137*bdf72556SOliver-Rainer Wittmann     }
1138641de097SOliver-Rainer Wittmann 
1139641de097SOliver-Rainer Wittmann     SwRedlineSaveData* pNewData;
1140641de097SOliver-Rainer Wittmann     const SwPosition *pStt = rRange.Start(), *pEnd = rRange.End();
1141641de097SOliver-Rainer Wittmann     const SwRedlineTbl& rTbl = rRange.GetDoc()->GetRedlineTbl();
1142641de097SOliver-Rainer Wittmann     sal_uInt16 n = 0;
1143641de097SOliver-Rainer Wittmann     rRange.GetDoc()->GetRedline( *pStt, &n );
1144641de097SOliver-Rainer Wittmann     for ( ; n < rTbl.Count(); ++n )
1145641de097SOliver-Rainer Wittmann     {
1146641de097SOliver-Rainer Wittmann         SwRedline* pRedl = rTbl[n];
1147641de097SOliver-Rainer Wittmann         if ( nsRedlineType_t::REDLINE_FORMAT == pRedl->GetType() )
1148641de097SOliver-Rainer Wittmann         {
1149*bdf72556SOliver-Rainer Wittmann             const SwComparePosition eCmpPos = ComparePosition( *pStt, *pEnd, *pRedl->Start(), *pRedl->End() );
1150*bdf72556SOliver-Rainer Wittmann             if ( eCmpPos != POS_BEFORE
1151*bdf72556SOliver-Rainer Wittmann                  && eCmpPos != POS_BEHIND
1152*bdf72556SOliver-Rainer Wittmann                  && eCmpPos != POS_COLLIDE_END
1153*bdf72556SOliver-Rainer Wittmann                  && eCmpPos != POS_COLLIDE_START )
1154641de097SOliver-Rainer Wittmann             {
1155*bdf72556SOliver-Rainer Wittmann                 pNewData = new SwRedlineSaveData( eCmpPos, *pStt, *pEnd, *pRedl, sal_True );
1156641de097SOliver-Rainer Wittmann                 rSData.Insert( pNewData, rSData.Count() );
1157641de097SOliver-Rainer Wittmann             }
1158cdf0e10cSrcweir 
1159641de097SOliver-Rainer Wittmann         }
1160641de097SOliver-Rainer Wittmann     }
1161641de097SOliver-Rainer Wittmann     return 0 != rSData.Count();
1162cdf0e10cSrcweir }
1163cdf0e10cSrcweir 
1164*bdf72556SOliver-Rainer Wittmann 
SetSaveData(SwDoc & rDoc,const SwRedlineSaveDatas & rSData)1165cdf0e10cSrcweir void SwUndo::SetSaveData( SwDoc& rDoc, const SwRedlineSaveDatas& rSData )
1166cdf0e10cSrcweir {
1167cdf0e10cSrcweir     RedlineMode_t eOld = rDoc.GetRedlineMode();
1168cdf0e10cSrcweir     rDoc.SetRedlineMode_intern( (RedlineMode_t)(( eOld & ~nsRedlineMode_t::REDLINE_IGNORE) | nsRedlineMode_t::REDLINE_ON ));
1169cdf0e10cSrcweir 	SwPaM aPam( rDoc.GetNodes().GetEndOfContent() );
1170cdf0e10cSrcweir 
1171cdf0e10cSrcweir 	for( sal_uInt16 n = rSData.Count(); n; )
1172cdf0e10cSrcweir 		rSData[ --n ]->RedlineToDoc( aPam );
1173cdf0e10cSrcweir 
1174cdf0e10cSrcweir     // check redline count against count saved in RedlineSaveData object
1175cdf0e10cSrcweir     DBG_ASSERT( (rSData.Count() == 0) ||
1176cdf0e10cSrcweir                 (rSData[0]->nRedlineCount == rDoc.GetRedlineTbl().Count()),
1177cdf0e10cSrcweir                 "redline count not restored properly" );
1178cdf0e10cSrcweir 
1179cdf0e10cSrcweir 	rDoc.SetRedlineMode_intern( eOld );
1180cdf0e10cSrcweir }
1181cdf0e10cSrcweir 
HasHiddenRedlines(const SwRedlineSaveDatas & rSData)1182cdf0e10cSrcweir sal_Bool SwUndo::HasHiddenRedlines( const SwRedlineSaveDatas& rSData )
1183cdf0e10cSrcweir {
1184cdf0e10cSrcweir 	for( sal_uInt16 n = rSData.Count(); n; )
1185cdf0e10cSrcweir 		if( rSData[ --n ]->GetMvSttIdx() )
1186cdf0e10cSrcweir 			return sal_True;
1187cdf0e10cSrcweir 	return sal_False;
1188cdf0e10cSrcweir }
1189cdf0e10cSrcweir 
CanRedlineGroup(SwRedlineSaveDatas & rCurr,const SwRedlineSaveDatas & rCheck,sal_Bool bCurrIsEnd)1190cdf0e10cSrcweir sal_Bool SwUndo::CanRedlineGroup( SwRedlineSaveDatas& rCurr,
1191cdf0e10cSrcweir 						const SwRedlineSaveDatas& rCheck, sal_Bool bCurrIsEnd )
1192cdf0e10cSrcweir {
1193cdf0e10cSrcweir 	sal_Bool bRet = sal_False;
1194cdf0e10cSrcweir 	sal_uInt16 n;
1195cdf0e10cSrcweir 
1196cdf0e10cSrcweir 	if( rCurr.Count() == rCheck.Count() )
1197cdf0e10cSrcweir 	{
1198cdf0e10cSrcweir 		bRet = sal_True;
1199cdf0e10cSrcweir 		for( n = 0; n < rCurr.Count(); ++n )
1200cdf0e10cSrcweir 		{
1201cdf0e10cSrcweir 			const SwRedlineSaveData& rSet = *rCurr[ n ];
1202cdf0e10cSrcweir 			const SwRedlineSaveData& rGet = *rCheck[ n ];
1203cdf0e10cSrcweir 			if( rSet.nSttNode != rGet.nSttNode ||
1204cdf0e10cSrcweir 				rSet.GetMvSttIdx() || rGet.GetMvSttIdx() ||
1205cdf0e10cSrcweir 				( bCurrIsEnd ? rSet.nSttCntnt != rGet.nEndCntnt
1206cdf0e10cSrcweir 							 : rSet.nEndCntnt != rGet.nSttCntnt ) ||
1207cdf0e10cSrcweir 				!rGet.CanCombine( rSet ) )
1208cdf0e10cSrcweir 			{
1209cdf0e10cSrcweir 				bRet = sal_False;
1210cdf0e10cSrcweir 				break;
1211cdf0e10cSrcweir 			}
1212cdf0e10cSrcweir 		}
1213cdf0e10cSrcweir 
1214cdf0e10cSrcweir 		if( bRet )
1215cdf0e10cSrcweir 			for( n = 0; n < rCurr.Count(); ++n )
1216cdf0e10cSrcweir 			{
1217cdf0e10cSrcweir 				SwRedlineSaveData& rSet = *rCurr[ n ];
1218cdf0e10cSrcweir 				const SwRedlineSaveData& rGet = *rCheck[ n ];
1219cdf0e10cSrcweir 				if( bCurrIsEnd )
1220cdf0e10cSrcweir 					rSet.nSttCntnt = rGet.nSttCntnt;
1221cdf0e10cSrcweir 				else
1222cdf0e10cSrcweir 					rSet.nEndCntnt = rGet.nEndCntnt;
1223cdf0e10cSrcweir 			}
1224cdf0e10cSrcweir 	}
1225cdf0e10cSrcweir 	return bRet;
1226cdf0e10cSrcweir }
1227cdf0e10cSrcweir 
1228cdf0e10cSrcweir // #111827#
ShortenString(const String & rStr,xub_StrLen nLength,const String & rFillStr)1229cdf0e10cSrcweir String ShortenString(const String & rStr, xub_StrLen nLength, const String & rFillStr)
1230cdf0e10cSrcweir {
1231cdf0e10cSrcweir     ASSERT( nLength - rFillStr.Len() >= 2, "improper arguments")
1232cdf0e10cSrcweir 
1233cdf0e10cSrcweir     String aResult;
1234cdf0e10cSrcweir 
1235cdf0e10cSrcweir     if (rStr.Len() <= nLength)
1236cdf0e10cSrcweir         aResult = rStr;
1237cdf0e10cSrcweir     else
1238cdf0e10cSrcweir     {
1239cdf0e10cSrcweir         long nTmpLength = nLength - rFillStr.Len();
1240cdf0e10cSrcweir         if ( nTmpLength < 2 )
1241cdf0e10cSrcweir             nTmpLength = 2;
1242cdf0e10cSrcweir 
1243cdf0e10cSrcweir         nLength = static_cast<xub_StrLen>(nTmpLength);
1244cdf0e10cSrcweir 
1245cdf0e10cSrcweir         const xub_StrLen nFrontLen = nLength - nLength / 2;
1246cdf0e10cSrcweir         const xub_StrLen nBackLen = nLength - nFrontLen;
1247cdf0e10cSrcweir 
1248cdf0e10cSrcweir         aResult += rStr.Copy(0, nFrontLen);
1249cdf0e10cSrcweir         aResult += rFillStr;
1250cdf0e10cSrcweir         aResult += rStr.Copy(rStr.Len() - nBackLen, nBackLen);
1251cdf0e10cSrcweir     }
1252cdf0e10cSrcweir 
1253cdf0e10cSrcweir     return aResult;
1254cdf0e10cSrcweir }
1255cdf0e10cSrcweir 
lcl_IsSpecialCharacter(sal_Unicode nChar)1256cdf0e10cSrcweir static bool lcl_IsSpecialCharacter(sal_Unicode nChar)
1257cdf0e10cSrcweir {
1258cdf0e10cSrcweir     switch (nChar)
1259cdf0e10cSrcweir     {
1260cdf0e10cSrcweir     case CH_TXTATR_BREAKWORD:
1261cdf0e10cSrcweir     case CH_TXTATR_INWORD:
1262cdf0e10cSrcweir     case CH_TXTATR_TAB:
1263cdf0e10cSrcweir     case CH_TXTATR_NEWLINE:
1264cdf0e10cSrcweir         return true;
1265cdf0e10cSrcweir 
1266cdf0e10cSrcweir     default:
1267cdf0e10cSrcweir         break;
1268cdf0e10cSrcweir     }
1269cdf0e10cSrcweir 
1270cdf0e10cSrcweir     return false;
1271cdf0e10cSrcweir }
1272cdf0e10cSrcweir 
lcl_DenotedPortion(String rStr,xub_StrLen nStart,xub_StrLen nEnd)1273cdf0e10cSrcweir static String lcl_DenotedPortion(String rStr, xub_StrLen nStart,
1274cdf0e10cSrcweir                                  xub_StrLen nEnd)
1275cdf0e10cSrcweir {
1276cdf0e10cSrcweir     String aResult;
1277cdf0e10cSrcweir 
1278cdf0e10cSrcweir     if (nEnd - nStart > 0)
1279cdf0e10cSrcweir     {
1280cdf0e10cSrcweir         sal_Unicode cLast = rStr.GetChar(nEnd - 1);
1281cdf0e10cSrcweir         if (lcl_IsSpecialCharacter(cLast))
1282cdf0e10cSrcweir         {
1283cdf0e10cSrcweir             switch(cLast)
1284cdf0e10cSrcweir             {
1285cdf0e10cSrcweir             case CH_TXTATR_TAB:
1286cdf0e10cSrcweir                 aResult += String(SW_RES(STR_UNDO_TABS));
1287cdf0e10cSrcweir 
1288cdf0e10cSrcweir                 break;
1289cdf0e10cSrcweir             case CH_TXTATR_NEWLINE:
1290cdf0e10cSrcweir                 aResult += String(SW_RES(STR_UNDO_NLS));
1291cdf0e10cSrcweir 
1292cdf0e10cSrcweir                 break;
1293cdf0e10cSrcweir 
1294cdf0e10cSrcweir             case CH_TXTATR_INWORD:
1295cdf0e10cSrcweir             case CH_TXTATR_BREAKWORD:
1296cdf0e10cSrcweir                 aResult += UNDO_ARG2;
1297cdf0e10cSrcweir 
1298cdf0e10cSrcweir                 break;
1299cdf0e10cSrcweir 
1300cdf0e10cSrcweir             }
1301cdf0e10cSrcweir             SwRewriter aRewriter;
1302cdf0e10cSrcweir             aRewriter.AddRule(UNDO_ARG1,
1303cdf0e10cSrcweir                               String::CreateFromInt32(nEnd - nStart));
1304cdf0e10cSrcweir             aResult = aRewriter.Apply(aResult);
1305cdf0e10cSrcweir         }
1306cdf0e10cSrcweir         else
1307cdf0e10cSrcweir         {
1308cdf0e10cSrcweir             aResult = String(SW_RES(STR_START_QUOTE));
1309cdf0e10cSrcweir             aResult += rStr.Copy(nStart, nEnd - nStart);
1310cdf0e10cSrcweir             aResult += String(SW_RES(STR_END_QUOTE));
1311cdf0e10cSrcweir         }
1312cdf0e10cSrcweir     }
1313cdf0e10cSrcweir 
1314cdf0e10cSrcweir     return aResult;
1315cdf0e10cSrcweir }
1316cdf0e10cSrcweir 
DenoteSpecialCharacters(const String & rStr)1317cdf0e10cSrcweir String DenoteSpecialCharacters(const String & rStr)
1318cdf0e10cSrcweir {
1319cdf0e10cSrcweir     String aResult;
1320cdf0e10cSrcweir 
1321cdf0e10cSrcweir     if (rStr.Len() > 0)
1322cdf0e10cSrcweir     {
1323cdf0e10cSrcweir         bool bStart = false;
1324cdf0e10cSrcweir         xub_StrLen nStart = 0;
1325cdf0e10cSrcweir         sal_Unicode cLast = 0;
1326cdf0e10cSrcweir 
1327cdf0e10cSrcweir         for (xub_StrLen i = 0; i < rStr.Len(); i++)
1328cdf0e10cSrcweir         {
1329cdf0e10cSrcweir             if (lcl_IsSpecialCharacter(rStr.GetChar(i)))
1330cdf0e10cSrcweir             {
1331cdf0e10cSrcweir                 if (cLast != rStr.GetChar(i))
1332cdf0e10cSrcweir                     bStart = true;
1333cdf0e10cSrcweir 
1334cdf0e10cSrcweir             }
1335cdf0e10cSrcweir             else
1336cdf0e10cSrcweir             {
1337cdf0e10cSrcweir                 if (lcl_IsSpecialCharacter(cLast))
1338cdf0e10cSrcweir                     bStart = true;
1339cdf0e10cSrcweir             }
1340cdf0e10cSrcweir 
1341cdf0e10cSrcweir             if (bStart)
1342cdf0e10cSrcweir             {
1343cdf0e10cSrcweir                 aResult += lcl_DenotedPortion(rStr, nStart, i);
1344cdf0e10cSrcweir 
1345cdf0e10cSrcweir                 nStart = i;
1346cdf0e10cSrcweir                 bStart = false;
1347cdf0e10cSrcweir             }
1348cdf0e10cSrcweir 
1349cdf0e10cSrcweir             cLast = rStr.GetChar(i);
1350cdf0e10cSrcweir         }
1351cdf0e10cSrcweir 
1352cdf0e10cSrcweir         aResult += lcl_DenotedPortion(rStr, nStart, rStr.Len());
1353cdf0e10cSrcweir     }
1354cdf0e10cSrcweir     else
1355cdf0e10cSrcweir         aResult = UNDO_ARG2;
1356cdf0e10cSrcweir 
1357cdf0e10cSrcweir     return aResult;
1358cdf0e10cSrcweir }
1359cdf0e10cSrcweir 
IsDestroyFrameAnchoredAtChar(SwPosition const & rAnchorPos,SwPosition const & rStart,SwPosition const & rEnd,DelCntntType const nDelCntntType)1360cdf0e10cSrcweir bool IsDestroyFrameAnchoredAtChar(SwPosition const & rAnchorPos,
1361cdf0e10cSrcweir         SwPosition const & rStart, SwPosition const & rEnd,
1362cdf0e10cSrcweir         DelCntntType const nDelCntntType)
1363cdf0e10cSrcweir {
1364cdf0e10cSrcweir 
1365cdf0e10cSrcweir     // Here we identified the objects to destroy:
1366cdf0e10cSrcweir     // - anchored between start and end of the selection
1367cdf0e10cSrcweir     // - anchored in start of the selection with "CheckNoContent"
1368cdf0e10cSrcweir     // - anchored in start of sel. and the selection start at pos 0
1369cdf0e10cSrcweir     return  (rAnchorPos.nNode < rEnd.nNode)
1370cdf0e10cSrcweir          && (   (nsDelCntntType::DELCNT_CHKNOCNTNT & nDelCntntType)
1371cdf0e10cSrcweir             ||  (rStart.nNode < rAnchorPos.nNode)
1372cdf0e10cSrcweir             ||  !rStart.nContent.GetIndex()
1373cdf0e10cSrcweir             );
1374cdf0e10cSrcweir }
1375cdf0e10cSrcweir 
1376