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