Coverage Report

Created: 2026-02-14 09:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/include/vcl/weld/MetricSpinButton.hxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
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
10
#pragma once
11
12
#include <vcl/dllapi.h>
13
#include <vcl/weld/SpinButton.hxx>
14
15
enum class FieldUnit : sal_uInt16;
16
17
namespace weld
18
{
19
class VCL_DLLPUBLIC MetricSpinButton final
20
{
21
    FieldUnit m_eSrcUnit;
22
    std::unique_ptr<weld::SpinButton> m_xSpinButton;
23
    Link<MetricSpinButton&, void> m_aValueChangedHdl;
24
25
    DECL_LINK(spin_button_value_changed, weld::SpinButton&, void);
26
    DECL_LINK(spin_button_output, sal_Int64, OUString);
27
    DECL_LINK(spin_button_input, const OUString&, std::optional<int>);
28
29
0
    void signal_value_changed() { m_aValueChangedHdl.Call(*this); }
30
31
    sal_Int64 ConvertValue(sal_Int64 nValue, FieldUnit eInUnit, FieldUnit eOutUnit) const;
32
    OUString format_number(sal_Int64 nValue) const;
33
    void update_width_chars();
34
35
public:
36
    MetricSpinButton(std::unique_ptr<SpinButton> pSpinButton, FieldUnit eSrcUnit)
37
0
        : m_eSrcUnit(eSrcUnit)
38
0
        , m_xSpinButton(std::move(pSpinButton))
39
0
    {
40
0
        update_width_chars();
41
0
        m_xSpinButton->set_value_formatter(LINK(this, MetricSpinButton, spin_button_output));
42
0
        m_xSpinButton->set_text_parser(LINK(this, MetricSpinButton, spin_button_input));
43
0
        m_xSpinButton->connect_value_changed(
44
0
            LINK(this, MetricSpinButton, spin_button_value_changed));
45
0
        m_xSpinButton->set_text(format_number(m_xSpinButton->get_value()));
46
0
    }
47
48
    static OUString MetricToString(FieldUnit rUnit);
49
50
0
    FieldUnit get_unit() const { return m_eSrcUnit; }
51
52
    void set_unit(FieldUnit eUnit);
53
54
    sal_Int64 convert_value_to(sal_Int64 nValue, FieldUnit eValueUnit) const
55
0
    {
56
0
        return ConvertValue(nValue, m_eSrcUnit, eValueUnit);
57
0
    }
58
59
    sal_Int64 convert_value_from(sal_Int64 nValue, FieldUnit eValueUnit) const
60
0
    {
61
0
        return ConvertValue(nValue, eValueUnit, m_eSrcUnit);
62
0
    }
63
64
    void set_value(sal_Int64 nValue, FieldUnit eValueUnit)
65
0
    {
66
0
        m_xSpinButton->set_value(convert_value_from(nValue, eValueUnit));
67
0
    }
68
69
    sal_Int64 get_value(FieldUnit eDestUnit) const
70
0
    {
71
0
        return convert_value_to(m_xSpinButton->get_value(), eDestUnit);
72
0
    }
73
74
    // typically you only need to call this if set_text (e.g. with "") was
75
    // previously called to display some arbitrary text instead of the
76
    // formatted value and now you want to show it as formatted again
77
    void reformat()
78
0
    {
79
0
        const OUString sText = format_number(m_xSpinButton->get_value());
80
0
        m_xSpinButton->set_text(sText);
81
0
    }
82
83
    void set_range(sal_Int64 min, sal_Int64 max, FieldUnit eValueUnit)
84
0
    {
85
0
        min = convert_value_from(min, eValueUnit);
86
0
        max = convert_value_from(max, eValueUnit);
87
0
        m_xSpinButton->set_range(min, max);
88
0
        update_width_chars();
89
0
    }
90
91
    void get_range(sal_Int64& min, sal_Int64& max, FieldUnit eDestUnit) const
92
0
    {
93
0
        m_xSpinButton->get_range(min, max);
94
0
        min = convert_value_to(min, eDestUnit);
95
0
        max = convert_value_to(max, eDestUnit);
96
0
    }
97
98
    void set_min(sal_Int64 min, FieldUnit eValueUnit)
99
0
    {
100
0
        sal_Int64 dummy, max;
101
0
        get_range(dummy, max, eValueUnit);
102
0
        set_range(min, max, eValueUnit);
103
0
    }
104
105
    void set_max(sal_Int64 max, FieldUnit eValueUnit)
106
0
    {
107
0
        sal_Int64 min, dummy;
108
0
        get_range(min, dummy, eValueUnit);
109
0
        set_range(min, max, eValueUnit);
110
0
    }
111
112
    sal_Int64 get_min(FieldUnit eValueUnit) const
113
0
    {
114
0
        sal_Int64 min, dummy;
115
0
        get_range(min, dummy, eValueUnit);
116
0
        return min;
117
0
    }
118
119
    sal_Int64 get_max(FieldUnit eValueUnit) const
120
0
    {
121
0
        sal_Int64 dummy, max;
122
0
        get_range(dummy, max, eValueUnit);
123
0
        return max;
124
0
    }
125
126
    void set_increments(sal_Int64 step, sal_Int64 page, FieldUnit eValueUnit)
127
0
    {
128
0
        step = convert_value_from(step, eValueUnit);
129
0
        page = convert_value_from(page, eValueUnit);
130
0
        m_xSpinButton->set_increments(step, page);
131
0
    }
132
133
    void get_increments(sal_Int64& step, sal_Int64& page, FieldUnit eDestUnit) const
134
0
    {
135
0
        m_xSpinButton->get_increments(step, page);
136
0
        step = convert_value_to(step, eDestUnit);
137
0
        page = convert_value_to(page, eDestUnit);
138
0
    }
139
140
    void connect_value_changed(const Link<MetricSpinButton&, void>& rLink)
141
0
    {
142
0
        m_aValueChangedHdl = rLink;
143
0
    }
144
145
0
    sal_Int64 normalize(sal_Int64 nValue) const { return m_xSpinButton->normalize(nValue); }
146
0
    sal_Int64 denormalize(sal_Int64 nValue) const { return m_xSpinButton->denormalize(nValue); }
147
0
    void set_sensitive(bool sensitive) { m_xSpinButton->set_sensitive(sensitive); }
148
0
    bool get_sensitive() const { return m_xSpinButton->get_sensitive(); }
149
0
    bool get_visible() const { return m_xSpinButton->get_visible(); }
150
0
    void grab_focus() { m_xSpinButton->grab_focus(); }
151
0
    bool has_focus() const { return m_xSpinButton->has_focus(); }
152
0
    void show() { m_xSpinButton->show(); }
153
0
    void set_visible(bool bShow) { m_xSpinButton->set_visible(bShow); }
154
0
    void hide() { m_xSpinButton->hide(); }
155
    void set_digits(unsigned int digits);
156
0
    void set_accessible_name(const OUString& rName) { m_xSpinButton->set_accessible_name(rName); }
157
0
    unsigned int get_digits() const { return m_xSpinButton->get_digits(); }
158
0
    void save_value() { m_xSpinButton->save_value(); }
159
    bool get_value_changed_from_saved() const
160
0
    {
161
0
        return m_xSpinButton->get_value_changed_from_saved();
162
0
    }
163
0
    void set_text(const OUString& rText) { m_xSpinButton->set_text(rText); }
164
0
    OUString get_text() const { return m_xSpinButton->get_text(); }
165
    void set_size_request(int nWidth, int nHeight)
166
0
    {
167
0
        m_xSpinButton->set_size_request(nWidth, nHeight);
168
0
    }
169
0
    Size get_size_request() const { return m_xSpinButton->get_size_request(); }
170
0
    Size get_preferred_size() const { return m_xSpinButton->get_preferred_size(); }
171
    void connect_focus_in(const Link<Widget&, void>& rLink)
172
0
    {
173
0
        m_xSpinButton->connect_focus_in(rLink);
174
0
    }
175
    void connect_focus_out(const Link<Widget&, void>& rLink)
176
0
    {
177
0
        m_xSpinButton->connect_focus_out(rLink);
178
0
    }
179
0
    OUString get_buildable_name() const { return m_xSpinButton->get_buildable_name(); }
180
0
    void set_help_id(const OUString& rName) { m_xSpinButton->set_help_id(rName); }
181
0
    void set_position(int nCursorPos) { m_xSpinButton->set_position(nCursorPos); }
182
    // set the width of the underlying widget in characters, this setting is
183
    // invalidated when changing the units, range or digits, so to have effect
184
    // must come after changing those values
185
0
    void set_width_chars(int nChars) { m_xSpinButton->set_width_chars(nChars); }
186
0
    int get_width_chars() const { return m_xSpinButton->get_width_chars(); }
187
0
    weld::SpinButton& get_widget() { return *m_xSpinButton; }
188
};
189
}
190
191
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */