xref: /AOO41X/main/sw/source/ui/wrtsh/delete.cxx (revision aa965f1ff83e91e51e53dc50c14128e1da93141f)
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 
41 inline void SwWrtShell::OpenMark()
42 {
43 	StartAllAction();
44 	ResetCursorStack();
45 	KillPams();
46 	SetMark();
47 }
48 
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#
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 
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 
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 
137 long SwWrtShell::DelToEndOfLine()
138 {
139 	OpenMark();
140 	SwCrsrShell::RightMargin();
141 	long nRet = Delete();
142 	CloseMark( 0 != nRet );
143 	return 1;
144 }
145 
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 
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 
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 
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 
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 
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 
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 
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