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 IDocumentMarkAccess::pMark_t& rpFirst,
70  const IDocumentMarkAccess::pMark_t& rpSecond)
71  {
72  return rpFirst->GetMarkEnd() > rpSecond->GetMarkEnd();
73  }
74 
75  bool lcl_IsInvisibleBookmark(const IDocumentMarkAccess::pMark_t& 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();
206  remove_copy_if(
207  upper_bound( // finds the first that is starting after
208  pMarkAccess->getBookmarksBegin(),
209  pMarkAccess->getBookmarksEnd(),
210  *GetCursor()->GetPoint(),
212  pMarkAccess->getBookmarksEnd(),
213  back_inserter(vCandidates),
214  &lcl_IsInvisibleBookmark);
215 
216  // watch Cursor-Moves
217  CursorStateHelper aCursorSt(*this);
218  IDocumentMarkAccess::const_iterator_t ppMark = vCandidates.begin();
219  for(; ppMark!=vCandidates.end(); ++ppMark)
220  {
221  if (sw::IsMarkHidden(*GetLayout(), **ppMark))
222  {
223  continue;
224  }
225  aCursorSt.SetCursorToMark(ppMark->get());
226  if(!aCursorSt.RollbackIfIllegal())
227  break; // found legal move
228  }
229  if(ppMark==vCandidates.end())
230  {
231  SttEndDoc(false);
232  return false;
233  }
234 
236  return true;
237 }
238 
240 {
241  IDocumentMarkAccess* pMarkAccess = getIDocumentMarkAccess();
242  // candidates from which to choose the mark before
243  // no need to consider marks starting after rPos
245  remove_copy_if(
246  pMarkAccess->getBookmarksBegin(),
247  upper_bound(
248  pMarkAccess->getBookmarksBegin(),
249  pMarkAccess->getBookmarksEnd(),
250  *GetCursor()->GetPoint(),
252  back_inserter(vCandidates),
253  &lcl_IsInvisibleBookmark);
254  sort(
255  vCandidates.begin(),
256  vCandidates.end(),
257  &lcl_ReverseMarkOrderingByEnd);
258 
259  // watch Cursor-Moves
260  CursorStateHelper aCursorSt(*this);
261  IDocumentMarkAccess::const_iterator_t ppMark = vCandidates.begin();
262  for(; ppMark!=vCandidates.end(); ++ppMark)
263  {
264  // ignoring those not ending before the Cursor
265  // (we were only able to eliminate those starting
266  // behind the Cursor by the upper_bound(..)
267  // above)
268  if(!(**ppMark).EndsBefore(*GetCursor()->GetPoint()))
269  continue;
270  if (sw::IsMarkHidden(*GetLayout(), **ppMark))
271  {
272  continue;
273  }
274  aCursorSt.SetCursorToMark(ppMark->get());
275  if(!aCursorSt.RollbackIfIllegal())
276  break; // found legal move
277  }
278  if(ppMark==vCandidates.end())
279  {
280  SttEndDoc(true);
281  return false;
282  }
283 
285  return true;
286 }
287 
289 {
290  return getIDocumentSettingAccess().get(DocumentSettingId::PROTECT_FORM);
291 }
292 
294 {
295  // TODO: Refactor
296  SwPosition pos(*GetCursor()->GetPoint());
297  return getIDocumentMarkAccess()->getFieldmarkFor(pos);
298 }
299 
301 {
302  SwPosition pos(*GetCursor()->GetPoint());
303  return getIDocumentMarkAccess()->getFieldmarkAfter(pos);
304 }
305 
307 {
308  SwPosition pos(*GetCursor()->GetPoint());
309  return getIDocumentMarkAccess()->getFieldmarkBefore(pos);
310 }
311 
313 {
314  if(pMark==nullptr) return false;
315 
316  // watch Cursor-Moves
317  CursorStateHelper aCursorSt(*this);
318  aCursorSt.SetCursorToMark(pMark);
319  ++aCursorSt.m_pCursor->GetPoint()->nContent;
320  --aCursorSt.m_pCursor->GetMark()->nContent;
321 
322  if(aCursorSt.RollbackIfIllegal()) return false;
323 
325  return true;
326 }
327 
328 /* 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:322
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 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 drop-down 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:288
container_t::const_iterator const_iterator_t
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:1254
::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:312
std::shared_ptr< ::sw::mark::IMark > pMark_t
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:300
::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:239
::sw::mark::IFieldmark * GetFieldmarkBefore()
Definition: crbm.cxx:306
make visible in spite of Readonly
Definition: crsrsh.hxx:159
virtual const SwPosition & GetMarkStart() const =0
virtual bool IsExpanded() const =0
std::vector< pMark_t > container_t
::sw::mark::IFieldmark * GetCurrentFieldmark()
Definition: crbm.cxx:293
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:842
virtual const SwPosition & GetOtherMarkPos() const =0