/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: */ |