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
OpenMark()41 inline void SwWrtShell::OpenMark()
42 {
43 StartAllAction();
44 ResetCursorStack();
45 KillPams();
46 SetMark();
47 }
48
CloseMark(sal_Bool bOkFlag)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#
TryRemoveIndent()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
DelLine()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
DelToStartOfLine()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
DelToEndOfLine()137 long SwWrtShell::DelToEndOfLine()
138 {
139 OpenMark();
140 SwCrsrShell::RightMargin();
141 long nRet = Delete();
142 CloseMark( 0 != nRet );
143 return 1;
144 }
145
DelLeft()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
DelRight()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
DelToEndOfPara()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
DelToStartOfPara()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
DelToStartOfSentence()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
DelToEndOfSentence()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
DelNxtWord()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
DelPrvWord()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