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