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
OpenMark()38 inline void SwWrtShell::OpenMark()
39 {
40 StartAllAction();
41 ResetCursorStack();
42 KillPams();
43 SetMark();
44 }
45
CloseMark(sal_Bool bOkFlag)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#
TryRemoveIndent()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
DelLine()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
DelToStartOfLine()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
DelToEndOfLine()134 long SwWrtShell::DelToEndOfLine()
135 {
136 OpenMark();
137 SwCrsrShell::RightMargin();
138 long nRet = Delete();
139 CloseMark( 0 != nRet );
140 return 1;
141 }
142
DelLeft()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
DelRight()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
DelToEndOfPara()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
DelToStartOfPara()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
DelToStartOfSentence()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
DelToEndOfSentence()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
DelNxtWord()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
DelPrvWord()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