xref: /AOO41X/main/editeng/source/editeng/editundo.cxx (revision 69ffbee119db80509b30f38e8f68183328897996)
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_uInt16 nPara)56 void lcl_DoSetSelection( EditView* pView, sal_uInt16 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_uInt16 n)189 EditUndoDelContent::EditUndoDelContent( ImpEditEngine* _pImpEE, ContentNode* pNode, sal_uInt16 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_uInt16 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_uInt16 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( (sal_uInt16)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_uInt16 nN,sal_uInt16 nSP)318 EditUndoSplitPara::EditUndoSplitPara( ImpEditEngine* _pImpEE, sal_uInt16 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_uInt16 n)461 EditUndoMoveParagraphs::EditUndoMoveParagraphs
462                             ( ImpEditEngine* _pImpEE, const Range& rParas, sal_uInt16 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_uInt16)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_uInt16 nP,const XubString & rPrevName,SfxStyleFamily ePrevFam,const XubString & rNewName,SfxStyleFamily eNewFam,const SfxItemSet & rPrevParaAttribs)506 EditUndoSetStyleSheet::EditUndoSetStyleSheet( ImpEditEngine* _pImpEE, sal_uInt16 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_uInt16 nP,const SfxItemSet & rPrevItems,const SfxItemSet & rNewItems)540 EditUndoSetParaAttribs::EditUndoSetParaAttribs( ImpEditEngine* _pImpEE, sal_uInt16 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_uInt16 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