LibreOffice Module sw (master)  1
delete.cxx
Go to the documentation of this file.
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 <swcrsr.hxx>
22 #include <editeng/lrspitem.hxx>
23 #include <view.hxx>
24 #include <drawbase.hxx>
25 #include <unobaseclass.hxx>
26 #include <rtl/character.hxx>
27 
28 inline void SwWrtShell::OpenMark()
29 {
32  KillPams();
33  SetMark();
34 }
35 
36 inline void SwWrtShell::CloseMark( bool bOkFlag )
37 {
38  if( bOkFlag )
39  UpdateAttr();
40  else
41  SwapPam();
42 
43  ClearMark();
44  EndAllAction();
45 }
46 
47 namespace {
48 
49 bool isUnicodeVariationSequenceSelector( sal_uInt32 nCode )
50 {
51  return ( nCode >= 0xFE00 && nCode <= 0xFE0F ) // Variation Selectors block
52  || ( nCode >= 0xE0100 && nCode <= 0xE01EF );// Variation Selectors Supplement block
53 }
54 
55 // Return if the character might be a base character of a CJK ideographic variation sequence
56 bool isCJKIVSCharacters( sal_uInt32 nCode )
57 {
58  return ( nCode >= 0x4E00 && nCode <= 0x9FFF ) // CJK Unified Ideographs
59  || ( nCode >= 0x3400 && nCode <= 0x4DBF ) // CJK Unified Ideographs Extension A
60  || ( nCode >= 0x20000 && nCode <= 0x2A6DF ); // CJK Unified Ideographs Extension B
61 }
62 
63 }
64 
65 
66 // #i23725#
68 {
69  bool bResult = false;
70 
72  GetCurAttr(aAttrSet);
73 
74  SvxLRSpaceItem aItem = aAttrSet.Get(RES_LR_SPACE);
75  short aOldFirstLineOfst = aItem.GetTextFirstLineOfst();
76 
77  if (aOldFirstLineOfst > 0)
78  {
79  aItem.SetTextFirstLineOfst(0);
80  bResult = true;
81  }
82  else if (aOldFirstLineOfst < 0)
83  {
84  aItem.SetTextFirstLineOfst(0);
85  aItem.SetLeft(aItem.GetLeft() + aOldFirstLineOfst);
86 
87  bResult = true;
88  }
89  else if (aItem.GetLeft() != 0)
90  {
91  aItem.SetLeft(0);
92  bResult = true;
93  }
94 
95  if (bResult)
96  {
97  aAttrSet.Put(aItem);
98  SetAttrSet(aAttrSet);
99  }
100 
101  return bResult;
102 }
103 
107 {
108  SwActContext aActContext(this);
110  // remember the old cursor
111  Push();
112  ClearMark();
114  SetMark();
116 
117  bool bRet = Delete();
119  if( bRet )
120  UpdateAttr();
121 }
122 
124 {
125  OpenMark();
127  bool bRet = Delete();
128  CloseMark( bRet );
129 }
130 
132 {
133  OpenMark();
135  bool bRet = Delete();
136  CloseMark( bRet );
137 }
138 
140 {
141  // If it's a Fly, throw it away
142  SelectionType nSelType = GetSelectionType();
144  if( nCmp & nSelType )
145  {
146  // #108205# Remember object's position.
147  Point aTmpPt = GetObjRect().TopLeft();
148 
149  DelSelectedObj();
150 
151  // #108205# Set cursor to remembered position.
152  SetCursor(&aTmpPt);
153 
155  UnSelectFrame();
156 
157  nSelType = GetSelectionType();
158  if ( nCmp & nSelType )
159  {
161  GotoNextFly();
162  }
163 
164  return true;
165  }
166 
167  // If a selection exists, erase this
168  if ( IsSelection() )
169  {
170  if( !IsBlockMode() || HasSelection() )
171  {
172  //OS: Once again Basic: SwActContext must be leaved
173  //before EnterStdMode!
174  {
175  SwActContext aActContext(this);
177  Delete();
178  UpdateAttr();
179  }
180  if( IsBlockMode() )
181  {
182  NormalizePam();
183  ClearMark();
184  EnterBlockMode();
185  }
186  else
187  EnterStdMode();
188  return true;
189  }
190  else
191  EnterStdMode();
192  }
193 
194  // JP 29.06.95: never erase a table standing in front of it.
195  bool bSwap = false;
196  const SwTableNode * pWasInTableNd = SwCursorShell::IsCursorInTable();
197 
199  {
200  // Start/EndAllAction to avoid cursor flickering
203 
204  // #i4032# Don't actually call a 'delete' if we
205  // changed the table cell, compare DelRight().
206  const SwStartNode * pSNdOld = pWasInTableNd ?
208  nullptr;
209 
210  // If the cursor is at the beginning of a paragraph, try to step
211  // backwards. On failure we are done.
212  bool bDoSomething = SwCursorShell::Left(1,CRSR_SKIP_CHARS);
213 
214  if (bDoSomething)
215  {
216  // If the cursor entered or left a table (or both) we are done.
217  const SwTableNode* pIsInTableNd = SwCursorShell::IsCursorInTable();
218  bDoSomething = pIsInTableNd == pWasInTableNd;
219 
220  if (bDoSomething)
221  {
222  const SwStartNode* pSNdNew = pIsInTableNd ?
224  nullptr;
225 
226  // #i4032# Don't actually call a 'delete' if we
227  // changed the table cell, compare DelRight().
228  bDoSomething = pSNdOld == pSNdNew;
229  }
230  }
231 
232  if (!bDoSomething)
233  {
234  // tdf#115132 Restore previous position and we are done
236  return false;
237  }
238 
240 
241  OpenMark();
244  bSwap = true;
245  }
246  else
247  {
248  // If we are just to the right to a fieldmark, then remove it completely
249  const SwPosition* pCurPos = GetCursor()->GetPoint();
250  SwPosition aPrevChar(*pCurPos);
251  --aPrevChar.nContent;
253  if (pFm && pFm->GetMarkEnd() == *pCurPos)
254  {
256  return true;
257  }
258 
259  OpenMark();
261  if (SvtScriptType::ASIAN == GetScriptType())
262  {
263  sal_uInt32 nCode = GetChar(false);
264  if ( rtl::isSurrogate( nCode ) )
265  {
266  OUString sStr = GetSelText();
267  sal_Int32 nIndex = 0;
268  nCode = sStr.iterateCodePoints( &nIndex );
269  }
270 
271  if ( isUnicodeVariationSequenceSelector( nCode ) )
272  {
275  OUString sStr = GetSelText();
276  sal_Int32 nIndex = 0;
277  nCode = sStr.iterateCodePoints( &nIndex );
278  if ( isCJKIVSCharacters( nCode ) )
280  else
282  }
283  }
284  }
285  bool bRet = Delete();
286  if( !bRet && bSwap )
288  CloseMark( bRet );
289  return bRet;
290 }
291 
293 {
294  // Will be or'ed, if a tableselection exists;
295  // will here be implemented on SelectionType::Table
296  bool bRet = false;
297  SelectionType nSelection = GetSelectionType();
298  if(nSelection & SelectionType::TableCell)
299  nSelection = SelectionType::Table;
300  if(nSelection & SelectionType::Text)
301  nSelection = SelectionType::Text;
302 
303  switch( nSelection & ~SelectionType::Ornament )
304  {
306  case SelectionType::Text:
309  // If a selection exists, erase it.
310  if( IsSelection() )
311  {
312  if( !IsBlockMode() || HasSelection() )
313  {
314  //OS: And once again Basic: SwActContext must be
315  //leaved before EnterStdMode !
316  {
317  SwActContext aActContext(this);
319  Delete();
320  UpdateAttr();
321  }
322  if( IsBlockMode() )
323  {
324  NormalizePam();
325  ClearMark();
326  EnterBlockMode();
327  }
328  else
329  EnterStdMode();
330  bRet = true;
331  break;
332  }
333  else
334  EnterStdMode();
335  }
336 
338  {
339  // Start/EndAllAction to avoid cursor flickering
341 
342  const SwTableNode* pWasInTableNd = IsCursorInTable();
343  // #108049# Save the startnode of the current cell
344  const SwStartNode* pSNdOld = pWasInTableNd ?
345  GetSwCursor()->GetNode().FindTableBoxStartNode() : nullptr;
346  bool bCheckDelFull = SelectionType::Text & nSelection && SwCursorShell::IsSttPara();
347  bool bDelFull = false;
348  bool bDoNothing = false;
349 
350  // #i41424# Introduced a couple of
351  // Push()-Pop() pairs here. The reason for this is that a
352  // Right()-Left() combination does not make sure, that
353  // the cursor will be in its initial state, because there
354  // may be a numbering in front of the next paragraph.
356 
358  {
359  const SwTableNode* pCurrTableNd = IsCursorInTable();
360  bDelFull = bCheckDelFull && pCurrTableNd && pCurrTableNd != pWasInTableNd;
361  if (!bDelFull && (IsCursorInTable() || (pCurrTableNd != pWasInTableNd)))
362  {
363  // #108049# Save the startnode of the current cell.
364  // May be different to pSNdOld as we have moved.
365  const SwStartNode* pSNdNew = pCurrTableNd ?
366  GetSwCursor()->GetNode().FindTableBoxStartNode() : nullptr;
367 
368  // tdf#115132 Only keep cursor position instead of deleting
369  // if we have moved to a different cell
370  bDoNothing = pSNdOld != pSNdNew;
371  }
372  }
373 
374  // restore cursor
376 
377  if (bDelFull)
378  {
379  DelFullPara();
380  UpdateAttr();
381  }
382  if (bDelFull || bDoNothing)
383  break;
384  }
385 
386  {
387  // If we are just ahead of a fieldmark, then remove it completely
389  if (pFm && pFm->GetMarkStart() == *GetCursor()->GetPoint())
390  {
392  bRet = true;
393  break;
394  }
395  }
396 
397  OpenMark();
399  bRet = Delete();
400  CloseMark( bRet );
401  break;
402 
405  case SelectionType::Ole:
409  {
410  // #108205# Remember object's position.
411  Point aTmpPt = GetObjRect().TopLeft();
412 
413  DelSelectedObj();
414 
415  // #108205# Set cursor to remembered position.
416  SetCursor(&aTmpPt);
417 
419  UnSelectFrame();
420  OSL_ENSURE( !IsFrameSelected(),
421  "<SwWrtShell::DelRight(..)> - <SwWrtShell::UnSelectFrame()> should unmark all objects" );
422  // leave draw mode, if necessary.
423  {
424  if (GetView().GetDrawFuncPtr())
425  {
427  GetView().SetDrawFuncPtr(nullptr);
428  }
429  if ( GetView().IsDrawMode() )
430  {
432  }
433  }
434  }
435 
436  // <IsFrameSelected()> can't be true - see above.
437  {
438  nSelection = GetSelectionType();
439  if ( SelectionType::Frame & nSelection ||
440  SelectionType::Graphic & nSelection ||
441  SelectionType::Ole & nSelection ||
442  SelectionType::DrawObject & nSelection )
443  {
445  GotoNextFly();
446  }
447  }
448  bRet = true;
449  break;
450  default: break;
451  }
452  return bRet;
453 }
454 
456 {
457  SwActContext aActContext(this);
459  Push();
460  SetMark();
462  {
464  return;
465  }
466  bool bRet = Delete();
468  if( bRet )
469  UpdateAttr();
470 }
471 
473 {
474  SwActContext aActContext(this);
476  Push();
477  SetMark();
479  {
481  return;
482  }
483  bool bRet = Delete();
485  if( bRet )
486  UpdateAttr();
487 }
488 
489 // All erase operations should work with Find instead with
490 // Nxt-/PrvDelim, because the latter works with Wrap Around
491 // -- that's probably not wished.
492 
494 {
495  if(IsStartOfDoc())
496  return;
497  OpenMark();
498  bool bRet = BwdSentence_() && Delete();
499  CloseMark( bRet );
500 }
501 
503 {
504  if(IsEndOfDoc())
505  return false;
506  OpenMark();
507  bool bRet(false);
508  // fdo#60967: special case that is documented in help: delete
509  // paragraph following table if cursor is at end of last cell in table
510  if (IsEndOfTable())
511  {
512  Push();
513  ClearMark();
515  {
516  SetMark();
517  if (!IsEndPara()) // can only be at the end if it's empty
518  { // for an empty paragraph this would actually select the _next_
520  }
521  if (!IsEndOfDoc()) // do not delete last paragraph in body text
522  {
523  bRet = DelFullPara();
524  }
525  }
527  }
528  else
529  {
530  bRet = FwdSentence_() && Delete();
531  }
532  CloseMark( bRet );
533  return bRet;
534 }
535 
537 {
538  if(IsEndOfDoc())
539  return;
540  SwActContext aActContext(this);
542  EnterStdMode();
543  SetMark();
544  if(IsEndWrd() && !IsStartWord())
545  NxtWrdForDelete(); // #i92468#
546  if(IsStartWord() || IsEndPara())
547  NxtWrdForDelete(); // #i92468#
548  else
549  EndWrd();
550 
551  bool bRet = Delete();
552  if( bRet )
553  UpdateAttr();
554  else
555  SwapPam();
556  ClearMark();
557 }
558 
560 {
561  if(IsStartOfDoc())
562  return;
563  SwActContext aActContext(this);
565  EnterStdMode();
566  SetMark();
567  if ( !IsStartWord() ||
568  !PrvWrdForDelete() ) // #i92468#
569  {
570  if (IsEndWrd() || IsSttPara())
571  PrvWrdForDelete(); // #i92468#
572  else
573  SttWrd();
574  }
575  bool bRet = Delete();
576  if( bRet )
577  UpdateAttr();
578  else
579  SwapPam();
580  ClearMark();
581 }
582 
583 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
long GetLeft() const
Starts a section of nodes in the document model.
Definition: node.hxx:303
void EnterBlockMode()
Definition: select.cxx:652
void KillPams()
Definition: crsrsh.cxx:1010
SwMoveFnCollection const & fnParaEnd
Definition: paminit.cxx:47
SwNode & GetNode(bool bPoint=true) const
Definition: pam.hxx:223
void ResetCursorStack()
Definition: wrtsh.hxx:613
Marks a position in the document model.
Definition: pam.hxx:35
bool Right(sal_uInt16 nCnt, sal_uInt16 nMode, bool bAllowVisual=false)
Definition: crsrsh.hxx:353
bool DelFullPara()
Remove a complete paragraph.
Definition: eddel.cxx:337
SwPaM * GetCursor(bool bMakeTableCursor=true) const
Return pointer to the current shell cursor.
Definition: crsrsh.cxx:185
void DelToStartOfPara()
Definition: delete.cxx:472
bool GoCurrPara(SwPaM &rPam, SwMoveFnCollection const &aPosPara)
Definition: pam.cxx:949
void DelNxtWord()
Definition: delete.cxx:536
short GetTextFirstLineOfst() const
sal_Unicode GetChar(bool bEnd=true, long nOffset=0)
get the nth character of the current SSelection
Definition: crsrsh.cxx:2485
bool IsSttPara() const
Definition: crsrsh.cxx:1083
bool IsStartOfDoc() const
Definition: crsrsh.cxx:2632
void SetAttrSet(const SfxItemSet &, SetAttrMode nFlags=SetAttrMode::DEFAULT, SwPaM *pCursor=nullptr, const bool bParagraphSetting=false)
Definition: edatmisc.cxx:152
bool Pop(SwCursorShell::PopMode=SwCursorShell::PopMode::DeleteStack)
Definition: wrtsh1.cxx:1690
SwCursor * GetSwCursor() const
Definition: crsrsh.hxx:864
SwMoveFnCollection const & fnParaStart
Definition: paminit.cxx:46
void UpdateAttr()
Definition: crsrsh.hxx:756
SAL_DLLPRIVATE void EndWrd()
Definition: wrtsh4.cxx:50
bool Left(sal_uInt16 nCnt, sal_uInt16 nMode, bool bAllowVisual=false)
Definition: crsrsh.hxx:351
void EnterStdMode()
Definition: select.cxx:552
SAL_DLLPRIVATE bool FwdSentence_()
Definition: wrtsh4.cxx:174
void DelToEndOfLine()
Definition: delete.cxx:131
void EndAllAction()
Definition: edws.cxx:96
bool GotoNextFly(GotoObjFlags eType=GotoObjFlags::FlyAny)
Independent selecting of flys.
Definition: fesh.hxx:409
bool DelRight()
Definition: delete.cxx:292
void SwapPam()
Definition: crsrsh.cxx:964
void SetDrawFuncPtr(std::unique_ptr< SwDrawBase > pFuncPtr)
Definition: viewdraw.cxx:642
const SwView & GetView() const
Definition: wrtsh.hxx:424
void SetLeft(const long nL, const sal_uInt16 nProp=100)
SwIndex nContent
Definition: pam.hxx:38
void NormalizePam(bool bPointFirst=true)
Ensure point and mark of the current PaM are in a specific order.
Definition: crsrsh.cxx:958
virtual ::sw::mark::IFieldmark * getFieldmarkFor(const SwPosition &pos) const =0
bool IsBlockMode() const
Definition: wrtsh.hxx:157
SwDoc * GetDoc() const
Definition: viewsh.hxx:284
const IDocumentMarkAccess * getIDocumentMarkAccess() const
Provides access to the document bookmark interface.
Definition: viewsh.cxx:2592
virtual void Deactivate()
Definition: drawbase.cxx:441
bool MovePara(SwWhichPara, SwMoveFnCollection const &)
Definition: crsrsh.cxx:684
const SfxItemPool & GetAttrPool() const
Definition: viewsh.hxx:614
Class for automated call of Start- and EndAction().
Definition: editsh.hxx:1016
bool IsSelection() const
Definition: crsrsh.hxx:875
bool LeftMargin()
Definition: crsrsh.hxx:357
const SwTableNode * IsCursorInTable() const
Definition: crsrsh.hxx:885
SvtScriptType GetScriptType() const
returns the script type of the selection
Definition: edattr.cxx:671
bool HasSelection() const
Definition: wrtsh.hxx:137
const SwPosition * GetPoint() const
Definition: pam.hxx:207
void Push()
store a copy of the current cursor on the cursor stack
Definition: crsrsh.cxx:2143
bool IsEndOfTable() const
at the very last SwPosition inside a table
Definition: crsrsh.cxx:1121
SAL_DLLPRIVATE bool BwdSentence_()
Definition: wrtsh4.cxx:191
void DelLine()
Description: Erase the line.
Definition: delete.cxx:106
bool RightMargin(bool bAPI=false)
Definition: crsrsh.hxx:358
void DelToStartOfLine()
Definition: delete.cxx:123
void SetMark()
Definition: crsrsh.hxx:871
SAL_DLLPRIVATE void CloseMark(bool bOkFlag)
Definition: delete.cxx:36
SAL_DLLPRIVATE bool PrvWrdForDelete()
Definition: wrtsh4.cxx:152
bool DelLeft()
Definition: delete.cxx:139
void DelPrvWord()
Definition: delete.cxx:559
void LeaveDrawCreate()
Definition: view.hxx:525
SwDrawBase * GetDrawFuncPtr() const
Definition: view.hxx:513
SAL_DLLPRIVATE void SttWrd()
Definition: wrtsh4.cxx:30
#define RES_LR_SPACE
Definition: hintids.hxx:196
const Point TopLeft() const
Definition: swrect.cxx:177
bool IsStartWord(sal_Int16 nWordType=css::i18n::WordType::ANYWORD_IGNOREWHITESPACES) const
Definition: crstrvl1.cxx:27
bool Delete()
Delete content of all ranges.
Definition: eddel.cxx:117
SelectionType
Definition: wrtsh.hxx:56
bool DelToEndOfSentence()
Definition: delete.cxx:502
const sal_uInt16 CRSR_SKIP_CELLS
Definition: swcrsr.hxx:64
void SetTextFirstLineOfst(const short nF, const sal_uInt16 nProp=100)
SAL_DLLPRIVATE void OpenMark()
Definition: delete.cxx:28
OUString GetSelText() const
get selected text of a node at current cursor
Definition: crsrsh.cxx:2429
SwRect GetObjRect() const
For adjustment of PosAttr when anchor changes.
Definition: fefly1.cxx:1263
void DelSelectedObj()
Definition: feshview.cxx:2297
void UnSelectFrame()
Definition: select.cxx:327
SAL_DLLPRIVATE long SetCursor(const Point *, bool bProp=false)
Definition: select.cxx:308
virtual const SwPosition & GetMarkEnd() const =0
void ClearMark()
Definition: crsrsh.cxx:927
bool GetCurAttr(SfxItemSet &, const bool bMergeIndentValuesOfNumRule=false) const
Definition: edattr.cxx:181
const SwStartNode * FindTableBoxStartNode() const
Definition: node.hxx:196
void LeaveSelFrameMode()
Definition: select.cxx:721
virtual std::shared_ptr< ILazyDeleter > deleteMark(const IDocumentMarkAccess::const_iterator_t &ppMark)=0
Deletes a mark.
bool IsEndOfDoc() const
Definition: crsrsh.cxx:2644
bool IsEndWrd()
Definition: wrtsh1.cxx:151
const sal_uInt16 CRSR_SKIP_CHARS
Definition: swcrsr.hxx:63
void EnterSelFrameMode(const Point *pStartDrag=nullptr)
Definition: select.cxx:703
virtual const SwPosition & GetMarkStart() const =0
bool IsEndPara() const
Definition: crsrsh.cxx:1102
bool Pop(PopMode)
delete cursor
Definition: crsrsh.cxx:2165
SelectionType GetSelectionType() const
Definition: wrtsh1.cxx:1373
bool TryRemoveIndent()
Definition: delete.cxx:67
void StartAllAction()
For all views of this document.
Definition: edws.cxx:85
void DelToEndOfPara()
Definition: delete.cxx:455
bool IsFrameSelected() const
Definition: feshview.cxx:1175
SAL_DLLPRIVATE bool NxtWrdForDelete()
Definition: wrtsh4.cxx:129
void DelToStartOfSentence()
Definition: delete.cxx:493
::sw::mark::IFieldmark * GetCurrentFieldmark()
Definition: crbm.cxx:293