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 SetAttr(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 263 const SwTableNode * pWasInTblNd = NULL; 264 265 switch( nSelection & ~(nsSelectionType::SEL_BEZ) ) 266 { 267 case nsSelectionType::SEL_POSTIT: 268 case nsSelectionType::SEL_TXT: 269 case nsSelectionType::SEL_TBL: 270 case nsSelectionType::SEL_NUM: 271 // wenn eine Selektion existiert, diese loeschen. 272 if( IsSelection() ) 273 { 274 if( !IsBlockMode() || HasSelection() ) 275 { 276 //OS: wieder einmal Basic: ACT_KONTEXT muss vor 277 //EnterStdMode verlassen werden! 278 { 279 ACT_KONTEXT(this); 280 ResetCursorStack(); 281 Delete(); 282 UpdateAttr(); 283 } 284 if( IsBlockMode() ) 285 { 286 NormalizePam(); 287 ClearMark(); 288 EnterBlockMode(); 289 } 290 else 291 EnterStdMode(); 292 nRet = 1L; 293 break; 294 } 295 else 296 EnterStdMode(); 297 } 298 299 pWasInTblNd = IsCrsrInTbl(); 300 301 if( nsSelectionType::SEL_TXT & nSelection && SwCrsrShell::IsSttPara() && 302 SwCrsrShell::IsEndPara() ) 303 { 304 // save cursor 305 SwCrsrShell::Push(); 306 307 bool bDelFull = false; 308 if ( SwCrsrShell::Right(1,CRSR_SKIP_CHARS) ) 309 { 310 const SwTableNode * pCurrTblNd = IsCrsrInTbl(); 311 bDelFull = pCurrTblNd && pCurrTblNd != pWasInTblNd; 312 } 313 314 // restore cursor 315 SwCrsrShell::Pop( sal_False ); 316 317 if( bDelFull ) 318 { 319 DelFullPara(); 320 UpdateAttr(); 321 break; 322 } 323 } 324 325 { 326 /* #108049# Save the startnode of the current cell */ 327 const SwStartNode * pSNdOld; 328 pSNdOld = GetSwCrsr()->GetNode()-> 329 FindTableBoxStartNode(); 330 331 if ( SwCrsrShell::IsEndPara() ) 332 { 333 // --> FME 2005-01-28 #i41424# Introduced a couple of 334 // Push()-Pop() pairs here. The reason for this is that a 335 // Right()-Left() combination does not make sure, that 336 // the cursor will be in its initial state, because there 337 // may be a numbering in front of the next paragraph. 338 SwCrsrShell::Push(); 339 // <-- 340 341 if ( SwCrsrShell::Right(1, CRSR_SKIP_CHARS) ) 342 { 343 if (IsCrsrInTbl() || (pWasInTblNd != IsCrsrInTbl())) 344 { 345 /* #108049# Save the startnode of the current 346 cell. May be different to pSNdOld as we have 347 moved. */ 348 const SwStartNode * pSNdNew = GetSwCrsr() 349 ->GetNode()->FindTableBoxStartNode(); 350 351 /* #108049# Only move instead of deleting if we 352 have moved to a different cell */ 353 if (pSNdOld != pSNdNew) 354 { 355 SwCrsrShell::Pop( sal_True ); 356 break; 357 } 358 } 359 } 360 361 // restore cursor 362 SwCrsrShell::Pop( sal_False ); 363 } 364 } 365 366 OpenMark(); 367 SwCrsrShell::Right(1,CRSR_SKIP_CELLS); 368 nRet = Delete(); 369 CloseMark( 0 != nRet ); 370 break; 371 372 case nsSelectionType::SEL_FRM: 373 case nsSelectionType::SEL_GRF: 374 case nsSelectionType::SEL_OLE: 375 case nsSelectionType::SEL_DRW: 376 case nsSelectionType::SEL_DRW_TXT: 377 case nsSelectionType::SEL_DRW_FORM: 378 { 379 /* #108205# Remember object's position. */ 380 Point aTmpPt = GetObjRect().TopLeft(); 381 382 DelSelectedObj(); 383 384 /* #108205# Set cursor to remembered position. */ 385 SetCrsr(&aTmpPt); 386 387 LeaveSelFrmMode(); 388 UnSelectFrm(); 389 // --> OD 2006-07-06 #134369# 390 ASSERT( !IsFrmSelected(), 391 "<SwWrtShell::DelRight(..)> - <SwWrtShell::UnSelectFrm()> should unmark all objects" ) 392 // <-- 393 // --> OD 2006-07-10 #134369# 394 // leave draw mode, if necessary. 395 { 396 if (GetView().GetDrawFuncPtr()) 397 { 398 GetView().GetDrawFuncPtr()->Deactivate(); 399 GetView().SetDrawFuncPtr(NULL); 400 } 401 if ( GetView().IsDrawMode() ) 402 { 403 GetView().LeaveDrawCreate(); 404 } 405 } 406 // <-- 407 } 408 409 // --> OD 2006-07-07 #134369# 410 // <IsFrmSelected()> can't be true - see above. 411 // <-- 412 { 413 nSelection = GetSelectionType(); 414 if ( nsSelectionType::SEL_FRM & nSelection || 415 nsSelectionType::SEL_GRF & nSelection || 416 nsSelectionType::SEL_OLE & nSelection || 417 nsSelectionType::SEL_DRW & nSelection ) 418 { 419 EnterSelFrmMode(); 420 GotoNextFly(); 421 } 422 } 423 nRet = 1; 424 break; 425 } 426 return nRet; 427 } 428 429 430 431 long SwWrtShell::DelToEndOfPara() 432 { 433 ACT_KONTEXT(this); 434 ResetCursorStack(); 435 Push(); 436 SetMark(); 437 if( !MovePara(fnParaCurr,fnParaEnd)) 438 { 439 Pop(sal_False); 440 return 0; 441 } 442 long nRet = Delete(); 443 Pop(sal_False); 444 if( nRet ) 445 UpdateAttr(); 446 return nRet; 447 } 448 449 450 451 long SwWrtShell::DelToStartOfPara() 452 { 453 ACT_KONTEXT(this); 454 ResetCursorStack(); 455 Push(); 456 SetMark(); 457 if( !MovePara(fnParaCurr,fnParaStart)) 458 { 459 Pop(sal_False); 460 return 0; 461 } 462 long nRet = Delete(); 463 Pop(sal_False); 464 if( nRet ) 465 UpdateAttr(); 466 return nRet; 467 } 468 /* 469 * alle Loeschoperationen sollten mit Find statt mit 470 * Nxt-/PrvDelim arbeiten, da letzteren mit Wrap Around arbeiten 471 * -- das ist wohl nicht gewuenscht. 472 */ 473 474 475 476 long SwWrtShell::DelToStartOfSentence() 477 { 478 if(IsStartOfDoc()) 479 return 0; 480 OpenMark(); 481 482 SwCrsrSaveState aSaveState( *(_GetCrsr()) ); 483 sal_Bool bSuccessfulSelection = _BwdSentence(); 484 if ( _GetCrsr()->IsInProtectTable( sal_True ) 485 || _GetCrsr()->IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE | 486 nsSwCursorSelOverFlags::SELOVER_CHANGEPOS ) ) 487 { 488 bSuccessfulSelection = sal_False; 489 } 490 long nRet = bSuccessfulSelection ? Delete() : 0; 491 492 CloseMark( 0 != nRet ); 493 return nRet; 494 } 495 496 497 498 long SwWrtShell::DelToEndOfSentence() 499 { 500 if(IsEndOfDoc()) 501 return 0; 502 OpenMark(); 503 long nRet = _FwdSentence() ? Delete() : 0; 504 CloseMark( 0 != nRet ); 505 return nRet; 506 } 507 508 509 510 long SwWrtShell::DelNxtWord() 511 { 512 if(IsEndOfDoc()) 513 return 0; 514 ACT_KONTEXT(this); 515 ResetCursorStack(); 516 EnterStdMode(); 517 SetMark(); 518 if(IsEndWrd() && !IsSttWrd()) 519 _NxtWrdForDelete(); // --> OD 2008-08-06 #i92468# 520 if(IsSttWrd() || IsEndPara()) 521 _NxtWrdForDelete(); // --> OD 2008-08-06 #i92468# 522 else 523 _EndWrd(); 524 525 long nRet = Delete(); 526 if( nRet ) 527 UpdateAttr(); 528 else 529 SwapPam(); 530 ClearMark(); 531 return nRet; 532 } 533 534 535 536 long SwWrtShell::DelPrvWord() 537 { 538 if(IsStartOfDoc()) 539 return 0; 540 ACT_KONTEXT(this); 541 ResetCursorStack(); 542 EnterStdMode(); 543 SetMark(); 544 if ( !IsSttWrd() || 545 !_PrvWrdForDelete() ) // --> OD 2008-08-06 #i92468# 546 { 547 if( IsEndWrd() ) 548 { 549 if ( _PrvWrdForDelete() ) // --> OD 2008-08-06 #i92468# 550 { 551 // skip over all-1 spaces 552 short n = -1; 553 while( ' ' == GetChar( sal_False, n )) 554 --n; 555 556 if( ++n ) 557 ExtendSelection( sal_False, -n ); 558 } 559 } 560 else if( IsSttPara()) 561 _PrvWrdForDelete(); // --> OD 2008-08-06 #i92468# 562 else 563 _SttWrd(); 564 } 565 long nRet = Delete(); 566 if( nRet ) 567 UpdateAttr(); 568 else 569 SwapPam(); 570 ClearMark(); 571 return nRet; 572 } 573 574 575 576 577