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