xref: /trunk/main/sw/source/ui/wrtsh/delete.cxx (revision 6e2947abcd32c68d8b41a6b46ee7d63b91c825fe)
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