Coverage Report

Created: 2026-11-06 11:29

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/include/vcl/seleng.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
20
#ifndef INCLUDED_VCL_SELENG_HXX
21
#define INCLUDED_VCL_SELENG_HXX
22
23
#include <vcl/dllapi.h>
24
#include <vcl/timer.hxx>
25
#include <vcl/event.hxx>
26
#include <o3tl/typed_flags_set.hxx>
27
28
class CommandEvent;
29
30
namespace vcl {
31
    class Window;
32
}
33
enum class SelectionMode;
34
35
// Timerticks
36
constexpr sal_uInt64 SELENG_DRAGDROP_TIMEOUT = 400;
37
constexpr sal_uInt64 SELENG_AUTOREPEAT_INTERVAL =  50;
38
constexpr sal_uInt64 SELENG_AUTOREPEAT_INTERVAL_MIN  = 25;
39
constexpr sal_uInt64 SELENG_AUTOREPEAT_INTERVAL_MAX  = 300;
40
41
class VCL_DLLPUBLIC FunctionSet
42
{
43
public:
44
    virtual ~FunctionSet() = 0;
45
46
    virtual void    BeginDrag() = 0;
47
48
    virtual void    CreateAnchor() = 0;  // Anker-Pos := Cursor-Pos
49
    virtual void    DestroyAnchor() = 0;
50
51
    // move cursor, at the same time match cursor position to the selection
52
    // starting at anchor. true == Ok
53
    virtual void    SetCursorAtPoint( const Point& rPointPixel,
54
                                          bool bDontSelectAtCursor = false ) = 0;
55
56
    virtual bool    IsSelectionAtPoint( const Point& rPointPixel ) = 0;
57
    virtual void        DeselectAtPoint( const Point& rPointPixel ) = 0;
58
    // delete anchor & deselect all
59
    virtual void        DeselectAll() = 0;
60
};
61
62
63
enum class SelectionEngineFlags {
64
    DRG_ENAB     = 0x0001,
65
    IN_SEL       = 0x0002,
66
    IN_ADD       = 0x0004,
67
    ADD_ALW      = 0x0008,
68
    HAS_ANCH     = 0x0020,
69
    CMDEVT       = 0x0040,
70
    WAIT_UPEVT   = 0x0080,
71
    EXPANDONMOVE = 0x0100,
72
};
73
namespace o3tl
74
{
75
    template<> struct typed_flags<SelectionEngineFlags> : is_typed_flags<SelectionEngineFlags, 0x01ef> {};
76
}
77
78
class VCL_DLLPUBLIC SelectionEngine
79
{
80
private:
81
    FunctionSet*        pFunctionSet;
82
    VclPtr<vcl::Window> pWin;
83
    tools::Rectangle           aArea;
84
    Timer               aWTimer; // generate fake mouse moves
85
    MouseEvent          aLastMove;
86
    SelectionMode       eSelMode;
87
    sal_uInt64               nUpdateInterval;
88
    sal_uInt16              nLockedMods;
89
    SelectionEngineFlags    nFlags;
90
    DECL_DLLPRIVATE_LINK( ImpWatchDog, Timer*, void );
91
92
    inline bool         ShouldDeselect( bool bModifierKey1 ) const;
93
                                // determines to deselect or not when Ctrl-key is pressed on CursorPosChanging
94
    bool                IsDragEnabled() const;
95
                                // checks if dragging is enabled via flag or drag gesture listeners
96
public:
97
98
                        SelectionEngine( vcl::Window* pWindow,
99
                                         FunctionSet* pFunctions = nullptr );
100
                        ~SelectionEngine();
101
                        // Avoid implicitly defined copy constructors/assignments for the
102
                        // DLLPUBLIC class (they may require forward-declared classes used
103
                        // internally to be defined in places using SelectionEngine)
104
                        SelectionEngine(const SelectionEngine&) = delete;
105
                        SelectionEngine(SelectionEngine&&) = delete;
106
                        SelectionEngine& operator=(const SelectionEngine&) = delete;
107
                        SelectionEngine& operator=(SelectionEngine&&) = delete;
108
109
    // true: Event was processed by Selection Engine
110
    bool                SelMouseButtonDown( const MouseEvent& rMEvt );
111
    bool                SelMouseButtonUp( const MouseEvent& rMEvt );
112
    bool                SelMouseMove( const MouseEvent& rMEvt );
113
    //SelMouseButtonDown captures mouse events, SelMouseButtonUp
114
    //releases the capture. If you need to release the mouse
115
    //capture after SelMouseButtonDown but before
116
    //SelMouseButtonUp, e.g. to allow events to go to a
117
    //context menu via "Command" which is delivered after
118
    //mouse down but before mouse up, then use this
119
    void                ReleaseMouse();
120
    void                CaptureMouse();
121
122
    // Keyboard
123
    void                CursorPosChanging( bool bShift, bool bMod1 );
124
125
    // is needed to generate a Move event via a Timer
126
    // when the mouse is outside the area
127
    void                SetVisibleArea( const tools::Rectangle& rNewArea )
128
0
                            { aArea = rNewArea; }
129
130
    void                SetAddMode( bool);
131
    bool                IsAddMode() const;
132
133
    void                AddAlways( bool bOn );
134
    bool                IsAlwaysAdding() const;
135
136
    void                EnableDrag( bool bOn );
137
138
    void                SetSelectionMode( SelectionMode eMode );
139
0
    SelectionMode       GetSelectionMode() const { return eSelMode; }
140
141
    void                SetFunctionSet( FunctionSet* pFuncs )
142
628k
                            { pFunctionSet = pFuncs; }
143
0
    const FunctionSet*  GetFunctionSet() const { return pFunctionSet; }
144
145
    const Point&        GetMousePosPixel() const
146
0
                            { return aLastMove.GetPosPixel(); }
147
0
    const MouseEvent&   GetMouseEvent() const { return aLastMove; }
148
149
    void                SetWindow( vcl::Window*);
150
0
    vcl::Window*             GetWindow() const { return pWin; }
151
152
    void                LockModifiers( sal_uInt16 nModifiers )
153
0
                            { nLockedMods = nModifiers; }
154
0
    sal_uInt16              GetLockedModifiers() const { return nLockedMods; }
155
156
    bool                IsInSelection() const;
157
    void                Reset();
158
159
    bool                Command(const CommandEvent& rCEvt);
160
161
    bool                HasAnchor() const;
162
    void                SetAnchor( bool bAnchor );
163
164
    void                SetUpdateInterval( sal_uInt64 nInterval );
165
166
    // is switched on in the Ctor
167
    void                ExpandSelectionOnMouseMove( bool bExpand = true )
168
0
                        {
169
0
                            if( bExpand )
170
0
                                nFlags |= SelectionEngineFlags::EXPANDONMOVE;
171
0
                            else
172
0
                                nFlags &= ~SelectionEngineFlags::EXPANDONMOVE;
173
0
                        }
174
};
175
176
inline bool SelectionEngine::IsAddMode()  const
177
0
{
178
0
    if ( nFlags & (SelectionEngineFlags::IN_ADD | SelectionEngineFlags::ADD_ALW) )
179
0
        return true;
180
0
    else
181
0
        return false;
182
0
}
183
184
inline void SelectionEngine::SetAddMode( bool bNewMode )
185
0
{
186
0
    if ( bNewMode )
187
0
        nFlags |= SelectionEngineFlags::IN_ADD;
188
0
    else
189
0
        nFlags &= ~SelectionEngineFlags::IN_ADD;
190
0
}
191
192
inline void SelectionEngine::EnableDrag( bool bOn )
193
628k
{
194
628k
    if ( bOn )
195
628k
        nFlags |= SelectionEngineFlags::DRG_ENAB;
196
0
    else
197
0
        nFlags &= ~SelectionEngineFlags::DRG_ENAB;
198
628k
}
199
200
inline void SelectionEngine::AddAlways( bool bOn )
201
0
{
202
0
    if( bOn )
203
0
        nFlags |= SelectionEngineFlags::ADD_ALW;
204
0
    else
205
0
        nFlags &= ~SelectionEngineFlags::ADD_ALW;
206
0
}
207
208
inline bool SelectionEngine::IsAlwaysAdding() const
209
0
{
210
0
    if ( nFlags & SelectionEngineFlags::ADD_ALW )
211
0
        return true;
212
0
    else
213
0
        return false;
214
0
}
215
216
inline bool SelectionEngine::IsInSelection() const
217
0
{
218
0
    if ( nFlags & SelectionEngineFlags::IN_SEL )
219
0
        return true;
220
0
    else
221
0
        return false;
222
0
}
223
224
inline bool SelectionEngine::HasAnchor() const
225
0
{
226
0
    if ( nFlags & SelectionEngineFlags::HAS_ANCH )
227
0
        return true;
228
0
    else
229
0
        return false;
230
0
}
231
232
inline void SelectionEngine::SetAnchor( bool bAnchor )
233
0
{
234
0
    if ( bAnchor )
235
0
        nFlags |= SelectionEngineFlags::HAS_ANCH;
236
0
    else
237
0
        nFlags &= ~SelectionEngineFlags::HAS_ANCH;
238
0
}
239
240
#endif // INCLUDED_VCL_SELENG_HXX
241
242
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */