summaryrefslogtreecommitdiff
path: root/sw/inc/swcrsr.hxx
blob: 234b0196d68ea5d08253ea51a02d41d25cf3d6eb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */
#ifndef INCLUDED_SW_INC_SWCRSR_HXX
#define INCLUDED_SW_INC_SWCRSR_HXX

#include "pam.hxx"
#include "tblsel.hxx"
#include "cshtyp.hxx"

class SfxItemSet;
struct SwCursor_SavePos;
class SvxSearchItem;
namespace i18nutil {
    struct SearchOptions2;
}

// Base structure for parameters of the find-methods.
// Returns values of found-call.
const int FIND_NOT_FOUND    = 0;
const int FIND_FOUND        = 1;
const int FIND_NO_RING      = 2;

struct SwFindParas
{
    // @param xSearchItem allocate in parent so we can do so outside the calling loop
    virtual int DoFind(SwPaM &, SwMoveFnCollection const &, const SwPaM&, bool, std::unique_ptr<SvxSearchItem>& xSearchItem) = 0;
    virtual bool IsReplaceMode() const = 0;

protected:
    ~SwFindParas() {}
};

enum class SwCursorSelOverFlags : sal_uInt16
{
    NONE                = 0x00,
    CheckNodeSection    = 0x01,
    Toggle              = 0x02,
    EnableRevDirection  = 0x04,
    ChangePos           = 0x08
};
namespace o3tl {
    template<> struct typed_flags<SwCursorSelOverFlags> : is_typed_flags<SwCursorSelOverFlags, 0x0f> {};
}

// define for cursor travelling normally in western text cells and chars do
// the same, but in complex text cell skip over ligatures and char skip
// into it.
// These defines exist only to cut off the dependencies to I18N project.
const sal_uInt16 CRSR_SKIP_CHARS  = 0;
const sal_uInt16 CRSR_SKIP_CELLS  = 1;
const sal_uInt16 CRSR_SKIP_HIDDEN = 2;


class SW_DLLPUBLIC SwCursor : public SwPaM
{
    friend class SwCursorSaveState;

    std::vector<SwCursor_SavePos> m_vSavePos; // the current entry is the last element
    tools::Long m_nRowSpanOffset;        // required for travelling in tabs with rowspans
    sal_uInt8 m_nCursorBidiLevel; // bidi level of the cursor
    bool m_bColumnSelection;      // true: cursor is aprt of a column selection

    sal_uLong FindAll( SwFindParas& , SwDocPositions, SwDocPositions, FindRanges, bool& bCancel );

    SwCursor(SwCursor const& rPaM) = delete;

protected:
    void SaveState();
    void RestoreState();

    const SwCursor_SavePos* GetSavePos() const { return m_vSavePos.empty() ? nullptr : &m_vSavePos.back(); }

    virtual const SwContentFrame* DoSetBidiLevelLeftRight(
        bool & io_rbLeft, bool bVisualAllowed, bool bInsertCursor);
    virtual void DoSetBidiLevelUpDown();
    virtual bool IsSelOvrCheck(SwCursorSelOverFlags eFlags);

public:
    // single argument ctors shall be explicit.
    SwCursor( const SwPosition &rPos, SwPaM* pRing );
    virtual ~SwCursor() override;

    SwCursor & operator =(SwCursor const &) = default;

    /// this takes a second parameter, which indicates the Ring that
    /// the new cursor should be part of (may be null)
    SwCursor(SwCursor const& rCursor, SwPaM* pRing);

public:

    virtual SwCursor* Create( SwPaM* pRing = nullptr ) const;

    virtual short MaxReplaceArived(); //returns RET_YES/RET_CANCEL/RET_NO
    virtual void SaveTableBoxContent( const SwPosition* pPos );

    void FillFindPos( SwDocPositions ePos, SwPosition& rPos ) const;
    SwMoveFnCollection const & MakeFindRange( SwDocPositions, SwDocPositions,
                                        SwPaM* ) const;

    // note: DO NOT call it FindText because windows.h
    sal_uLong Find_Text( const i18nutil::SearchOptions2& rSearchOpt,
                bool bSearchInNotes,
                SwDocPositions nStart, SwDocPositions nEnd,
                bool& bCancel,
                FindRanges,
                bool bReplace = false,
                SwRootFrame const*const pLayout = nullptr);
    sal_uLong FindFormat( const SwTextFormatColl& rFormatColl,
                SwDocPositions nStart, SwDocPositions nEnd,
                bool& bCancel,
                FindRanges,
                const SwTextFormatColl* pReplFormat,
                SwRootFrame const*const pLayout = nullptr);
    sal_uLong FindAttrs( const SfxItemSet& rSet, bool bNoCollections,
                SwDocPositions nStart, SwDocPositions nEnd,
                bool& bCancel,
                FindRanges,
                const i18nutil::SearchOptions2* pSearchOpt,
                const SfxItemSet* rReplSet = nullptr,
                SwRootFrame const*const pLayout = nullptr);

    // UI versions
    bool IsStartEndSentence(bool bEnd, SwRootFrame const* pLayout) const;
    bool SelectWord( SwViewShell const * pViewShell, const Point* pPt );

    // API versions of above functions (will be used with a different
    // WordType for the break iterator)
    bool IsStartWordWT(sal_Int16 nWordType, SwRootFrame const* pLayout = nullptr) const;
    bool IsEndWordWT(sal_Int16 nWordType, SwRootFrame const* pLayout = nullptr) const;
    bool IsInWordWT(sal_Int16 nWordType, SwRootFrame const* pLayout = nullptr) const;
    bool GoStartWordWT(sal_Int16 nWordType, SwRootFrame const* pLayout = nullptr);
    bool GoEndWordWT(sal_Int16 nWordType, SwRootFrame const* pLayout = nullptr);
    bool GoNextWordWT(sal_Int16 nWordType, SwRootFrame const* pLayout = nullptr);
    bool GoPrevWordWT(sal_Int16 nWordType, SwRootFrame const* pLayout = nullptr);
    bool SelectWordWT( SwViewShell const * pViewShell, sal_Int16 nWordType, const Point* pPt );

    enum SentenceMoveType
    {
        NEXT_SENT,
        PREV_SENT,
        START_SENT,
        END_SENT
    };
    bool GoSentence(SentenceMoveType eMoveType, SwRootFrame const*pLayout = nullptr);
    bool ExpandToSentenceBorders(SwRootFrame const* pLayout);

    virtual bool LeftRight( bool bLeft, sal_uInt16 nCnt, sal_uInt16 nMode,
        bool bAllowVisual, bool bSkipHidden, bool bInsertCursor,
        SwRootFrame const* pLayout, bool isFieldNames);
    bool UpDown(bool bUp, sal_uInt16 nCnt, Point const * pPt, tools::Long nUpDownX, SwRootFrame & rLayout);
    bool LeftRightMargin(SwRootFrame const& rLayout, bool bLeftMargin, bool bAPI);
    bool IsAtLeftRightMargin(SwRootFrame const& rLayout, bool bLeftMargin, bool bAPI) const;
    bool SttEndDoc( bool bSttDoc );
    bool GoPrevNextCell( bool bNext, sal_uInt16 nCnt );

    bool Left( sal_uInt16 nCnt )   { return LeftRight(true, nCnt, CRSR_SKIP_CHARS, false/*bAllowVisual*/, false/*bSkipHidden*/, false, nullptr, false); }
    bool Right( sal_uInt16 nCnt )  { return LeftRight(false, nCnt, CRSR_SKIP_CHARS, false/*bAllowVisual*/, false/*bSkipHidden*/, false, nullptr, false); }
    bool GoNextCell( sal_uInt16 nCnt = 1 )  { return GoPrevNextCell( true, nCnt ); }
    bool GoPrevCell( sal_uInt16 nCnt = 1 )  { return GoPrevNextCell( false, nCnt ); }
    virtual bool GotoTable( const OUString& rName );
    bool GotoTableBox( const OUString& rName );
    bool GotoRegion( std::u16string_view rName );
    bool GotoFootnoteAnchor();
    bool GotoFootnoteText();
    bool GotoNextFootnoteAnchor();
    bool GotoPrevFootnoteAnchor();

    bool MovePara( SwWhichPara, SwMoveFnCollection const & );
    bool MoveSection( SwWhichSection, SwMoveFnCollection const & );
    bool MoveTable( SwWhichTable, SwMoveFnCollection const & );
    bool MoveRegion( SwWhichRegion, SwMoveFnCollection const & );

    // Is there a selection of content in table?
    // Return value indicates if cursor remains at its old position.
    virtual bool IsSelOvr( SwCursorSelOverFlags eFlags =
                                SwCursorSelOverFlags::CheckNodeSection |
                                SwCursorSelOverFlags::Toggle |
                                SwCursorSelOverFlags::ChangePos );
    bool IsInProtectTable( bool bMove = false,
                                   bool bChgCursor = true );
    bool IsNoContent() const;

    /** Restore cursor state to the one saved by SwCursorSaveState **/
    void RestoreSavePos();

    // true: cursor can be set at this position.
    virtual bool IsAtValidPos( bool bPoint = true ) const;

    // Is cursor allowed in ready only ranges?
    virtual bool IsReadOnlyAvailable() const;

    virtual bool IsSkipOverProtectSections() const;
    virtual bool IsSkipOverHiddenSections() const;

    sal_uInt8 GetCursorBidiLevel() const { return m_nCursorBidiLevel; }
    void SetCursorBidiLevel( sal_uInt8 nNewLevel ) { m_nCursorBidiLevel = nNewLevel; }

    bool IsColumnSelection() const { return m_bColumnSelection; }
    void SetColumnSelection( bool bNew ) { m_bColumnSelection = bNew; }

    tools::Long GetCursorRowSpanOffset() const { return m_nRowSpanOffset; }

    SwCursor* GetNext()             { return dynamic_cast<SwCursor *>(GetNextInRing()); }
    const SwCursor* GetNext() const { return dynamic_cast<SwCursor const *>(GetNextInRing()); }
    SwCursor* GetPrev()             { return dynamic_cast<SwCursor *>(GetPrevInRing()); }
    const SwCursor* GetPrev() const { return dynamic_cast<SwCursor const *>(GetPrevInRing()); }
};

/**
 A helper class to save cursor state (position). Create SwCursorSaveState
 object to save current state, use SwCursor::RestoreSavePos() to actually
 restore cursor state to the saved state (SwCursorSaveState destructor only
 removes the saved state from an internal stack). It is possible to stack
 several SwCursorSaveState objects.
**/
class SwCursorSaveState
{
private:
    SwCursor& m_rCursor;
public:
    SwCursorSaveState( SwCursor& rC ) : m_rCursor( rC ) { rC.SaveState(); }
    ~SwCursorSaveState() { m_rCursor.RestoreState(); }
};

// internal, used by SwCursor::SaveState() etc.
struct SwCursor_SavePos final
{
    sal_uLong nNode;
    sal_Int32 nContent;

    SwCursor_SavePos( const SwCursor& rCursor )
        : nNode( rCursor.GetPoint()->nNode.GetIndex() ),
          nContent( rCursor.GetPoint()->nContent.GetIndex() )
    {}
};

class SwTableCursor : public virtual SwCursor
{

protected:
    sal_uLong m_nTablePtNd;
    sal_uLong m_nTableMkNd;
    sal_Int32 m_nTablePtCnt;
    sal_Int32 m_nTableMkCnt;
    SwSelBoxes m_SelectedBoxes;
    bool m_bChanged : 1;
    bool m_bParked : 1;       // Table-cursor was parked.

    virtual bool IsSelOvrCheck(SwCursorSelOverFlags eFlags) override;

public:
    SwTableCursor( const SwPosition &rPos );
    SwTableCursor( SwTableCursor& );
    virtual ~SwTableCursor() override;

    virtual bool LeftRight( bool bLeft, sal_uInt16 nCnt, sal_uInt16 nMode,
        bool bAllowVisual, bool bSkipHidden, bool bInsertCursor,
        SwRootFrame const*, bool) override;
    virtual bool GotoTable( const OUString& rName ) override;

    void InsertBox( const SwTableBox& rTableBox );
    void DeleteBox(size_t nPos);
    size_t GetSelectedBoxesCount() const { return m_SelectedBoxes.size(); }
    const SwSelBoxes& GetSelectedBoxes() const { return m_SelectedBoxes; }

    // Creates cursor for all boxes.
    SwCursor* MakeBoxSels( SwCursor* pCurrentCursor );
    // Any boxes protected?
    bool HasReadOnlyBoxSel() const;

    // Has table cursor been changed? If so, save new values immediately.
    bool IsCursorMovedUpdate();
    // Has table cursor been changed?
    bool IsCursorMoved() const
    {
        return  m_nTableMkNd != GetMark()->nNode.GetIndex() ||
                m_nTablePtNd != GetPoint()->nNode.GetIndex() ||
                m_nTableMkCnt != GetMark()->nContent.GetIndex() ||
                m_nTablePtCnt != GetPoint()->nContent.GetIndex();
    }

    bool IsChgd() const { return m_bChanged; }
    void SetChgd() { m_bChanged = true; }

    // Park table cursor at start node of boxes.
    void ParkCursor();

    bool NewTableSelection();
    void ActualizeSelection( const SwSelBoxes &rBoxes );

    SwTableCursor* GetNext()             { return dynamic_cast<SwTableCursor *>(GetNextInRing()); }
    const SwTableCursor* GetNext() const { return dynamic_cast<SwTableCursor const *>(GetNextInRing()); }
    SwTableCursor* GetPrev()             { return dynamic_cast<SwTableCursor *>(GetPrevInRing()); }
    const SwTableCursor* GetPrev() const { return dynamic_cast<SwTableCursor const *>(GetPrevInRing()); }
};

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */