Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <wrtsh.hxx>
21 : #include <crsskip.hxx>
22 : #include <swcrsr.hxx>
23 : #include <editeng/lrspitem.hxx> // #i23725#
24 : // #134369#
25 : #include <view.hxx>
26 : #include <drawbase.hxx>
27 :
28 0 : inline void SwWrtShell::OpenMark()
29 : {
30 0 : StartAllAction();
31 0 : ResetCursorStack();
32 0 : KillPams();
33 0 : SetMark();
34 0 : }
35 :
36 0 : inline void SwWrtShell::CloseMark( bool bOkFlag )
37 : {
38 0 : if( bOkFlag )
39 0 : UpdateAttr();
40 : else
41 0 : SwapPam();
42 :
43 0 : ClearMark();
44 0 : EndAllAction();
45 0 : }
46 :
47 : // #i23725#
48 0 : bool SwWrtShell::TryRemoveIndent()
49 : {
50 0 : bool bResult = false;
51 :
52 0 : SfxItemSet aAttrSet(GetAttrPool(), RES_LR_SPACE, RES_LR_SPACE);
53 0 : GetCurAttr(aAttrSet);
54 :
55 0 : SvxLRSpaceItem aItem = (const SvxLRSpaceItem &)aAttrSet.Get(RES_LR_SPACE);
56 0 : short aOldFirstLineOfst = aItem.GetTxtFirstLineOfst();
57 :
58 0 : if (aOldFirstLineOfst > 0)
59 : {
60 0 : aItem.SetTxtFirstLineOfst(0);
61 0 : bResult = true;
62 : }
63 0 : else if (aOldFirstLineOfst < 0)
64 : {
65 0 : aItem.SetTxtFirstLineOfst(0);
66 0 : aItem.SetLeft(aItem.GetLeft() + aOldFirstLineOfst);
67 :
68 0 : bResult = true;
69 : }
70 0 : else if (aItem.GetLeft() != 0)
71 : {
72 0 : aItem.SetLeft(0);
73 0 : bResult = true;
74 : }
75 :
76 0 : if (bResult)
77 : {
78 0 : aAttrSet.Put(aItem);
79 0 : SetAttr(aAttrSet);
80 : }
81 :
82 0 : return bResult;
83 : }
84 :
85 : /** Description: Erase the line. */
86 :
87 0 : long SwWrtShell::DelLine()
88 : {
89 0 : SwActContext aActContext(this);
90 0 : ResetCursorStack();
91 : // remember the old cursor
92 0 : Push();
93 0 : ClearMark();
94 0 : SwCrsrShell::LeftMargin();
95 0 : SetMark();
96 0 : SwCrsrShell::RightMargin();
97 :
98 0 : long nRet = Delete();
99 0 : Pop(sal_False);
100 0 : if( nRet )
101 0 : UpdateAttr();
102 0 : return nRet;
103 : }
104 :
105 :
106 :
107 0 : long SwWrtShell::DelToStartOfLine()
108 : {
109 0 : OpenMark();
110 0 : SwCrsrShell::LeftMargin();
111 0 : long nRet = Delete();
112 0 : CloseMark( 0 != nRet );
113 0 : return nRet;
114 : }
115 :
116 :
117 :
118 0 : long SwWrtShell::DelToEndOfLine()
119 : {
120 0 : OpenMark();
121 0 : SwCrsrShell::RightMargin();
122 0 : long nRet = Delete();
123 0 : CloseMark( 0 != nRet );
124 0 : return 1;
125 : }
126 :
127 0 : long SwWrtShell::DelLeft()
128 : {
129 : // If it's a Fly, throw it away
130 0 : int nSelType = GetSelectionType();
131 0 : const int nCmp = nsSelectionType::SEL_FRM | nsSelectionType::SEL_GRF | nsSelectionType::SEL_OLE | nsSelectionType::SEL_DRW;
132 0 : if( nCmp & nSelType )
133 : {
134 : // #108205# Remember object's position.
135 0 : Point aTmpPt = GetObjRect().TopLeft();
136 :
137 0 : DelSelectedObj();
138 :
139 : // #108205# Set cursor to remembered position.
140 0 : SetCrsr(&aTmpPt);
141 :
142 0 : LeaveSelFrmMode();
143 0 : UnSelectFrm();
144 :
145 0 : nSelType = GetSelectionType();
146 0 : if ( nCmp & nSelType )
147 : {
148 0 : EnterSelFrmMode();
149 0 : GotoNextFly();
150 : }
151 :
152 0 : return 1L;
153 : }
154 :
155 : // If a selection exists, erase this
156 0 : if ( IsSelection() )
157 : {
158 0 : if( !IsBlockMode() || HasSelection() )
159 : {
160 : //OS: Once again Basic: SwActContext must be leaved
161 : //before EnterStdMode!
162 : {
163 0 : SwActContext aActContext(this);
164 0 : ResetCursorStack();
165 0 : Delete();
166 0 : UpdateAttr();
167 : }
168 0 : if( IsBlockMode() )
169 : {
170 0 : NormalizePam();
171 0 : ClearMark();
172 0 : EnterBlockMode();
173 : }
174 : else
175 0 : EnterStdMode();
176 0 : return 1L;
177 : }
178 : else
179 0 : EnterStdMode();
180 : }
181 :
182 : // JP 29.06.95: never erase a table standing in front of it.
183 0 : bool bSwap = false;
184 0 : const SwTableNode * pWasInTblNd = SwCrsrShell::IsCrsrInTbl();
185 :
186 0 : if( SwCrsrShell::IsSttPara())
187 : {
188 : // #i4032# Don't actually call a 'delete' if we
189 : // changed the table cell, compare DelRight().
190 : const SwStartNode * pSNdOld = pWasInTblNd ?
191 0 : GetSwCrsr()->GetNode()->FindTableBoxStartNode() :
192 0 : 0;
193 :
194 : // If the cursor is at the beginning of a paragraph, try to step
195 : // backwards. On failure we are done.
196 0 : if( !SwCrsrShell::Left(1,CRSR_SKIP_CHARS) )
197 0 : return 0;
198 :
199 : // If the cursor entered or left a table (or both) we are done. No step
200 : // back.
201 0 : const SwTableNode* pIsInTblNd = SwCrsrShell::IsCrsrInTbl();
202 0 : if( pIsInTblNd != pWasInTblNd )
203 0 : return 0;
204 :
205 : const SwStartNode* pSNdNew = pIsInTblNd ?
206 0 : GetSwCrsr()->GetNode()->FindTableBoxStartNode() :
207 0 : 0;
208 :
209 : // #i4032# Don't actually call a 'delete' if we
210 : // changed the table cell, compare DelRight().
211 0 : if ( pSNdOld != pSNdNew )
212 0 : return 0;
213 :
214 0 : OpenMark();
215 0 : SwCrsrShell::Right(1,CRSR_SKIP_CHARS);
216 0 : SwCrsrShell::SwapPam();
217 0 : bSwap = true;
218 : }
219 : else
220 : {
221 0 : OpenMark();
222 0 : SwCrsrShell::Left(1,CRSR_SKIP_CHARS);
223 : }
224 0 : long nRet = Delete();
225 0 : if( !nRet && bSwap )
226 0 : SwCrsrShell::SwapPam();
227 0 : CloseMark( 0 != nRet );
228 0 : return nRet;
229 : }
230 :
231 0 : long SwWrtShell::DelRight()
232 : {
233 : // Will be or'ed, if a tableselection exists;
234 : // will here be implemented on nsSelectionType::SEL_TBL
235 0 : long nRet = 0;
236 0 : int nSelection = GetSelectionType();
237 0 : if(nSelection & nsSelectionType::SEL_TBL_CELLS)
238 0 : nSelection = nsSelectionType::SEL_TBL;
239 0 : if(nSelection & nsSelectionType::SEL_TXT)
240 0 : nSelection = nsSelectionType::SEL_TXT;
241 :
242 0 : const SwTableNode * pWasInTblNd = NULL;
243 :
244 0 : switch( nSelection & ~(nsSelectionType::SEL_BEZ) )
245 : {
246 : case nsSelectionType::SEL_POSTIT:
247 : case nsSelectionType::SEL_TXT:
248 : case nsSelectionType::SEL_TBL:
249 : case nsSelectionType::SEL_NUM:
250 : // If a selection exists, erase it.
251 0 : if( IsSelection() )
252 : {
253 0 : if( !IsBlockMode() || HasSelection() )
254 : {
255 : //OS: And once again Basic: SwActContext must be
256 : //leaved before EnterStdMode !
257 : {
258 0 : SwActContext aActContext(this);
259 0 : ResetCursorStack();
260 0 : Delete();
261 0 : UpdateAttr();
262 : }
263 0 : if( IsBlockMode() )
264 : {
265 0 : NormalizePam();
266 0 : ClearMark();
267 0 : EnterBlockMode();
268 : }
269 : else
270 0 : EnterStdMode();
271 0 : nRet = 1L;
272 0 : break;
273 : }
274 : else
275 0 : EnterStdMode();
276 : }
277 :
278 0 : pWasInTblNd = IsCrsrInTbl();
279 :
280 0 : if( nsSelectionType::SEL_TXT & nSelection && SwCrsrShell::IsSttPara() &&
281 0 : SwCrsrShell::IsEndPara() )
282 : {
283 : // save cursor
284 0 : SwCrsrShell::Push();
285 :
286 0 : bool bDelFull = false;
287 0 : if ( SwCrsrShell::Right(1,CRSR_SKIP_CHARS) )
288 : {
289 0 : const SwTableNode * pCurrTblNd = IsCrsrInTbl();
290 0 : bDelFull = pCurrTblNd && pCurrTblNd != pWasInTblNd;
291 : }
292 :
293 : // restore cursor
294 0 : SwCrsrShell::Pop( sal_False );
295 :
296 0 : if( bDelFull )
297 : {
298 0 : DelFullPara();
299 0 : UpdateAttr();
300 0 : break;
301 : }
302 : }
303 :
304 : {
305 : // #108049# Save the startnode of the current cell
306 : const SwStartNode * pSNdOld;
307 0 : pSNdOld = GetSwCrsr()->GetNode()->
308 0 : FindTableBoxStartNode();
309 :
310 0 : if ( SwCrsrShell::IsEndPara() )
311 : {
312 : // #i41424# Introduced a couple of
313 : // Push()-Pop() pairs here. The reason for this is that a
314 : // Right()-Left() combination does not make sure, that
315 : // the cursor will be in its initial state, because there
316 : // may be a numbering in front of the next paragraph.
317 0 : SwCrsrShell::Push();
318 :
319 0 : if ( SwCrsrShell::Right(1, CRSR_SKIP_CHARS) )
320 : {
321 0 : if (IsCrsrInTbl() || (pWasInTblNd != IsCrsrInTbl()))
322 : {
323 : /** #108049# Save the startnode of the current
324 : cell. May be different to pSNdOld as we have
325 : moved. */
326 0 : const SwStartNode * pSNdNew = GetSwCrsr()
327 0 : ->GetNode()->FindTableBoxStartNode();
328 :
329 : /** #108049# Only move instead of deleting if we
330 : have moved to a different cell */
331 0 : if (pSNdOld != pSNdNew)
332 : {
333 0 : SwCrsrShell::Pop( sal_True );
334 0 : break;
335 : }
336 : }
337 : }
338 :
339 : // restore cursor
340 0 : SwCrsrShell::Pop( sal_False );
341 : }
342 : }
343 :
344 0 : OpenMark();
345 0 : SwCrsrShell::Right(1,CRSR_SKIP_CELLS);
346 0 : nRet = Delete();
347 0 : CloseMark( 0 != nRet );
348 0 : break;
349 :
350 : case nsSelectionType::SEL_FRM:
351 : case nsSelectionType::SEL_GRF:
352 : case nsSelectionType::SEL_OLE:
353 : case nsSelectionType::SEL_DRW:
354 : case nsSelectionType::SEL_DRW_TXT:
355 : case nsSelectionType::SEL_DRW_FORM:
356 : {
357 : // #108205# Remember object's position.
358 0 : Point aTmpPt = GetObjRect().TopLeft();
359 :
360 0 : DelSelectedObj();
361 :
362 : // #108205# Set cursor to remembered position.
363 0 : SetCrsr(&aTmpPt);
364 :
365 0 : LeaveSelFrmMode();
366 0 : UnSelectFrm();
367 : // #134369#
368 : OSL_ENSURE( !IsFrmSelected(),
369 : "<SwWrtShell::DelRight(..)> - <SwWrtShell::UnSelectFrm()> should unmark all objects" );
370 : // #134369#
371 : // leave draw mode, if necessary.
372 : {
373 0 : if (GetView().GetDrawFuncPtr())
374 : {
375 0 : GetView().GetDrawFuncPtr()->Deactivate();
376 0 : GetView().SetDrawFuncPtr(NULL);
377 : }
378 0 : if ( GetView().IsDrawMode() )
379 : {
380 0 : GetView().LeaveDrawCreate();
381 : }
382 : }
383 : }
384 :
385 : // #134369#
386 : // <IsFrmSelected()> can't be true - see above.
387 : {
388 0 : nSelection = GetSelectionType();
389 0 : if ( nsSelectionType::SEL_FRM & nSelection ||
390 0 : nsSelectionType::SEL_GRF & nSelection ||
391 0 : nsSelectionType::SEL_OLE & nSelection ||
392 0 : nsSelectionType::SEL_DRW & nSelection )
393 : {
394 0 : EnterSelFrmMode();
395 0 : GotoNextFly();
396 : }
397 : }
398 0 : nRet = 1;
399 0 : break;
400 : }
401 0 : return nRet;
402 : }
403 :
404 0 : long SwWrtShell::DelToEndOfPara()
405 : {
406 0 : SwActContext aActContext(this);
407 0 : ResetCursorStack();
408 0 : Push();
409 0 : SetMark();
410 0 : if( !MovePara(fnParaCurr,fnParaEnd))
411 : {
412 0 : Pop(sal_False);
413 0 : return 0;
414 : }
415 0 : long nRet = Delete();
416 0 : Pop(sal_False);
417 0 : if( nRet )
418 0 : UpdateAttr();
419 0 : return nRet;
420 : }
421 :
422 0 : long SwWrtShell::DelToStartOfPara()
423 : {
424 0 : SwActContext aActContext(this);
425 0 : ResetCursorStack();
426 0 : Push();
427 0 : SetMark();
428 0 : if( !MovePara(fnParaCurr,fnParaStart))
429 : {
430 0 : Pop(sal_False);
431 0 : return 0;
432 : }
433 0 : long nRet = Delete();
434 0 : Pop(sal_False);
435 0 : if( nRet )
436 0 : UpdateAttr();
437 0 : return nRet;
438 : }
439 :
440 : // All erase operations should work with Find instead with
441 : // Nxt-/PrvDelim, because the latter works with Wrap Around
442 : // -- that's probably not wished.
443 :
444 0 : long SwWrtShell::DelToStartOfSentence()
445 : {
446 0 : if(IsStartOfDoc())
447 0 : return 0;
448 0 : OpenMark();
449 0 : long nRet = _BwdSentence() ? Delete() : 0;
450 0 : CloseMark( 0 != nRet );
451 0 : return nRet;
452 : }
453 :
454 0 : long SwWrtShell::DelToEndOfSentence()
455 : {
456 0 : if(IsEndOfDoc())
457 0 : return 0;
458 0 : OpenMark();
459 0 : long nRet(0);
460 : // fdo#60967: special case that is documented in help: delete
461 : // paragraph following table if cursor is at end of last cell in table
462 0 : if (IsEndOfTable())
463 : {
464 0 : Push();
465 0 : ClearMark();
466 0 : if (SwCrsrShell::Right(1,CRSR_SKIP_CHARS))
467 : {
468 0 : SetMark();
469 0 : SwCrsrShell::MovePara(fnParaCurr, fnParaEnd);
470 0 : if (!IsEndOfDoc()) // do not delete last paragraph in body text
471 : {
472 0 : nRet = DelFullPara() ? 1 : 0;
473 : }
474 : }
475 0 : Pop(false);
476 : }
477 : else
478 : {
479 0 : nRet = _FwdSentence() ? Delete() : 0;
480 : }
481 0 : CloseMark( 0 != nRet );
482 0 : return nRet;
483 : }
484 :
485 0 : long SwWrtShell::DelNxtWord()
486 : {
487 0 : if(IsEndOfDoc())
488 0 : return 0;
489 0 : SwActContext aActContext(this);
490 0 : ResetCursorStack();
491 0 : EnterStdMode();
492 0 : SetMark();
493 0 : if(IsEndWrd() && !IsSttWrd())
494 0 : _NxtWrdForDelete(); // #i92468#
495 0 : if(IsSttWrd() || IsEndPara())
496 0 : _NxtWrdForDelete(); // #i92468#
497 : else
498 0 : _EndWrd();
499 :
500 0 : long nRet = Delete();
501 0 : if( nRet )
502 0 : UpdateAttr();
503 : else
504 0 : SwapPam();
505 0 : ClearMark();
506 0 : return nRet;
507 : }
508 :
509 0 : long SwWrtShell::DelPrvWord()
510 : {
511 0 : if(IsStartOfDoc())
512 0 : return 0;
513 0 : SwActContext aActContext(this);
514 0 : ResetCursorStack();
515 0 : EnterStdMode();
516 0 : SetMark();
517 0 : if ( !IsSttWrd() ||
518 0 : !_PrvWrdForDelete() ) // #i92468#
519 : {
520 0 : if( IsEndWrd() )
521 : {
522 0 : if ( _PrvWrdForDelete() ) // #i92468#
523 : {
524 : // skip over all-1 spaces
525 0 : short n = -1;
526 0 : while( ' ' == GetChar( sal_False, n ))
527 0 : --n;
528 :
529 0 : if( ++n )
530 0 : ExtendSelection( sal_False, -n );
531 : }
532 : }
533 0 : else if( IsSttPara())
534 0 : _PrvWrdForDelete(); // #i92468#
535 : else
536 0 : _SttWrd();
537 : }
538 0 : long nRet = Delete();
539 0 : if( nRet )
540 0 : UpdateAttr();
541 : else
542 0 : SwapPam();
543 0 : ClearMark();
544 0 : return nRet;
545 99 : }
546 :
547 :
548 :
549 :
550 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|