Coverage Report

Created: 2026-05-16 09:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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: */