xref: /trunk/main/editeng/source/editeng/editundo.cxx (revision 434f02ca)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_editeng.hxx"
26 
27 #include <eeng_pch.hxx>
28 
29 #include <impedit.hxx>
30 #include <editundo.hxx>
31 #include <editeng/editview.hxx>
32 #include <editeng/editeng.hxx>
33 
34 DBG_NAME( EditUndo )
35 
36 #define MAX_UNDOS	100		// ab dieser Menge darf geloescht werden....
37 #define MIN_UNDOS	50		// soviel muss stehen bleiben...
38 
39 #define NO_UNDO			0xFFFF
40 #define GROUP_NOTFOUND	0xFFFF
41 
42 TYPEINIT1( EditUndo, SfxUndoAction );
43 TYPEINIT1( EditUndoDelContent, EditUndo );
44 TYPEINIT1( EditUndoConnectParas, EditUndo );
45 TYPEINIT1( EditUndoSplitPara, EditUndo );
46 TYPEINIT1( EditUndoInsertChars, EditUndo );
47 TYPEINIT1( EditUndoRemoveChars, EditUndo );
48 TYPEINIT1( EditUndoInsertFeature, EditUndo );
49 TYPEINIT1( EditUndoMoveParagraphs, EditUndo );
50 TYPEINIT1( EditUndoSetStyleSheet, EditUndo );
51 TYPEINIT1( EditUndoSetParaAttribs, EditUndo );
52 TYPEINIT1( EditUndoSetAttribs, EditUndo );
53 TYPEINIT1( EditUndoTransliteration, EditUndo );
54 TYPEINIT1( EditUndoMarkSelection, EditUndo );
55 
lcl_DoSetSelection(EditView * pView,sal_uInt32 nPara)56 void lcl_DoSetSelection( EditView* pView, sal_uInt32 nPara )
57 {
58 	EPaM aEPaM( nPara, 0 );
59 	EditPaM aPaM( pView->GetImpEditEngine()->CreateEditPaM( aEPaM ) );
60 	aPaM.SetIndex( aPaM.GetNode()->Len() );
61 	EditSelection aSel( aPaM, aPaM );
62 	pView->GetImpEditView()->SetEditSelection( aSel );
63 }
64 
65 // -----------------------------------------------------------------------
66 // EditUndoManager
67 // ------------------------------------------------------------------------
EditUndoManager(sal_uInt16 nMaxUndoActionCount)68 EditUndoManager::EditUndoManager(sal_uInt16 nMaxUndoActionCount )
69 :   SfxUndoManager(nMaxUndoActionCount),
70     mpImpEE(0)
71 {
72 }
73 
SetImpEditEngine(ImpEditEngine * pNew)74 void EditUndoManager::SetImpEditEngine(ImpEditEngine* pNew)
75 {
76     mpImpEE = pNew;
77 }
78 
Undo()79 sal_Bool __EXPORT EditUndoManager::Undo()
80 {
81 	if ( !mpImpEE || GetUndoActionCount() == 0 )
82 		return sal_False;
83 
84 	DBG_ASSERT( mpImpEE->GetActiveView(), "Active View?" );
85 
86 	if ( !mpImpEE->GetActiveView() )
87 	{
88 		if ( mpImpEE->GetEditViews().Count() )
89 			mpImpEE->SetActiveView( mpImpEE->GetEditViews().GetObject(0) );
90 		else
91 		{
92 			DBG_ERROR( "Undo in Engine ohne View nicht moeglich!" );
93 			return sal_False;
94 		}
95 	}
96 
97 	mpImpEE->GetActiveView()->GetImpEditView()->DrawSelection();	// alte Selektion entfernen
98 
99 	mpImpEE->SetUndoMode( sal_True );
100 	sal_Bool bDone = SfxUndoManager::Undo();
101 	mpImpEE->SetUndoMode( sal_False );
102 
103 	EditSelection aNewSel( mpImpEE->GetActiveView()->GetImpEditView()->GetEditSelection() );
104 	DBG_ASSERT( !aNewSel.IsInvalid(), "Ungueltige Selektion nach Undo()" );
105 	DBG_ASSERT( !aNewSel.DbgIsBuggy( mpImpEE->GetEditDoc() ), "Kaputte Selektion nach Undo()" );
106 
107 	aNewSel.Min() = aNewSel.Max();
108 	mpImpEE->GetActiveView()->GetImpEditView()->SetEditSelection( aNewSel );
109 	mpImpEE->FormatAndUpdate( mpImpEE->GetActiveView() );
110 
111 	return bDone;
112 }
113 
Redo()114 sal_Bool __EXPORT EditUndoManager::Redo()
115 {
116 	if ( !mpImpEE || GetRedoActionCount() == 0 )
117 		return sal_False;
118 
119 	DBG_ASSERT( mpImpEE->GetActiveView(), "Active View?" );
120 
121 	if ( !mpImpEE->GetActiveView() )
122 	{
123 		if ( mpImpEE->GetEditViews().Count() )
124 			mpImpEE->SetActiveView( mpImpEE->GetEditViews().GetObject(0) );
125 		else
126 		{
127 			DBG_ERROR( "Redo in Engine ohne View nicht moeglich!" );
128 			return sal_False;
129 		}
130 	}
131 
132 	mpImpEE->GetActiveView()->GetImpEditView()->DrawSelection();	// alte Selektion entfernen
133 
134 	mpImpEE->SetUndoMode( sal_True );
135 	sal_Bool bDone = SfxUndoManager::Redo();
136 	mpImpEE->SetUndoMode( sal_False );
137 
138 	EditSelection aNewSel( mpImpEE->GetActiveView()->GetImpEditView()->GetEditSelection() );
139 	DBG_ASSERT( !aNewSel.IsInvalid(), "Ungueltige Selektion nach Undo()" );
140 	DBG_ASSERT( !aNewSel.DbgIsBuggy( mpImpEE->GetEditDoc() ), "Kaputte Selektion nach Redo()" );
141 
142 	aNewSel.Min() = aNewSel.Max();
143 	mpImpEE->GetActiveView()->GetImpEditView()->SetEditSelection( aNewSel );
144 	mpImpEE->FormatAndUpdate( mpImpEE->GetActiveView() );
145 
146 	return bDone;
147 }
148 
149 // -----------------------------------------------------------------------
150 // EditUndo
151 // ------------------------------------------------------------------------
EditUndo(sal_uInt16 nI,ImpEditEngine * p)152 EditUndo::EditUndo( sal_uInt16 nI, ImpEditEngine* p )
153 {
154 	DBG_CTOR( EditUndo, 0 );
155 	nId = nI;
156 	pImpEE = p;
157 }
158 
~EditUndo()159 EditUndo::~EditUndo()
160 {
161 	DBG_DTOR( EditUndo, 0 );
162 }
163 
GetId() const164 sal_uInt16 __EXPORT EditUndo::GetId() const
165 {
166 	DBG_CHKTHIS( EditUndo, 0 );
167 	return nId;
168 }
169 
CanRepeat(SfxRepeatTarget &) const170 sal_Bool __EXPORT EditUndo::CanRepeat(SfxRepeatTarget&) const
171 {
172 	return sal_False;
173 }
174 
GetComment() const175 XubString __EXPORT EditUndo::GetComment() const
176 {
177 	XubString aComment;
178 	if ( pImpEE )
179 	{
180 		EditEngine* pEditEng = pImpEE->GetEditEnginePtr();
181 		aComment = pEditEng->GetUndoComment( GetId() );
182 	}
183 	return aComment;
184 }
185 
186 // -----------------------------------------------------------------------
187 // EditUndoDelContent
188 // ------------------------------------------------------------------------
EditUndoDelContent(ImpEditEngine * _pImpEE,ContentNode * pNode,sal_uInt32 n)189 EditUndoDelContent::EditUndoDelContent( ImpEditEngine* _pImpEE, ContentNode* pNode, sal_uInt32 n )
190 					: EditUndo( EDITUNDO_DELCONTENT, _pImpEE )
191 {
192 	pContentNode = pNode;
193 	nNode = n;
194 	bDelObject = sal_True;
195 }
196 
~EditUndoDelContent()197 EditUndoDelContent::~EditUndoDelContent()
198 {
199 	if ( bDelObject )
200 		delete pContentNode;
201 }
202 
Undo()203 void __EXPORT EditUndoDelContent::Undo()
204 {
205 	DBG_ASSERT( GetImpEditEngine()->GetActiveView(), "Undo/Redo: Keine Active View!" );
206 	GetImpEditEngine()->InsertContent( pContentNode, nNode );
207 	bDelObject = sal_False;	// gehoert wieder der Engine
208 	EditSelection aSel( EditPaM( pContentNode, 0 ), EditPaM( pContentNode, pContentNode->Len() ) );
209 	GetImpEditEngine()->GetActiveView()->GetImpEditView()->SetEditSelection( aSel );
210 }
211 
Redo()212 void __EXPORT EditUndoDelContent::Redo()
213 {
214 	DBG_ASSERT( GetImpEditEngine()->GetActiveView(), "Undo/Redo: Keine Active View!" );
215 
216 	ImpEditEngine* _pImpEE = GetImpEditEngine();
217 
218 	// pNode stimmt nicht mehr, falls zwischendurch Undos, in denen
219 	// Absaetze verschmolzen sind.
220 	pContentNode = _pImpEE->GetEditDoc().SaveGetObject( nNode );
221 	DBG_ASSERT( pContentNode, "EditUndoDelContent::Redo(): Node?!" );
222 
223 	delete _pImpEE->GetParaPortions()[nNode];
224 	_pImpEE->GetParaPortions().Remove( nNode );
225 
226 	// Node nicht loeschen, haengt im Undo!
227 	_pImpEE->GetEditDoc().Remove( nNode );
228 	if( _pImpEE->IsCallParaInsertedOrDeleted() )
229 		_pImpEE->GetEditEnginePtr()->ParagraphDeleted( nNode );
230 
231 	DeletedNodeInfo* pInf = new DeletedNodeInfo( (sal_uLong)pContentNode, nNode );
232 	_pImpEE->aDeletedNodes.Insert( pInf, _pImpEE->aDeletedNodes.Count() );
233 	_pImpEE->UpdateSelections();
234 
235 	ContentNode* pN = ( nNode < _pImpEE->GetEditDoc().Count() )
236 		? _pImpEE->GetEditDoc().SaveGetObject( nNode )
237 		: _pImpEE->GetEditDoc().SaveGetObject( nNode-1 );
238 	DBG_ASSERT( pN && ( pN != pContentNode ), "?! RemoveContent !? " );
239 	EditPaM aPaM( pN, pN->Len() );
240 
241 	bDelObject = sal_True;	// gehoert wieder dem Undo
242 
243 	_pImpEE->GetActiveView()->GetImpEditView()->SetEditSelection( EditSelection( aPaM, aPaM ) );
244 }
245 
246 // -----------------------------------------------------------------------
247 // EditUndoConnectParas
248 // ------------------------------------------------------------------------
EditUndoConnectParas(ImpEditEngine * _pImpEE,sal_uInt32 nN,sal_uInt16 nSP,const SfxItemSet & rLeftParaAttribs,const SfxItemSet & rRightParaAttribs,const SfxStyleSheet * pLeftStyle,const SfxStyleSheet * pRightStyle,sal_Bool bBkwrd)249 EditUndoConnectParas::EditUndoConnectParas( ImpEditEngine* _pImpEE, sal_uInt32 nN, sal_uInt16 nSP,
250 											const SfxItemSet& rLeftParaAttribs, const SfxItemSet& rRightParaAttribs,
251 											const SfxStyleSheet* pLeftStyle, const SfxStyleSheet* pRightStyle, sal_Bool bBkwrd )
252 					: 	EditUndo( EDITUNDO_CONNECTPARAS, _pImpEE ),
253 						aLeftParaAttribs( rLeftParaAttribs ),
254 						aRightParaAttribs( rRightParaAttribs )
255 {
256 	nNode	= nN;
257 	nSepPos	= nSP;
258 
259 	if ( pLeftStyle )
260 	{
261 		aLeftStyleName = pLeftStyle->GetName();
262 		eLeftStyleFamily = pLeftStyle->GetFamily();
263 	}
264 	if ( pRightStyle )
265 	{
266 		aRightStyleName = pRightStyle->GetName();
267 		eRightStyleFamily = pRightStyle->GetFamily();
268 	}
269 
270 	bBackward = bBkwrd;
271 }
272 
~EditUndoConnectParas()273 EditUndoConnectParas::~EditUndoConnectParas()
274 {
275 }
276 
Undo()277 void __EXPORT EditUndoConnectParas::Undo()
278 {
279 	DBG_ASSERT( GetImpEditEngine()->GetActiveView(), "Undo/Redo: Keine Active View!" );
280 
281 	// Bei SplitContent darf noch kein ParagraphInserted gerufen werden,
282 	// weil der Outliner sich auf die Attribute verlaesst um die Tiefe
283 	// des Absatzes zu initialisieren
284 
285 	sal_Bool bCall = GetImpEditEngine()->IsCallParaInsertedOrDeleted();
286 	GetImpEditEngine()->SetCallParaInsertedOrDeleted( sal_False );
287 
288 	EditPaM aPaM = GetImpEditEngine()->SplitContent( nNode, nSepPos );
289 	GetImpEditEngine()->SetParaAttribs( nNode, aLeftParaAttribs );
290 	GetImpEditEngine()->SetParaAttribs( nNode+1, aRightParaAttribs );
291 
292 	GetImpEditEngine()->SetCallParaInsertedOrDeleted( bCall );
293 	if ( GetImpEditEngine()->IsCallParaInsertedOrDeleted() )
294 		GetImpEditEngine()->GetEditEnginePtr()->ParagraphInserted( nNode+1 );
295 
296 	if ( GetImpEditEngine()->GetStyleSheetPool() )
297 	{
298 		if ( aLeftStyleName.Len() )
299 			GetImpEditEngine()->SetStyleSheet( nNode, (SfxStyleSheet*)GetImpEditEngine()->GetStyleSheetPool()->Find( aLeftStyleName, eLeftStyleFamily ) );
300 		if ( aRightStyleName.Len() )
301 			GetImpEditEngine()->SetStyleSheet( nNode+1, (SfxStyleSheet*)GetImpEditEngine()->GetStyleSheetPool()->Find( aRightStyleName, eRightStyleFamily ) );
302 	}
303 
304 	GetImpEditEngine()->GetActiveView()->GetImpEditView()->SetEditSelection( EditSelection( aPaM, aPaM ) );
305 }
306 
Redo()307 void __EXPORT EditUndoConnectParas::Redo()
308 {
309 	DBG_ASSERT( GetImpEditEngine()->GetActiveView(), "Undo/Redo: Keine Active View!" );
310 	EditPaM aPaM = GetImpEditEngine()->ConnectContents( nNode, bBackward );
311 
312 	GetImpEditEngine()->GetActiveView()->GetImpEditView()->SetEditSelection( EditSelection( aPaM, aPaM ) );
313 }
314 
315 // -----------------------------------------------------------------------
316 // EditUndoSplitPara
317 // ------------------------------------------------------------------------
EditUndoSplitPara(ImpEditEngine * _pImpEE,sal_uInt32 nN,sal_uInt16 nSP)318 EditUndoSplitPara::EditUndoSplitPara( ImpEditEngine* _pImpEE, sal_uInt32 nN, sal_uInt16 nSP )
319 					: EditUndo( EDITUNDO_SPLITPARA, _pImpEE )
320 {
321 	nNode	= nN;
322 	nSepPos	= nSP;
323 }
324 
~EditUndoSplitPara()325 EditUndoSplitPara::~EditUndoSplitPara()
326 {
327 }
328 
Undo()329 void __EXPORT EditUndoSplitPara::Undo()
330 {
331 	DBG_ASSERT( GetImpEditEngine()->GetActiveView(), "Undo/Redo: Keine Active View!" );
332 	EditPaM aPaM = GetImpEditEngine()->ConnectContents( nNode, sal_False );
333 	GetImpEditEngine()->GetActiveView()->GetImpEditView()->SetEditSelection( EditSelection( aPaM, aPaM ) );
334 }
335 
Redo()336 void __EXPORT EditUndoSplitPara::Redo()
337 {
338 	DBG_ASSERT( GetImpEditEngine()->GetActiveView(), "Undo/Redo: Keine Active View!" );
339 	EditPaM aPaM = GetImpEditEngine()->SplitContent( nNode, nSepPos );
340 	GetImpEditEngine()->GetActiveView()->GetImpEditView()->SetEditSelection( EditSelection( aPaM, aPaM ) );
341 }
342 
343 // -----------------------------------------------------------------------
344 // EditUndoInsertChars
345 // ------------------------------------------------------------------------
EditUndoInsertChars(ImpEditEngine * _pImpEE,const EPaM & rEPaM,const XubString & rStr)346 EditUndoInsertChars::EditUndoInsertChars( ImpEditEngine* _pImpEE, const EPaM& rEPaM, const XubString& rStr )
347 					: EditUndo( EDITUNDO_INSERTCHARS, _pImpEE ),
348 						aEPaM( rEPaM ), aText( rStr )
349 {
350 }
351 
Undo()352 void __EXPORT EditUndoInsertChars::Undo()
353 {
354 	DBG_ASSERT( GetImpEditEngine()->GetActiveView(), "Undo/Redo: Keine Active View!" );
355 	EditPaM aPaM( GetImpEditEngine()->CreateEditPaM( aEPaM ) );
356 	EditSelection aSel( aPaM, aPaM );
357 	aSel.Max().GetIndex() = aSel.Max().GetIndex() + aText.Len();
358 	EditPaM aNewPaM( GetImpEditEngine()->ImpDeleteSelection( aSel ) );
359 	GetImpEditEngine()->GetActiveView()->GetImpEditView()->SetEditSelection( EditSelection( aNewPaM, aNewPaM ) );
360 }
361 
Redo()362 void __EXPORT EditUndoInsertChars::Redo()
363 {
364 	DBG_ASSERT( GetImpEditEngine()->GetActiveView(), "Undo/Redo: Keine Active View!" );
365 	EditPaM aPaM( GetImpEditEngine()->CreateEditPaM( aEPaM ) );
366 	GetImpEditEngine()->ImpInsertText( EditSelection( aPaM, aPaM ), aText );
367 	EditPaM aNewPaM( aPaM );
368 	aNewPaM.GetIndex() = aNewPaM.GetIndex() + aText.Len();
369 	GetImpEditEngine()->GetActiveView()->GetImpEditView()->SetEditSelection( EditSelection( aPaM, aNewPaM ) );
370 }
371 
Merge(SfxUndoAction * pNextAction)372 sal_Bool __EXPORT EditUndoInsertChars::Merge( SfxUndoAction* pNextAction )
373 {
374 	if ( !pNextAction->ISA( EditUndoInsertChars ) )
375 		return sal_False;
376 
377 	EditUndoInsertChars* pNext = (EditUndoInsertChars*)pNextAction;
378 
379 	if ( aEPaM.nPara != pNext->aEPaM.nPara )
380 		return sal_False;
381 
382 	if ( ( aEPaM.nIndex + aText.Len() ) == pNext->aEPaM.nIndex )
383 	{
384 		aText += pNext->aText;
385 		return sal_True;
386 	}
387 	return sal_False;
388 }
389 
390 // -----------------------------------------------------------------------
391 // EditUndoRemoveChars
392 // ------------------------------------------------------------------------
EditUndoRemoveChars(ImpEditEngine * _pImpEE,const EPaM & rEPaM,const XubString & rStr)393 EditUndoRemoveChars::EditUndoRemoveChars( ImpEditEngine* _pImpEE, const EPaM& rEPaM, const XubString& rStr )
394 					: EditUndo( EDITUNDO_REMOVECHARS, _pImpEE ),
395 						aEPaM( rEPaM ), aText( rStr )
396 {
397 }
398 
Undo()399 void __EXPORT EditUndoRemoveChars::Undo()
400 {
401 	DBG_ASSERT( GetImpEditEngine()->GetActiveView(), "Undo/Redo: Keine Active View!" );
402 	EditPaM aPaM( GetImpEditEngine()->CreateEditPaM( aEPaM ) );
403 	EditSelection aSel( aPaM, aPaM );
404 	GetImpEditEngine()->ImpInsertText( aSel, aText );
405 	aSel.Max().GetIndex() = aSel.Max().GetIndex() + aText.Len();
406 	GetImpEditEngine()->GetActiveView()->GetImpEditView()->SetEditSelection( aSel );
407 }
408 
Redo()409 void __EXPORT EditUndoRemoveChars::Redo()
410 {
411 	DBG_ASSERT( GetImpEditEngine()->GetActiveView(), "Undo/Redo: Keine Active View!" );
412 	EditPaM aPaM( GetImpEditEngine()->CreateEditPaM( aEPaM ) );
413 	EditSelection aSel( aPaM, aPaM );
414 	aSel.Max().GetIndex() = aSel.Max().GetIndex() + aText.Len();
415 	EditPaM aNewPaM = GetImpEditEngine()->ImpDeleteSelection( aSel );
416 	GetImpEditEngine()->GetActiveView()->GetImpEditView()->SetEditSelection( aNewPaM );
417 }
418 
419 // -----------------------------------------------------------------------
420 // EditUndoInsertFeature
421 // ------------------------------------------------------------------------
EditUndoInsertFeature(ImpEditEngine * _pImpEE,const EPaM & rEPaM,const SfxPoolItem & rFeature)422 EditUndoInsertFeature::EditUndoInsertFeature( ImpEditEngine* _pImpEE, const EPaM& rEPaM, const SfxPoolItem& rFeature)
423 					: EditUndo( EDITUNDO_INSERTFEATURE, _pImpEE ), aEPaM( rEPaM )
424 {
425 	pFeature = rFeature.Clone();
426 	DBG_ASSERT( pFeature, "Feature konnte nicht dupliziert werden: EditUndoInsertFeature" );
427 }
428 
~EditUndoInsertFeature()429 EditUndoInsertFeature::~EditUndoInsertFeature()
430 {
431 	delete pFeature;
432 }
433 
Undo()434 void __EXPORT EditUndoInsertFeature::Undo()
435 {
436 	DBG_ASSERT( GetImpEditEngine()->GetActiveView(), "Undo/Redo: Keine Active View!" );
437 	EditPaM aPaM( GetImpEditEngine()->CreateEditPaM( aEPaM ) );
438 	EditSelection aSel( aPaM, aPaM );
439 	// Attribute werden dort implizit vom Dokument korrigiert...
440 	aSel.Max().GetIndex()++;
441 	EditPaM aNewPaM = GetImpEditEngine()->ImpDeleteSelection( aSel );
442 	aSel.Max().GetIndex()--;	// Fuer Selektion
443 	GetImpEditEngine()->GetActiveView()->GetImpEditView()->SetEditSelection( aSel );
444 }
445 
Redo()446 void __EXPORT EditUndoInsertFeature::Redo()
447 {
448 	DBG_ASSERT( GetImpEditEngine()->GetActiveView(), "Undo/Redo: Keine Active View!" );
449 	EditPaM aPaM( GetImpEditEngine()->CreateEditPaM( aEPaM ) );
450 	EditSelection aSel( aPaM, aPaM );
451 	GetImpEditEngine()->ImpInsertFeature( aSel, *pFeature );
452 	if ( pFeature->Which() == EE_FEATURE_FIELD )
453 		GetImpEditEngine()->UpdateFields();
454 	aSel.Max().GetIndex()++;
455 	GetImpEditEngine()->GetActiveView()->GetImpEditView()->SetEditSelection( aSel );
456 }
457 
458 // -----------------------------------------------------------------------
459 // EditUndoMoveParagraphs
460 // ------------------------------------------------------------------------
EditUndoMoveParagraphs(ImpEditEngine * _pImpEE,const Range & rParas,sal_uInt32 n)461 EditUndoMoveParagraphs::EditUndoMoveParagraphs
462 							( ImpEditEngine* _pImpEE, const Range& rParas, sal_uInt32 n )
463 							: 	EditUndo( EDITUNDO_MOVEPARAGRAPHS, _pImpEE ),
464 								nParagraphs( rParas )
465 {
466 	nDest = n;
467 }
468 
~EditUndoMoveParagraphs()469 EditUndoMoveParagraphs::~EditUndoMoveParagraphs()
470 {
471 }
472 
Undo()473 void __EXPORT EditUndoMoveParagraphs::Undo()
474 {
475 	DBG_ASSERT( GetImpEditEngine()->GetActiveView(), "Undo/Redo: Keine Active View!" );
476 	Range aTmpRange( nParagraphs );
477 	long nTmpDest = aTmpRange.Min();
478 
479 	long nDiff = ( nDest - aTmpRange.Min() );
480 	aTmpRange.Min() += nDiff;
481 	aTmpRange.Max() += nDiff;
482 
483 	if ( nParagraphs.Min() < (long)nDest )
484 	{
485 		long nLen = aTmpRange.Len();
486 		aTmpRange.Min() -= nLen;
487 		aTmpRange.Max() -= nLen;
488 	}
489 	else
490 		nTmpDest += aTmpRange.Len();
491 
492 	EditSelection aNewSel( GetImpEditEngine()->MoveParagraphs( aTmpRange, (sal_uInt32)nTmpDest, 0 ) );
493 	GetImpEditEngine()->GetActiveView()->GetImpEditView()->SetEditSelection( aNewSel );
494 }
495 
Redo()496 void __EXPORT EditUndoMoveParagraphs::Redo()
497 {
498 	DBG_ASSERT( GetImpEditEngine()->GetActiveView(), "Undo/Redo: Keine Active View!" );
499 	EditSelection aNewSel( GetImpEditEngine()->MoveParagraphs( nParagraphs, nDest, 0 ) );
500 	GetImpEditEngine()->GetActiveView()->GetImpEditView()->SetEditSelection( aNewSel );
501 }
502 
503 // -----------------------------------------------------------------------
504 // EditUndoSetStyleSheet
505 // ------------------------------------------------------------------------
EditUndoSetStyleSheet(ImpEditEngine * _pImpEE,sal_uInt32 nP,const XubString & rPrevName,SfxStyleFamily ePrevFam,const XubString & rNewName,SfxStyleFamily eNewFam,const SfxItemSet & rPrevParaAttribs)506 EditUndoSetStyleSheet::EditUndoSetStyleSheet( ImpEditEngine* _pImpEE, sal_uInt32 nP,
507 						const XubString& rPrevName, SfxStyleFamily ePrevFam,
508 						const XubString& rNewName, SfxStyleFamily eNewFam,
509 						const SfxItemSet& rPrevParaAttribs )
510 	: EditUndo( EDITUNDO_STYLESHEET, _pImpEE ), aPrevName( rPrevName ), aNewName( rNewName ),
511 	  aPrevParaAttribs( rPrevParaAttribs )
512 {
513 	ePrevFamily = ePrevFam;
514 	eNewFamily = eNewFam;
515 	nPara = nP;
516 }
517 
~EditUndoSetStyleSheet()518 EditUndoSetStyleSheet::~EditUndoSetStyleSheet()
519 {
520 }
521 
Undo()522 void __EXPORT EditUndoSetStyleSheet::Undo()
523 {
524 	DBG_ASSERT( GetImpEditEngine()->GetActiveView(), "Undo/Redo: Keine Active View!" );
525 	GetImpEditEngine()->SetStyleSheet( nPara, (SfxStyleSheet*)GetImpEditEngine()->GetStyleSheetPool()->Find( aPrevName, ePrevFamily ) );
526 	GetImpEditEngine()->SetParaAttribs( nPara, aPrevParaAttribs );
527 	lcl_DoSetSelection( GetImpEditEngine()->GetActiveView(), nPara );
528 }
529 
Redo()530 void __EXPORT EditUndoSetStyleSheet::Redo()
531 {
532 	DBG_ASSERT( GetImpEditEngine()->GetActiveView(), "Undo/Redo: Keine Active View!" );
533 	GetImpEditEngine()->SetStyleSheet( nPara, (SfxStyleSheet*)GetImpEditEngine()->GetStyleSheetPool()->Find( aNewName, eNewFamily ) );
534 	lcl_DoSetSelection( GetImpEditEngine()->GetActiveView(), nPara );
535 }
536 
537 // -----------------------------------------------------------------------
538 // EditUndoSetParaAttribs
539 // ------------------------------------------------------------------------
EditUndoSetParaAttribs(ImpEditEngine * _pImpEE,sal_uInt32 nP,const SfxItemSet & rPrevItems,const SfxItemSet & rNewItems)540 EditUndoSetParaAttribs::EditUndoSetParaAttribs( ImpEditEngine* _pImpEE, sal_uInt32 nP, const SfxItemSet& rPrevItems, const SfxItemSet& rNewItems )
541 	: EditUndo( EDITUNDO_PARAATTRIBS, _pImpEE ),
542 	  aPrevItems( rPrevItems ),
543 	  aNewItems(rNewItems )
544 {
545 	nPara = nP;
546 }
547 
~EditUndoSetParaAttribs()548 EditUndoSetParaAttribs::~EditUndoSetParaAttribs()
549 {
550 }
551 
Undo()552 void __EXPORT EditUndoSetParaAttribs::Undo()
553 {
554 	DBG_ASSERT( GetImpEditEngine()->GetActiveView(), "Undo/Redo: Keine Active View!" );
555 	GetImpEditEngine()->SetParaAttribs( nPara, aPrevItems );
556 	lcl_DoSetSelection( GetImpEditEngine()->GetActiveView(), nPara );
557 }
558 
Redo()559 void __EXPORT EditUndoSetParaAttribs::Redo()
560 {
561 	DBG_ASSERT( GetImpEditEngine()->GetActiveView(), "Undo/Redo: Keine Active View!" );
562 	GetImpEditEngine()->SetParaAttribs( nPara, aNewItems );
563 	lcl_DoSetSelection( GetImpEditEngine()->GetActiveView(), nPara );
564 }
565 
566 // -----------------------------------------------------------------------
567 // EditUndoSetAttribs
568 // ------------------------------------------------------------------------
EditUndoSetAttribs(ImpEditEngine * _pImpEE,const ESelection & rESel,const SfxItemSet & rNewItems)569 EditUndoSetAttribs::EditUndoSetAttribs( ImpEditEngine* _pImpEE, const ESelection& rESel, const SfxItemSet& rNewItems )
570 	: EditUndo( EDITUNDO_ATTRIBS, _pImpEE ),
571 	  aESel( rESel ),
572 	  aNewAttribs( rNewItems )
573 {
574 	// Wenn das EditUndoSetAttribs eigentlich ein RemoveAttribs ist, koennte
575 	// man das eigentlich an einem leeren ItemSet erkennen, aber dann muesste
576 	// an einigen Stellen abgefangen werden, das ggf. ein SetAttribs mit einem
577 	// leeren ItemSet gemacht wird.
578 	// => Ich habe lieber diesen Member spendiert...
579 	bSetIsRemove = sal_False;
580 	bRemoveParaAttribs = sal_False;
581 	nRemoveWhich = 0;
582 	nSpecial = 0;
583 }
584 
~EditUndoSetAttribs()585 EditUndoSetAttribs::~EditUndoSetAttribs()
586 {
587 	// Items aus Pool holen...
588 	SfxItemPool* pPool = aNewAttribs.GetPool();
589 	sal_uInt16 nContents = aPrevAttribs.Count();
590 	for ( sal_uInt16 n = 0; n < nContents; n++ )
591 	{
592 		ContentAttribsInfo* pInf = aPrevAttribs[n];
593 		DBG_ASSERT( pInf, "Undo_DTOR (SetAttribs): pInf = NULL!" );
594 		for ( sal_uInt16 nAttr = 0; nAttr < pInf->GetPrevCharAttribs().Count(); nAttr++ )
595 		{
596 			EditCharAttrib* pX = pInf->GetPrevCharAttribs()[nAttr];
597 			DBG_ASSERT( pX, "Undo_DTOR (SetAttribs): pX = NULL!" );
598 			pPool->Remove( *pX->GetItem() );
599 			delete pX;
600 		}
601 		delete pInf;
602 	}
603 }
604 
Undo()605 void __EXPORT EditUndoSetAttribs::Undo()
606 {
607 	DBG_ASSERT( GetImpEditEngine()->GetActiveView(), "Undo/Redo: Keine Active View!" );
608 	ImpEditEngine* _pImpEE = GetImpEditEngine();
609 	sal_Bool bFields = sal_False;
610 	for ( sal_uInt32 nPara = aESel.nStartPara; nPara <= aESel.nEndPara; nPara++ )
611 	{
612 		ContentAttribsInfo* pInf = aPrevAttribs[ (sal_uInt16)(nPara-aESel.nStartPara) ];
613 		DBG_ASSERT( pInf, "Undo (SetAttribs): pInf = NULL!" );
614 
615 		// erstmal die Absatzattribute...
616 		_pImpEE->SetParaAttribs( nPara, pInf->GetPrevParaAttribs() );
617 
618 		// Dann die Zeichenattribute...
619 		// Alle Attribute inkl. Features entfernen, werden wieder neu eingestellt.
620 		_pImpEE->RemoveCharAttribs( nPara, 0, sal_True );
621 		DBG_ASSERT( _pImpEE->GetEditDoc().SaveGetObject( nPara ), "Undo (SetAttribs): pNode = NULL!" );
622 		ContentNode* pNode = _pImpEE->GetEditDoc().GetObject( nPara );
623 		for ( sal_uInt16 nAttr = 0; nAttr < pInf->GetPrevCharAttribs().Count(); nAttr++ )
624 		{
625 			EditCharAttrib* pX = pInf->GetPrevCharAttribs()[nAttr];
626 			DBG_ASSERT( pX, "Redo (SetAttribs): pX = NULL!" );
627 			// wird autom. 'eingepoolt'.
628 			_pImpEE->GetEditDoc().InsertAttrib( pNode, pX->GetStart(), pX->GetEnd(), *pX->GetItem() );
629 			if ( pX->Which() == EE_FEATURE_FIELD )
630 				bFields = sal_True;
631 		}
632 	}
633 	if ( bFields )
634 		_pImpEE->UpdateFields();
635 	ImpSetSelection( GetImpEditEngine()->GetActiveView() );
636 }
637 
Redo()638 void __EXPORT EditUndoSetAttribs::Redo()
639 {
640 	DBG_ASSERT( GetImpEditEngine()->GetActiveView(), "Undo/Redo: Keine Active View!" );
641 	ImpEditEngine* _pImpEE = GetImpEditEngine();
642 
643 	EditSelection aSel( _pImpEE->CreateSel( aESel ) );
644 	if ( !bSetIsRemove )
645 		_pImpEE->SetAttribs( aSel, aNewAttribs, nSpecial );
646 	else
647 		_pImpEE->RemoveCharAttribs( aSel, bRemoveParaAttribs, nRemoveWhich );
648 
649 	ImpSetSelection( GetImpEditEngine()->GetActiveView() );
650 }
651 
ImpSetSelection(EditView *)652 void EditUndoSetAttribs::ImpSetSelection( EditView* /*pView*/ )
653 {
654 	ImpEditEngine* _pImpEE = GetImpEditEngine();
655 	EditSelection aSel( _pImpEE->CreateSel( aESel ) );
656 	GetImpEditEngine()->GetActiveView()->GetImpEditView()->SetEditSelection( aSel );
657 }
658 
659 // -----------------------------------------------------------------------
660 // EditUndoTransliteration
661 // ------------------------------------------------------------------------
EditUndoTransliteration(ImpEditEngine * _pImpEE,const ESelection & rESel,sal_Int32 nM)662 EditUndoTransliteration::EditUndoTransliteration( ImpEditEngine* _pImpEE, const ESelection& rESel, sal_Int32 nM )
663 	: EditUndo( EDITUNDO_TRANSLITERATE, _pImpEE ), aOldESel( rESel )
664 {
665 	nMode = nM;
666 	pTxtObj = NULL;
667 }
668 
~EditUndoTransliteration()669 EditUndoTransliteration::~EditUndoTransliteration()
670 {
671 	delete pTxtObj;
672 }
673 
Undo()674 void __EXPORT EditUndoTransliteration::Undo()
675 {
676 	DBG_ASSERT( GetImpEditEngine()->GetActiveView(), "Undo/Redo: Keine Active View!" );
677 
678 	ImpEditEngine* _pImpEE = GetImpEditEngine();
679 
680 	EditSelection aSel( _pImpEE->CreateSel( aNewESel ) );
681 
682 	// Insert text, but don't expand Atribs at the current position:
683 	aSel = _pImpEE->DeleteSelected( aSel );
684 	EditSelection aDelSel( aSel );
685 	aSel = _pImpEE->InsertParaBreak( aSel );
686 	aDelSel.Max() = aSel.Min();
687 	aDelSel.Max().GetNode()->GetCharAttribs().DeleteEmptyAttribs( _pImpEE->GetEditDoc().GetItemPool() );
688     EditSelection aNewSel;
689 	if ( pTxtObj )
690 	{
691 		aNewSel = _pImpEE->InsertText( *pTxtObj, aSel );
692 	}
693 	else
694 	{
695 		aNewSel = _pImpEE->InsertText( aSel, aText );
696 	}
697     if ( aNewSel.Min().GetNode() == aDelSel.Max().GetNode() )
698     {
699         aNewSel.Min().SetNode( aDelSel.Min().GetNode() );
700         aNewSel.Min().GetIndex() =
701             aNewSel.Min().GetIndex() + aDelSel.Min().GetIndex();
702     }
703     if ( aNewSel.Max().GetNode() == aDelSel.Max().GetNode() )
704     {
705         aNewSel.Max().SetNode( aDelSel.Min().GetNode() );
706         aNewSel.Max().GetIndex() =
707             aNewSel.Max().GetIndex() + aDelSel.Min().GetIndex();
708     }
709 	_pImpEE->DeleteSelected( aDelSel );
710 
711 	GetImpEditEngine()->GetActiveView()->GetImpEditView()->SetEditSelection( aNewSel );
712 }
713 
Redo()714 void __EXPORT EditUndoTransliteration::Redo()
715 {
716 	DBG_ASSERT( GetImpEditEngine()->GetActiveView(), "Undo/Redo: Keine Active View!" );
717 	ImpEditEngine* _pImpEE = GetImpEditEngine();
718 
719 	EditSelection aSel( _pImpEE->CreateSel( aOldESel ) );
720 	EditSelection aNewSel = _pImpEE->TransliterateText( aSel, nMode );
721 	GetImpEditEngine()->GetActiveView()->GetImpEditView()->SetEditSelection( aNewSel );
722 }
723 
724 // -----------------------------------------------------------------------
725 // EditUndoMarkSelection
726 // ------------------------------------------------------------------------
EditUndoMarkSelection(ImpEditEngine * _pImpEE,const ESelection & rSel)727 EditUndoMarkSelection::EditUndoMarkSelection( ImpEditEngine* _pImpEE, const ESelection& rSel )
728 	: EditUndo( EDITUNDO_MARKSELECTION, _pImpEE ), aSelection( rSel )
729 {
730 }
731 
~EditUndoMarkSelection()732 EditUndoMarkSelection::~EditUndoMarkSelection()
733 {
734 }
735 
Undo()736 void __EXPORT EditUndoMarkSelection::Undo()
737 {
738 	DBG_ASSERT( GetImpEditEngine()->GetActiveView(), "Undo/Redo: Keine Active View!" );
739 	if ( GetImpEditEngine()->GetActiveView() )
740     {
741         if ( GetImpEditEngine()->IsFormatted() )
742 		    GetImpEditEngine()->GetActiveView()->SetSelection( aSelection );
743         else
744 	        GetImpEditEngine()->GetActiveView()->GetImpEditView()->SetEditSelection( GetImpEditEngine()->CreateSel( aSelection ) );
745     }
746 }
747 
Redo()748 void __EXPORT EditUndoMarkSelection::Redo()
749 {
750 	// Fuer Redo unwichtig, weil am Anfang der Undo-Klammerung
751 }
752 
753