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_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 // ------------------------------------------------------------------------ 68 EditUndoManager::EditUndoManager(sal_uInt16 nMaxUndoActionCount ) 69 : SfxUndoManager(nMaxUndoActionCount), 70 mpImpEE(0) 71 { 72 } 73 74 void EditUndoManager::SetImpEditEngine(ImpEditEngine* pNew) 75 { 76 mpImpEE = pNew; 77 } 78 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 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 // ------------------------------------------------------------------------ 152 EditUndo::EditUndo( sal_uInt16 nI, ImpEditEngine* p ) 153 { 154 DBG_CTOR( EditUndo, 0 ); 155 nId = nI; 156 pImpEE = p; 157 } 158 159 EditUndo::~EditUndo() 160 { 161 DBG_DTOR( EditUndo, 0 ); 162 } 163 164 sal_uInt16 __EXPORT EditUndo::GetId() const 165 { 166 DBG_CHKTHIS( EditUndo, 0 ); 167 return nId; 168 } 169 170 sal_Bool __EXPORT EditUndo::CanRepeat(SfxRepeatTarget&) const 171 { 172 return sal_False; 173 } 174 175 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 // ------------------------------------------------------------------------ 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 197 EditUndoDelContent::~EditUndoDelContent() 198 { 199 if ( bDelObject ) 200 delete pContentNode; 201 } 202 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 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 // ------------------------------------------------------------------------ 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 273 EditUndoConnectParas::~EditUndoConnectParas() 274 { 275 } 276 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 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 // ------------------------------------------------------------------------ 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 325 EditUndoSplitPara::~EditUndoSplitPara() 326 { 327 } 328 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 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 // ------------------------------------------------------------------------ 346 EditUndoInsertChars::EditUndoInsertChars( ImpEditEngine* _pImpEE, const EPaM& rEPaM, const XubString& rStr ) 347 : EditUndo( EDITUNDO_INSERTCHARS, _pImpEE ), 348 aEPaM( rEPaM ), aText( rStr ) 349 { 350 } 351 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 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 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 // ------------------------------------------------------------------------ 393 EditUndoRemoveChars::EditUndoRemoveChars( ImpEditEngine* _pImpEE, const EPaM& rEPaM, const XubString& rStr ) 394 : EditUndo( EDITUNDO_REMOVECHARS, _pImpEE ), 395 aEPaM( rEPaM ), aText( rStr ) 396 { 397 } 398 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 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 // ------------------------------------------------------------------------ 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 429 EditUndoInsertFeature::~EditUndoInsertFeature() 430 { 431 delete pFeature; 432 } 433 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 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 // ------------------------------------------------------------------------ 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 469 EditUndoMoveParagraphs::~EditUndoMoveParagraphs() 470 { 471 } 472 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 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 // ------------------------------------------------------------------------ 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 518 EditUndoSetStyleSheet::~EditUndoSetStyleSheet() 519 { 520 } 521 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 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 // ------------------------------------------------------------------------ 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 548 EditUndoSetParaAttribs::~EditUndoSetParaAttribs() 549 { 550 } 551 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 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 // ------------------------------------------------------------------------ 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 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 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 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 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 // ------------------------------------------------------------------------ 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 669 EditUndoTransliteration::~EditUndoTransliteration() 670 { 671 delete pTxtObj; 672 } 673 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 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 // ------------------------------------------------------------------------ 727 EditUndoMarkSelection::EditUndoMarkSelection( ImpEditEngine* _pImpEE, const ESelection& rSel ) 728 : EditUndo( EDITUNDO_MARKSELECTION, _pImpEE ), aSelection( rSel ) 729 { 730 } 731 732 EditUndoMarkSelection::~EditUndoMarkSelection() 733 { 734 } 735 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 748 void __EXPORT EditUndoMarkSelection::Redo() 749 { 750 // Fuer Redo unwichtig, weil am Anfang der Undo-Klammerung 751 } 752 753