1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sw.hxx" 30 31 32 #include <wrtsh.hxx> 33 #include <crsskip.hxx> 34 #include <swcrsr.hxx> 35 #include <editeng/lrspitem.hxx> // #i23725# 36 // --> OD 2006-07-10 #134369# 37 #ifndef _VIEW_HXX 38 #include <view.hxx> 39 #endif 40 #ifndef _DRAWBASE_HXX 41 #include <drawbase.hxx> 42 #endif 43 // <-- 44 45 inline void SwWrtShell::OpenMark() 46 { 47 StartAllAction(); 48 ResetCursorStack(); 49 KillPams(); 50 SetMark(); 51 } 52 53 inline void SwWrtShell::CloseMark( sal_Bool bOkFlag ) 54 { 55 if( bOkFlag ) 56 UpdateAttr(); 57 else 58 SwapPam(); 59 60 ClearMark(); 61 EndAllAction(); 62 } 63 64 // #i23725# 65 sal_Bool SwWrtShell::TryRemoveIndent() 66 { 67 sal_Bool bResult = sal_False; 68 69 SfxItemSet aAttrSet(GetAttrPool(), RES_LR_SPACE, RES_LR_SPACE); 70 GetCurAttr(aAttrSet); 71 72 SvxLRSpaceItem aItem = (const SvxLRSpaceItem &)aAttrSet.Get(RES_LR_SPACE); 73 short aOldFirstLineOfst = aItem.GetTxtFirstLineOfst(); 74 75 if (aOldFirstLineOfst > 0) 76 { 77 aItem.SetTxtFirstLineOfst(0); 78 bResult = sal_True; 79 } 80 else if (aOldFirstLineOfst < 0) 81 { 82 aItem.SetTxtFirstLineOfst(0); 83 aItem.SetLeft(aItem.GetLeft() + aOldFirstLineOfst); 84 85 bResult = sal_True; 86 } 87 else if (aItem.GetLeft() != 0) 88 { 89 aItem.SetLeft(0); 90 bResult = sal_True; 91 } 92 93 if (bResult) 94 { 95 aAttrSet.Put(aItem); 96 SetAttr(aAttrSet); 97 } 98 99 return bResult; 100 } 101 102 /*------------------------------------------------------------------------ 103 Beschreibung: Zeile loeschen 104 ------------------------------------------------------------------------*/ 105 106 107 108 long SwWrtShell::DelLine() 109 { 110 ACT_KONTEXT(this); 111 ResetCursorStack(); 112 // alten Cursor merken 113 Push(); 114 ClearMark(); 115 SwCrsrShell::LeftMargin(); 116 SetMark(); 117 SwCrsrShell::RightMargin(); 118 //Warum soll hier noch ein Zeichen in der naechsten Zeile geloescht werden? 119 // if(!IsEndOfPara()) 120 // SwCrsrShell::Right(); 121 long nRet = Delete(); 122 Pop(sal_False); 123 if( nRet ) 124 UpdateAttr(); 125 return nRet; 126 } 127 128 129 130 long SwWrtShell::DelToStartOfLine() 131 { 132 OpenMark(); 133 SwCrsrShell::LeftMargin(); 134 long nRet = Delete(); 135 CloseMark( 0 != nRet ); 136 return nRet; 137 } 138 139 140 141 long SwWrtShell::DelToEndOfLine() 142 { 143 OpenMark(); 144 SwCrsrShell::RightMargin(); 145 long nRet = Delete(); 146 CloseMark( 0 != nRet ); 147 return 1; 148 } 149 150 long SwWrtShell::DelLeft() 151 { 152 // wenns denn ein Fly ist, wech damit 153 int nSelType = GetSelectionType(); 154 const int nCmp = nsSelectionType::SEL_FRM | nsSelectionType::SEL_GRF | nsSelectionType::SEL_OLE | nsSelectionType::SEL_DRW; 155 if( nCmp & nSelType ) 156 { 157 /* #108205# Remember object's position. */ 158 Point aTmpPt = GetObjRect().TopLeft(); 159 160 DelSelectedObj(); 161 162 /* #108205# Set cursor to remembered position. */ 163 SetCrsr(&aTmpPt); 164 165 LeaveSelFrmMode(); 166 UnSelectFrm(); 167 168 nSelType = GetSelectionType(); 169 if ( nCmp & nSelType ) 170 { 171 EnterSelFrmMode(); 172 GotoNextFly(); 173 } 174 175 return 1L; 176 } 177 178 // wenn eine Selektion existiert, diese loeschen. 179 if ( IsSelection() ) 180 { 181 if( !IsBlockMode() || HasSelection() ) 182 { 183 //OS: wieder einmal Basic: ACT_KONTEXT muss vor 184 //EnterStdMode verlassen werden! 185 { 186 ACT_KONTEXT(this); 187 ResetCursorStack(); 188 Delete(); 189 UpdateAttr(); 190 } 191 if( IsBlockMode() ) 192 { 193 NormalizePam(); 194 ClearMark(); 195 EnterBlockMode(); 196 } 197 else 198 EnterStdMode(); 199 return 1L; 200 } 201 else 202 EnterStdMode(); 203 } 204 205 // JP 29.06.95: nie eine davor stehende Tabelle loeschen. 206 sal_Bool bSwap = sal_False; 207 const SwTableNode * pWasInTblNd = SwCrsrShell::IsCrsrInTbl(); 208 209 if( SwCrsrShell::IsSttPara()) 210 { 211 // --> FME 2007-02-15 #i4032# Don't actually call a 'delete' if we 212 // changed the table cell, compare DelRight(). 213 const SwStartNode * pSNdOld = pWasInTblNd ? 214 GetSwCrsr()->GetNode()->FindTableBoxStartNode() : 215 0; 216 // <-- 217 218 /* If the cursor is at the beginning of a paragraph, try to step 219 backwards. On failure we are done. */ 220 if( !SwCrsrShell::Left(1,CRSR_SKIP_CHARS) ) 221 return 0; 222 223 /* If the cursor entered or left a table (or both) we are done. No step 224 back. */ 225 const SwTableNode* pIsInTblNd = SwCrsrShell::IsCrsrInTbl(); 226 if( pIsInTblNd != pWasInTblNd ) 227 return 0; 228 229 const SwStartNode* pSNdNew = pIsInTblNd ? 230 GetSwCrsr()->GetNode()->FindTableBoxStartNode() : 231 0; 232 233 // --> FME 2007-02-15 #i4032# Don't actually call a 'delete' if we 234 // changed the table cell, compare DelRight(). 235 if ( pSNdOld != pSNdNew ) 236 return 0; 237 // <-- 238 239 OpenMark(); 240 SwCrsrShell::Right(1,CRSR_SKIP_CHARS); 241 SwCrsrShell::SwapPam(); 242 bSwap = sal_True; 243 } 244 else 245 { 246 OpenMark(); 247 SwCrsrShell::Left(1,CRSR_SKIP_CHARS); 248 } 249 long nRet = Delete(); 250 if( !nRet && bSwap ) 251 SwCrsrShell::SwapPam(); 252 CloseMark( 0 != nRet ); 253 return nRet; 254 } 255 256 long SwWrtShell::DelRight() 257 { 258 // werden verodert, wenn Tabellenselektion vorliegt; 259 // wird hier auf nsSelectionType::SEL_TBL umgesetzt. 260 long nRet = 0; 261 int nSelection = GetSelectionType(); 262 if(nSelection & nsSelectionType::SEL_TBL_CELLS) 263 nSelection = nsSelectionType::SEL_TBL; 264 if(nSelection & nsSelectionType::SEL_TXT) 265 nSelection = nsSelectionType::SEL_TXT; 266 267 const SwTableNode * pWasInTblNd = NULL; 268 269 switch( nSelection & ~(nsSelectionType::SEL_BEZ) ) 270 { 271 case nsSelectionType::SEL_POSTIT: 272 case nsSelectionType::SEL_TXT: 273 case nsSelectionType::SEL_TBL: 274 case nsSelectionType::SEL_NUM: 275 // wenn eine Selektion existiert, diese loeschen. 276 if( IsSelection() ) 277 { 278 if( !IsBlockMode() || HasSelection() ) 279 { 280 //OS: wieder einmal Basic: ACT_KONTEXT muss vor 281 //EnterStdMode verlassen werden! 282 { 283 ACT_KONTEXT(this); 284 ResetCursorStack(); 285 Delete(); 286 UpdateAttr(); 287 } 288 if( IsBlockMode() ) 289 { 290 NormalizePam(); 291 ClearMark(); 292 EnterBlockMode(); 293 } 294 else 295 EnterStdMode(); 296 nRet = 1L; 297 break; 298 } 299 else 300 EnterStdMode(); 301 } 302 303 pWasInTblNd = IsCrsrInTbl(); 304 305 if( nsSelectionType::SEL_TXT & nSelection && SwCrsrShell::IsSttPara() && 306 SwCrsrShell::IsEndPara() ) 307 { 308 // save cursor 309 SwCrsrShell::Push(); 310 311 bool bDelFull = false; 312 if ( SwCrsrShell::Right(1,CRSR_SKIP_CHARS) ) 313 { 314 const SwTableNode * pCurrTblNd = IsCrsrInTbl(); 315 bDelFull = pCurrTblNd && pCurrTblNd != pWasInTblNd; 316 } 317 318 // restore cursor 319 SwCrsrShell::Pop( sal_False ); 320 321 if( bDelFull ) 322 { 323 DelFullPara(); 324 UpdateAttr(); 325 break; 326 } 327 } 328 329 { 330 /* #108049# Save the startnode of the current cell */ 331 const SwStartNode * pSNdOld; 332 pSNdOld = GetSwCrsr()->GetNode()-> 333 FindTableBoxStartNode(); 334 335 if ( SwCrsrShell::IsEndPara() ) 336 { 337 // --> FME 2005-01-28 #i41424# Introduced a couple of 338 // Push()-Pop() pairs here. The reason for this is that a 339 // Right()-Left() combination does not make sure, that 340 // the cursor will be in its initial state, because there 341 // may be a numbering in front of the next paragraph. 342 SwCrsrShell::Push(); 343 // <-- 344 345 if ( SwCrsrShell::Right(1, CRSR_SKIP_CHARS) ) 346 { 347 if (IsCrsrInTbl() || (pWasInTblNd != IsCrsrInTbl())) 348 { 349 /* #108049# Save the startnode of the current 350 cell. May be different to pSNdOld as we have 351 moved. */ 352 const SwStartNode * pSNdNew = GetSwCrsr() 353 ->GetNode()->FindTableBoxStartNode(); 354 355 /* #108049# Only move instead of deleting if we 356 have moved to a different cell */ 357 if (pSNdOld != pSNdNew) 358 { 359 SwCrsrShell::Pop( sal_True ); 360 break; 361 } 362 } 363 } 364 365 // restore cursor 366 SwCrsrShell::Pop( sal_False ); 367 } 368 } 369 370 OpenMark(); 371 SwCrsrShell::Right(1,CRSR_SKIP_CELLS); 372 nRet = Delete(); 373 CloseMark( 0 != nRet ); 374 break; 375 376 case nsSelectionType::SEL_FRM: 377 case nsSelectionType::SEL_GRF: 378 case nsSelectionType::SEL_OLE: 379 case nsSelectionType::SEL_DRW: 380 case nsSelectionType::SEL_DRW_TXT: 381 case nsSelectionType::SEL_DRW_FORM: 382 { 383 /* #108205# Remember object's position. */ 384 Point aTmpPt = GetObjRect().TopLeft(); 385 386 DelSelectedObj(); 387 388 /* #108205# Set cursor to remembered position. */ 389 SetCrsr(&aTmpPt); 390 391 LeaveSelFrmMode(); 392 UnSelectFrm(); 393 // --> OD 2006-07-06 #134369# 394 ASSERT( !IsFrmSelected(), 395 "<SwWrtShell::DelRight(..)> - <SwWrtShell::UnSelectFrm()> should unmark all objects" ) 396 // <-- 397 // --> OD 2006-07-10 #134369# 398 // leave draw mode, if necessary. 399 { 400 if (GetView().GetDrawFuncPtr()) 401 { 402 GetView().GetDrawFuncPtr()->Deactivate(); 403 GetView().SetDrawFuncPtr(NULL); 404 } 405 if ( GetView().IsDrawMode() ) 406 { 407 GetView().LeaveDrawCreate(); 408 } 409 } 410 // <-- 411 } 412 413 // --> OD 2006-07-07 #134369# 414 // <IsFrmSelected()> can't be true - see above. 415 // <-- 416 { 417 nSelection = GetSelectionType(); 418 if ( nsSelectionType::SEL_FRM & nSelection || 419 nsSelectionType::SEL_GRF & nSelection || 420 nsSelectionType::SEL_OLE & nSelection || 421 nsSelectionType::SEL_DRW & nSelection ) 422 { 423 EnterSelFrmMode(); 424 GotoNextFly(); 425 } 426 } 427 nRet = 1; 428 break; 429 } 430 return nRet; 431 } 432 433 434 435 long SwWrtShell::DelToEndOfPara() 436 { 437 ACT_KONTEXT(this); 438 ResetCursorStack(); 439 Push(); 440 SetMark(); 441 if( !MovePara(fnParaCurr,fnParaEnd)) 442 { 443 Pop(sal_False); 444 return 0; 445 } 446 long nRet = Delete(); 447 Pop(sal_False); 448 if( nRet ) 449 UpdateAttr(); 450 return nRet; 451 } 452 453 454 455 long SwWrtShell::DelToStartOfPara() 456 { 457 ACT_KONTEXT(this); 458 ResetCursorStack(); 459 Push(); 460 SetMark(); 461 if( !MovePara(fnParaCurr,fnParaStart)) 462 { 463 Pop(sal_False); 464 return 0; 465 } 466 long nRet = Delete(); 467 Pop(sal_False); 468 if( nRet ) 469 UpdateAttr(); 470 return nRet; 471 } 472 /* 473 * alle Loeschoperationen sollten mit Find statt mit 474 * Nxt-/PrvDelim arbeiten, da letzteren mit Wrap Around arbeiten 475 * -- das ist wohl nicht gewuenscht. 476 */ 477 478 479 480 long SwWrtShell::DelToStartOfSentence() 481 { 482 if(IsStartOfDoc()) 483 return 0; 484 OpenMark(); 485 long nRet = _BwdSentence() ? Delete() : 0; 486 CloseMark( 0 != nRet ); 487 return nRet; 488 } 489 490 491 492 long SwWrtShell::DelToEndOfSentence() 493 { 494 if(IsEndOfDoc()) 495 return 0; 496 OpenMark(); 497 long nRet = _FwdSentence() ? Delete() : 0; 498 CloseMark( 0 != nRet ); 499 return nRet; 500 } 501 502 503 504 long SwWrtShell::DelNxtWord() 505 { 506 if(IsEndOfDoc()) 507 return 0; 508 ACT_KONTEXT(this); 509 ResetCursorStack(); 510 EnterStdMode(); 511 SetMark(); 512 if(IsEndWrd() && !IsSttWrd()) 513 _NxtWrdForDelete(); // --> OD 2008-08-06 #i92468# 514 if(IsSttWrd() || IsEndPara()) 515 _NxtWrdForDelete(); // --> OD 2008-08-06 #i92468# 516 else 517 _EndWrd(); 518 519 long nRet = Delete(); 520 if( nRet ) 521 UpdateAttr(); 522 else 523 SwapPam(); 524 ClearMark(); 525 return nRet; 526 } 527 528 529 530 long SwWrtShell::DelPrvWord() 531 { 532 if(IsStartOfDoc()) 533 return 0; 534 ACT_KONTEXT(this); 535 ResetCursorStack(); 536 EnterStdMode(); 537 SetMark(); 538 if ( !IsSttWrd() || 539 !_PrvWrdForDelete() ) // --> OD 2008-08-06 #i92468# 540 { 541 if( IsEndWrd() ) 542 { 543 if ( _PrvWrdForDelete() ) // --> OD 2008-08-06 #i92468# 544 { 545 // skip over all-1 spaces 546 short n = -1; 547 while( ' ' == GetChar( sal_False, n )) 548 --n; 549 550 if( ++n ) 551 ExtendSelection( sal_False, -n ); 552 } 553 } 554 else if( IsSttPara()) 555 _PrvWrdForDelete(); // --> OD 2008-08-06 #i92468# 556 else 557 _SttWrd(); 558 } 559 long nRet = Delete(); 560 if( nRet ) 561 UpdateAttr(); 562 else 563 SwapPam(); 564 ClearMark(); 565 return nRet; 566 } 567 568 569 570 571