Coverage Report

Created: 2026-05-16 09:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/include/vcl/weld/ComboBox.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/weld.hxx>
14
15
namespace weld
16
{
17
class Menu;
18
19
struct VCL_DLLPUBLIC ComboBoxEntry
20
{
21
    OUString sString;
22
    OUString sId;
23
    OUString sImage;
24
    ComboBoxEntry(OUString _aString)
25
        : sString(std::move(_aString))
26
0
    {
27
0
    }
28
    ComboBoxEntry(OUString _aString, OUString _aId)
29
        : sString(std::move(_aString))
30
        , sId(std::move(_aId))
31
0
    {
32
0
    }
33
    ComboBoxEntry(OUString _aString, OUString _aId, OUString _aImage)
34
        : sString(std::move(_aString))
35
        , sId(std::move(_aId))
36
        , sImage(std::move(_aImage))
37
0
    {
38
0
    }
39
};
40
41
/// A widget used to choose from a list of items.
42
class VCL_DLLPUBLIC ComboBox : virtual public Widget
43
{
44
private:
45
    OUString m_sSavedValue;
46
    std::vector<OUString> m_aSavedValues;
47
48
public:
49
    // OUString is the id of the row, it may be null to measure the height of a generic line
50
    typedef std::tuple<vcl::RenderContext&, const tools::Rectangle&, bool, const OUString&>
51
        render_args;
52
53
protected:
54
    Link<ComboBox&, void> m_aChangeHdl;
55
    Link<ComboBox&, void> m_aPopupToggledHdl;
56
    Link<ComboBox&, bool> m_aEntryActivateHdl;
57
    Link<OUString&, bool> m_aEntryInsertTextHdl;
58
59
    friend class ::LOKTrigger;
60
61
    void signal_changed()
62
0
    {
63
0
        if (notify_events_disabled())
64
0
            return;
65
0
        m_aChangeHdl.Call(*this);
66
0
    }
67
68
0
    virtual void signal_popup_toggled() { m_aPopupToggledHdl.Call(*this); }
69
70
    Link<render_args, void> m_aRenderHdl;
71
    void signal_custom_render(vcl::RenderContext& rDevice, const tools::Rectangle& rRect,
72
                              bool bSelected, const OUString& rId)
73
0
    {
74
0
        m_aRenderHdl.Call(render_args(rDevice, rRect, bSelected, rId));
75
0
    }
76
77
    Link<vcl::RenderContext&, Size> m_aGetSizeHdl;
78
0
    Size signal_custom_get_size(vcl::RenderContext& rDevice) { return m_aGetSizeHdl.Call(rDevice); }
79
80
    virtual void do_insert(int pos, const OUString& rStr, const OUString* pId,
81
                           const OUString* pIconName, VirtualDevice* pImageSurface)
82
        = 0;
83
    virtual void do_set_active(int pos) = 0;
84
    virtual void do_set_active_id(const OUString& rStr) = 0;
85
86
public:
87
    void insert(int pos, const OUString& rStr, const OUString* pId, const OUString* pIconName,
88
                VirtualDevice* pImageSurface);
89
    virtual void insert_vector(const std::vector<weld::ComboBoxEntry>& rItems, bool bKeepExisting)
90
        = 0;
91
    void insert(int pos, const weld::ComboBoxEntry& rItem)
92
0
    {
93
0
        insert(pos, rItem.sString, rItem.sId.isEmpty() ? nullptr : &rItem.sId,
94
0
               rItem.sImage.isEmpty() ? nullptr : &rItem.sImage, nullptr);
95
0
    }
96
    void insert_text(int pos, const OUString& rStr)
97
0
    {
98
0
        insert(pos, rStr, nullptr, nullptr, nullptr);
99
0
    }
100
0
    void append(const weld::ComboBoxEntry& rItem) { insert(-1, rItem); }
101
0
    void append_text(const OUString& rStr) { insert(-1, rStr, nullptr, nullptr, nullptr); }
102
    void append(const OUString& rId, const OUString& rStr)
103
0
    {
104
0
        insert(-1, rStr, &rId, nullptr, nullptr);
105
0
    }
106
    void append(const OUString& rId, const OUString& rStr, const OUString& rImage)
107
0
    {
108
0
        insert(-1, rStr, &rId, &rImage, nullptr);
109
0
    }
110
    void append(const OUString& rId, const OUString& rStr, VirtualDevice& rImage)
111
0
    {
112
0
        insert(-1, rStr, &rId, nullptr, &rImage);
113
0
    }
114
    void append(int pos, const OUString& rId, const OUString& rStr)
115
0
    {
116
0
        insert(pos, rStr, &rId, nullptr, nullptr);
117
0
    }
118
    virtual void insert_separator(int pos, const OUString& rId) = 0;
119
0
    void append_separator(const OUString& rId) { insert_separator(-1, rId); }
120
121
    virtual int get_count() const = 0;
122
    virtual void make_sorted() = 0;
123
    virtual void clear() = 0;
124
125
    //by index, returns -1 if nothing is selected
126
    virtual int get_active() const = 0;
127
    void set_active(int pos);
128
    virtual void remove(int pos) = 0;
129
130
    //by text
131
    virtual OUString get_active_text() const = 0;
132
0
    void set_active_text(const OUString& rStr) { set_active(find_text(rStr)); }
133
    virtual OUString get_text(int pos) const = 0;
134
    virtual int find_text(const OUString& rStr) const = 0;
135
0
    void remove_text(const OUString& rText) { remove(find_text(rText)); }
136
137
    //by id
138
    virtual OUString get_active_id() const = 0;
139
    void set_active_id(const OUString& rStr);
140
    virtual OUString get_id(int pos) const = 0;
141
    virtual void set_id(int row, const OUString& rId) = 0;
142
    virtual int find_id(const OUString& rId) const = 0;
143
0
    void remove_id(const OUString& rId) { remove(find_id(rId)); }
144
145
    /* m_aChangeHdl is called when the active item is changed. The can be due
146
       to the user selecting a different item from the list or while typing
147
       into the entry of a combo box with an entry.
148
149
       Use changed_by_direct_pick() to discover whether an item was actually explicitly
150
       selected, e.g. from the menu.
151
     */
152
0
    void connect_changed(const Link<ComboBox&, void>& rLink) { m_aChangeHdl = rLink; }
153
154
    virtual bool changed_by_direct_pick() const = 0;
155
156
    virtual void connect_popup_toggled(const Link<ComboBox&, void>& rLink)
157
0
    {
158
0
        m_aPopupToggledHdl = rLink;
159
0
    }
160
161
    //entry related
162
    virtual bool has_entry() const = 0;
163
    virtual void set_entry_message_type(EntryMessageType eType) = 0;
164
    virtual void set_entry_text(const OUString& rStr) = 0;
165
    virtual void set_entry_width_chars(int nChars) = 0;
166
    virtual void set_entry_max_length(int nChars) = 0;
167
    virtual void select_entry_region(int nStartPos, int nEndPos) = 0;
168
    virtual bool get_entry_selection_bounds(int& rStartPos, int& rEndPos) = 0;
169
    virtual void set_entry_completion(bool bEnable, bool bCaseSensitive = false) = 0;
170
    virtual void set_entry_placeholder_text(const OUString& rText) = 0;
171
    virtual void set_entry_editable(bool bEditable) = 0;
172
    virtual void cut_entry_clipboard() = 0;
173
    virtual void copy_entry_clipboard() = 0;
174
    virtual void paste_entry_clipboard() = 0;
175
176
    // font size is in points, not pixels, e.g. see Window::[G]etPointFont
177
    virtual void set_font(const vcl::Font& rFont) = 0;
178
179
    // font size is in points, not pixels, e.g. see Window::[G]etPointFont
180
    virtual void set_entry_font(const vcl::Font& rFont) = 0;
181
    virtual vcl::Font get_entry_font() = 0;
182
183
    virtual bool get_popup_shown() const = 0;
184
185
    void connect_entry_insert_text(const Link<OUString&, bool>& rLink)
186
0
    {
187
0
        m_aEntryInsertTextHdl = rLink;
188
0
    }
189
190
    // callback returns true to indicated no further processing of activate wanted
191
0
    void connect_entry_activate(const Link<ComboBox&, bool>& rLink) { m_aEntryActivateHdl = rLink; }
192
193
0
    void save_value() { m_sSavedValue = get_active_text(); }
194
195
    void save_values_by_id(const OUString& rId)
196
0
    {
197
0
        m_aSavedValues.push_back(get_text(find_id(rId)));
198
0
    }
199
200
0
    OUString const& get_saved_value() const { return m_sSavedValue; }
201
0
    OUString const& get_saved_values(int pos) const { return m_aSavedValues[pos]; }
202
0
    bool get_value_changed_from_saved() const { return m_sSavedValue != get_active_text(); }
203
    bool get_values_changed_from_saved() const;
204
205
0
    void removeSavedValues() { m_aSavedValues.clear(); }
206
207
    // for custom rendering a row
208
    void connect_custom_get_size(const Link<vcl::RenderContext&, Size>& rLink)
209
0
    {
210
0
        m_aGetSizeHdl = rLink;
211
0
    }
212
0
    void connect_custom_render(const Link<render_args, void>& rLink) { m_aRenderHdl = rLink; }
213
    // call set_custom_renderer after setting custom callbacks
214
    virtual void set_custom_renderer(bool bOn) = 0;
215
    // set a sub menu for a entry, only works with custom rendering
216
    virtual void set_item_menu(const OUString& rIdent, weld::Menu* pMenu) = 0;
217
    // get the width needed to show the menu launcher in a custom row
218
    virtual int get_menu_button_width() const = 0;
219
220
    // for mru support
221
    virtual int get_max_mru_count() const = 0;
222
    virtual void set_max_mru_count(int nCount) = 0;
223
    virtual std::vector<OUString> get_mru_entries() const = 0;
224
    virtual void set_mru_entries(const std::vector<OUString>& rEntries) = 0;
225
226
    // Backwards compatibility, should be avoided to allow
227
    // UI consistency.
228
    virtual void set_max_drop_down_rows(int nRows) = 0;
229
};
230
}
231
232
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */