Coverage Report

Created: 2026-11-06 11:29

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/include/vcl/toolkit/button.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
#if !defined(VCL_DLLIMPLEMENTATION) && !defined(TOOLKIT_DLLIMPLEMENTATION) && !defined(VCL_INTERNALS)
23
#error "don't use this in new code"
24
#endif
25
26
#include <vcl/dllapi.h>
27
#include <vcl/image.hxx>
28
#include <vcl/ctrl.hxx>
29
#include <vcl/vclenum.hxx>
30
#include <memory>
31
#include <vector>
32
33
namespace com::sun::star::frame { struct FeatureStateEvent; class XFrame; }
34
template <class T> class VclPtr;
35
36
class Color;
37
class ImplCommonButtonData;
38
enum class DrawButtonFlags;
39
40
class VCL_DLLPUBLIC Button : public Control
41
{
42
private:
43
    std::unique_ptr<ImplCommonButtonData> mpButtonData;
44
    Link<Button*,void> maClickHdl;
45
46
    /// Command URL (like .uno:Save) in case the button should handle it.
47
    OUString maCommand;
48
49
                                    Button (const Button &) = delete;
50
                                    Button & operator= (const Button &) = delete;
51
public:
52
    SAL_DLLPRIVATE DrawTextFlags    ImplGetTextStyle( WinBits nWinStyle, SystemTextColorFlags nSystemTextColorFlags ) const;
53
    SAL_DLLPRIVATE void             ImplDrawAlignedImage(OutputDevice* pDev, Point& rPos, Size& rSize,
54
                                              sal_Int32 nImageSep,
55
                                              DrawTextFlags nTextStyle, tools::Rectangle *pSymbolRect=nullptr, bool bAddImageSep = false );
56
    SAL_DLLPRIVATE void             ImplSetFocusRect( const tools::Rectangle &rFocusRect );
57
    SAL_DLLPRIVATE const tools::Rectangle& ImplGetFocusRect() const;
58
    SAL_DLLPRIVATE void             ImplSetSymbolAlign( SymbolAlign eAlign );
59
60
protected:
61
    SAL_DLLPRIVATE explicit Button( WindowType eType );
62
63
    // for drawing RadioButton or CheckButton that has Text and/or Image
64
    SAL_DLLPRIVATE void ImplDrawRadioCheck(OutputDevice* pDev, WinBits nWinStyle, SystemTextColorFlags nSystemTextColorFlags,
65
                                           const Point& rPos, const Size& rSize,
66
                                           const Size& rImageSize, tools::Rectangle& rStateRect,
67
                                           tools::Rectangle& rMouseRect);
68
    SAL_DLLPRIVATE tools::Long ImplGetImageToTextDistance() const;
69
70
public:
71
    virtual            ~Button() override;
72
    virtual void        dispose() override;
73
74
    virtual void        Click();
75
76
0
    void                SetClickHdl( const Link<Button*,void>& rLink ) { maClickHdl = rLink; }
77
0
    const Link<Button*,void>& GetClickHdl() const { return maClickHdl; }
78
79
    /// Setup handler for UNO commands so that commands like .uno:Something are handled automagically by this button.
80
    SAL_DLLPRIVATE void SetCommandHandler(const OUString& aCommand, const css::uno::Reference<css::frame::XFrame>& rFrame);
81
0
    OUString const &    GetCommand() const { return maCommand; }
82
83
    void                SetModeImage( const Image& rImage );
84
    SAL_DLLPRIVATE Image const & GetModeImage( ) const;
85
    SAL_DLLPRIVATE bool HasImage() const;
86
    void                SetImageAlign( ImageAlign eAlign );
87
    ImageAlign          GetImageAlign() const;
88
    SAL_DLLPRIVATE DrawButtonFlags  GetButtonState() const;
89
    SAL_DLLPRIVATE DrawButtonFlags& GetButtonState();
90
91
    /// Set an image to use as the complete render view of a custom button,
92
    /// instead of the usual contents of a button
93
    SAL_DLLPRIVATE void SetCustomButtonImage( const Image& rImage );
94
    SAL_DLLPRIVATE Image const & GetCustomButtonImage() const;
95
96
    SAL_DLLPRIVATE bool IsSmallSymbol() const;
97
    SAL_DLLPRIVATE void SetSmallSymbol();
98
    virtual bool        set_property(const OUString &rKey, const OUString &rValue) override;
99
100
    /// Sets the button state according to the FeatureStateEvent emitted by a Uno state change.
101
    virtual void        statusChanged(const css::frame::FeatureStateEvent& rEvent);
102
103
    virtual FactoryFunction GetUITestFactory() const override;
104
105
protected:
106
107
    /// Handler for click, in case we want the button to handle uno commands (.uno:Something).
108
    DECL_DLLPRIVATE_STATIC_LINK(Button, dispatchCommandHandler, Button*, void);
109
};
110
111
enum class PushButtonDropdownStyle
112
{
113
    NONE            = 0x0000,
114
    MenuButton      = 0x0002, //visual down arrow
115
};
116
117
class VCL_DLLPUBLIC PushButton : public Button
118
{
119
public:
120
    SAL_DLLPRIVATE void            ImplSetDefButton( bool bSet );
121
    SAL_DLLPRIVATE void            ImplDrawPushButtonFrame(vcl::RenderContext& rRenderContext, tools::Rectangle& rRect, DrawButtonFlags nStyle);
122
    SAL_DLLPRIVATE static bool     ImplHitTestPushButton(vcl::Window const * pDev, const Point& rPos);
123
    SAL_DLLPRIVATE bool            ImplIsDefButton() const;
124
125
    explicit        PushButton( vcl::Window* pParent, WinBits nStyle = 0 );
126
127
    virtual rtl::Reference<comphelper::OAccessible> CreateAccessible() override;
128
129
    virtual void    MouseButtonDown( const MouseEvent& rMEvt ) override;
130
    virtual void    Tracking( const TrackingEvent& rTEvt ) override;
131
    virtual void    KeyInput( const KeyEvent& rKEvt ) override;
132
    virtual void    KeyUp( const KeyEvent& rKEvt ) override;
133
    virtual void    Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect ) override;
134
    virtual void Draw(OutputDevice& rDev, const Point& rPos, SystemTextColorFlags nFlags) override;
135
    virtual void    Resize() override;
136
    virtual void    GetFocus() override;
137
    virtual void    LoseFocus() override;
138
    virtual void    StateChanged( StateChangedType nType ) override;
139
    virtual void    DataChanged( const DataChangedEvent& rDCEvt ) override;
140
    virtual bool    PreNotify( NotifyEvent& rNEvt ) override;
141
142
    void            Toggle();
143
144
    SAL_DLLPRIVATE void            SetSymbol( SymbolType eSymbol );
145
0
    SymbolType      GetSymbol() const { return meSymbol; }
146
    SAL_DLLPRIVATE void            SetSymbolAlign( SymbolAlign eAlign );
147
148
    SAL_DLLPRIVATE void            SetDropDown( PushButtonDropdownStyle nStyle );
149
150
    void            SetState( TriState eState );
151
0
    TriState        GetState() const { return meState; }
152
    virtual void    statusChanged(const css::frame::FeatureStateEvent& rEvent) override;
153
154
    void            Check( bool bCheck = true );
155
    bool            IsChecked() const;
156
157
    void            SetPressed( bool bPressed );
158
0
    bool            IsPressed() const { return mbPressed; }
159
160
    SAL_DLLPRIVATE void            EndSelection();
161
162
    Size            CalcMinimumSize() const;
163
    virtual Size    GetOptimalSize() const override;
164
165
    virtual bool    set_property(const OUString &rKey, const OUString &rValue) override;
166
    virtual void    ShowFocus(const tools::Rectangle& rRect) override;
167
168
    void setAction(bool bIsAction)
169
0
    {
170
0
        mbIsAction = bIsAction;
171
0
    }
172
173
    bool isAction() const
174
0
    {
175
0
        return mbIsAction;
176
0
    }
177
178
0
    bool isToggleButton() { return mbIsToggleButton; }
179
0
    void setToggleButton(bool bIsToggleButton) { mbIsToggleButton = bIsToggleButton; }
180
181
protected:
182
    PushButtonDropdownStyle mnDDStyle;
183
184
    SAL_DLLPRIVATE void            ImplInitPushButtonData();
185
    SAL_DLLPRIVATE static WinBits  ImplInitStyle( const vcl::Window* pPrevWindow, WinBits nStyle );
186
    SAL_DLLPRIVATE void            ImplInitSettings( bool bBackground );
187
    SAL_DLLPRIVATE void            ImplDrawPushButtonContent(OutputDevice* pDev, SystemTextColorFlags nSystemTextColorFlags,
188
                                                             const tools::Rectangle& rRect, bool bMenuBtnSep,
189
                                                             DrawButtonFlags nButtonFlags);
190
    SAL_DLLPRIVATE void            ImplDrawPushButton(vcl::RenderContext& rRenderContext);
191
    using Button::ImplGetTextStyle;
192
    SAL_DLLPRIVATE DrawTextFlags   ImplGetTextStyle( SystemTextColorFlags nSystemTextColorFlags ) const;
193
0
    SAL_DLLPRIVATE bool            IsSymbol() const { return ( (meSymbol != SymbolType::DONTKNOW) && (meSymbol != SymbolType::IMAGE) ); }
194
195
                                   PushButton( const PushButton & ) = delete;
196
                                   PushButton& operator=( const PushButton & )
197
                                       = delete;
198
199
    SAL_DLLPRIVATE void            ImplInit( vcl::Window* pParent, WinBits nStyle );
200
201
    using Control::ImplInitSettings;
202
    using Window::ImplInit;
203
204
    SAL_DLLPRIVATE explicit        PushButton( WindowType nType );
205
206
    virtual void    FillLayoutData() const override;
207
    virtual const vcl::Font&
208
                    GetCanonicalFont( const StyleSettings& _rStyle ) const override;
209
    virtual const Color&
210
                    GetCanonicalTextColor( const StyleSettings& _rStyle ) const override;
211
212
private:
213
    SymbolType      meSymbol;
214
    TriState        meState;
215
    bool            mbPressed;
216
    bool            mbIsAction;
217
    bool            mbIsToggleButton = false;
218
};
219
220
inline void PushButton::Check( bool bCheck )
221
0
{
222
0
    SetState( bCheck ? TRISTATE_TRUE : TRISTATE_FALSE );
223
0
}
224
225
inline bool PushButton::IsChecked() const
226
0
{
227
0
    return (GetState() == TRISTATE_TRUE);
228
0
}
229
230
class VCL_DLLPUBLIC OKButton final : public PushButton
231
{
232
private:
233
    using PushButton::ImplInit;
234
235
    SAL_DLLPRIVATE void            ImplInit( vcl::Window* pParent, WinBits nStyle );
236
237
                                   OKButton (const OKButton &) = delete;
238
                                   OKButton & operator= (const OKButton &) = delete;
239
240
public:
241
    explicit        OKButton( vcl::Window* pParent, WinBits nStyle = WB_DEFBUTTON );
242
243
    virtual void    Click() override;
244
};
245
246
class VCL_DLLPUBLIC CancelButton : public PushButton
247
{
248
protected:
249
    using PushButton::ImplInit;
250
private:
251
    SAL_DLLPRIVATE void ImplInit( vcl::Window* pParent, WinBits nStyle );
252
253
                        CancelButton (const CancelButton &) = delete;
254
                        CancelButton & operator= (const CancelButton &) = delete;
255
256
public:
257
    explicit        CancelButton( vcl::Window* pParent, WinBits nStyle = 0 );
258
259
    virtual void    Click() override;
260
};
261
262
class CloseButton final : public CancelButton
263
{
264
public:
265
    explicit CloseButton(vcl::Window* pParent);
266
};
267
268
class VCL_DLLPUBLIC HelpButton final : public PushButton
269
{
270
private:
271
    using PushButton::ImplInit;
272
    SAL_DLLPRIVATE void ImplInit( vcl::Window* pParent, WinBits nStyle );
273
274
                        HelpButton( const HelpButton & ) = delete;
275
                        HelpButton & operator= ( const HelpButton & ) = delete;
276
277
    virtual void    StateChanged( StateChangedType nStateChange ) override;
278
279
public:
280
    explicit        HelpButton( vcl::Window* pParent, WinBits nStyle = 0 );
281
282
    virtual void    Click() override;
283
};
284
285
class VCL_DLLPUBLIC CheckBox : public Button
286
{
287
private:
288
    tools::Rectangle       maStateRect;
289
    tools::Rectangle       maMouseRect;
290
    TriState        meState;
291
    bool            mbTriState;
292
    Link<CheckBox&,void> maToggleHdl;
293
    SAL_DLLPRIVATE void         ImplInitCheckBoxData();
294
    SAL_DLLPRIVATE static WinBits ImplInitStyle( const vcl::Window* pPrevWindow, WinBits nStyle );
295
    SAL_DLLPRIVATE void         ImplInitSettings( bool bBackground );
296
    SAL_DLLPRIVATE void         ImplDraw( OutputDevice* pDev, SystemTextColorFlags nSystemTextColorFlags,
297
                                    const Point& rPos, const Size& rSize,
298
                                    const Size& rImageSize, tools::Rectangle& rStateRect,
299
                                    tools::Rectangle& rMouseRect );
300
    SAL_DLLPRIVATE void         ImplDrawCheckBox(vcl::RenderContext& rRenderContext );
301
    SAL_DLLPRIVATE Size         ImplGetCheckImageSize() const;
302
303
                                CheckBox(const CheckBox &) = delete;
304
                                CheckBox& operator= (const CheckBox &) = delete;
305
306
protected:
307
    using Control::ImplInitSettings;
308
    using Window::ImplInit;
309
    SAL_DLLPRIVATE void         ImplInit( vcl::Window* pParent, WinBits nStyle );
310
    virtual void                FillLayoutData() const override;
311
    virtual const vcl::Font&    GetCanonicalFont( const StyleSettings& _rStyle ) const override;
312
    virtual const Color&        GetCanonicalTextColor( const StyleSettings& _rStyle ) const override;
313
    void                        ImplAdjustNWFSizes() override;
314
315
    virtual void ImplDrawCheckBoxState(vcl::RenderContext& rRenderContext);
316
0
    SAL_DLLPRIVATE const tools::Rectangle& GetStateRect() const { return maStateRect; }
317
0
    SAL_DLLPRIVATE const tools::Rectangle& GetMouseRect() const { return maMouseRect; }
318
319
public:
320
    SAL_DLLPRIVATE void         ImplCheck();
321
public:
322
    explicit        CheckBox( vcl::Window* pParent, WinBits nStyle = 0 );
323
324
    virtual rtl::Reference<comphelper::OAccessible> CreateAccessible() override;
325
326
    virtual void    MouseButtonDown( const MouseEvent& rMEvt ) override;
327
    virtual void    Tracking( const TrackingEvent& rTEvt ) override;
328
    virtual void    KeyInput( const KeyEvent& rKEvt ) override;
329
    virtual void    KeyUp( const KeyEvent& rKEvt ) override;
330
    virtual void    Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect ) override;
331
    virtual void Draw(OutputDevice& rDev, const Point& rPos, SystemTextColorFlags nFlags) override;
332
    virtual void    Resize() override;
333
    virtual void    GetFocus() override;
334
    virtual void    LoseFocus() override;
335
    virtual void    StateChanged( StateChangedType nType ) override;
336
    virtual void    DataChanged( const DataChangedEvent& rDCEvt ) override;
337
    virtual bool    PreNotify( NotifyEvent& rNEvt ) override;
338
339
    void            Toggle();
340
341
    void            SetState( TriState eState );
342
0
    TriState        GetState() const { return meState; }
343
344
    void            Check( bool bCheck = true )
345
0
    {
346
0
        SetState( bCheck ? TRISTATE_TRUE : TRISTATE_FALSE );
347
0
    }
348
349
    bool            IsChecked() const
350
0
    {
351
0
        return (GetState() == TRISTATE_TRUE);
352
0
    }
353
354
    void            EnableTriState( bool bTriState = true );
355
0
    bool            IsTriStateEnabled() const { return mbTriState; }
356
357
    static Image    GetCheckImage( const AllSettings& rSettings, DrawButtonFlags nFlags );
358
359
    Size            CalcMinimumSize( tools::Long nMaxWidth = 0 ) const;
360
    virtual Size    GetOptimalSize() const override;
361
362
0
    void            SetToggleHdl( const Link<CheckBox&,void>& rLink ) { maToggleHdl = rLink; }
363
364
    virtual bool set_property(const OUString &rKey, const OUString &rValue) override;
365
    virtual void ShowFocus(const tools::Rectangle& rRect) override;
366
367
    virtual FactoryFunction GetUITestFactory() const override;
368
};
369
370
class VCL_DLLPUBLIC RadioButton : public Button
371
{
372
private:
373
    friend class VclBuilder;
374
375
    std::shared_ptr< std::vector< VclPtr< RadioButton > > > m_xGroup;
376
    tools::Rectangle       maStateRect;
377
    tools::Rectangle       maMouseRect;
378
    Image           maImage;
379
    bool            mbChecked;
380
    bool            mbRadioCheck;
381
    bool            mbStateChanged;
382
    bool            mbUsesExplicitGroup;
383
    Link<RadioButton&,void> maToggleHdl;
384
    SAL_DLLPRIVATE void     ImplInitRadioButtonData();
385
    SAL_DLLPRIVATE WinBits  ImplInitStyle( const vcl::Window* pPrevWindow, WinBits nStyle ) const;
386
    SAL_DLLPRIVATE void     ImplInitSettings( bool bBackground );
387
    SAL_DLLPRIVATE void     ImplDrawRadioButtonState(vcl::RenderContext& rRenderContext);
388
    SAL_DLLPRIVATE void     ImplDraw( OutputDevice* pDev, SystemTextColorFlags nSystemTextColorFlags,
389
                              const Point& rPos, const Size& rSize,
390
                              const Size& rImageSize, tools::Rectangle& rStateRect,
391
                              tools::Rectangle& rMouseRect );
392
    SAL_DLLPRIVATE void     ImplDrawRadioButton(vcl::RenderContext& rRenderContext );
393
    SAL_DLLPRIVATE void     ImplUncheckAllOther();
394
    SAL_DLLPRIVATE Size     ImplGetRadioImageSize() const;
395
396
                            RadioButton(const RadioButton &) = delete;
397
                            RadioButton& operator= (const RadioButton &) = delete;
398
399
protected:
400
    using Control::ImplInitSettings;
401
    using Window::ImplInit;
402
    SAL_DLLPRIVATE void     ImplInit( vcl::Window* pParent, WinBits nStyle );
403
404
public:
405
    SAL_DLLPRIVATE void     ImplCallClick( bool bGrabFocus = false, GetFocusFlags nFocusFlags = GetFocusFlags::NONE );
406
407
protected:
408
    virtual void    FillLayoutData() const override;
409
    virtual const vcl::Font&
410
                    GetCanonicalFont( const StyleSettings& _rStyle ) const override;
411
    virtual const Color&
412
                    GetCanonicalTextColor( const StyleSettings& _rStyle ) const override;
413
    void            ImplAdjustNWFSizes() override;
414
415
public:
416
    /*
417
     bUsesExplicitGroup of true means that group() is used to set what radiobuttons are part of a group
418
     while false means that contiguous radiobuttons are considered part of a group where WB_GROUP designates
419
     the start of the group and all contiguous radiobuttons without WB_GROUP set form the rest of the group.
420
421
     true is fairly straightforward, false leads to trick situations and is the legacy case
422
    */
423
    explicit        RadioButton(vcl::Window* pParent, bool bUsesExplicitGroup, WinBits nWinStyle);
424
    virtual         ~RadioButton() override;
425
    virtual void    dispose() override;
426
427
    virtual rtl::Reference<comphelper::OAccessible> CreateAccessible() override;
428
429
    virtual void    MouseButtonDown( const MouseEvent& rMEvt ) override;
430
    virtual void    Tracking( const TrackingEvent& rTEvt ) override;
431
    virtual void    KeyInput( const KeyEvent& rKEvt ) override;
432
    virtual void    KeyUp( const KeyEvent& rKEvt ) override;
433
    virtual void    Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect ) override;
434
    virtual void Draw(OutputDevice& rDev, const Point& rPos, SystemTextColorFlags nFlags) override;
435
    virtual void    Resize() override;
436
    virtual void    GetFocus() override;
437
    virtual void    LoseFocus() override;
438
    virtual void    StateChanged( StateChangedType nType ) override;
439
    virtual void    DataChanged( const DataChangedEvent& rDCEvt ) override;
440
    virtual bool    PreNotify( NotifyEvent& rNEvt ) override;
441
442
    SAL_DLLPRIVATE void            Toggle();
443
444
0
    bool            IsStateChanged() const { return mbStateChanged; }
445
446
0
    void            EnableRadioCheck( bool bRadioCheck ) { mbRadioCheck = bRadioCheck; }
447
0
    bool            IsRadioCheckEnabled() const { return mbRadioCheck; }
448
449
    SAL_DLLPRIVATE void            SetModeRadioImage( const Image& rImage );
450
451
    void            SetState( bool bCheck );
452
    void            Check( bool bCheck = true );
453
0
    bool            IsChecked() const { return mbChecked; }
454
455
    SAL_DLLPRIVATE static Image    GetRadioImage( const AllSettings& rSettings, DrawButtonFlags nFlags );
456
457
    Size            CalcMinimumSize( tools::Long nMaxWidth = 0 ) const;
458
    virtual Size    GetOptimalSize() const override;
459
460
0
    void            SetToggleHdl( const Link<RadioButton&,void>& rLink ) { maToggleHdl = rLink; }
461
462
    /** GetRadioButtonGroup returns a list of pointers to <code>RadioButton</code>s in the same group.
463
464
    The pointers in the returned list are valid at the time call returns. However rescheduling
465
    or giving up the SolarMutex may mean events get executed that lead to the pointers getting
466
    invalid.
467
468
    @param bIncludeThis
469
    defines whether <code>this</code> is contained in the returned list
470
471
    @return
472
    on return contains the <code>RadioButton</code>s
473
    in the same group as this <code>RadioButton</code>.
474
    */
475
    std::vector<VclPtr<RadioButton> > GetRadioButtonGroup(bool bIncludeThis = true) const;
476
477
    virtual bool set_property(const OUString &rKey, const OUString &rValue) override;
478
479
    /*
480
     * Group this RadioButton with another
481
     */
482
    SAL_DLLPRIVATE void group(RadioButton &rOther);
483
    virtual void ShowFocus(const tools::Rectangle& rRect) override;
484
485
    virtual FactoryFunction GetUITestFactory() const override;
486
};
487
488
class UNLESS_MERGELIBS(VCL_DLLPUBLIC) ImageButton final : public PushButton
489
{
490
private:
491
    using PushButton::ImplInitStyle;
492
493
    SAL_DLLPRIVATE void     ImplInitStyle();
494
495
                            ImageButton( const ImageButton & ) = delete;
496
                            ImageButton & operator= ( const ImageButton & ) = delete;
497
498
public:
499
                 ImageButton( vcl::Window* pParent, WinBits nStyle = 0 );
500
};
501
502
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */