xref: /aoo41x/main/sw/source/ui/wrtsh/delete.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sw.hxx"
30 
31 
32 #include <wrtsh.hxx>
33 #include <crsskip.hxx>
34 #include <swcrsr.hxx>
35 #include <editeng/lrspitem.hxx> // #i23725#
36 // --> OD 2006-07-10 #134369#
37 #ifndef _VIEW_HXX
38 #include <view.hxx>
39 #endif
40 #ifndef _DRAWBASE_HXX
41 #include <drawbase.hxx>
42 #endif
43 // <--
44 
45 inline void SwWrtShell::OpenMark()
46 {
47 	StartAllAction();
48 	ResetCursorStack();
49 	KillPams();
50 	SetMark();
51 }
52 
53 inline void SwWrtShell::CloseMark( sal_Bool bOkFlag )
54 {
55 	if( bOkFlag )
56 		UpdateAttr();
57 	else
58 		SwapPam();
59 
60 	ClearMark();
61 	EndAllAction();
62 }
63 
64 // #i23725#
65 sal_Bool SwWrtShell::TryRemoveIndent()
66 {
67     sal_Bool bResult = sal_False;
68 
69     SfxItemSet aAttrSet(GetAttrPool(), RES_LR_SPACE, RES_LR_SPACE);
70     GetCurAttr(aAttrSet);
71 
72     SvxLRSpaceItem aItem = (const SvxLRSpaceItem &)aAttrSet.Get(RES_LR_SPACE);
73     short aOldFirstLineOfst = aItem.GetTxtFirstLineOfst();
74 
75     if (aOldFirstLineOfst > 0)
76     {
77         aItem.SetTxtFirstLineOfst(0);
78         bResult = sal_True;
79     }
80     else if (aOldFirstLineOfst < 0)
81     {
82         aItem.SetTxtFirstLineOfst(0);
83         aItem.SetLeft(aItem.GetLeft() + aOldFirstLineOfst);
84 
85         bResult = sal_True;
86     }
87     else if (aItem.GetLeft() != 0)
88     {
89         aItem.SetLeft(0);
90         bResult = sal_True;
91     }
92 
93     if (bResult)
94     {
95         aAttrSet.Put(aItem);
96         SetAttr(aAttrSet);
97     }
98 
99     return bResult;
100 }
101 
102 /*------------------------------------------------------------------------
103  Beschreibung:	Zeile loeschen
104 ------------------------------------------------------------------------*/
105 
106 
107 
108 long SwWrtShell::DelLine()
109 {
110 	ACT_KONTEXT(this);
111 	ResetCursorStack();
112 		// alten Cursor merken
113 	Push();
114 	ClearMark();
115 	SwCrsrShell::LeftMargin();
116 	SetMark();
117 	SwCrsrShell::RightMargin();
118 //Warum soll hier noch ein Zeichen in der naechsten Zeile geloescht werden?
119 //	if(!IsEndOfPara())
120 //		SwCrsrShell::Right();
121 	long nRet = Delete();
122 	Pop(sal_False);
123 	if( nRet )
124 		UpdateAttr();
125 	return nRet;
126 }
127 
128 
129 
130 long SwWrtShell::DelToStartOfLine()
131 {
132 	OpenMark();
133 	SwCrsrShell::LeftMargin();
134 	long nRet = Delete();
135 	CloseMark( 0 != nRet );
136 	return nRet;
137 }
138 
139 
140 
141 long SwWrtShell::DelToEndOfLine()
142 {
143 	OpenMark();
144 	SwCrsrShell::RightMargin();
145 	long nRet = Delete();
146 	CloseMark( 0 != nRet );
147 	return 1;
148 }
149 
150 long SwWrtShell::DelLeft()
151 {
152 	// wenns denn ein Fly ist, wech damit
153 	int nSelType = GetSelectionType();
154     const int nCmp = nsSelectionType::SEL_FRM | nsSelectionType::SEL_GRF | nsSelectionType::SEL_OLE | nsSelectionType::SEL_DRW;
155 	if( nCmp & nSelType )
156 	{
157         /*  #108205# Remember object's position. */
158         Point aTmpPt = GetObjRect().TopLeft();
159 
160 		DelSelectedObj();
161 
162         /*  #108205# Set cursor to remembered position. */
163         SetCrsr(&aTmpPt);
164 
165 		LeaveSelFrmMode();
166 		UnSelectFrm();
167 
168 		nSelType = GetSelectionType();
169 		if ( nCmp & nSelType )
170 		{
171 			EnterSelFrmMode();
172 			GotoNextFly();
173 		}
174 
175 		return 1L;
176 	}
177 
178 	// wenn eine Selektion existiert, diese loeschen.
179 	if ( IsSelection() )
180 	{
181 		if( !IsBlockMode() || HasSelection() )
182         {
183              //OS: wieder einmal Basic: ACT_KONTEXT muss vor
184             //EnterStdMode verlassen werden!
185             {
186                 ACT_KONTEXT(this);
187                 ResetCursorStack();
188                 Delete();
189                 UpdateAttr();
190             }
191             if( IsBlockMode() )
192             {
193                 NormalizePam();
194                 ClearMark();
195                 EnterBlockMode();
196             }
197             else
198                 EnterStdMode();
199             return 1L;
200         }
201         else
202             EnterStdMode();
203 	}
204 
205 	// JP 29.06.95: nie eine davor stehende Tabelle loeschen.
206 	sal_Bool bSwap = sal_False;
207 	const SwTableNode * pWasInTblNd = SwCrsrShell::IsCrsrInTbl();
208 
209 	if( SwCrsrShell::IsSttPara())
210 	{
211         // --> FME 2007-02-15 #i4032# Don't actually call a 'delete' if we
212         // changed the table cell, compare DelRight().
213         const SwStartNode * pSNdOld = pWasInTblNd ?
214                                       GetSwCrsr()->GetNode()->FindTableBoxStartNode() :
215                                       0;
216         // <--
217 
218         /* If the cursor is at the beginning of a paragraph, try to step
219            backwards. On failure we are done. */
220 		if( !SwCrsrShell::Left(1,CRSR_SKIP_CHARS) )
221 			return 0;
222 
223 		/* If the cursor entered or left a table (or both) we are done. No step
224            back. */
225         const SwTableNode* pIsInTblNd = SwCrsrShell::IsCrsrInTbl();
226         if( pIsInTblNd != pWasInTblNd )
227 			return 0;
228 
229         const SwStartNode* pSNdNew = pIsInTblNd ?
230                                      GetSwCrsr()->GetNode()->FindTableBoxStartNode() :
231                                      0;
232 
233         // --> FME 2007-02-15 #i4032# Don't actually call a 'delete' if we
234         // changed the table cell, compare DelRight().
235         if ( pSNdOld != pSNdNew )
236             return 0;
237         // <--
238 
239 		OpenMark();
240 		SwCrsrShell::Right(1,CRSR_SKIP_CHARS);
241 		SwCrsrShell::SwapPam();
242 		bSwap = sal_True;
243 	}
244 	else
245 	{
246 		OpenMark();
247 		SwCrsrShell::Left(1,CRSR_SKIP_CHARS);
248 	}
249 	long nRet = Delete();
250 	if( !nRet && bSwap )
251 		SwCrsrShell::SwapPam();
252 	CloseMark( 0 != nRet );
253 	return nRet;
254 }
255 
256 long SwWrtShell::DelRight()
257 {
258 		// werden verodert, wenn Tabellenselektion vorliegt;
259         // wird hier auf nsSelectionType::SEL_TBL umgesetzt.
260 	long nRet = 0;
261 	int nSelection = GetSelectionType();
262 	if(nSelection & nsSelectionType::SEL_TBL_CELLS)
263 		nSelection = nsSelectionType::SEL_TBL;
264 	if(nSelection & nsSelectionType::SEL_TXT)
265 		nSelection = nsSelectionType::SEL_TXT;
266 
267 	const SwTableNode * pWasInTblNd = NULL;
268 
269     switch( nSelection & ~(nsSelectionType::SEL_BEZ) )
270 	{
271 	case nsSelectionType::SEL_POSTIT:
272     case nsSelectionType::SEL_TXT:
273     case nsSelectionType::SEL_TBL:
274     case nsSelectionType::SEL_NUM:
275 			//	wenn eine Selektion existiert, diese loeschen.
276 		if( IsSelection() )
277 		{
278             if( !IsBlockMode() || HasSelection() )
279             {
280                 //OS: wieder einmal Basic: ACT_KONTEXT muss vor
281                 //EnterStdMode verlassen werden!
282                 {
283                     ACT_KONTEXT(this);
284                     ResetCursorStack();
285                     Delete();
286                     UpdateAttr();
287                 }
288                 if( IsBlockMode() )
289                 {
290                     NormalizePam();
291                     ClearMark();
292                     EnterBlockMode();
293                 }
294                 else
295                     EnterStdMode();
296                 nRet = 1L;
297                 break;
298             }
299             else
300                 EnterStdMode();
301 		}
302 
303 		pWasInTblNd = IsCrsrInTbl();
304 
305         if( nsSelectionType::SEL_TXT & nSelection && SwCrsrShell::IsSttPara() &&
306             SwCrsrShell::IsEndPara() )
307         {
308             // save cursor
309             SwCrsrShell::Push();
310 
311             bool bDelFull = false;
312             if ( SwCrsrShell::Right(1,CRSR_SKIP_CHARS) )
313 		    {
314             	const SwTableNode * pCurrTblNd = IsCrsrInTbl();
315 			    bDelFull = pCurrTblNd && pCurrTblNd != pWasInTblNd;
316             }
317 
318             // restore cursor
319             SwCrsrShell::Pop( sal_False );
320 
321     	    if( bDelFull )
322 		    {
323     			DelFullPara();
324 			    UpdateAttr();
325 			    break;
326 		    }
327 		}
328 
329         {
330             /* #108049# Save the startnode of the current cell */
331             const SwStartNode * pSNdOld;
332             pSNdOld = GetSwCrsr()->GetNode()->
333                 FindTableBoxStartNode();
334 
335             if ( SwCrsrShell::IsEndPara() )
336             {
337                 // --> FME 2005-01-28 #i41424# Introduced a couple of
338                 // Push()-Pop() pairs here. The reason for this is that a
339                 // Right()-Left() combination does not make sure, that
340                 // the cursor will be in its initial state, because there
341                 // may be a numbering in front of the next paragraph.
342                 SwCrsrShell::Push();
343                 // <--
344 
345                 if ( SwCrsrShell::Right(1, CRSR_SKIP_CHARS) )
346                 {
347                     if (IsCrsrInTbl() || (pWasInTblNd != IsCrsrInTbl()))
348                     {
349                         /* #108049# Save the startnode of the current
350                             cell. May be different to pSNdOld as we have
351                             moved. */
352                         const SwStartNode * pSNdNew = GetSwCrsr()
353                             ->GetNode()->FindTableBoxStartNode();
354 
355                         /* #108049# Only move instead of deleting if we
356                             have moved to a different cell */
357                         if (pSNdOld != pSNdNew)
358                         {
359                             SwCrsrShell::Pop( sal_True );
360                             break;
361                         }
362                     }
363                 }
364 
365                 // restore cursor
366                 SwCrsrShell::Pop( sal_False );
367             }
368         }
369 
370 		OpenMark();
371 		SwCrsrShell::Right(1,CRSR_SKIP_CELLS);
372 		nRet = Delete();
373 		CloseMark( 0 != nRet );
374 		break;
375 
376     case nsSelectionType::SEL_FRM:
377     case nsSelectionType::SEL_GRF:
378     case nsSelectionType::SEL_OLE:
379     case nsSelectionType::SEL_DRW:
380     case nsSelectionType::SEL_DRW_TXT:
381     case nsSelectionType::SEL_DRW_FORM:
382         {
383             /*  #108205# Remember object's position. */
384             Point aTmpPt = GetObjRect().TopLeft();
385 
386             DelSelectedObj();
387 
388             /*  #108205# Set cursor to remembered position. */
389             SetCrsr(&aTmpPt);
390 
391             LeaveSelFrmMode();
392             UnSelectFrm();
393             // --> OD 2006-07-06 #134369#
394             ASSERT( !IsFrmSelected(),
395                     "<SwWrtShell::DelRight(..)> - <SwWrtShell::UnSelectFrm()> should unmark all objects" )
396             // <--
397             // --> OD 2006-07-10 #134369#
398             // leave draw mode, if necessary.
399             {
400                 if (GetView().GetDrawFuncPtr())
401                 {
402                     GetView().GetDrawFuncPtr()->Deactivate();
403                     GetView().SetDrawFuncPtr(NULL);
404                 }
405                 if ( GetView().IsDrawMode() )
406                 {
407                     GetView().LeaveDrawCreate();
408                 }
409             }
410             // <--
411         }
412 
413         // --> OD 2006-07-07 #134369#
414         // <IsFrmSelected()> can't be true - see above.
415         // <--
416 		{
417 			nSelection = GetSelectionType();
418             if ( nsSelectionType::SEL_FRM & nSelection ||
419                  nsSelectionType::SEL_GRF & nSelection ||
420                  nsSelectionType::SEL_OLE & nSelection ||
421                  nsSelectionType::SEL_DRW & nSelection )
422 			{
423 				EnterSelFrmMode();
424 				GotoNextFly();
425 			}
426 		}
427 		nRet = 1;
428 		break;
429 	}
430 	return nRet;
431 }
432 
433 
434 
435 long SwWrtShell::DelToEndOfPara()
436 {
437 	ACT_KONTEXT(this);
438 	ResetCursorStack();
439 	Push();
440 	SetMark();
441 	if( !MovePara(fnParaCurr,fnParaEnd))
442 	{
443 		Pop(sal_False);
444 		return 0;
445 	}
446 	long nRet = Delete();
447 	Pop(sal_False);
448 	if( nRet )
449 		UpdateAttr();
450 	return nRet;
451 }
452 
453 
454 
455 long SwWrtShell::DelToStartOfPara()
456 {
457 	ACT_KONTEXT(this);
458 	ResetCursorStack();
459 	Push();
460 	SetMark();
461 	if( !MovePara(fnParaCurr,fnParaStart))
462 	{
463 		Pop(sal_False);
464 		return 0;
465 	}
466 	long nRet = Delete();
467 	Pop(sal_False);
468 	if( nRet )
469 		UpdateAttr();
470 	return nRet;
471 }
472 /*
473  * alle Loeschoperationen sollten mit Find statt mit
474  * Nxt-/PrvDelim arbeiten, da letzteren mit Wrap Around arbeiten
475  * -- das ist wohl nicht gewuenscht.
476  */
477 
478 
479 
480 long SwWrtShell::DelToStartOfSentence()
481 {
482 	if(IsStartOfDoc())
483 		return 0;
484 	OpenMark();
485 	long nRet = _BwdSentence() ? Delete() : 0;
486 	CloseMark( 0 != nRet );
487 	return nRet;
488 }
489 
490 
491 
492 long SwWrtShell::DelToEndOfSentence()
493 {
494 	if(IsEndOfDoc())
495 		return 0;
496 	OpenMark();
497 	long nRet = _FwdSentence() ? Delete() : 0;
498 	CloseMark( 0 != nRet );
499 	return nRet;
500 }
501 
502 
503 
504 long SwWrtShell::DelNxtWord()
505 {
506 	if(IsEndOfDoc())
507 		return 0;
508 	ACT_KONTEXT(this);
509 	ResetCursorStack();
510 	EnterStdMode();
511 	SetMark();
512 	if(IsEndWrd() && !IsSttWrd())
513         _NxtWrdForDelete(); // --> OD 2008-08-06 #i92468#
514 	if(IsSttWrd() || IsEndPara())
515         _NxtWrdForDelete(); // --> OD 2008-08-06 #i92468#
516 	else
517 		_EndWrd();
518 
519 	long nRet = Delete();
520 	if( nRet )
521 		UpdateAttr();
522 	else
523 		SwapPam();
524 	ClearMark();
525 	return nRet;
526 }
527 
528 
529 
530 long SwWrtShell::DelPrvWord()
531 {
532 	if(IsStartOfDoc())
533 		return 0;
534 	ACT_KONTEXT(this);
535 	ResetCursorStack();
536 	EnterStdMode();
537 	SetMark();
538     if ( !IsSttWrd() ||
539          !_PrvWrdForDelete() ) // --> OD 2008-08-06 #i92468#
540 	{
541 		if( IsEndWrd() )
542 		{
543             if ( _PrvWrdForDelete() ) // --> OD 2008-08-06 #i92468#
544 			{
545 				// skip over all-1 spaces
546 				short n = -1;
547 				while( ' ' == GetChar( sal_False, n ))
548 					--n;
549 
550 				if( ++n )
551 					ExtendSelection( sal_False, -n );
552 			}
553 		}
554 		else if( IsSttPara())
555             _PrvWrdForDelete(); // --> OD 2008-08-06 #i92468#
556 		else
557 			_SttWrd();
558 	}
559 	long nRet = Delete();
560 	if( nRet )
561 		UpdateAttr();
562 	else
563 		SwapPam();
564 	ClearMark();
565 	return nRet;
566 }
567 
568 
569 
570 
571