Coverage Report

Created: 2026-03-31 11:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/vcl/inc/svimpbox.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
#pragma once
21
22
#include <vcl/seleng.hxx>
23
#include <vcl/idle.hxx>
24
#include <vcl/image.hxx>
25
#include <vcl/vclevent.hxx>
26
#include <vcl/toolkit/scrbar.hxx>
27
#include <vcl/toolkit/treelistbox.hxx>
28
#include <o3tl/enumarray.hxx>
29
#include <memory>
30
#include <vector>
31
32
class SvLBoxButton;
33
class SvTreeList;
34
class SvImpLBox;
35
class SvTreeListEntry;
36
namespace comphelper::string { class NaturalStringSorter; }
37
38
class ImpLBSelEng final : public FunctionSet
39
{
40
    SvImpLBox*          pImp;
41
    VclPtr<SvTreeListBox>  pView;
42
43
public:
44
    ImpLBSelEng( SvImpLBox* pImp, SvTreeListBox* pView );
45
    virtual ~ImpLBSelEng() override;
46
    void        BeginDrag() override;
47
    void        CreateAnchor() override;
48
    void        DestroyAnchor() override;
49
    void        SetCursorAtPoint( const Point& rPoint,
50
                    bool bDontSelectAtCursor=false ) override;
51
    bool        IsSelectionAtPoint( const Point& rPoint ) override;
52
    void        DeselectAtPoint( const Point& rPoint ) override;
53
    void        DeselectAll() override;
54
};
55
56
// Flags for nFlag
57
enum class LBoxFlags {
58
    NONE                        = 0x0000,
59
    DeselectAll                 = 0x0002,
60
    StartEditTimer              = 0x0004,  // MAC only
61
    IgnoreSelect                = 0x0008,
62
    InResize                    = 0x0010,
63
    RemovedEntryInvisible       = 0x0020,
64
    RemovedRecalcMostRight      = 0x0040,
65
    IgnoreChangedTabs           = 0x0080,
66
    InPaint                     = 0x0100,
67
    EndScrollSetVisSize         = 0x0200,
68
    Filling                     = 0x0400,
69
};
70
namespace o3tl
71
{
72
    template<> struct typed_flags<LBoxFlags> : is_typed_flags<LBoxFlags, 0x07fe> {};
73
}
74
75
0
#define NODE_BMP_TABDIST_NOTVALID   -2000000
76
#define FIRST_ENTRY_TAB             1
77
78
class SvImpLBox
79
{
80
friend class ImpLBSelEng;
81
friend class SvTreeListBox;
82
friend class SalInstanceTreeView;
83
friend class IconView;
84
private:
85
    SvTreeList*          m_pTree;
86
    SvTreeListEntry*     m_pAnchor;
87
    SvTreeListEntry*     m_pMostRightEntry;
88
    SvLBoxButton*        m_pActiveButton;
89
    SvTreeListEntry*     m_pActiveEntry;
90
    VclPtr<ScrollBarBox> m_aScrBarBox;
91
92
    static Image*       s_pDefCollapsed;
93
    static Image*       s_pDefExpanded;
94
    static oslInterlockedCount  s_nImageRefCount; /// When 0 all static images will be destroyed
95
96
    // Node Bitmaps
97
    enum class ImageType
98
    {
99
        NodeExpanded = 0,     // node is expanded ( usually a bitmap showing a minus )
100
        NodeCollapsed,        // node is collapsed ( usually a bitmap showing a plus )
101
        EntryDefExpanded,     // default for expanded entries
102
        EntryDefCollapsed,    // default for collapsed entries
103
        LAST = EntryDefCollapsed
104
    };
105
106
    // all our images
107
    o3tl::enumarray<ImageType, Image>
108
                        m_aNodeAndEntryImages;
109
110
    ImpLBSelEng         m_aFctSet;
111
112
    tools::Long                m_nNodeBmpWidth;
113
    tools::Long                m_nMostRight;
114
    short               m_nHorSBarHeight, m_nVerSBarWidth;
115
116
    bool                m_bUpdateMode : 1;
117
    bool                m_bSubLstOpLR : 1;    // open/close sublist with cursor left/right, defaulted with false
118
    bool                mbForceMakeVisible;
119
120
    Point               m_aEditClickPos;
121
    Idle                m_aEditIdle;
122
123
    std::unique_ptr<comphelper::string::NaturalStringSorter> m_pStringSorter;
124
125
    std::vector< short > m_aContextBmpWidthVector;
126
127
    DECL_LINK(EditTimerCall, Timer *, void);
128
129
    void                InvalidateEntriesFrom( tools::Long nY ) const;
130
    bool                IsLineVisible( tools::Long nY ) const;
131
    void                KeyLeftRight( tools::Long nDiff );
132
133
    void                DrawNet(vcl::RenderContext& rRenderContext);
134
135
    // ScrollBar-Handler
136
    DECL_LINK( ScrollUpDownHdl, ScrollBar*, void );
137
    DECL_LINK( ScrollLeftRightHdl, ScrollBar*, void );
138
    DECL_LINK( EndScrollHdl, ScrollBar*, void );
139
140
    void                SetNodeBmpWidth( const Image& );
141
    void                SetNodeBmpTabDistance();
142
143
    // Selection-Engine
144
    SvTreeListEntry*    MakePointVisible( const Point& rPoint );
145
146
    void                SetAnchorSelection( SvTreeListEntry* pOld,
147
                            SvTreeListEntry* pNewCursor );
148
    void                BeginDrag();
149
    bool                ButtonDownCheckCtrl( const MouseEvent& rMEvt, SvTreeListEntry* pEntry );
150
    bool                MouseMoveCheckCtrl( const MouseEvent& rMEvt, SvTreeListEntry const * pEntry );
151
    bool                ButtonUpCheckCtrl( const MouseEvent& rMEvt );
152
    bool                ButtonDownCheckExpand( const MouseEvent&, SvTreeListEntry* );
153
154
    bool                EntryReallyHit(SvTreeListEntry* pEntry, const Point& rPos, tools::Long nLine);
155
    void                InitScrollBarBox();
156
    SvLBoxTab*          NextTab( SvLBoxTab const * );
157
158
    void                SetMostRight( SvTreeListEntry* pEntry );
159
    void                FindMostRight( SvTreeListEntry* pParent );
160
    void                FindMostRight_Impl( SvTreeListEntry* pParent );
161
    void                NotifyTabsChanged();
162
163
    // if element at cursor can be expanded in general
164
    bool                IsExpandable() const;
165
166
    static  void        implInitDefaultNodeImages();
167
168
    void                UpdateStringSorter();
169
170
    short               UpdateContextBmpWidthVector( SvTreeListEntry const * pEntry, short nWidth );
171
    void                UpdateContextBmpWidthMax( SvTreeListEntry const * pEntry );
172
    void                UpdateContextBmpWidthVectorFromMovedEntry( SvTreeListEntry* pEntry );
173
174
    void ExpandAll();
175
    void CollapseTo(SvTreeListEntry* pParentToCollapse);
176
177
protected:
178
    SvTreeListBox& m_rView;
179
    VclPtr<ScrollBar>       m_aHorSBar;
180
    VclPtr<ScrollBar>       m_aVerSBar;
181
    SvTreeListEntry*        m_pCursor;
182
    SvTreeListEntry*        m_pCursorOld;
183
    SvTreeListEntry*        m_pStartEntry;
184
    ImplSVEvent*            m_nCurUserEvent;
185
    Size                    m_aOutputSize;
186
    LBoxFlags               m_nFlags;
187
    WinBits                 m_nStyle;
188
    bool                    mbNoAutoCurEntry; // disable the behavior of automatically selecting a "CurEntry" upon painting the control
189
    SelectionEngine         m_aSelEng;
190
    sal_uLong               m_nVisibleCount;  // Number of lines in control
191
    bool                    m_bInVScrollHdl : 1;
192
    bool                    m_bSimpleTravel : 1; // is true if SelectionMode::Single
193
    tools::Long                    m_nNextVerVisSize;
194
    tools::Long                    m_nNodeBmpTabDistance; // typical smaller than 0
195
196
    virtual tools::Long        GetEntryLine(const SvTreeListEntry* pEntry) const;
197
    virtual void        CursorDown();
198
    virtual void        CursorUp();
199
    virtual void        PageDown( sal_uInt16 nDelta );
200
    virtual void        PageUp( sal_uInt16 nDelta );
201
    // set Thumb to FirstEntryToDraw
202
    virtual void        SyncVerThumb();
203
    virtual void        AdjustScrollBars( Size& rSize );
204
    virtual void        InvalidateEntry( tools::Long nY ) const;
205
206
    tools::Rectangle           GetVisibleArea() const;
207
    void                SetCursor( SvTreeListEntry* pEntry, bool bForceNoSelect = false );
208
    void                PositionScrollBars( Size& rOSize, sal_uInt16 nMask );
209
    void                FindMostRight();
210
    void                FillView();
211
    void                ShowVerSBar();
212
    void                StopUserEvent();
213
214
    DECL_LINK( MyUserEvent,  void*, void);
215
216
public:
217
    SvImpLBox(SvTreeListBox& rView, SvTreeList*, WinBits nWinStyle);
218
    virtual ~SvImpLBox();
219
220
    void                Clear();
221
    void                SetStyle( WinBits i_nWinStyle );
222
    void                SetNoAutoCurEntry( bool b );
223
0
    void                SetModel( SvTreeList* pModel ) { m_pTree = pModel;}
224
225
    void                EntryInserted( SvTreeListEntry*);
226
    void                RemovingEntry( SvTreeListEntry* pEntry );
227
    void                EntryRemoved();
228
    void                MovingEntry( SvTreeListEntry* pEntry );
229
    void                EntryMoved( SvTreeListEntry* pEntry );
230
    void                TreeInserted( SvTreeListEntry* pEntry );
231
232
    void                EntryExpanded( SvTreeListEntry* pEntry );
233
    void                EntryCollapsed( SvTreeListEntry* pEntry );
234
    void                CollapsingEntry( SvTreeListEntry* pEntry );
235
    void                EntrySelected( SvTreeListEntry* pEntry, bool bSelect );
236
237
    virtual void        Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect);
238
    void                MouseButtonDown( const MouseEvent& );
239
    void                MouseButtonUp( const MouseEvent& );
240
    void                MouseMove( const MouseEvent&);
241
    virtual bool        KeyInput( const KeyEvent& );
242
    void                Resize();
243
    void                GetFocus();
244
    void                LoseFocus();
245
    virtual void        UpdateAll();
246
    void                SetEntryHeight();
247
    void                InvalidateEntry( SvTreeListEntry* );
248
    void                RecalcFocusRect();
249
250
    void                SelectEntry( SvTreeListEntry* pEntry, bool bSelect );
251
    void                SetDragDropMode( DragDropMode eDDMode );
252
    void                SetSelectionMode( SelectionMode eSelMode  );
253
254
    virtual bool        IsEntryInView( SvTreeListEntry* pEntry ) const;
255
    virtual SvTreeListEntry*    GetEntry( const Point& rPos ) const;
256
    // returns last entry, if Pos below last entry
257
    virtual SvTreeListEntry*    GetClickedEntry( const Point& ) const;
258
0
    SvTreeListEntry*    GetCurEntry() const { return m_pCursor; }
259
    void                SetCurEntry( SvTreeListEntry* );
260
    virtual Point       GetEntryPosition(const SvTreeListEntry*) const;
261
    void                MakeVisible( SvTreeListEntry* pEntry, bool bMoveToTop = false );
262
    void                ScrollToAbsPos( tools::Long nPos );
263
264
    void                PaintDDCursor(SvTreeListEntry* pEntry, bool bShow);
265
266
    // Images
267
    inline Image&       implGetImageLocation( const ImageType _eType );
268
269
    inline void         SetExpandedNodeBmp(  const Image& _rImg );
270
    inline void         SetCollapsedNodeBmp( const Image& _rImg );
271
272
    inline const Image& GetExpandedNodeBmp( );
273
    inline const Image& GetCollapsedNodeBmp( );
274
275
    inline void         SetDefaultEntryExpBmp( const Image& _rImg );
276
    inline void         SetDefaultEntryColBmp( const Image& _rImg );
277
    inline const Image& GetDefaultEntryExpBmp( );
278
    inline const Image& GetDefaultEntryColBmp( );
279
280
    static const Image& GetDefaultExpandedNodeImage( );
281
    static const Image& GetDefaultCollapsedNodeImage( );
282
283
0
    const Size&         GetOutputSize() const { return m_aOutputSize;}
284
    virtual void        KeyUp( bool bPageUp );
285
    virtual void        KeyDown( bool bPageDown );
286
    void                Command( const CommandEvent& rCEvt );
287
288
    void                Invalidate();
289
0
    void                DestroyAnchor() { m_pAnchor=nullptr; m_aSelEng.Reset(); }
290
    void                SelAllDestrAnch( bool bSelect, bool bDestroyAnchor = true, bool bSingleSelToo = false );
291
    void                ShowCursor( bool bShow );
292
293
    bool                RequestHelp( const HelpEvent& rHEvt );
294
    bool                IsNodeButton( const Point& rPosPixel, const SvTreeListEntry* pEntry ) const;
295
    void                SetUpdateMode( bool bMode );
296
0
    bool                GetUpdateMode() const { return m_bUpdateMode; }
297
    tools::Rectangle    GetClipRegionRect() const;
298
0
    bool                HasHorScrollBar() const { return m_aHorSBar->IsVisible(); }
299
    void                CallEventListeners( VclEventId nEvent, void* pData = nullptr );
300
301
    bool                IsSelectable( const SvTreeListEntry* pEntry ) const;
302
0
    void                SetForceMakeVisible(bool bEnable) { mbForceMakeVisible = bEnable; }
303
304
    // tdf#143114 allow to ask if CaptureOnButton is active
305
    // (MouseButtonDown hit on SvLBoxButton, CaptureMouse() active)
306
    bool                IsCaptureOnButtonActive() const;
307
};
308
309
inline bool SvImpLBox::IsCaptureOnButtonActive() const
310
0
{
311
0
    return nullptr != m_pActiveButton && nullptr != m_pActiveEntry;
312
0
}
313
314
inline Image& SvImpLBox::implGetImageLocation( const ImageType _eType )
315
0
{
316
0
    return m_aNodeAndEntryImages[_eType];
317
0
}
318
319
inline void SvImpLBox::SetExpandedNodeBmp( const Image& rImg )
320
0
{
321
0
    implGetImageLocation( ImageType::NodeExpanded ) = rImg;
322
0
    SetNodeBmpWidth( rImg );
323
0
}
324
325
inline void SvImpLBox::SetCollapsedNodeBmp( const Image& rImg )
326
0
{
327
0
    implGetImageLocation( ImageType::NodeCollapsed ) = rImg;
328
0
    SetNodeBmpWidth( rImg );
329
0
}
330
331
inline const Image& SvImpLBox::GetExpandedNodeBmp( )
332
0
{
333
0
    return implGetImageLocation( ImageType::NodeExpanded );
334
0
}
335
336
inline const Image& SvImpLBox::GetCollapsedNodeBmp( )
337
0
{
338
0
    return implGetImageLocation( ImageType::NodeCollapsed );
339
0
}
340
341
inline void SvImpLBox::SetDefaultEntryExpBmp( const Image& _rImg )
342
0
{
343
0
    implGetImageLocation( ImageType::EntryDefExpanded ) = _rImg;
344
0
}
345
346
inline void SvImpLBox::SetDefaultEntryColBmp( const Image& _rImg )
347
0
{
348
0
    implGetImageLocation( ImageType::EntryDefCollapsed ) = _rImg;
349
0
}
350
351
inline const Image& SvImpLBox::GetDefaultEntryExpBmp( )
352
0
{
353
0
    return implGetImageLocation( ImageType::EntryDefExpanded );
354
0
}
355
356
inline const Image& SvImpLBox::GetDefaultEntryColBmp( )
357
0
{
358
0
    return implGetImageLocation( ImageType::EntryDefCollapsed );
359
0
}
360
361
inline Point SvImpLBox::GetEntryPosition(const SvTreeListEntry* pEntry) const
362
0
{
363
0
    return Point(0, GetEntryLine(pEntry));
364
0
}
365
366
inline bool SvImpLBox::IsLineVisible( tools::Long nY ) const
367
0
{
368
0
    bool bRet = true;
369
0
    if ( nY < 0 || nY >= m_aOutputSize.Height() )
370
0
        bRet = false;
371
0
    return bRet;
372
0
}
373
374
inline void SvImpLBox::TreeInserted( SvTreeListEntry* pInsTree )
375
0
{
376
0
    EntryInserted( pInsTree );
377
0
}
378
379
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */