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 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
DelToEndOfPara()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
DelToStartOfPara()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
DelToStartOfSentence()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
DelToEndOfSentence()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
DelNxtWord()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
DelPrvWord()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