xref: /trunk/main/sw/source/ui/wrtsh/delete.cxx (revision 30d6b308)
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 spaces
552                 short n = 0;
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