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_CRSRSH_HXX
20 #define INCLUDED_SW_INC_CRSRSH_HXX
21 
22 #include <com/sun/star/i18n/WordType.hpp>
23 
24 #include <rtl/ustring.hxx>
25 #include <tools/link.hxx>
26 #include <vcl/keycod.hxx>
27 #include <o3tl/typed_flags_set.hxx>
28 
29 #include "IShellCursorSupplier.hxx"
30 #include "swdllapi.h"
31 #include "docary.hxx"
32 #include "viewsh.hxx"
33 #include "calbck.hxx"
34 #include "cshtyp.hxx"
35 #include "crstate.hxx"
36 #include "toxe.hxx"
37 #include "tblsel.hxx"
38 #include "viscrs.hxx"
39 #include "node.hxx"
40 #include "fldbas.hxx"
41 #include "IDocumentMarkAccess.hxx"
42 
43 class SfxItemSet;
44 class SfxPoolItem;
45 class SwContentFrame;
46 class SwUnoCursor;
47 class SwFormatField;
48 class SwTextFormatColl;
49 class SwTextINetFormat;
50 class SwFormatINetFormat;
51 class SwTextAttr;
52 class SwTableBox;
53 class SwTOXMark;
54 class SwRangeRedline;
55 class SwBlockCursor;
56 class SwPostItField;
57 class SwTextField;
58 
59 namespace i18nutil {
60     struct SearchOptions2;
61 }
62 namespace com { namespace sun { namespace star { namespace text {
63     class XTextRange;
64 }}}}
65 namespace com { namespace sun { namespace star { namespace container {
66     class XStringKeyMap;
67 }}}}
68 
69 // enum and struct to get information via the Doc-Position
70 
71 enum class IsAttrAtPos
72 {
73     NONE             = 0x0000,
74     Field            = 0x0001,
75     ClickField       = 0x0002,
76     Ftn              = 0x0004,
77     InetAttr         = 0x0008,
78     TableBoxFml      = 0x0010,
79     Redline          = 0x0020,
80     Outline          = 0x0040,
81     ToxMark          = 0x0080,
82     RefMark          = 0x0100,
83     NumLabel         = 0x0200,
84     ContentCheck     = 0x0400,
85     SmartTag         = 0x0800,
86     FormControl      = 0x1000
87 #ifdef DBG_UTIL
88     ,CurrAttrs       = 0x2000        ///< only for debugging
89     ,TableBoxValue   = 0x4000        ///< only for debugging
90 #endif
91 };
92 namespace o3tl {
93     template<> struct typed_flags<IsAttrAtPos> : is_typed_flags<IsAttrAtPos, 0x7fff> {};
94 }
95 
96 struct SwContentAtPos
97 {
98     union {
99         const SwField* pField;
100         const SfxPoolItem* pAttr;
101         const SwRangeRedline* pRedl;
102         SwContentNode * pNode;
103         const sw::mark::IFieldmark* pFieldmark;
104     } aFnd;
105     IsAttrAtPos eContentAtPos;
106     int nDist;
107     OUString sStr;
108     const SwTextAttr* pFndTextAttr;
109 
SwContentAtPosSwContentAtPos110     SwContentAtPos( IsAttrAtPos eGetAtPos )
111         : eContentAtPos( eGetAtPos )
112     {
113         aFnd.pField = nullptr;
114         pFndTextAttr = nullptr;
115         nDist = 0; // #i23726#
116     }
117 
118     bool IsInProtectSect() const;
119     bool IsInRTLText() const;
120 };
121 
122 // return values of SetCursor (can be combined via ||)
123 const int CRSR_POSOLD = 0x01,   // cursor stays at old position
124           CRSR_POSCHG = 0x02;   // position changed by the layout
125 
126 namespace sw {
127 
128 bool ReplaceImpl(SwPaM & rCursor, OUString const& rReplacement,
129         bool const bRegExp, SwDoc & rDoc, SwRootFrame const*const pLayout);
130 
131 /// Helperfunction to resolve backward references in regular expressions
132 boost::optional<OUString> ReplaceBackReferences(const i18nutil::SearchOptions2& rSearchOpt,
133         SwPaM* pPam, SwRootFrame const* pLayout );
134 
135 bool GetRanges(std::vector<std::shared_ptr<SwUnoCursor>> & rRanges,
136         SwDoc & rDoc, SwPaM const& rDelPam);
137 
138 } // namespace sw
139 
140 class SW_DLLPUBLIC SwCursorShell
141     : public SwViewShell
142     , public SwModify
143     , public ::sw::IShellCursorSupplier
144 {
145     friend class SwCallLink;
146     friend class SwVisibleCursor;
147     friend class SwSelPaintRects;
148 
149     // requires the Cursor as InternalCursor
150     friend bool GetAutoSumSel( const SwCursorShell&, SwCellFrames& );
151 
152 public:
153 
154     /** for calling UpdateCursor */
155     enum CursorFlag {
156         UPDOWN      = (1 << 0),     ///< keep Up/Down on columns
157         SCROLLWIN   = (1 << 1),     ///< scroll window
158         CHKRANGE    = (1 << 2),     ///< check overlapping PaMs
159         READONLY    = (1 << 3)      ///< make visible in spite of Readonly
160     };
161 
162     SAL_DLLPRIVATE void UpdateCursor(
163         sal_uInt16 eFlags = SwCursorShell::SCROLLWIN|SwCursorShell::CHKRANGE,
164         bool bIdleEnd = false );
165 
166 private:
167 
168     SwRect  m_aCharRect;          ///< Char-SRectangle on which the cursor is located
169     Point   m_aCursorHeight;        ///< height & offset from visible Cursor
170     Point   m_aOldRBPos;          ///< Right/Bottom of last VisArea
171                                 // (used in Invalidate by Cursor)
172 
173     Link<const SwFlyFrameFormat*,void> m_aFlyMacroLnk;        /**< Link will be called, if the Cursor is set
174                                    into a fly. A macro can then be called */
175     Link<LinkParamNone*,void> m_aChgLnk;             /**< link will be called by every attribute/
176                                    format changes at cursor position.*/
177     Link<SwCursorShell&,void> m_aGrfArrivedLnk;      ///< Link calls to UI if a graphic is arrived
178 
179     SwShellCursor* m_pCurrentCursor;      ///< current cursor
180     SwShellCursor* m_pStackCursor;      ///< stack for the cursor
181     SwVisibleCursor *m_pVisibleCursor;        ///< the visible cursor
182 
183     SwBlockCursor *m_pBlockCursor;   ///< interface of cursor for block (=rectangular) selection
184 
185     SwShellTableCursor* m_pTableCursor; /**< table Cursor; only in tables when the
186                                    selection lays over 2 columns */
187 
188     SwNodeIndex* m_pBoxIdx;       ///< for recognizing of the changed
189     SwTableBox* m_pBoxPtr;        ///< table row
190 
191     long m_nUpDownX;              /**< try to move the cursor on up/down always
192                                    in the same column */
193     long m_nLeftFramePos;
194     sal_uLong m_nCurrentNode;     // save CursorPos at Start-Action
195     sal_Int32 m_nCurrentContent;
196     SwNodeType m_nCurrentNdTyp;
197 
198     /*
199      * Via the Method SttCursorMove and EndCursorMove this counter gets
200      * incremented/decremented. As long as the counter is inequal to 0, the
201      * current Cursor gets no update. This way, "complicated" cursor movements
202      * (via Find()) can be realised.
203      */
204     sal_uInt16 m_nCursorMove;
205     CursorMoveState m_eMvState;     ///< Status for Cursor-Travelling - GetCursorOfst
206     SwTable::SearchType m_eEnhancedTableSel; /// table rows or columns selected by not cell by cell
207 
208     OUString m_sMarkedListId;
209     int m_nMarkedListLevel;
210 
211     bool m_bHasFocus : 1;         ///< Shell is "active" in a window
212     bool m_bSVCursorVis : 1;        ///< SV-Cursor visible/invisible
213     bool m_bChgCallFlag : 1;      ///< attribute change inside Start- and EndAction
214     bool m_bVisPortChgd : 1;      ///< in VisPortChg-Call
215                                 // (used in Invalidate by the Cursor)
216 
217     bool m_bCallChgLnk : 1;       ///< flag for derived classes
218                                 // true -> call ChgLnk
219                                 // access only via SwChgLinkFlag
220     bool m_bAllProtect : 1;       ///< Flag for areas
221                                 // true -> everything protected / hidden
222     bool m_bInCMvVisportChgd : 1; ///< Flag for CursorMoves
223                                 // true -> view was moved
224     bool m_bGCAttr : 1;           // true -> non expanded attributes exist.
225     bool m_bIgnoreReadonly : 1;   // true -> make the cursor visible on next
226                                 // EndAction in spite of Readonly
227     bool m_bSelTableCells : 1;      // true -> select cells over the InputWin
228     bool m_bAutoUpdateCells : 1;  // true -> autoformat cells
229     bool m_bBasicHideCursor : 1;    // true -> HideCursor from Basic
230     bool m_bSetCursorInReadOnly : 1;// true -> Cursor is allowed in ReadOnly-Areas
231     bool m_bOverwriteCursor : 1;    // true -> show Overwrite Cursor
232 
233     bool m_bMacroExecAllowed : 1;
234 
235     SwFrame* m_oldColFrame;
236 
237     SAL_DLLPRIVATE void MoveCursorToNum();
238 
239     SAL_DLLPRIVATE void ParkPams( SwPaM* pDelRg, SwShellCursor** ppDelRing );
240 
241     /** Mark a certain list level of a certain list
242 
243         levels of a certain lists are marked now
244 
245         @param sListId    list Id of the list whose level is marked
246         @param nLevel     to be marked list level
247 
248         An empty sListId denotes that no level of a list is marked.
249      */
250     SAL_DLLPRIVATE void MarkListLevel( const OUString& sListId,
251                                       const int nLevel );
252 
253     // private method(s) accessed from public inline method(s) must be exported.
254                    bool LeftRight( bool, sal_uInt16, sal_uInt16, bool );
255     SAL_DLLPRIVATE bool UpDown( bool, sal_uInt16 );
256     SAL_DLLPRIVATE bool LRMargin( bool, bool bAPI = false );
257     SAL_DLLPRIVATE bool IsAtLRMargin( bool, bool bAPI = false ) const;
258 
259     SAL_DLLPRIVATE bool isInHiddenTextFrame(SwShellCursor* pShellCursor);
260 
261     SAL_DLLPRIVATE bool GoStartWordImpl();
262     SAL_DLLPRIVATE bool GoEndWordImpl();
263     SAL_DLLPRIVATE bool GoNextWordImpl();
264     SAL_DLLPRIVATE bool GoPrevWordImpl();
265     SAL_DLLPRIVATE bool GoNextSentenceImpl();
266     SAL_DLLPRIVATE bool GoEndSentenceImpl();
267     SAL_DLLPRIVATE bool GoStartSentenceImpl();
268 
269     typedef bool (SwCursor::*FNCursor)();
270     typedef bool (SwCursorShell::*FNCursorShell)();
271     SAL_DLLPRIVATE bool CallCursorFN( FNCursor );
272     SAL_DLLPRIVATE bool CallCursorShellFN( FNCursorShell );
273 
274     SAL_DLLPRIVATE const SwRangeRedline* GotoRedline_( SwRedlineTable::size_type nArrPos, bool bSelect );
275 
276     SAL_DLLPRIVATE void sendLOKCursorUpdates();
277 protected:
278 
279     inline SwMoveFnCollection const & MakeFindRange( SwDocPositions, SwDocPositions, SwPaM* ) const;
280 
281     /*
282      * Compare-Method for the StackCursor and the current Cursor.
283      * The Methods return -1, 0, 1 for lower, equal, greater.
284      */
285     int CompareCursorStackMkCurrPt() const;
286 
287     bool SelTableRowOrCol( bool bRow, bool bRowSimple = false );
288 
289     bool SetInFrontOfLabel( bool bNew );
290 
291     void RefreshBlockCursor();
292 
293     /** Updates the marked list level according to the cursor.
294     */
295     SAL_DLLPRIVATE void UpdateMarkedListLevel();
296 
297 protected:
298     virtual void Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew) override;
299 
300 public:
301     SwCursorShell( SwDoc& rDoc, vcl::Window *pWin, const SwViewOption *pOpt );
302     // disguised copy constructor
303     SwCursorShell( SwCursorShell& rShell, vcl::Window *pWin );
304     virtual ~SwCursorShell() override;
305 
306     // create new cursor and append the old one
307     virtual SwPaM & CreateNewShellCursor() override;
308     virtual SwPaM & GetCurrentShellCursor() override;
309 
310     SwPaM * CreateCursor();
311     ///< delete the current cursor and make the following into the current
312     void DestroyCursor();
313     ///< transform TableCursor to normal cursor, nullify Tablemode
314     void TableCursorToCursor();
315     ///< enter block mode, change normal cursor into block cursor
316     void CursorToBlockCursor();
317     ///< leave block mode, change block cursor into normal cursor
318     void BlockCursorToCursor();
319 
320     // SelAll() selects the document body content
321     // if ExtendedSelect() is called afterwards, the whole nodes array is selected
322     // only for usage in special cases allowed!
323     void ExtendedSelectAll(bool bFootnotes = true);
324     /// If ExtendedSelectAll() was called and selection didn't change since then.
325     bool ExtendedSelectedAll();
326     /// If document body starts with a table.
327     bool StartsWithTable();
328 
329     SwPaM* GetCursor( bool bMakeTableCursor = true ) const;
330     inline SwCursor* GetSwCursor() const;
331     // return only the current cursor
GetCursor_()332           SwShellCursor* GetCursor_()                       { return m_pCurrentCursor; }
GetCursor_() const333     const SwShellCursor* GetCursor_() const                 { return m_pCurrentCursor; }
334 
335     // show passed cursor - for UNO
336     void    SetSelection(const SwPaM& rCursor);
337 
338     // remove all cursors from ContentNodes and set to 0
339     void ParkCursor( const SwNodeIndex &rIdx );
340 
341     // return the current cursor stack
342     // (required in EditShell when deleting contents)
343     inline SwPaM* GetStackCursor() const;
344 
345     // start parenthesing, hide SV-Cursor and selected areas
346     void StartAction();
347     // end parenthesing, show SV-Cursor and selected areas
348     void EndAction( const bool bIdleEnd = false, const bool DoSetPosX = false );
349 
350     // basic cursor travelling
GetUpDownX() const351     long GetUpDownX() const             { return m_nUpDownX; }
352 
Left(sal_uInt16 nCnt,sal_uInt16 nMode,bool bAllowVisual=false)353     bool Left( sal_uInt16 nCnt, sal_uInt16 nMode, bool bAllowVisual = false )
354         { return LeftRight( true, nCnt, nMode, bAllowVisual ); }
Right(sal_uInt16 nCnt,sal_uInt16 nMode,bool bAllowVisual=false)355     bool Right( sal_uInt16 nCnt, sal_uInt16 nMode, bool bAllowVisual = false )
356         { return LeftRight( false, nCnt, nMode, bAllowVisual ); }
Up(sal_uInt16 nCnt=1)357     bool Up( sal_uInt16 nCnt = 1 )      { return UpDown( true, nCnt ); }
Down(sal_uInt16 nCnt=1)358     bool Down( sal_uInt16 nCnt = 1 )    { return UpDown( false, nCnt ); }
LeftMargin()359     bool LeftMargin()               { return LRMargin( true ); }
RightMargin(bool bAPI=false)360     bool RightMargin(bool bAPI = false) { return LRMargin( false, bAPI ); }
361     bool SttEndDoc( bool bStt );
362 
363     bool MovePage( SwWhichPage, SwPosPage );
364     bool MovePara( SwWhichPara, SwMoveFnCollection const & );
365     bool MoveSection( SwWhichSection, SwMoveFnCollection const & );
366     bool MoveTable( SwWhichTable, SwMoveFnCollection const & );
367     void MoveColumn( SwWhichColumn, SwPosColumn );
368     bool MoveRegion( SwWhichRegion, SwMoveFnCollection const & );
369 
370     // note: DO NOT call it FindText because windows.h
371     sal_uLong Find_Text( const i18nutil::SearchOptions2& rSearchOpt,
372                 bool bSearchInNotes,
373                 SwDocPositions eStart, SwDocPositions eEnd,
374                 bool& bCancel,
375                 FindRanges eRng, bool bReplace = false );
376 
377     sal_uLong FindFormat( const SwTextFormatColl& rFormatColl,
378                 SwDocPositions eStart, SwDocPositions eEnd,
379                 bool& bCancel,
380                 FindRanges eRng, const SwTextFormatColl* pReplFormat );
381 
382     sal_uLong FindAttrs( const SfxItemSet& rSet, bool bNoCollections,
383                 SwDocPositions eStart, SwDocPositions eEnd,
384                 bool& bCancel,
385                 FindRanges eRng,
386                 const i18nutil::SearchOptions2* pSearchOpt,
387                 const SfxItemSet* rReplSet );
388 
389     //  Position the Cursor
390     //  return values:
391     //      CRSR_POSCHG: when cursor was corrected from SPoint by the layout
392     //      CRSR_POSOLD: when the cursor was not changed
393     int SetCursor( const Point &rPt, bool bOnlyText = false, bool bBlock = true );
394 
395     /*
396      * Notification that the visible area was changed. m_aVisArea is reset, then
397      * scrolling is done. The passed Rectangle lays on pixel borders to avoid
398      * pixel errors.
399      */
400     virtual void VisPortChgd( const SwRect & ) override;
401 
402     /*
403      * virtual paint method to make selection visible again after Paint
404      */
405     void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle & rRect) override;
406 
407     // Areas
408     inline void SetMark();
409     inline bool HasMark() const;
410 
411     void ClearMark();
412 
413     /**
414        Ensure point and mark of the current PaM are in a specific order.
415 
416        @param bPointFirst true: If the point is behind the mark then
417        swap the PaM. false: If the mark is behind the point then swap
418        the PaM.
419     */
420     void NormalizePam(bool bPointFirst = true);
421 
422     void SwapPam();
423     bool TestCurrPam( const Point & rPt,
424                       bool bTstHit = false);   // only exact matches
425     void KillPams();
426 
427     /// store a copy of the current cursor on the cursor stack
428     void Push();
429     enum class PopMode { DeleteCurrent, DeleteStack };
430     /*
431      * Delete a cursor
432      *    - either from the top of the stack
433      *    - or delete the current one and replace it with the cursor from the
434      *      stack
435      *  @return <true> if there was one on the stack, <false> otherwise
436      */
437     bool Pop(PopMode);
438     /*
439      * Combine 2 Cursors.
440      * Delete the topmost from the stack and move its Mark into the current.
441      */
442     void Combine();
443 
444     void SttCursorMove();
445     void EndCursorMove( const bool bIdleEnd = false );
446 
447     /*
448      * When the focus is lost the selected ranges are not displayed anymore.
449      * On the other hand, on receiving the focus all selected ranges are displayed again
450      * (ranges must be recalculated!).
451      */
HasShellFocus() const452     bool HasShellFocus() const { return m_bHasFocus; }
453     void ShellLoseFocus();
454     void ShellGetFocus();
455 
456     // Methods for displaying or hiding the visible text cursor.
457     void ShowCursor();
458     void HideCursor();
459     // Methods for displaying or hiding the selected ranges with visible cursor.
460     void ShowCursors( bool bCursorVis );
461     void HideCursors();
462 
IsOverwriteCursor() const463     bool IsOverwriteCursor() const { return m_bOverwriteCursor; }
SetOverwriteCursor(bool bFlag)464     void SetOverwriteCursor( bool bFlag ) { m_bOverwriteCursor = bFlag; }
465 
466     // Return current frame in which the cursor is placed.
467     SwContentFrame *GetCurrFrame( const bool bCalcFrame = true ) const;
468 
469     //true if cursor is hidden because of readonly.
470     //false if it is working despite readonly.
471     bool IsCursorReadonly() const;
472 
473     // Cursor is placed in something that is protected or selection contains
474     // something that is protected.
475     bool HasReadonlySel() const;
476 
477     // Can the cursor be set to read only ranges?
IsReadOnlyAvailable() const478     bool IsReadOnlyAvailable() const { return m_bSetCursorInReadOnly; }
479     void SetReadOnlyAvailable( bool bFlag );
480     bool IsOverReadOnlyPos( const Point& rPt ) const;
481 
482     // Methods for aFlyMacroLnk.
SetFlyMacroLnk(const Link<const SwFlyFrameFormat *,void> & rLnk)483     void        SetFlyMacroLnk( const Link<const SwFlyFrameFormat*,void>& rLnk ) { m_aFlyMacroLnk = rLnk; }
GetFlyMacroLnk() const484     const Link<const SwFlyFrameFormat*,void>& GetFlyMacroLnk() const           { return m_aFlyMacroLnk; }
485 
486     // Methods returning/altering link for changes of attributes/formats.
SetChgLnk(const Link<LinkParamNone *,void> & rLnk)487     void        SetChgLnk( const Link<LinkParamNone*,void> &rLnk ) { m_aChgLnk = rLnk; }
GetChgLnk() const488     const Link<LinkParamNone*,void>& GetChgLnk() const           { return m_aChgLnk; }
489 
490     // Methods returning/altering link for "graphic completely loaded".
SetGrfArrivedLnk(const Link<SwCursorShell &,void> & rLnk)491     void        SetGrfArrivedLnk( const Link<SwCursorShell&,void> &rLnk ) { m_aGrfArrivedLnk = rLnk; }
GetGrfArrivedLnk() const492     const Link<SwCursorShell&,void>& GetGrfArrivedLnk() const           { return m_aGrfArrivedLnk; }
493 
494     //Call ChgLink. When within an action calling will be delayed.
495     void CallChgLnk();
496 
497     // Check if the current cursor contains a selection, i.e.
498     // if Mark is set and SPoint and Mark are different.
499     bool HasSelection() const;
500 
501     // Check if a selection exists, i.e. if the current cursor comprises a selection.
502     inline bool IsSelection() const;
503     // returns if multiple cursors are available
504     inline bool IsMultiSelection() const;
505 
506     // Check if a complete paragraph was selected.
507     bool IsSelFullPara() const;
508 
509     // Check if selection is within one paragraph.
510 
511     //Should WaitPtr be activated for Clipboard.
512     bool ShouldWait() const;
513 
514     // Check if selection is within one paragraph.
515     bool IsSelOnePara() const;
516 
517     /*
518      * Returns SRectangle, at which the cursor is located.
519      */
GetCharRect() const520     const SwRect &GetCharRect() const { return m_aCharRect; }
521     /*
522      * Returns if cursor is wholly or partly within visible range.
523      */
IsCursorVisible() const524     bool IsCursorVisible() const { return VisArea().IsOver( GetCharRect() ); }
525     /*
526      * Returns SwRect, at which the character is located.
527      */
528     void GetCharRectAt(SwRect& rRect, const SwPosition* pPos);
529 
530     // Return current page number:
531     // true:  in which cursor is located.
532     // false: which is visible at the upper margin.
533     void GetPageNum( sal_uInt16 &rnPhyNum, sal_uInt16 &rnVirtNum,
534                      bool bAtCursorPos = true, const bool bCalcFrame = true );
535     // Returns current page's sequential number (1-based),in which cursor is located, ignoring autoinserted empty pages.
536     // Returns 0 on error
537     sal_uInt16 GetPageNumSeqNonEmpty();
538     // Determine how "empty pages" are handled
539     // (used in PhyPage).
540     sal_uInt16 GetNextPrevPageNum( bool bNext = true );
541 
542     // Move cursor at the beginning of page "nPage".
543     bool GotoPage( sal_uInt16 nPage );
544 
545     sal_uInt16 GetPageCnt();
546 
547     bool GoNextCursor();
548 
549     bool GoPrevCursor();
550 
551     bool GoNextPrevCursorSetSearchLabel(const bool bNext);
552 
553     // at CurrentCursor.SPoint
554     ::sw::mark::IMark* SetBookmark(
555         const vcl::KeyCode&,
556         const OUString& rName,
557         IDocumentMarkAccess::MarkType eMark = IDocumentMarkAccess::MarkType::BOOKMARK);
558     ::sw::mark::IMark* SetBookmark2(
559         const vcl::KeyCode&,
560         const OUString& rName,
561         bool bHide,
562         const OUString& rCondition);
563     bool GotoMark( const ::sw::mark::IMark* const pMark );    // sets CurrentCursor.SPoint
564     bool GotoMark( const ::sw::mark::IMark* const pMark, bool bAtStart );
565     bool GoNextBookmark(); // true, if there was one
566     bool GoPrevBookmark();
567 
568     bool IsFormProtected();
569     ::sw::mark::IFieldmark* GetCurrentFieldmark();
570     ::sw::mark::IFieldmark* GetFieldmarkAfter();
571     ::sw::mark::IFieldmark* GetFieldmarkBefore();
572     bool GotoFieldmark( const ::sw::mark::IFieldmark* const pMark );
573 
574     // update Cursr, i.e. reset it into content should only be called when the
575     // cursor was set to a random position e.g. when deleting frames
576     void UpdateCursorPos();
577 
578     // get the selected text at the current cursor. It will be filled with
579     // fields etc.
580     OUString GetSelText() const;
581 
582     // Check of SPoint or Mark of current cursor are placed within a table.
583     inline const SwTableNode* IsCursorInTable() const;
584 
585     bool IsCursorInFootnote() const;
586 
587     inline Point& GetCursorDocPos() const;
588     inline bool IsCursorPtAtEnd() const;
589 
590     inline const  SwPaM* GetTableCrs() const;
591     inline        SwPaM* GetTableCrs();
592 
593     bool IsTableComplexForChart();
594     // get current table selection as text
595     OUString GetBoxNms() const;
596 
597     // set Cursor to the next/previous cell
598     bool GoNextCell( bool bAppendLine = true );
599     bool GoPrevCell();
600     // go to this box (if available and inside of table)
601     bool GotoTable( const OUString& rName );
602 
603     // select a table row, column or box (based on the current cursor)
SelTableRow()604     bool SelTableRow() { return SelTableRowOrCol( true  ); }
SelTableCol()605     bool SelTableCol() { return SelTableRowOrCol( false ); }
606     bool SelTableBox();
607 
608     bool SelTable();
609 
610     void GotoNextNum();
611     void GotoPrevNum();
612 
613     bool GotoOutline( const OUString& rName );
614     // to the next/previous or the given OutlineNode
615     void GotoOutline( SwOutlineNodes::size_type nIdx );
616     // find the "outline position" in the nodes array of the current chapter
617     SwOutlineNodes::size_type GetOutlinePos( sal_uInt8 nLevel = UCHAR_MAX );
618     // select the given range of OutlineNodes. Optionally including the children
619     // the sal_uInt16s are the positions in OutlineNodes-Array (EditShell)
620     bool MakeOutlineSel( SwOutlineNodes::size_type nSttPos, SwOutlineNodes::size_type nEndPos,
621                          bool bWithChildren );
622 
623     bool GotoNextOutline();
624     bool GotoPrevOutline();
625 
626     /** Delivers the current shell cursor
627 
628         Some operations have to run on the current cursor ring,
629         some on the m_pTableCursor (if exist) or the current cursor ring and
630         some on the m_pTableCursor or m_pBlockCursor or the current cursor ring.
631         This small function checks the existence and delivers the wished cursor.
632 
633         @param bBlock [bool]
634         if the block cursor is of interest or not
635 
636         @return m_pTableCursor if exist,
637         m_pBlockCursor if exist and of interest (param bBlock)
638         otherwise m_pCurrentCursor
639     */
640     SwShellCursor* getShellCursor( bool bBlock );
getShellCursor(bool bBlock) const641     const SwShellCursor* getShellCursor( bool bBlock ) const
642         { return const_cast<SwCursorShell*>(this)->getShellCursor( bBlock ); }
643 
IsBlockMode() const644     bool IsBlockMode() const { return nullptr != m_pBlockCursor; }
645 
646     // is the Cursor in a table and is the selection over 2 columns
IsTableMode() const647     bool IsTableMode() const { return nullptr != m_pTableCursor; }
648 
GetTableCursor() const649     const SwShellTableCursor* GetTableCursor() const { return m_pTableCursor; }
GetTableCursor()650     SwShellTableCursor* GetTableCursor() { return m_pTableCursor; }
651     size_t UpdateTableSelBoxes();
652 
653     bool GotoFootnoteText();      ///< jump from content to footnote
654     bool GotoFootnoteAnchor();   ///< jump from footnote to anchor
655     bool GotoPrevFootnoteAnchor();
656     bool GotoNextFootnoteAnchor();
657 
658     void GotoFlyAnchor();       ///< jump from the frame to the anchor
659     bool GotoHeaderText();       ///< jump from the content to the header
660     bool GotoFooterText();       ///< jump from the content to the footer
661     // jump to the header/footer of the given or current PageDesc
662     bool SetCursorInHdFt( size_t nDescNo, bool bInHeader );
663     // is point of cursor in header/footer. pbInHeader return true if it is
664     // in a headerframe otherwise in a footerframe
665     bool IsInHeaderFooter( bool* pbInHeader = nullptr ) const;
666 
667     bool GotoNextTOXBase( const OUString* = nullptr );
668     bool GotoPrevTOXBase( const OUString* = nullptr );
669     void GotoTOXMarkBase();
670     // jump to the next or previous index entry
671     bool GotoNxtPrvTOXMark( bool bNext = true );
672     // jump to the next/previous index mark of this type
673     const SwTOXMark& GotoTOXMark( const SwTOXMark& rStart, SwTOXSearch eDir );
674 
675     // jump to the next or previous table formula
676     // optionally only to broken formulas
677     bool GotoNxtPrvTableFormula( bool bNext = true,
678                                bool bOnlyErrors = false );
679     // jump to the next / previous hyperlink - inside text and also
680     // on graphics
681     bool SelectNxtPrvHyperlink( bool bNext );
682 
683     bool GotoRefMark( const OUString& rRefMark, sal_uInt16 nSubType,
684                             sal_uInt16 nSeqNo );
685 
686     // get the nth character from the start or end of the  current selection
687     sal_Unicode GetChar( bool bEnd = true, long nOffset = 0 );
688     bool ExtendSelection( bool bEnd = true, sal_Int32 nCount = 1 );
689 
690     // Place only the visible cursor at the given position in the document.
691     // Return false if SPoint was corrected by layout.
692     // (This is needed for displaying the Drag&Drop/Copy-Cursor.)
693     bool SetVisibleCursor( const Point &rPt );
694     inline void UnSetVisibleCursor();
695     SwVisibleCursor* GetVisibleCursor() const;
696 
697     // jump to the next or previous field of the corresponding type
698     bool MoveFieldType(
699         const SwFieldType* pFieldType,
700         const bool bNext,
701         const SwFieldIds nResType = SwFieldIds::Unknown,
702         const bool bAddSetExpressionFieldsToInputFields = true );
703 
704     bool GotoFormatField( const SwFormatField& rField );
705 
706     static SwTextField* GetTextFieldAtPos(
707         const SwPosition* pPos,
708         const bool bIncludeInputFieldAtStart );
709     static SwTextField* GetTextFieldAtCursor(
710         const SwPaM* pCursor,
711         const bool bIncludeInputFieldAtStart );
712     static SwField* GetFieldAtCursor(
713         const SwPaM* pCursor,
714         const bool bIncludeInputFieldAtStart );
715     SwField* GetCurField( const bool bIncludeInputFieldAtStart = false ) const;
716     bool CursorInsideInputField() const;
717     static bool PosInsideInputField( const SwPosition& rPos );
718     bool DocPtInsideInputField( const Point& rDocPt ) const;
719     static sal_Int32 StartOfInputFieldAtPos( const SwPosition& rPos );
720     static sal_Int32 EndOfInputFieldAtPos( const SwPosition& rPos );
721 
722     // Return number of cursors in ring (The flag indicates whether
723     // only cursors containing selections are requested).
724     sal_uInt16 GetCursorCnt( bool bAll = true ) const;
725 
726     // Char Travelling - methods (in crstrvl1.cxx)
727     bool GoStartWord();
728     bool GoEndWord();
729     bool GoNextWord();
730     bool GoPrevWord();
731     bool GoNextSentence();
732     bool GoStartSentence();
733     bool GoEndSentence();
734     bool SelectWord( const Point* pPt );
735     void ExpandToSentenceBorders();
736 
737     // get position from current cursor
738     bool IsStartWord( sal_Int16 nWordType = css::i18n::WordType::ANYWORD_IGNOREWHITESPACES )const;
739     bool IsEndWord( sal_Int16 nWordType = css::i18n::WordType::ANYWORD_IGNOREWHITESPACES ) const;
740     bool IsInWord( sal_Int16 nWordType = css::i18n::WordType::ANYWORD_IGNOREWHITESPACES ) const;
741     bool IsStartSentence() const;
742     bool IsEndSentence() const;
743     bool IsSttPara() const;
744     bool IsEndPara() const;
745     bool IsEndOfTable() const; ///< at the very last SwPosition inside a table
746     bool IsStartOfDoc() const;
747     bool IsEndOfDoc() const;
748     bool IsInFrontOfLabel() const;
IsAtLeftMargin() const749     bool IsAtLeftMargin()   const       { return IsAtLRMargin( true ); }
IsAtRightMargin() const750     bool IsAtRightMargin() const   { return IsAtLRMargin( false, true/*bAPI*/ ); }
751 
752     // delete all created cursors, set the table cursor and the last cursor to
753     // its TextNode (or StartNode?)
754     // They all get created on the next ::GetCursor again
755     // Used for Drag&Drop/Clipboard-Paste in tables
756     bool ParkTableCursor();
757 
758     // Non expanded attributes?
IsGCAttr() const759     bool IsGCAttr() const { return m_bGCAttr; }
ClearGCAttr()760     void ClearGCAttr() { m_bGCAttr = false; }
UpdateAttr()761     void    UpdateAttr() {  m_bGCAttr = true; }
762 
763     // is the whole document protected/hidden (for UI...)
IsAllProtect() const764     bool IsAllProtect() const { return m_bAllProtect; }
765 
766     bool GotoRegion( const OUString& rName );
767 
768     // show the current selection
769     virtual void MakeSelVisible();
770 
771     // set the cursor to a NOT protected/hidden node
772     bool FindValidContentNode( bool bOnlyText );
773 
774     bool GetContentAtPos( const Point& rPt,
775                           SwContentAtPos& rContentAtPos,
776                           bool bSetCursor = false,
777                           SwRect* pFieldRect = nullptr );
778 
779     const SwPostItField* GetPostItFieldAtCursor() const;
780 
781     // get smart tags rectangle for the given point
782     void GetSmartTagRect( const Point& rPt, SwRect& rSelectRect );
783 
784     // get smart tags at current cursor position
785     void GetSmartTagTerm( std::vector< OUString >& rSmartTagTypes,
786                           css::uno::Sequence< css::uno::Reference< css::container::XStringKeyMap > >& rStringKeyMaps,
787                           css::uno::Reference<css::text::XTextRange>& rRange ) const;
788 
789     bool IsPageAtPos( const Point &rPt ) const;
790 
791     bool SelectTextAttr( sal_uInt16 nWhich, bool bExpand, const SwTextAttr* pAttr = nullptr );
792     bool GotoINetAttr( const SwTextINetFormat& rAttr );
793     const SwFormatINetFormat* FindINetAttr( const OUString& rName ) const;
794 
795     bool SelectText( const sal_Int32 nStart,
796                         const sal_Int32 nEnd );
797 
798     bool CheckTableBoxContent( const SwPosition* pPos = nullptr );
799     void SaveTableBoxContent( const SwPosition* pPos = nullptr );
800     void ClearTableBoxContent();
801     bool EndAllTableBoxEdit();
802 
SetSelTableCells(bool bFlag)803     void SetSelTableCells( bool bFlag )           { m_bSelTableCells = bFlag; }
IsSelTableCells() const804     bool IsSelTableCells() const                  { return m_bSelTableCells; }
805 
UnsetEnhancedTableSelection()806     void UnsetEnhancedTableSelection()            { m_eEnhancedTableSel = SwTable::SEARCH_NONE; }
GetEnhancedTableSelection() const807     SwTable::SearchType GetEnhancedTableSelection() const  { return m_eEnhancedTableSel; }
808 
IsAutoUpdateCells() const809     bool IsAutoUpdateCells() const              { return m_bAutoUpdateCells; }
SetAutoUpdateCells(bool bFlag)810     void SetAutoUpdateCells( bool bFlag )       { m_bAutoUpdateCells = bFlag; }
811 
812     bool GetShadowCursorPos( const Point& rPt, SwFillMode eFillMode,
813                             SwRect& rRect, sal_Int16& rOrient );
814     bool SetShadowCursorPos( const Point& rPt, SwFillMode eFillMode );
815 
816     const SwRangeRedline* SelNextRedline();
817     const SwRangeRedline* SelPrevRedline();
818     const SwRangeRedline* GotoRedline( SwRedlineTable::size_type nArrPos, bool bSelect );
819 
820     SAL_DLLPRIVATE SvxFrameDirection GetTextDirection( const Point* pPt = nullptr ) const;
821     // is cursor or the point in/over a vertical formatted text?
822     bool IsInVerticalText( const Point* pPt = nullptr ) const;
823     // is cursor or the point in/over a right to left formatted text?
824     bool IsInRightToLeftText() const;
825 
826     static void FirePageChangeEvent(sal_uInt16 nOldPage, sal_uInt16 nNewPage);
827     bool   bColumnChange();
828     static void FireSectionChangeEvent(sal_uInt16 nOldSection, sal_uInt16 nNewSection);
829     static void FireColumnChangeEvent(sal_uInt16 nOldColumn, sal_uInt16 nNewColumn);
830     // If the current cursor position is inside a hidden range, the hidden range
831     // is selected and true is returned:
832     bool SelectHiddenRange();
833 
834     // remove all invalid cursors
835     void ClearUpCursors();
836 
SetMacroExecAllowed(const bool _bMacroExecAllowed)837     void SetMacroExecAllowed( const bool _bMacroExecAllowed )
838     {
839         m_bMacroExecAllowed = _bMacroExecAllowed;
840     }
IsMacroExecAllowed() const841     bool IsMacroExecAllowed() const
842     {
843         return m_bMacroExecAllowed;
844     }
845 
846     /**
847        Returns textual description of the current selection.
848 
849        - If the current selection is a multi-selection the result is
850          STR_MULTISEL.
851        - Else the result is the text of the selection.
852 
853        @return the textual description of the current selection
854      */
855     OUString GetCursorDescr() const;
856 
857     virtual void dumpAsXml(xmlTextWriterPtr pWriter) const override;
858     /// Implementation of lok::Document::getPartPageRectangles() for Writer.
859     OUString getPageRectangles();
860 
861     /// See SwView::NotifyCursor().
862     void NotifyCursor(SfxViewShell* pViewShell) const;
863 };
864 
865 // Cursor Inlines:
MakeFindRange(SwDocPositions nStt,SwDocPositions nEnd,SwPaM * pPam) const866 inline SwMoveFnCollection const & SwCursorShell::MakeFindRange(
867             SwDocPositions nStt, SwDocPositions nEnd, SwPaM* pPam ) const
868 {
869     return m_pCurrentCursor->MakeFindRange( nStt, nEnd, pPam );
870 }
871 
GetSwCursor() const872 inline SwCursor* SwCursorShell::GetSwCursor() const
873 {
874     return static_cast<SwCursor*>(GetCursor());
875 }
876 
GetStackCursor() const877 inline SwPaM* SwCursorShell::GetStackCursor() const { return m_pStackCursor; }
878 
SetMark()879 inline void SwCursorShell::SetMark() { m_pCurrentCursor->SetMark(); }
880 
HasMark() const881 inline bool SwCursorShell::HasMark() const { return m_pCurrentCursor->HasMark(); }
882 
IsSelection() const883 inline bool SwCursorShell::IsSelection() const
884 {
885     return IsTableMode() || m_pCurrentCursor->HasMark() ||
886             m_pCurrentCursor->GetNext() != m_pCurrentCursor;
887 }
IsMultiSelection() const888 inline bool SwCursorShell::IsMultiSelection() const
889 {
890     return m_pCurrentCursor->GetNext() != m_pCurrentCursor;
891 }
892 
IsCursorInTable() const893 inline const SwTableNode* SwCursorShell::IsCursorInTable() const
894 {
895     return m_pCurrentCursor->GetNode().FindTableNode();
896 }
897 
IsCursorPtAtEnd() const898 inline bool SwCursorShell::IsCursorPtAtEnd() const
899 {
900     return m_pCurrentCursor->End() == m_pCurrentCursor->GetPoint();
901 }
902 
GetCursorDocPos() const903 inline Point& SwCursorShell::GetCursorDocPos() const
904 {
905     return m_pCurrentCursor->GetPtPos();
906 }
907 
GetTableCrs() const908 inline const SwPaM* SwCursorShell::GetTableCrs() const
909 {
910     return m_pTableCursor;
911 }
912 
GetTableCrs()913 inline SwPaM* SwCursorShell::GetTableCrs()
914 {
915     return m_pTableCursor;
916 }
917 
UnSetVisibleCursor()918 inline void SwCursorShell::UnSetVisibleCursor()
919 {
920     m_pVisibleCursor->Hide();
921     m_pVisibleCursor->SetDragCursor( false );
922 }
923 
924 #endif  // _CRSRSH_HXX
925 
926 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
927