xref: /AOO41X/main/sw/source/ui/wrtsh/delete.cxx (revision 04b6b6870a929068b71eb32da22b56d2ed2733d5)
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