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