LibreOffice Module sw (master)  1
crbm.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 <crsrsh.hxx>
21 #include <ndtxt.hxx>
22 #include <rootfrm.hxx>
23 #include <txtfrm.hxx>
24 #include <IMark.hxx>
25 #include <swcrsr.hxx>
26 #include <IDocumentMarkAccess.hxx>
28 
29 using namespace std;
30 
31 namespace
32 {
33  struct CursorStateHelper
34  {
35  explicit CursorStateHelper(SwCursorShell const & rShell)
36  : m_pCursor(rShell.GetSwCursor())
37  , m_aSaveState(*m_pCursor)
38  { }
39 
40  void SetCursorToMark(::sw::mark::IMark const * const pMark)
41  {
42  *(m_pCursor->GetPoint()) = pMark->GetMarkStart();
43  if(pMark->IsExpanded())
44  {
45  m_pCursor->SetMark();
46  *(m_pCursor->GetMark()) = pMark->GetMarkEnd();
47  }
48  }
49 
51  bool RollbackIfIllegal()
52  {
53  if(m_pCursor->IsSelOvr(SwCursorSelOverFlags::CheckNodeSection
55  {
56  m_pCursor->DeleteMark();
57  m_pCursor->RestoreSavePos();
58  return true;
59  }
60  return false;
61  }
62 
63  SwCursor* m_pCursor;
64  SwCursorSaveState const m_aSaveState;
65  };
66 
67  bool lcl_ReverseMarkOrderingByEnd(const ::sw::mark::IMark* pFirst,
68  const ::sw::mark::IMark* pSecond)
69  {
70  return pFirst->GetMarkEnd() > pSecond->GetMarkEnd();
71  }
72 
73  bool lcl_IsInvisibleBookmark(const ::sw::mark::IMark* pMark)
74  {
76  }
77 }
78 
79 // at CurrentCursor.SPoint
81  const vcl::KeyCode& rCode,
82  const OUString& rName,
84 {
85  StartAction();
86  ::sw::mark::IMark* pMark = getIDocumentMarkAccess()->makeMark(
87  *GetCursor(),
88  rName,
90  ::sw::mark::IBookmark* pBookmark = dynamic_cast< ::sw::mark::IBookmark* >(pMark);
91  if(pBookmark)
92  {
93  pBookmark->SetKeyCode(rCode);
94  pBookmark->SetShortName(OUString());
95  }
96  EndAction();
97  return pMark;
98 }
99 // set CurrentCursor.SPoint
100 
101 // at CurrentCursor.SPoint
103  const vcl::KeyCode& rCode,
104  const OUString& rName,
105  bool bHide,
106  const OUString& rCondition)
107 {
108  StartAction();
109  ::sw::mark::IMark* pMark = getIDocumentMarkAccess()->makeMark(
110  *GetCursor(),
111  rName,
113  ::sw::mark::IBookmark* pBookmark = dynamic_cast< ::sw::mark::IBookmark* >(pMark);
114  if (pBookmark)
115  {
116  pBookmark->SetKeyCode(rCode);
117  pBookmark->SetShortName(OUString());
118  pBookmark->Hide(bHide);
119  pBookmark->SetHideCondition(rCondition);
120  }
121  EndAction();
122  return pMark;
123 }
124 
125 namespace sw {
126 
127 bool IsMarkHidden(SwRootFrame const& rLayout, ::sw::mark::IMark const& rMark)
128 {
129  if (!rLayout.IsHideRedlines())
130  {
131  return false;
132  }
133  SwTextNode const& rNode(*rMark.GetMarkPos().nNode.GetNode().GetTextNode());
134  SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(
135  rNode.getLayoutFrame(&rLayout)));
136  if (!pFrame)
137  {
138  return true;
139  }
140  if (rMark.IsExpanded())
141  {
142  SwTextFrame const*const pOtherFrame(static_cast<SwTextFrame const*>(
143  rMark.GetOtherMarkPos().nNode.GetNode().GetTextNode()->getLayoutFrame(&rLayout)));
144  return pFrame == pOtherFrame
145  && pFrame->MapModelToViewPos(rMark.GetMarkPos())
146  == pFrame->MapModelToViewPos(rMark.GetOtherMarkPos());
147  }
148  else
149  {
150  if (rMark.GetMarkPos().nContent.GetIndex() == rNode.Len())
151  { // at end of node: never deleted (except if node deleted)
152  return rNode.GetRedlineMergeFlag() == SwNode::Merge::Hidden;
153  }
154  else
155  { // check character following mark pos
156  return pFrame->MapModelToViewPos(rMark.GetMarkPos())
157  == pFrame->MapModelToView(&rNode, rMark.GetMarkPos().nContent.GetIndex() + 1);
158  }
159  }
160 }
161 
162 } // namespace sw
163 
164 // set CurrentCursor.SPoint
165 bool SwCursorShell::GotoMark(const ::sw::mark::IMark* const pMark, bool bAtStart)
166 {
167  if (sw::IsMarkHidden(*GetLayout(), *pMark))
168  {
169  return false;
170  }
171  // watch Cursor-Moves
172  CursorStateHelper aCursorSt(*this);
173  if ( bAtStart )
174  *aCursorSt.m_pCursor->GetPoint() = pMark->GetMarkStart();
175  else
176  *aCursorSt.m_pCursor->GetPoint() = pMark->GetMarkEnd();
177 
178  if(aCursorSt.RollbackIfIllegal()) return false;
179 
181  return true;
182 }
183 
184 bool SwCursorShell::GotoMark(const ::sw::mark::IMark* const pMark)
185 {
186  if (sw::IsMarkHidden(*GetLayout(), *pMark))
187  {
188  return false;
189  }
190  // watch Cursor-Moves
191  CursorStateHelper aCursorSt(*this);
192  aCursorSt.SetCursorToMark(pMark);
193 
194  if(aCursorSt.RollbackIfIllegal()) return false;
195 
197  return true;
198 }
199 
201 {
202  IDocumentMarkAccess* pMarkAccess = getIDocumentMarkAccess();
203  std::vector<::sw::mark::IMark*> vCandidates;
204  remove_copy_if(
205  pMarkAccess->findFirstBookmarkStartsAfter(*GetCursor()->GetPoint()),
206  pMarkAccess->getBookmarksEnd(),
207  back_inserter(vCandidates),
208  &lcl_IsInvisibleBookmark);
209 
210  // watch Cursor-Moves
211  CursorStateHelper aCursorSt(*this);
212  auto ppMark = vCandidates.begin();
213  for(; ppMark!=vCandidates.end(); ++ppMark)
214  {
215  if (sw::IsMarkHidden(*GetLayout(), **ppMark))
216  {
217  continue;
218  }
219  aCursorSt.SetCursorToMark(*ppMark);
220  if(!aCursorSt.RollbackIfIllegal())
221  break; // found legal move
222  }
223  if(ppMark==vCandidates.end())
224  {
225  SttEndDoc(false);
226  return false;
227  }
228 
230  return true;
231 }
232 
234 {
235  IDocumentMarkAccess* pMarkAccess = getIDocumentMarkAccess();
236  // candidates from which to choose the mark before
237  // no need to consider marks starting after rPos
238  std::vector<::sw::mark::IMark*> vCandidates;
239  remove_copy_if(
240  pMarkAccess->getBookmarksBegin(),
241  pMarkAccess->findFirstBookmarkStartsAfter(*GetCursor()->GetPoint()),
242  back_inserter(vCandidates),
243  &lcl_IsInvisibleBookmark);
244  sort(
245  vCandidates.begin(),
246  vCandidates.end(),
247  &lcl_ReverseMarkOrderingByEnd);
248 
249  // watch Cursor-Moves
250  CursorStateHelper aCursorSt(*this);
251  auto ppMark = vCandidates.begin();
252  for(; ppMark!=vCandidates.end(); ++ppMark)
253  {
254  // ignoring those not ending before the Cursor
255  // (we were only able to eliminate those starting
256  // behind the Cursor by the upper_bound(..)
257  // above)
258  if(!((**ppMark).GetMarkEnd() < *GetCursor()->GetPoint()))
259  continue;
260  if (sw::IsMarkHidden(*GetLayout(), **ppMark))
261  {
262  continue;
263  }
264  aCursorSt.SetCursorToMark(*ppMark);
265  if(!aCursorSt.RollbackIfIllegal())
266  break; // found legal move
267  }
268  if(ppMark==vCandidates.end())
269  {
270  SttEndDoc(true);
271  return false;
272  }
273 
275  return true;
276 }
277 
279 {
280  return getIDocumentSettingAccess().get(DocumentSettingId::PROTECT_FORM);
281 }
282 
284 {
285  // TODO: Refactor
286  SwPosition pos(*GetCursor()->GetPoint());
287  return getIDocumentMarkAccess()->getFieldmarkFor(pos);
288 }
289 
291 {
292  SwPosition pos(*GetCursor()->GetPoint());
293  return getIDocumentMarkAccess()->getFieldmarkAfter(pos);
294 }
295 
297 {
298  SwPosition pos(*GetCursor()->GetPoint());
299  return getIDocumentMarkAccess()->getFieldmarkBefore(pos);
300 }
301 
303 {
304  if(pMark==nullptr) return false;
305 
306  // watch Cursor-Moves
307  CursorStateHelper aCursorSt(*this);
308  aCursorSt.SetCursorToMark(pMark);
309  ++aCursorSt.m_pCursor->GetPoint()->nContent;
310  --aCursorSt.m_pCursor->GetMark()->nContent;
311 
312  if(aCursorSt.RollbackIfIllegal()) return false;
313 
315  return true;
316 }
317 
318 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:149
Marks a position in the document model.
Definition: pam.hxx:35
check overlapping PaMs
Definition: crsrsh.hxx:158
SwNodeIndex nNode
Definition: pam.hxx:37
static SW_DLLPUBLIC MarkType GetType(const ::sw::mark::IMark &rMark)
Returns the MarkType used to create the mark.
Definition: docbm.cxx:483
SwContentFrame * getLayoutFrame(const SwRootFrame *, const SwPosition *pPos=nullptr, std::pair< Point, bool > const *pViewPosAndCalcFrame=nullptr) const
Definition: node.cxx:1148
Provides access to the marks of a document.
virtual const_iterator_t findFirstBookmarkStartsAfter(const SwPosition &rPos) const =0
Finds the first mark that is starting after.
virtual const SwPosition & GetMarkPos() const =0
bool IsMarkHidden(SwRootFrame const &rLayout,::sw::mark::IMark const &rMark)
Definition: crbm.cxx:127
SwNode & GetNode() const
Definition: ndindex.hxx:118
Dialog to specify the properties of date form field.
bool GotoMark(const ::sw::mark::IMark *const pMark)
Definition: crbm.cxx:184
The root element of a Writer document layout.
Definition: rootfrm.hxx:79
SwIndex nContent
Definition: pam.hxx:38
virtual void SetKeyCode(const vcl::KeyCode &)=0
virtual void SetShortName(const OUString &)=0
bool IsFormProtected()
Definition: crbm.cxx:278
virtual const_iterator_t getBookmarksEnd() const =0
returns a STL-like random access iterator to the end of the sequence of IBookmarks.
virtual void Hide(bool hide)=0
A helper class to save cursor state (position).
Definition: swcrsr.hxx:230
TextFrameIndex MapModelToViewPos(SwPosition const &rPos) const
Definition: txtfrm.cxx:1266
::sw::mark::IMark * SetBookmark(const vcl::KeyCode &, const OUString &rName, IDocumentMarkAccess::MarkType eMark=IDocumentMarkAccess::MarkType::BOOKMARK)
Definition: crbm.cxx:80
bool GotoFieldmark(const ::sw::mark::IFieldmark *const pMark)
Definition: crbm.cxx:302
bool GoNextBookmark()
Definition: crbm.cxx:200
virtual void SetHideCondition(const OUString &)=0
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
::sw::mark::IFieldmark * GetFieldmarkAfter()
Definition: crbm.cxx:290
::sw::mark::IMark * SetBookmark2(const vcl::KeyCode &, const OUString &rName, bool bHide, const OUString &rCondition)
Definition: crbm.cxx:102
virtual const_iterator_t getBookmarksBegin() const =0
returns a STL-like random access iterator to the begin of the sequence the IBookmarks.
sal_Int32 GetIndex() const
Definition: index.hxx:95
scroll window
Definition: crsrsh.hxx:157
bool IsHideRedlines() const
Replacement for sw::DocumentRedlineManager::GetRedlineFlags() (this is layout-level redline hiding)...
Definition: rootfrm.hxx:416
virtual const SwPosition & GetMarkEnd() const =0
bool GoPrevBookmark()
Definition: crbm.cxx:233
::sw::mark::IFieldmark * GetFieldmarkBefore()
Definition: crbm.cxx:296
make visible in spite of Readonly
Definition: crsrsh.hxx:159
virtual const SwPosition & GetMarkStart() const =0
virtual bool IsExpanded() const =0
::sw::mark::IFieldmark * GetCurrentFieldmark()
Definition: crbm.cxx:283
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:843
virtual const SwPosition & GetOtherMarkPos() const =0