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