/src/libreoffice/sw/inc/swcrsr.hxx
Line | Count | Source |
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 | | #ifndef INCLUDED_SW_INC_SWCRSR_HXX |
20 | | #define INCLUDED_SW_INC_SWCRSR_HXX |
21 | | |
22 | | #include "pam.hxx" |
23 | | #include "tblsel.hxx" |
24 | | #include "cshtyp.hxx" |
25 | | |
26 | | class SfxItemSet; |
27 | | struct SwCursor_SavePos; |
28 | | class SvxSearchItem; |
29 | | namespace i18nutil { |
30 | | struct SearchOptions2; |
31 | | } |
32 | | |
33 | | // Base structure for parameters of the find-methods. |
34 | | // Returns values of found-call. |
35 | | const int FIND_NOT_FOUND = 0; |
36 | | const int FIND_FOUND = 1; |
37 | | const int FIND_NO_RING = 2; |
38 | | |
39 | | struct SwFindParas |
40 | | { |
41 | | // @param xSearchItem allocate in parent so we can do so outside the calling loop |
42 | | virtual int DoFind(SwPaM &, SwMoveFnCollection const &, const SwPaM&, bool, std::unique_ptr<SvxSearchItem>& xSearchItem) = 0; |
43 | | virtual bool IsReplaceMode() const = 0; |
44 | | |
45 | | protected: |
46 | 0 | ~SwFindParas() {} |
47 | | }; |
48 | | |
49 | | enum class SwCursorSelOverFlags : sal_uInt16 |
50 | | { |
51 | | NONE = 0x00, |
52 | | CheckNodeSection = 0x01, |
53 | | Toggle = 0x02, |
54 | | EnableRevDirection = 0x04, |
55 | | ChangePos = 0x08 |
56 | | }; |
57 | | namespace o3tl { |
58 | | template<> struct typed_flags<SwCursorSelOverFlags> : is_typed_flags<SwCursorSelOverFlags, 0x0f> {}; |
59 | | } |
60 | | |
61 | | // define for cursor travelling normally in western text cells and chars do |
62 | | // the same, but in complex text cell skip over ligatures and char skip |
63 | | // into it. |
64 | | // These defines exist only to cut off the dependencies to I18N project. |
65 | | enum class SwCursorSkipMode { Chars = 0, Cells = 1, Hidden = 2 }; |
66 | | namespace o3tl { |
67 | | template<> struct typed_flags<SwCursorSkipMode> : is_typed_flags<SwCursorSkipMode, 0x3> {}; |
68 | | } |
69 | | |
70 | | /// SwCursor is a base class for UI/shell, table and UNO/API cursors. |
71 | | /// |
72 | | /// It's more than just a pair of doc model positions (SwPaM), e.g. can go left/right or up/down. |
73 | | class SAL_DLLPUBLIC_RTTI SwCursor : public SwPaM |
74 | | { |
75 | | friend class SwCursorSaveState; |
76 | | |
77 | | std::vector<SwCursor_SavePos> m_vSavePos; // the current entry is the last element |
78 | | sal_Int32 m_nRowSpanOffset; // required for travelling in tabs with rowspans |
79 | | sal_uInt8 m_nCursorBidiLevel; // bidi level of the cursor |
80 | | bool m_bColumnSelection; // true: cursor is aprt of a column selection |
81 | | |
82 | | sal_Int32 FindAll( SwFindParas& , SwDocPositions, SwDocPositions, FindRanges, bool& bCancel ); |
83 | | |
84 | | SwCursor(SwCursor const& rPaM) = delete; |
85 | | |
86 | | protected: |
87 | | void SaveState(); |
88 | | void RestoreState(); |
89 | | |
90 | | inline const SwCursor_SavePos* GetSavePos() const; |
91 | | |
92 | | virtual const SwContentFrame* DoSetBidiLevelLeftRight( |
93 | | bool & io_rbLeft, bool bVisualAllowed, bool bInsertCursor); |
94 | | virtual void DoSetBidiLevelUpDown(); |
95 | | virtual bool IsSelOvrCheck(SwCursorSelOverFlags eFlags); |
96 | | |
97 | | public: |
98 | | // single argument ctors shall be explicit. |
99 | | SW_DLLPUBLIC SwCursor( const SwPosition &rPos, SwPaM* pRing ); |
100 | | SW_DLLPUBLIC virtual ~SwCursor() override; |
101 | | |
102 | | inline SwCursor & operator =(SwCursor const &); |
103 | | |
104 | | /// this takes a second parameter, which indicates the Ring that |
105 | | /// the new cursor should be part of (may be null) |
106 | | SwCursor(SwCursor const& rCursor, SwPaM* pRing); |
107 | | |
108 | | public: |
109 | | |
110 | | virtual SwCursor* Create( SwPaM* pRing = nullptr ) const; |
111 | | |
112 | | virtual short MaxReplaceArived(); //returns RET_YES/RET_CANCEL/RET_NO |
113 | | virtual void SaveTableBoxContent( const SwPosition* pPos ); |
114 | | |
115 | | void FillFindPos( SwDocPositions ePos, SwPosition& rPos ) const; |
116 | | SwMoveFnCollection const & MakeFindRange( SwDocPositions, SwDocPositions, |
117 | | SwPaM* ) const; |
118 | | |
119 | | // note: DO NOT call it FindText because windows.h |
120 | | SW_DLLPUBLIC sal_Int32 Find_Text( const i18nutil::SearchOptions2& rSearchOpt, |
121 | | bool bSearchInNotes, |
122 | | SwDocPositions nStart, SwDocPositions nEnd, |
123 | | bool& bCancel, |
124 | | FindRanges, |
125 | | bool bReplace = false, |
126 | | SwRootFrame const*const pLayout = nullptr); |
127 | | sal_Int32 FindFormat( const SwTextFormatColl& rFormatColl, |
128 | | SwDocPositions nStart, SwDocPositions nEnd, |
129 | | bool& bCancel, |
130 | | FindRanges, |
131 | | const SwTextFormatColl* pReplFormat, |
132 | | SwRootFrame const*const pLayout = nullptr); |
133 | | sal_Int32 FindAttrs( const SfxItemSet& rSet, bool bNoCollections, |
134 | | SwDocPositions nStart, SwDocPositions nEnd, |
135 | | bool& bCancel, |
136 | | FindRanges, |
137 | | const i18nutil::SearchOptions2* pSearchOpt, |
138 | | const SfxItemSet* rReplSet = nullptr, |
139 | | SwRootFrame const*const pLayout = nullptr); |
140 | | |
141 | | // UI versions |
142 | | bool IsStartEndSentence(bool bEnd, SwRootFrame const* pLayout) const; |
143 | | bool SelectWord( SwViewShell const * pViewShell, const Point* pPt ); |
144 | | |
145 | | // API versions of above functions (will be used with a different |
146 | | // WordType for the break iterator) |
147 | | bool IsStartWordWT(sal_Int16 nWordType, SwRootFrame const* pLayout = nullptr) const; |
148 | | bool IsEndWordWT(sal_Int16 nWordType, SwRootFrame const* pLayout = nullptr) const; |
149 | | bool IsInWordWT(sal_Int16 nWordType, SwRootFrame const* pLayout = nullptr) const; |
150 | | bool GoStartWordWT(sal_Int16 nWordType, SwRootFrame const* pLayout = nullptr); |
151 | | bool GoEndWordWT(sal_Int16 nWordType, SwRootFrame const* pLayout = nullptr); |
152 | | bool GoNextWordWT(sal_Int16 nWordType, SwRootFrame const* pLayout = nullptr); |
153 | | bool GoPrevWordWT(sal_Int16 nWordType, SwRootFrame const* pLayout = nullptr); |
154 | | bool SelectWordWT( SwViewShell const * pViewShell, sal_Int16 nWordType, const Point* pPt ); |
155 | | |
156 | | enum SentenceMoveType |
157 | | { |
158 | | NEXT_SENT, |
159 | | PREV_SENT, |
160 | | START_SENT, |
161 | | END_SENT |
162 | | }; |
163 | | bool GoSentence(SentenceMoveType eMoveType, SwRootFrame const*pLayout = nullptr); |
164 | | void ExpandToSentenceBorders(SwRootFrame const* pLayout); |
165 | | |
166 | | virtual bool LeftRight( bool bLeft, sal_uInt16 nCnt, SwCursorSkipMode nMode, |
167 | | bool bAllowVisual, bool bSkipHidden, bool bInsertCursor, |
168 | | SwRootFrame const* pLayout, bool isFieldNames); |
169 | | bool UpDown(bool bUp, sal_uInt16 nCnt, Point const * pPt, tools::Long nUpDownX, SwRootFrame & rLayout); |
170 | | bool LeftRightMargin(SwRootFrame const& rLayout, bool bLeftMargin, bool bAPI); |
171 | | bool IsAtLeftRightMargin(SwRootFrame const& rLayout, bool bLeftMargin, bool bAPI) const; |
172 | | SW_DLLPUBLIC bool SttEndDoc( bool bSttDoc ); |
173 | | bool GoPrevNextCell( bool bNext, sal_uInt16 nCnt ); |
174 | | |
175 | 141k | bool Left( sal_uInt16 nCnt ) { return LeftRight(true, nCnt, SwCursorSkipMode::Chars, false/*bAllowVisual*/, false/*bSkipHidden*/, false, nullptr, false); } |
176 | 15.5k | bool Right( sal_uInt16 nCnt ) { return LeftRight(false, nCnt, SwCursorSkipMode::Chars, false/*bAllowVisual*/, false/*bSkipHidden*/, false, nullptr, false); } |
177 | 0 | bool GoNextCell( sal_uInt16 nCnt = 1 ) { return GoPrevNextCell( true, nCnt ); } |
178 | 0 | bool GoPrevCell( sal_uInt16 nCnt = 1 ) { return GoPrevNextCell( false, nCnt ); } |
179 | | virtual bool GotoTable( const UIName& rName ); |
180 | | bool GotoTableBox( const OUString& rName ); |
181 | | bool GotoRegion( std::u16string_view rName ); |
182 | | SW_DLLPUBLIC bool GotoFootnoteAnchor(); |
183 | | bool GotoFootnoteText(); |
184 | | SW_DLLPUBLIC bool GotoNextFootnoteAnchor(); |
185 | | SW_DLLPUBLIC bool GotoPrevFootnoteAnchor(); |
186 | | |
187 | | SW_DLLPUBLIC bool MovePara( SwWhichPara, SwMoveFnCollection const & ); |
188 | | bool MoveSection( SwWhichSection, SwMoveFnCollection const & ); |
189 | | bool MoveTable( SwWhichTable, SwMoveFnCollection const & ); |
190 | | bool MoveRegion( SwWhichRegion, SwMoveFnCollection const & ); |
191 | | |
192 | | // Is there a selection of content in table? |
193 | | // Return value indicates if cursor remains at its old position. |
194 | | virtual bool IsSelOvr( SwCursorSelOverFlags eFlags = |
195 | | SwCursorSelOverFlags::CheckNodeSection | |
196 | | SwCursorSelOverFlags::Toggle | |
197 | | SwCursorSelOverFlags::ChangePos ); |
198 | | bool IsInProtectTable( bool bMove = false, |
199 | | bool bChgCursor = true ); |
200 | | bool IsNoContent() const; |
201 | | |
202 | | /** Restore cursor state to the one saved by SwCursorSaveState **/ |
203 | | void RestoreSavePos(); |
204 | | |
205 | | // true: cursor can be set at this position. |
206 | | virtual bool IsAtValidPos( bool bPoint = true ) const; |
207 | | |
208 | | // Is cursor allowed in ready only ranges? |
209 | | virtual bool IsReadOnlyAvailable() const; |
210 | | |
211 | | virtual bool IsSkipOverProtectSections() const; |
212 | | virtual bool IsSkipOverHiddenSections() const; |
213 | | |
214 | 74.8k | sal_uInt8 GetCursorBidiLevel() const { return m_nCursorBidiLevel; } |
215 | 747 | void SetCursorBidiLevel( sal_uInt8 nNewLevel ) { m_nCursorBidiLevel = nNewLevel; } |
216 | | |
217 | 0 | bool IsColumnSelection() const { return m_bColumnSelection; } |
218 | 0 | void SetColumnSelection( bool bNew ) { m_bColumnSelection = bNew; } |
219 | | |
220 | 0 | sal_Int32 GetCursorRowSpanOffset() const { return m_nRowSpanOffset; } |
221 | | |
222 | 1.05M | SwCursor* GetNext() { return dynamic_cast<SwCursor *>(GetNextInRing()); } |
223 | 0 | const SwCursor* GetNext() const { return dynamic_cast<SwCursor const *>(GetNextInRing()); } |
224 | 17 | SwCursor* GetPrev() { return dynamic_cast<SwCursor *>(GetPrevInRing()); } |
225 | 0 | const SwCursor* GetPrev() const { return dynamic_cast<SwCursor const *>(GetPrevInRing()); } |
226 | | |
227 | | bool IsInHyphenatedWord( SwRootFrame const& rLayout ) const; |
228 | | }; |
229 | | |
230 | | /** |
231 | | A helper class to save cursor state (position). Create SwCursorSaveState |
232 | | object to save current state, use SwCursor::RestoreSavePos() to actually |
233 | | restore cursor state to the saved state (SwCursorSaveState destructor only |
234 | | removes the saved state from an internal stack). It is possible to stack |
235 | | several SwCursorSaveState objects. |
236 | | **/ |
237 | | class SwCursorSaveState |
238 | | { |
239 | | private: |
240 | | SwCursor& m_rCursor; |
241 | | public: |
242 | 288k | SwCursorSaveState( SwCursor& rC ) : m_rCursor( rC ) { rC.SaveState(); } |
243 | 288k | ~SwCursorSaveState() { m_rCursor.RestoreState(); } |
244 | | }; |
245 | | |
246 | | // internal, used by SwCursor::SaveState() etc. |
247 | | struct SwCursor_SavePos final |
248 | | { |
249 | | SwNodeOffset nNode; |
250 | | sal_Int32 nContent; |
251 | | |
252 | | SwCursor_SavePos( const SwCursor& rCursor ) |
253 | 288k | : nNode( rCursor.GetPoint()->GetNodeIndex() ), |
254 | 288k | nContent( rCursor.GetPoint()->GetContentIndex() ) |
255 | 288k | {} |
256 | | }; |
257 | | |
258 | | class SwTableCursor : public virtual SwCursor |
259 | | { |
260 | | |
261 | | protected: |
262 | | SwNodeOffset m_nTablePtNd; |
263 | | SwNodeOffset m_nTableMkNd; |
264 | | sal_Int32 m_nTablePtCnt; |
265 | | sal_Int32 m_nTableMkCnt; |
266 | | SwSelBoxes m_SelectedBoxes; |
267 | | bool m_bChanged : 1; |
268 | | bool m_bParked : 1; // Table-cursor was parked. |
269 | | |
270 | | virtual bool IsSelOvrCheck(SwCursorSelOverFlags eFlags) override; |
271 | | |
272 | | public: |
273 | | SwTableCursor( const SwPosition &rPos ); |
274 | | SwTableCursor( SwTableCursor& ); |
275 | | virtual ~SwTableCursor() override; |
276 | | |
277 | | virtual bool LeftRight( bool bLeft, sal_uInt16 nCnt, SwCursorSkipMode nMode, |
278 | | bool bAllowVisual, bool bSkipHidden, bool bInsertCursor, |
279 | | SwRootFrame const*, bool) override; |
280 | | virtual bool GotoTable( const UIName& rName ) override; |
281 | | |
282 | | void InsertBox( const SwTableBox& rTableBox ); |
283 | | void DeleteBox(size_t nPos); |
284 | 34 | size_t GetSelectedBoxesCount() const { return m_SelectedBoxes.size(); } |
285 | 0 | const SwSelBoxes& GetSelectedBoxes() const { return m_SelectedBoxes; } |
286 | | |
287 | | // Creates cursor for all boxes. |
288 | | SwCursor* MakeBoxSels( SwCursor* pCurrentCursor ); |
289 | | // Any boxes protected? |
290 | | bool HasReadOnlyBoxSel() const; |
291 | | // Any boxes hidden? |
292 | | bool HasHiddenBoxSel() const; |
293 | | |
294 | | // Has table cursor been changed? If so, save new values immediately. |
295 | | bool IsCursorMovedUpdate(); |
296 | | // Has table cursor been changed? |
297 | | bool IsCursorMoved() const |
298 | 0 | { |
299 | 0 | return m_nTableMkNd != GetMark()->GetNodeIndex() || |
300 | 0 | m_nTablePtNd != GetPoint()->GetNodeIndex() || |
301 | 0 | m_nTableMkCnt != GetMark()->GetContentIndex() || |
302 | 0 | m_nTablePtCnt != GetPoint()->GetContentIndex(); |
303 | 0 | } |
304 | | |
305 | 51 | bool IsChgd() const { return m_bChanged; } |
306 | 0 | void SetChgd() { m_bChanged = true; } |
307 | | |
308 | | // Park table cursor at start node of boxes. |
309 | | void ParkCursor(); |
310 | | |
311 | | bool NewTableSelection(); |
312 | | void ActualizeSelection( const SwSelBoxes &rBoxes ); |
313 | | |
314 | 0 | SwTableCursor* GetNext() { return dynamic_cast<SwTableCursor *>(GetNextInRing()); } |
315 | 0 | const SwTableCursor* GetNext() const { return dynamic_cast<SwTableCursor const *>(GetNextInRing()); } |
316 | 0 | SwTableCursor* GetPrev() { return dynamic_cast<SwTableCursor *>(GetPrevInRing()); } |
317 | 0 | const SwTableCursor* GetPrev() const { return dynamic_cast<SwTableCursor const *>(GetPrevInRing()); } |
318 | | }; |
319 | | |
320 | 198k | const SwCursor_SavePos* SwCursor::GetSavePos() const { return m_vSavePos.empty() ? nullptr : &m_vSavePos.back(); } |
321 | | |
322 | 0 | SwCursor & SwCursor::operator =(SwCursor const &) = default; |
323 | | |
324 | | #endif |
325 | | |
326 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |