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 
10 #ifndef INCLUDED_VCL_WELD_HXX
11 #define INCLUDED_VCL_WELD_HXX
12 
13 #include <basegfx/range/b2irange.hxx>
14 #include <rtl/ustring.hxx>
15 #include <tools/color.hxx>
16 #include <tools/date.hxx>
17 #include <tools/fldunit.hxx>
18 #include <tools/gen.hxx>
19 #include <tools/link.hxx>
20 #include <vcl/dllapi.h>
21 #include <vcl/vclenum.hxx>
22 #include <vcl/font.hxx>
23 #include <vcl/vclptr.hxx>
24 #include <vcl/uitest/factory.hxx>
25 
26 #include <com/sun/star/accessibility/XAccessibleRelationSet.hpp>
27 #include <com/sun/star/accessibility/XAccessible.hpp>
28 
29 #include <assert.h>
30 #include <memory>
31 #include <vector>
32 
33 namespace com::sun::star::awt
34 {
35 class XWindow;
36 }
37 namespace com::sun::star::datatransfer::clipboard
38 {
39 class XClipboard;
40 }
41 namespace com::sun::star::datatransfer::dnd
42 {
43 class XDropTarget;
44 }
45 namespace com::sun::star::graphic
46 {
47 class XGraphic;
48 }
49 typedef css::uno::Reference<css::accessibility::XAccessible> a11yref;
50 typedef css::uno::Reference<css::accessibility::XAccessibleRelationSet> a11yrelationset;
51 enum class PointerStyle;
52 class CommandEvent;
53 class Formatter;
54 class InputContext;
55 class KeyEvent;
56 class MouseEvent;
57 class SvNumberFormatter;
58 class TransferDataContainer;
59 class OutputDevice;
60 class VirtualDevice;
61 struct SystemEnvData;
62 
63 namespace vcl
64 {
65 class ILibreOfficeKitNotifier;
66 typedef OutputDevice RenderContext;
67 }
68 namespace tools
69 {
70 class JsonWriter;
71 }
72 
73 class LOKTrigger;
74 
75 namespace weld
76 {
77 class Container;
78 class DialogController;
79 
80 class VCL_DLLPUBLIC Widget
81 {
82 protected:
83     Link<Widget&, void> m_aFocusInHdl;
84     Link<Widget&, void> m_aFocusOutHdl;
85     Link<Widget&, bool> m_aMnemonicActivateHdl;
86     Link<const Size&, void> m_aSizeAllocateHdl;
87     Link<const KeyEvent&, bool> m_aKeyPressHdl;
88     Link<const KeyEvent&, bool> m_aKeyReleaseHdl;
89     Link<const MouseEvent&, bool> m_aMousePressHdl;
90     Link<const MouseEvent&, bool> m_aMouseMotionHdl;
91     Link<const MouseEvent&, bool> m_aMouseReleaseHdl;
92 
93 public:
94     virtual void set_sensitive(bool sensitive) = 0;
95     virtual bool get_sensitive() const = 0;
96 
97     /* visibility */
98 
99     virtual void show() = 0;
100     virtual void hide() = 0;
101 
102     // This function simply calls show() or hide() but is convenient when the
103     // visibility depends on some condition
set_visible(bool visible)104     virtual void set_visible(bool visible)
105     {
106         if (visible)
107             show();
108         else
109             hide();
110     }
111 
112     // return if this widget's visibility is true
113     virtual bool get_visible() const = 0;
114 
115     // return if this widget's visibility and that of all its parents is true
116     virtual bool is_visible() const = 0;
117 
118     /* focus */
119 
120     // sets if this widget can own the keyboard focus
121     virtual void set_can_focus(bool bCanFocus) = 0;
122 
123     // causes this widget to have the keyboard focus
124     virtual void grab_focus() = 0;
125 
126     // returns if this widget has the keyboard focus
127     virtual bool has_focus() const = 0;
128 
129     // if the widget that has focus is a child, which includes toplevel popup
130     // children, of this widget. So an Entry with an active popup (or dialog)
131     // has has_child_focus of true, but has_focus of false, while its popup is
132     // shown
133     virtual bool has_child_focus() const = 0;
134 
135     // return if this widget has the keyboard focus within the active window
136     // TODO: review if this has any practical difference from has_focus()
137     virtual bool is_active() const = 0;
138 
139     virtual void set_has_default(bool has_default) = 0;
140     virtual bool get_has_default() const = 0;
141 
142     /* size */
143     virtual void set_size_request(int nWidth, int nHeight) = 0;
144     virtual Size get_size_request() const = 0;
145     virtual Size get_preferred_size() const = 0;
146 
147     /* measure */
148     virtual float get_approximate_digit_width() const = 0;
149     virtual int get_text_height() const = 0;
150     virtual Size get_pixel_size(const OUString& rText) const = 0;
151 
152     // The name of the widget in the GtkBuilder UI definition used to construct it.
153     virtual OString get_buildable_name() const = 0;
154     /*
155        Typically there is no need to change the buildable name at runtime, changing
156        the id in .ui file itself is preferred.
157 
158        But for ui-testing purposes it can sometimes be useful to rename
159        different widgets, that were loaded from the same .ui, to unique names
160        in order to distinguish between them
161     */
162     virtual void set_buildable_name(const OString& rName) = 0;
163 
164     /*
165       The help id of the widget used to identify help for this widget.
166 
167       By default the help id of a widget is a path-like sequence of (load-time)
168       buildable-names from the widgets UI definition ancestor to this widget,
169       e.g. grandparent/parent/widget.
170 
171       The default can be overwritten with set_help_id
172     */
173     virtual OString get_help_id() const = 0;
174     virtual void set_help_id(const OString& rName) = 0;
175 
176     virtual void set_grid_left_attach(int nAttach) = 0;
177     virtual int get_grid_left_attach() const = 0;
178     virtual void set_grid_width(int nCols) = 0;
179     virtual void set_grid_top_attach(int nAttach) = 0;
180     virtual int get_grid_top_attach() const = 0;
181 
182     virtual void set_hexpand(bool bExpand) = 0;
183     virtual bool get_hexpand() const = 0;
184     virtual void set_vexpand(bool bExpand) = 0;
185     virtual bool get_vexpand() const = 0;
186 
187     virtual void set_margin_top(int nMargin) = 0;
188     virtual void set_margin_bottom(int nMargin) = 0;
189     virtual void set_margin_start(int nMargin) = 0;
190     virtual void set_margin_end(int nMargin) = 0;
191 
192     virtual int get_margin_top() const = 0;
193     virtual int get_margin_bottom() const = 0;
194     virtual int get_margin_start() const = 0;
195     virtual int get_margin_end() const = 0;
196 
197     /*
198      * Report the extents of this widget relative to the rRelative target widget.
199      *
200      * To succeed, both widgets must be realized, and must share a common toplevel.
201      *
202      * returns false if the relative extents could not be determined, e.g. if
203      * either widget was not realized, or there was no common ancestor.
204      * Otherwise true.
205      */
206     virtual bool get_extents_relative_to(const Widget& rRelative, int& x, int& y, int& width,
207                                          int& height) const = 0;
208 
209     virtual void set_accessible_name(const OUString& rName) = 0;
210     virtual void set_accessible_description(const OUString& rDescription) = 0;
211     virtual OUString get_accessible_name() const = 0;
212 
213     virtual OUString get_accessible_description() const = 0;
214 
215     virtual void set_accessible_relation_labeled_by(weld::Widget* pLabel) = 0;
216     virtual void set_accessible_relation_label_for(weld::Widget* pLabeled) = 0;
217 
218     virtual void set_tooltip_text(const OUString& rTip) = 0;
219     virtual OUString get_tooltip_text() const = 0;
220 
connect_focus_in(const Link<Widget &,void> & rLink)221     virtual void connect_focus_in(const Link<Widget&, void>& rLink)
222     {
223         assert(!m_aFocusInHdl.IsSet() || !rLink.IsSet());
224         m_aFocusInHdl = rLink;
225     }
226 
connect_focus_out(const Link<Widget &,void> & rLink)227     virtual void connect_focus_out(const Link<Widget&, void>& rLink)
228     {
229         assert(!m_aFocusOutHdl.IsSet() || !rLink.IsSet());
230         m_aFocusOutHdl = rLink;
231     }
232 
233     // rLink is called when the mnemonic for the Widget is called.
234     // If rLink returns true the Widget will not automatically gain
235     // focus as normally occurs
connect_mnemonic_activate(const Link<Widget &,bool> & rLink)236     virtual void connect_mnemonic_activate(const Link<Widget&, bool>& rLink)
237     {
238         assert(!m_aMnemonicActivateHdl.IsSet() || !rLink.IsSet());
239         m_aMnemonicActivateHdl = rLink;
240     }
241 
connect_size_allocate(const Link<const Size &,void> & rLink)242     virtual void connect_size_allocate(const Link<const Size&, void>& rLink)
243     {
244         assert(!m_aSizeAllocateHdl.IsSet() || !rLink.IsSet());
245         m_aSizeAllocateHdl = rLink;
246     }
247 
connect_key_press(const Link<const KeyEvent &,bool> & rLink)248     virtual void connect_key_press(const Link<const KeyEvent&, bool>& rLink)
249     {
250         assert(!m_aKeyPressHdl.IsSet() || !rLink.IsSet());
251         m_aKeyPressHdl = rLink;
252     }
253 
connect_key_release(const Link<const KeyEvent &,bool> & rLink)254     virtual void connect_key_release(const Link<const KeyEvent&, bool>& rLink)
255     {
256         assert(!m_aKeyReleaseHdl.IsSet() || !rLink.IsSet());
257         m_aKeyReleaseHdl = rLink;
258     }
259 
connect_mouse_press(const Link<const MouseEvent &,bool> & rLink)260     virtual void connect_mouse_press(const Link<const MouseEvent&, bool>& rLink)
261     {
262         assert(!m_aMousePressHdl.IsSet() || !rLink.IsSet());
263         m_aMousePressHdl = rLink;
264     }
265 
connect_mouse_move(const Link<const MouseEvent &,bool> & rLink)266     virtual void connect_mouse_move(const Link<const MouseEvent&, bool>& rLink)
267     {
268         assert(!m_aMouseMotionHdl.IsSet() || !rLink.IsSet());
269         m_aMouseMotionHdl = rLink;
270     }
271 
connect_mouse_release(const Link<const MouseEvent &,bool> & rLink)272     virtual void connect_mouse_release(const Link<const MouseEvent&, bool>& rLink)
273     {
274         assert(!m_aMouseReleaseHdl.IsSet() || !rLink.IsSet());
275         m_aMouseReleaseHdl = rLink;
276     }
277 
278     virtual void grab_add() = 0;
279     virtual bool has_grab() const = 0;
280     virtual void grab_remove() = 0;
281 
282     // font size is in points, not pixels, e.g. see Window::[G]etPointFont
283     virtual vcl::Font get_font() = 0;
284 
285     //true for rtl, false otherwise
286     virtual bool get_direction() const = 0;
287     virtual void set_direction(bool bRTL) = 0;
288 
289     /* Increases the freeze count on widget.
290 
291        If the freeze count is non-zero, emission of the widget's notifications
292        is stopped. The notifications are queued until the freeze count is
293        decreased to zero. Duplicate notifications may be squashed together.
294     */
295     virtual void freeze() = 0;
296 
297     /* Reverts the effect of a previous call to freeze.
298 
299        The freeze count is decreased on the widget and when it reaches zero,
300        queued notifications are emitted.
301     */
302     virtual void thaw() = 0;
303 
304     /* push/pop busy mouse cursor state
305 
306       bBusy of true to push a busy state onto the stack and false
307       to pop it off, calls to this should balance.
308 
309       see weld::WaitObject */
310     virtual void set_busy_cursor(bool bBusy) = 0;
311 
312     virtual void queue_resize() = 0;
313 
314     virtual std::unique_ptr<Container> weld_parent() const = 0;
315 
316     //iterate upwards through the hierarchy starting at this widgets parent,
317     //calling func with their helpid until func returns true or we run out of
318     //parents
319     virtual void help_hierarchy_foreach(const std::function<bool(const OString&)>& func) = 0;
320 
321     virtual OUString strip_mnemonic(const OUString& rLabel) const = 0;
322 
323     virtual VclPtr<VirtualDevice> create_virtual_device() const = 0;
324 
325     //make this widget look like a page in a notebook
326     virtual void set_stack_background() = 0;
327     //make this widget look like it has a highlighted background
328     virtual void set_highlight_background() = 0;
329     //make this widget suitable as parent for a title
330     virtual void set_title_background() = 0;
331     //make this widget suitable for use in a toolbar
332     virtual void set_toolbar_background() = 0;
333     //trying to use a custom color for a background is generally a bad idea. If your need
334     //fits one of the above categories then that's a somewhat better choice
335     virtual void set_background(const Color& rBackColor) = 0;
336 
337     virtual css::uno::Reference<css::datatransfer::dnd::XDropTarget> get_drop_target() = 0;
338     virtual css::uno::Reference<css::datatransfer::clipboard::XClipboard> get_clipboard() const = 0;
339 
340     virtual void connect_get_property_tree(const Link<tools::JsonWriter&, void>& rLink) = 0;
341     virtual void get_property_tree(tools::JsonWriter& rJsonWriter) = 0;
342 
343     // render the widget to an output device
344     virtual void draw(OutputDevice& rOutput, const Point& rPos, const Size& rSizePixel) = 0;
345 
~Widget()346     virtual ~Widget() {}
347 };
348 
349 class VCL_DLLPUBLIC Container : virtual public Widget
350 {
351 protected:
352     Link<Container&, void> m_aContainerFocusChangedHdl;
353 
signal_container_focus_changed()354     void signal_container_focus_changed() { m_aContainerFocusChangedHdl.Call(*this); }
355 
356 public:
357     // remove and add in one go
358     virtual void move(weld::Widget* pWidget, weld::Container* pNewParent) = 0;
359     // recursively unset has-default on any buttons in the widget hierarchy
360     virtual void recursively_unset_default_buttons() = 0;
361     // create an XWindow as a child of this container. The XWindow is
362     // suitable to contain css::awt::XControl items
363     virtual css::uno::Reference<css::awt::XWindow> CreateChildFrame() = 0;
364     // rLink is called when the focus transitions from a widget outside the container
365     // to a widget inside the container or vice versa
connect_container_focus_changed(const Link<Container &,void> & rLink)366     virtual void connect_container_focus_changed(const Link<Container&, void>& rLink)
367     {
368         m_aContainerFocusChangedHdl = rLink;
369     }
370     // causes a child of the container to have the keyboard focus
371     virtual void child_grab_focus() = 0;
372 };
373 
374 class VCL_DLLPUBLIC Box : virtual public Container
375 {
376 public:
377     // Moves child to a new position in the list of children
378     virtual void reorder_child(weld::Widget* pWidget, int position) = 0;
379     // Sort ok/cancel etc buttons in platform order
380     virtual void sort_native_button_order() = 0;
381 };
382 
383 class VCL_DLLPUBLIC Paned : virtual public Container
384 {
385 public:
386     // set pixel position of divider
387     virtual void set_position(int nPos) = 0;
388     // get pixel position of divider
389     virtual int get_position() const = 0;
390 };
391 
392 class VCL_DLLPUBLIC ScrolledWindow : virtual public Container
393 {
394 protected:
395     Link<ScrolledWindow&, void> m_aVChangeHdl;
396     Link<ScrolledWindow&, void> m_aHChangeHdl;
397 
signal_vadjustment_changed()398     void signal_vadjustment_changed() { m_aVChangeHdl.Call(*this); }
signal_hadjustment_changed()399     void signal_hadjustment_changed() { m_aHChangeHdl.Call(*this); }
400 
401 public:
402     virtual void hadjustment_configure(int value, int lower, int upper, int step_increment,
403                                        int page_increment, int page_size)
404         = 0;
405     virtual int hadjustment_get_value() const = 0;
406     virtual void hadjustment_set_value(int value) = 0;
407     virtual int hadjustment_get_upper() const = 0;
408     virtual void hadjustment_set_upper(int upper) = 0;
409     virtual int hadjustment_get_page_size() const = 0;
410     virtual void hadjustment_set_page_size(int size) = 0;
411     virtual void hadjustment_set_page_increment(int size) = 0;
412     virtual void hadjustment_set_step_increment(int size) = 0;
413     virtual void set_hpolicy(VclPolicyType eHPolicy) = 0;
414     virtual VclPolicyType get_hpolicy() const = 0;
connect_hadjustment_changed(const Link<ScrolledWindow &,void> & rLink)415     void connect_hadjustment_changed(const Link<ScrolledWindow&, void>& rLink)
416     {
417         m_aHChangeHdl = rLink;
418     }
419 
420     virtual void vadjustment_configure(int value, int lower, int upper, int step_increment,
421                                        int page_increment, int page_size)
422         = 0;
423     virtual int vadjustment_get_value() const = 0;
424     virtual void vadjustment_set_value(int value) = 0;
425     virtual int vadjustment_get_upper() const = 0;
426     virtual void vadjustment_set_upper(int upper) = 0;
427     virtual int vadjustment_get_page_size() const = 0;
428     virtual void vadjustment_set_page_size(int size) = 0;
429     virtual void vadjustment_set_page_increment(int size) = 0;
430     virtual void vadjustment_set_step_increment(int size) = 0;
431     virtual int vadjustment_get_lower() const = 0;
432     virtual void vadjustment_set_lower(int upper) = 0;
433     virtual void set_vpolicy(VclPolicyType eVPolicy) = 0;
434     virtual VclPolicyType get_vpolicy() const = 0;
connect_vadjustment_changed(const Link<ScrolledWindow &,void> & rLink)435     void connect_vadjustment_changed(const Link<ScrolledWindow&, void>& rLink)
436     {
437         m_aVChangeHdl = rLink;
438     }
439     virtual int get_scroll_thickness() const = 0;
440     virtual void set_scroll_thickness(int nThickness) = 0;
441 
442     //trying to use custom color for a scrollbar is generally a bad idea.
443     virtual void customize_scrollbars(const Color& rBackgroundColor, const Color& rShadowColor,
444                                       const Color& rFaceColor)
445         = 0;
446 };
447 
448 class Label;
449 
450 class VCL_DLLPUBLIC Frame : virtual public Container
451 {
452 public:
453     virtual void set_label(const OUString& rText) = 0;
454     virtual OUString get_label() const = 0;
455     virtual std::unique_ptr<Label> weld_label_widget() const = 0;
456 };
457 
458 class VCL_DLLPUBLIC Notebook : virtual public Widget
459 {
460 protected:
461     Link<const OString&, bool> m_aLeavePageHdl;
462     Link<const OString&, void> m_aEnterPageHdl;
463 
464 public:
465     virtual int get_current_page() const = 0;
466     virtual int get_page_index(const OString& rIdent) const = 0;
467     virtual OString get_page_ident(int nPage) const = 0;
468     virtual OString get_current_page_ident() const = 0;
469     virtual void set_current_page(int nPage) = 0;
470     virtual void set_current_page(const OString& rIdent) = 0;
471     virtual void remove_page(const OString& rIdent) = 0;
472     virtual void insert_page(const OString& rIdent, const OUString& rLabel, int nPos) = 0;
append_page(const OString & rIdent,const OUString & rLabel)473     void append_page(const OString& rIdent, const OUString& rLabel)
474     {
475         insert_page(rIdent, rLabel, -1);
476     }
477     virtual void set_tab_label_text(const OString& rIdent, const OUString& rLabel) = 0;
478     virtual OUString get_tab_label_text(const OString& rIdent) const = 0;
479     virtual int get_n_pages() const = 0;
480     virtual weld::Container* get_page(const OString& rIdent) const = 0;
481 
connect_leave_page(const Link<const OString &,bool> & rLink)482     void connect_leave_page(const Link<const OString&, bool>& rLink) { m_aLeavePageHdl = rLink; }
483 
connect_enter_page(const Link<const OString &,void> & rLink)484     void connect_enter_page(const Link<const OString&, void>& rLink) { m_aEnterPageHdl = rLink; }
485 };
486 
487 class VCL_DLLPUBLIC ScreenShotEntry
488 {
489 public:
ScreenShotEntry(const OString & rHelpId,const basegfx::B2IRange & rB2IRange)490     ScreenShotEntry(const OString& rHelpId, const basegfx::B2IRange& rB2IRange)
491         : msHelpId(rHelpId)
492         , maB2IRange(rB2IRange)
493     {
494     }
495 
getB2IRange() const496     const basegfx::B2IRange& getB2IRange() const { return maB2IRange; }
497 
GetHelpId() const498     const OString& GetHelpId() const { return msHelpId; }
499 
500 private:
501     OString msHelpId;
502     basegfx::B2IRange maB2IRange;
503 };
504 
505 typedef std::vector<ScreenShotEntry> ScreenShotCollection;
506 
507 class VCL_DLLPUBLIC Window : virtual public Container
508 {
509 protected:
510     Link<Widget&, bool> m_aHelpRequestHdl;
511 
512 public:
513     virtual void set_title(const OUString& rTitle) = 0;
514     virtual OUString get_title() const = 0;
515     virtual void window_move(int x, int y) = 0;
516     virtual void set_modal(bool bModal) = 0;
517     virtual bool get_modal() const = 0;
518     virtual bool get_resizable() const = 0;
519     virtual Size get_size() const = 0;
520     virtual Point get_position() const = 0;
521     virtual tools::Rectangle get_monitor_workarea() const = 0;
522     // center window on is parent
523     //
524     // bTrackGeometryRequests set to true tries to ensure the window will end
525     // up still centered on its parent windows final size, taking into account
526     // that there may currently be pending geometry requests for the parent not
527     // yet processed by the underlying toolkit
528     //
529     // for e.g gtk this will means the window is always centered even when
530     // resized, calling set_centered_on_parent with false will turn this
531     // off again.
532     virtual void set_centered_on_parent(bool bTrackGeometryRequests) = 0;
533     // returns whether the widget that has focus is within this Window
534     // (its very possible to move this to weld::Container if that becomes
535     // desirable)
536     virtual bool has_toplevel_focus() const = 0;
537     virtual void present() = 0;
538     virtual void set_window_state(const OString& rStr) = 0;
539     virtual OString get_window_state(WindowStateMask nMask) const = 0;
540 
541     virtual css::uno::Reference<css::awt::XWindow> GetXWindow() = 0;
542 
connect_help(const Link<Widget &,bool> & rLink)543     void connect_help(const Link<Widget&, bool>& rLink) { m_aHelpRequestHdl = rLink; }
544 
545     virtual SystemEnvData get_system_data() const = 0;
546 
547     virtual void resize_to_request() = 0;
548 
549     // collect positions of widgets and their help ids for screenshot purposes
550     virtual ScreenShotCollection collect_screenshot_data() = 0;
551 
552     // render the widget to an output device
553     virtual VclPtr<VirtualDevice> screenshot() = 0;
554 };
555 
556 class VCL_DLLPUBLIC WaitObject
557 {
558 private:
559     weld::Widget* m_pWindow;
560 
561 public:
WaitObject(weld::Widget * pWindow)562     WaitObject(weld::Widget* pWindow)
563         : m_pWindow(pWindow)
564     {
565         if (m_pWindow)
566             m_pWindow->set_busy_cursor(true);
567     }
~WaitObject()568     ~WaitObject()
569     {
570         if (m_pWindow)
571             m_pWindow->set_busy_cursor(false);
572     }
573 };
574 
575 class Button;
576 
577 class VCL_DLLPUBLIC Dialog : virtual public Window
578 {
579 private:
580     friend DialogController;
581     virtual bool runAsync(std::shared_ptr<DialogController>,
582                           const std::function<void(sal_Int32)>& func)
583         = 0;
584 
585 public:
586     virtual int run() = 0;
587     // Run async without a controller
588     // @param self - must point to this, to enforce that the dialog was created/held by a shared_ptr
589     virtual bool runAsync(std::shared_ptr<Dialog> const& rxSelf,
590                           const std::function<void(sal_Int32)>& func)
591         = 0;
592     virtual void response(int response) = 0;
593     virtual void add_button(const OUString& rText, int response, const OString& rHelpId = OString())
594         = 0;
595     virtual void set_default_response(int response) = 0;
596     virtual Button* weld_widget_for_response(int response) = 0;
597     virtual Container* weld_content_area() = 0;
598 
599     // shrink the dialog down to shown just these widgets
600     virtual void collapse(weld::Widget* pEdit, weld::Widget* pButton) = 0;
601     // undo previous dialog collapse
602     virtual void undo_collapse() = 0;
603 
604     virtual void SetInstallLOKNotifierHdl(const Link<void*, vcl::ILibreOfficeKitNotifier*>& rLink)
605         = 0;
606 };
607 
608 class VCL_DLLPUBLIC MessageDialog : virtual public Dialog
609 {
610 public:
611     virtual void set_primary_text(const OUString& rText) = 0;
612     virtual OUString get_primary_text() const = 0;
613     virtual void set_secondary_text(const OUString& rText) = 0;
614     virtual OUString get_secondary_text() const = 0;
615     virtual Container* weld_message_area() = 0;
616 };
617 
618 class VCL_DLLPUBLIC Assistant : virtual public Dialog
619 {
620 protected:
621     Link<const OString&, bool> m_aJumpPageHdl;
622 
signal_jump_page(const OString & rIdent)623     bool signal_jump_page(const OString& rIdent) { return m_aJumpPageHdl.Call(rIdent); }
624 
625 public:
626     virtual int get_current_page() const = 0;
627     virtual int get_n_pages() const = 0;
628     virtual OString get_page_ident(int nPage) const = 0;
629     virtual OString get_current_page_ident() const = 0;
630     virtual void set_current_page(int nPage) = 0;
631     virtual void set_current_page(const OString& rIdent) = 0;
632     // move the page rIdent to position nIndex
633     virtual void set_page_index(const OString& rIdent, int nIndex) = 0;
634     virtual void set_page_title(const OString& rIdent, const OUString& rTitle) = 0;
635     virtual OUString get_page_title(const OString& rIdent) const = 0;
636     virtual void set_page_sensitive(const OString& rIdent, bool bSensitive) = 0;
637     virtual weld::Container* append_page(const OString& rIdent) = 0;
638 
639     virtual void set_page_side_help_id(const OString& rHelpId) = 0;
640 
connect_jump_page(const Link<const OString &,bool> & rLink)641     void connect_jump_page(const Link<const OString&, bool>& rLink) { m_aJumpPageHdl = rLink; }
642 };
643 
644 struct VCL_DLLPUBLIC ComboBoxEntry
645 {
646     OUString sString;
647     OUString sId;
648     OUString sImage;
ComboBoxEntryweld::ComboBoxEntry649     ComboBoxEntry(const OUString& rString)
650         : sString(rString)
651     {
652     }
ComboBoxEntryweld::ComboBoxEntry653     ComboBoxEntry(const OUString& rString, const OUString& rId)
654         : sString(rString)
655         , sId(rId)
656     {
657     }
ComboBoxEntryweld::ComboBoxEntry658     ComboBoxEntry(const OUString& rString, const OUString& rId, const OUString& rImage)
659         : sString(rString)
660         , sId(rId)
661         , sImage(rImage)
662     {
663     }
664 };
665 
666 enum class EntryMessageType
667 {
668     Normal,
669     Warning,
670     Error,
671 };
672 
673 class Menu;
674 
675 /// A widget used to choose from a list of items.
676 class VCL_DLLPUBLIC ComboBox : virtual public Widget
677 {
678 private:
679     OUString m_sSavedValue;
680 
681 public:
682     // OUString is the id of the row, it may be null to measure the height of a generic line
683     typedef std::tuple<vcl::RenderContext&, const tools::Rectangle&, bool, const OUString&>
684         render_args;
685 
686 protected:
687     Link<ComboBox&, void> m_aChangeHdl;
688     Link<ComboBox&, void> m_aPopupToggledHdl;
689     Link<ComboBox&, bool> m_aEntryActivateHdl;
690     Link<OUString&, bool> m_aEntryInsertTextHdl;
691 
692     friend class ::LOKTrigger;
693 
signal_changed()694     void signal_changed() { m_aChangeHdl.Call(*this); }
695 
signal_popup_toggled()696     virtual void signal_popup_toggled() { m_aPopupToggledHdl.Call(*this); }
697 
698     Link<render_args, void> m_aRenderHdl;
signal_custom_render(vcl::RenderContext & rDevice,const tools::Rectangle & rRect,bool bSelected,const OUString & rId)699     void signal_custom_render(vcl::RenderContext& rDevice, const tools::Rectangle& rRect,
700                               bool bSelected, const OUString& rId)
701     {
702         m_aRenderHdl.Call(render_args(rDevice, rRect, bSelected, rId));
703     }
704 
705     Link<vcl::RenderContext&, Size> m_aGetSizeHdl;
signal_custom_get_size(vcl::RenderContext & rDevice)706     Size signal_custom_get_size(vcl::RenderContext& rDevice) { return m_aGetSizeHdl.Call(rDevice); }
707 
708 public:
709     virtual void insert(int pos, const OUString& rStr, const OUString* pId,
710                         const OUString* pIconName, VirtualDevice* pImageSurface)
711         = 0;
712     virtual void insert_vector(const std::vector<weld::ComboBoxEntry>& rItems, bool bKeepExisting)
713         = 0;
insert_text(int pos,const OUString & rStr)714     void insert_text(int pos, const OUString& rStr)
715     {
716         insert(pos, rStr, nullptr, nullptr, nullptr);
717     }
append_text(const OUString & rStr)718     void append_text(const OUString& rStr) { insert(-1, rStr, nullptr, nullptr, nullptr); }
append(const OUString & rId,const OUString & rStr)719     void append(const OUString& rId, const OUString& rStr)
720     {
721         insert(-1, rStr, &rId, nullptr, nullptr);
722     }
append(const OUString & rId,const OUString & rStr,const OUString & rImage)723     void append(const OUString& rId, const OUString& rStr, const OUString& rImage)
724     {
725         insert(-1, rStr, &rId, &rImage, nullptr);
726     }
append(const OUString & rId,const OUString & rStr,VirtualDevice & rImage)727     void append(const OUString& rId, const OUString& rStr, VirtualDevice& rImage)
728     {
729         insert(-1, rStr, &rId, nullptr, &rImage);
730     }
731     virtual void insert_separator(int pos, const OUString& rId) = 0;
append_separator(const OUString & rId)732     void append_separator(const OUString& rId) { insert_separator(-1, rId); }
733 
734     virtual int get_count() const = 0;
735     virtual void make_sorted() = 0;
736     virtual void clear() = 0;
737 
738     //by index
739     virtual int get_active() const = 0;
740     virtual void set_active(int pos) = 0;
741     virtual void remove(int pos) = 0;
742 
743     //by text
744     virtual OUString get_active_text() const = 0;
set_active_text(const OUString & rStr)745     void set_active_text(const OUString& rStr) { set_active(find_text(rStr)); }
746     virtual OUString get_text(int pos) const = 0;
747     virtual int find_text(const OUString& rStr) const = 0;
remove_text(const OUString & rText)748     void remove_text(const OUString& rText) { remove(find_text(rText)); }
749 
750     //by id
751     virtual OUString get_active_id() const = 0;
752     virtual void set_active_id(const OUString& rStr) = 0;
753     virtual OUString get_id(int pos) const = 0;
754     virtual void set_id(int row, const OUString& rId) = 0;
755     virtual int find_id(const OUString& rId) const = 0;
remove_id(const OUString & rId)756     void remove_id(const OUString& rId) { remove(find_id(rId)); }
757 
758     /* m_aChangeHdl is called when the active item is changed. The can be due
759        to the user selecting a different item from the list or while typing
760        into the entry of a combo box with an entry.
761 
762        Use changed_by_direct_pick() to discover whether an item was actually explicitly
763        selected, e.g. from the menu.
764      */
connect_changed(const Link<ComboBox &,void> & rLink)765     void connect_changed(const Link<ComboBox&, void>& rLink) { m_aChangeHdl = rLink; }
766 
767     virtual bool changed_by_direct_pick() const = 0;
768 
connect_popup_toggled(const Link<ComboBox &,void> & rLink)769     virtual void connect_popup_toggled(const Link<ComboBox&, void>& rLink)
770     {
771         m_aPopupToggledHdl = rLink;
772     }
773 
774     //entry related
775     virtual bool has_entry() const = 0;
776     virtual void set_entry_message_type(EntryMessageType eType) = 0;
777     virtual void set_entry_text(const OUString& rStr) = 0;
778     virtual void set_entry_width_chars(int nChars) = 0;
779     virtual void set_entry_max_length(int nChars) = 0;
780     virtual void select_entry_region(int nStartPos, int nEndPos) = 0;
781     virtual bool get_entry_selection_bounds(int& rStartPos, int& rEndPos) = 0;
782     virtual void set_entry_completion(bool bEnable, bool bCaseSensitive = false) = 0;
783     virtual void set_entry_placeholder_text(const OUString& rText) = 0;
784     virtual void set_entry_editable(bool bEditable) = 0;
785     virtual void cut_entry_clipboard() = 0;
786     virtual void copy_entry_clipboard() = 0;
787     virtual void paste_entry_clipboard() = 0;
788 
789     // font size is in points, not pixels, e.g. see Window::[G]etPointFont
790     virtual void set_font(const vcl::Font& rFont) = 0;
791 
792     // font size is in points, not pixels, e.g. see Window::[G]etPointFont
793     virtual void set_entry_font(const vcl::Font& rFont) = 0;
794     virtual vcl::Font get_entry_font() = 0;
795 
796     virtual bool get_popup_shown() const = 0;
797 
connect_entry_insert_text(const Link<OUString &,bool> & rLink)798     void connect_entry_insert_text(const Link<OUString&, bool>& rLink)
799     {
800         m_aEntryInsertTextHdl = rLink;
801     }
802 
803     // callback returns true to indicated no further processing of activate wanted
connect_entry_activate(const Link<ComboBox &,bool> & rLink)804     void connect_entry_activate(const Link<ComboBox&, bool>& rLink) { m_aEntryActivateHdl = rLink; }
805 
save_value()806     void save_value() { m_sSavedValue = get_active_text(); }
get_saved_value() const807     OUString const& get_saved_value() const { return m_sSavedValue; }
get_value_changed_from_saved() const808     bool get_value_changed_from_saved() const { return m_sSavedValue != get_active_text(); }
809 
810     // for custom rendering a row
connect_custom_get_size(const Link<vcl::RenderContext &,Size> & rLink)811     void connect_custom_get_size(const Link<vcl::RenderContext&, Size>& rLink)
812     {
813         m_aGetSizeHdl = rLink;
814     }
connect_custom_render(const Link<render_args,void> & rLink)815     void connect_custom_render(const Link<render_args, void>& rLink) { m_aRenderHdl = rLink; }
816     // call set_custom_renderer after setting custom callbacks
817     virtual void set_custom_renderer(bool bOn) = 0;
818     // create a virtual device compatible with the device passed in render_args wrt alpha
819     virtual VclPtr<VirtualDevice> create_render_virtual_device() const = 0;
820     // set a sub menu for a entry, only works with custom rendering
821     virtual void set_item_menu(const OString& rIdent, weld::Menu* pMenu) = 0;
822     // get the width needed to show the menu launcher in a custom row
823     virtual int get_menu_button_width() const = 0;
824 
825     // for mru support
826     virtual int get_max_mru_count() const = 0;
827     virtual void set_max_mru_count(int nCount) = 0;
828     virtual OUString get_mru_entries() const = 0;
829     virtual void set_mru_entries(const OUString& rEntries) = 0;
830 };
831 
832 enum class ColumnToggleType
833 {
834     Check,
835     Radio
836 };
837 
838 class VCL_DLLPUBLIC TreeIter
839 {
840 private:
841     TreeIter(const TreeIter&) = delete;
842     TreeIter& operator=(const TreeIter&) = delete;
843 
844 public:
TreeIter()845     TreeIter() {}
846     virtual bool equal(const TreeIter& rOther) const = 0;
~TreeIter()847     virtual ~TreeIter() {}
848 };
849 
850 /* Model column indexes are considered to begin at 0, but with special columns
851    before index 0. A expander image column (and an additional optional toggle
852    button column when enable_toggle_buttons is used). Column index -1 is
853    reserved to access those columns.
854 */
855 class VCL_DLLPUBLIC TreeView : virtual public Widget
856 {
857     friend class ::LOKTrigger;
858 
859 public:
860     typedef std::pair<const TreeIter&, int> iter_col;
861     typedef std::pair<const TreeIter&, OUString> iter_string;
862     // OUString is the id of the row, it may be null to measure the height of a generic line
863     typedef std::pair<vcl::RenderContext&, const OUString&> get_size_args;
864     typedef std::tuple<vcl::RenderContext&, const tools::Rectangle&, bool, const OUString&>
865         render_args;
866 
867 private:
868     OUString m_sSavedValue;
869 
870 protected:
871     Link<TreeView&, void> m_aChangeHdl;
872     Link<TreeView&, bool> m_aRowActivatedHdl;
873     Link<int, void> m_aColumnClickedHdl;
874     Link<const iter_col&, void> m_aRadioToggleHdl;
875     Link<const TreeIter&, bool> m_aEditingStartedHdl;
876     Link<const iter_string&, bool> m_aEditingDoneHdl;
877     // if handler returns false, the expansion of the row is refused
878     Link<const TreeIter&, bool> m_aExpandingHdl;
879     // if handler returns false, the collapse of the row is refused
880     Link<const TreeIter&, bool> m_aCollapsingHdl;
881     Link<TreeView&, void> m_aVisibleRangeChangedHdl;
882     Link<TreeView&, void> m_aModelChangedHdl;
883     // if handler returns true, then menu has been show and event is consumed
884     Link<const CommandEvent&, bool> m_aPopupMenuHdl;
885     // if handler returns true, drag is disallowed, consumer can change bool
886     // arg to false to disable the treeview default dnd icon
887     Link<bool&, bool> m_aDragBeginHdl;
888     std::function<int(const weld::TreeIter&, const weld::TreeIter&)> m_aCustomSort;
889 
890 protected:
signal_changed()891     void signal_changed() { m_aChangeHdl.Call(*this); }
signal_row_activated()892     bool signal_row_activated() { return m_aRowActivatedHdl.Call(*this); }
signal_column_clicked(int nColumn)893     void signal_column_clicked(int nColumn) { m_aColumnClickedHdl.Call(nColumn); }
signal_expanding(const TreeIter & rIter)894     bool signal_expanding(const TreeIter& rIter)
895     {
896         return !m_aExpandingHdl.IsSet() || m_aExpandingHdl.Call(rIter);
897     }
signal_collapsing(const TreeIter & rIter)898     bool signal_collapsing(const TreeIter& rIter)
899     {
900         return !m_aCollapsingHdl.IsSet() || m_aCollapsingHdl.Call(rIter);
901     }
signal_visible_range_changed()902     void signal_visible_range_changed() { m_aVisibleRangeChangedHdl.Call(*this); }
signal_model_changed()903     void signal_model_changed() { m_aModelChangedHdl.Call(*this); }
904 
signal_toggled(const iter_col & rIterCol)905     void signal_toggled(const iter_col& rIterCol) { m_aRadioToggleHdl.Call(rIterCol); }
906 
signal_editing_started(const TreeIter & rIter)907     bool signal_editing_started(const TreeIter& rIter) { return m_aEditingStartedHdl.Call(rIter); }
908 
signal_editing_done(const iter_string & rIterText)909     bool signal_editing_done(const iter_string& rIterText)
910     {
911         return m_aEditingDoneHdl.Call(rIterText);
912     }
913 
914     Link<const TreeIter&, OUString> m_aQueryTooltipHdl;
signal_query_tooltip(const TreeIter & rIter)915     OUString signal_query_tooltip(const TreeIter& rIter) { return m_aQueryTooltipHdl.Call(rIter); }
916 
917     Link<render_args, void> m_aRenderHdl;
signal_custom_render(vcl::RenderContext & rDevice,const tools::Rectangle & rRect,bool bSelected,const OUString & rId)918     void signal_custom_render(vcl::RenderContext& rDevice, const tools::Rectangle& rRect,
919                               bool bSelected, const OUString& rId)
920     {
921         m_aRenderHdl.Call(render_args(rDevice, rRect, bSelected, rId));
922     }
923 
924     Link<get_size_args, Size> m_aGetSizeHdl;
signal_custom_get_size(vcl::RenderContext & rDevice,const OUString & rId)925     Size signal_custom_get_size(vcl::RenderContext& rDevice, const OUString& rId)
926     {
927         return m_aGetSizeHdl.Call(get_size_args(rDevice, rId));
928     }
929 
930 public:
connect_query_tooltip(const Link<const TreeIter &,OUString> & rLink)931     virtual void connect_query_tooltip(const Link<const TreeIter&, OUString>& rLink)
932     {
933         assert(!m_aQueryTooltipHdl.IsSet() || !rLink.IsSet());
934         m_aQueryTooltipHdl = rLink;
935     }
936 
937     // see 'expanding on-demand node details' for bChildrenOnDemand of true
938     virtual void insert(const TreeIter* pParent, int pos, const OUString* pStr, const OUString* pId,
939                         const OUString* pIconName, VirtualDevice* pImageSurface,
940                         bool bChildrenOnDemand, TreeIter* pRet)
941         = 0;
942 
insert(int nRow,TreeIter * pRet=nullptr)943     void insert(int nRow, TreeIter* pRet = nullptr)
944     {
945         insert(nullptr, nRow, nullptr, nullptr, nullptr, nullptr, false, pRet);
946     }
947 
append(TreeIter * pRet=nullptr)948     void append(TreeIter* pRet = nullptr) { insert(-1, pRet); }
949 
insert(int pos,const OUString & rStr,const OUString * pId,const OUString * pIconName,VirtualDevice * pImageSurface)950     void insert(int pos, const OUString& rStr, const OUString* pId, const OUString* pIconName,
951                 VirtualDevice* pImageSurface)
952     {
953         insert(nullptr, pos, &rStr, pId, pIconName, pImageSurface, false, nullptr);
954     }
insert_text(int pos,const OUString & rStr)955     void insert_text(int pos, const OUString& rStr)
956     {
957         insert(nullptr, pos, &rStr, nullptr, nullptr, nullptr, false, nullptr);
958     }
append_text(const OUString & rStr)959     void append_text(const OUString& rStr)
960     {
961         insert(nullptr, -1, &rStr, nullptr, nullptr, nullptr, false, nullptr);
962     }
append(const OUString & rId,const OUString & rStr)963     void append(const OUString& rId, const OUString& rStr)
964     {
965         insert(nullptr, -1, &rStr, &rId, nullptr, nullptr, false, nullptr);
966     }
append(const OUString & rId,const OUString & rStr,const OUString & rImage)967     void append(const OUString& rId, const OUString& rStr, const OUString& rImage)
968     {
969         insert(nullptr, -1, &rStr, &rId, &rImage, nullptr, false, nullptr);
970     }
append(const TreeIter * pParent,const OUString & rStr)971     void append(const TreeIter* pParent, const OUString& rStr)
972     {
973         insert(pParent, -1, &rStr, nullptr, nullptr, nullptr, false, nullptr);
974     }
975 
976     virtual void insert_separator(int pos, const OUString& rId) = 0;
append_separator(const OUString & rId)977     void append_separator(const OUString& rId) { insert_separator(-1, rId); }
978 
connect_changed(const Link<TreeView &,void> & rLink)979     void connect_changed(const Link<TreeView&, void>& rLink) { m_aChangeHdl = rLink; }
980 
981     /* A row is "activated" when the user double clicks a treeview row. It may
982        also be emitted when a row is selected and Space or Enter is pressed.
983 
984        a return of "true" means the activation has been handled, a "false" propagates
985        the activation to the default handler which expands/collapses the row, if possible.
986     */
connect_row_activated(const Link<TreeView &,bool> & rLink)987     void connect_row_activated(const Link<TreeView&, bool>& rLink) { m_aRowActivatedHdl = rLink; }
988 
989     // Argument is a pair of iter, col describing the toggled node
connect_toggled(const Link<const iter_col &,void> & rLink)990     void connect_toggled(const Link<const iter_col&, void>& rLink) { m_aRadioToggleHdl = rLink; }
991 
connect_column_clicked(const Link<int,void> & rLink)992     void connect_column_clicked(const Link<int, void>& rLink) { m_aColumnClickedHdl = rLink; }
connect_model_changed(const Link<TreeView &,void> & rLink)993     void connect_model_changed(const Link<TreeView&, void>& rLink) { m_aModelChangedHdl = rLink; }
994 
995     virtual OUString get_selected_text() const = 0;
996     virtual OUString get_selected_id() const = 0;
997 
998     // call before inserting any content and connecting to toggle signals,
999     // an pre-inserted checkbutton column will exist at the start of every row
1000     // inserted after this call which can be accessed with col index -1
1001     virtual void enable_toggle_buttons(ColumnToggleType eType) = 0;
1002 
1003     virtual void set_clicks_to_toggle(int nToggleBehavior) = 0;
1004 
1005     //by index
1006     virtual int get_selected_index() const = 0;
1007     //Don't select when frozen, select after thaw. Note selection doesn't survive a freeze.
1008     virtual void select(int pos) = 0;
1009     virtual void unselect(int pos) = 0;
1010     virtual void remove(int pos) = 0;
1011     // col index -1 gets the first text column
1012     virtual OUString get_text(int row, int col = -1) const = 0;
1013     // col index -1 sets the first text column
1014     virtual void set_text(int row, const OUString& rText, int col = -1) = 0;
1015     // col index -1 sets the first text column
1016     virtual void set_sensitive(int row, bool bSensitive, int col = -1) = 0;
1017     virtual void set_id(int row, const OUString& rId) = 0;
1018     // col index -1 sets the expander toggle, enable_toggle_buttons must have been called to create that column
1019     virtual void set_toggle(int row, TriState eState, int col = -1) = 0;
1020     // col index -1 gets the expander toggle, enable_toggle_buttons must have been called to create that column
1021     virtual TriState get_toggle(int row, int col = -1) const = 0;
1022     // col index -1 sets the expander image
1023     virtual void set_image(int row, const OUString& rImage, int col = -1) = 0;
1024     // col index -1 sets the expander image
1025     virtual void set_image(int row, VirtualDevice& rImage, int col = -1) = 0;
1026     // col index -1 sets the expander image
1027     virtual void set_image(int row, const css::uno::Reference<css::graphic::XGraphic>& rImage,
1028                            int col = -1)
1029         = 0;
1030     virtual void set_text_emphasis(int row, bool bOn, int col) = 0;
1031     virtual bool get_text_emphasis(int row, int col) const = 0;
1032     virtual void set_text_align(int row, double fAlign, int col) = 0;
1033     virtual void swap(int pos1, int pos2) = 0;
1034     virtual std::vector<int> get_selected_rows() const = 0;
1035     virtual void set_font_color(int pos, const Color& rColor) = 0;
1036     // scroll to make 'row' visible, this will also expand all parent rows of 'row' as necessary to
1037     // make 'row' visible
1038     virtual void scroll_to_row(int row) = 0;
1039     virtual bool is_selected(int pos) const = 0;
1040     virtual int get_cursor_index() const = 0;
1041     virtual void set_cursor(int pos) = 0;
1042 
1043     //by text
1044     virtual int find_text(const OUString& rText) const = 0;
1045     //Don't select when frozen, select after thaw. Note selection doesn't survive a freeze.
select_text(const OUString & rText)1046     void select_text(const OUString& rText) { select(find_text(rText)); }
remove_text(const OUString & rText)1047     void remove_text(const OUString& rText) { remove(find_text(rText)); }
get_selected_rows_text() const1048     std::vector<OUString> get_selected_rows_text() const
1049     {
1050         std::vector<int> aRows(get_selected_rows());
1051         std::vector<OUString> aRet;
1052         aRet.reserve(aRows.size());
1053         for (auto a : aRows)
1054             aRet.push_back(get_text(a));
1055         return aRet;
1056     }
1057 
1058     //by id
1059     virtual OUString get_id(int pos) const = 0;
1060     virtual int find_id(const OUString& rId) const = 0;
1061     //Don't select when frozen, select after thaw. Note selection doesn't survive a freeze.
select_id(const OUString & rId)1062     void select_id(const OUString& rId) { select(find_id(rId)); }
remove_id(const OUString & rText)1063     void remove_id(const OUString& rText) { remove(find_id(rText)); }
1064 
1065     //via iter
1066     virtual std::unique_ptr<TreeIter> make_iterator(const TreeIter* pOrig = nullptr) const = 0;
1067     virtual void copy_iterator(const TreeIter& rSource, TreeIter& rDest) const = 0;
1068     virtual bool get_selected(TreeIter* pIter) const = 0;
1069     virtual bool get_cursor(TreeIter* pIter) const = 0;
1070     virtual void set_cursor(const TreeIter& rIter) = 0;
1071     virtual bool get_iter_first(TreeIter& rIter) const = 0;
1072     // set iter to point to next node at the current level
1073     virtual bool iter_next_sibling(TreeIter& rIter) const = 0;
1074     // set iter to point to previous node at the current level
1075     virtual bool iter_previous_sibling(TreeIter& rIter) const = 0;
1076     // set iter to point to next node, depth first, then sibling
1077     virtual bool iter_next(TreeIter& rIter) const = 0;
1078     // set iter to point to previous node, sibling first then depth
1079     virtual bool iter_previous(TreeIter& rIter) const = 0;
1080     // set iter to point to first child node
1081     virtual bool iter_children(TreeIter& rIter) const = 0;
iter_nth_sibling(TreeIter & rIter,int nChild) const1082     bool iter_nth_sibling(TreeIter& rIter, int nChild) const
1083     {
1084         bool bRet = true;
1085         for (int i = 0; i < nChild && bRet; ++i)
1086             bRet = iter_next_sibling(rIter);
1087         return bRet;
1088     }
iter_nth_child(TreeIter & rIter,int nChild) const1089     bool iter_nth_child(TreeIter& rIter, int nChild) const
1090     {
1091         if (!iter_children(rIter))
1092             return false;
1093         return iter_nth_sibling(rIter, nChild);
1094     }
1095     virtual bool iter_parent(TreeIter& rIter) const = 0;
1096     virtual int get_iter_depth(const TreeIter& rIter) const = 0;
1097     virtual int get_iter_index_in_parent(const TreeIter& rIter) const = 0;
1098     /* Compares two paths. If a appears before b in a tree, then -1 is returned.
1099        If b appears before a , then 1 is returned. If the two nodes are equal,
1100        then 0 is returned.
1101     */
1102     virtual int iter_compare(const TreeIter& a, const TreeIter& b) const = 0;
1103     virtual bool iter_has_child(const TreeIter& rIter) const = 0;
1104     // returns the number of direct children rIter has
1105     virtual int iter_n_children(const TreeIter& rIter) const = 0;
1106     virtual void remove(const TreeIter& rIter) = 0;
1107     //Don't select when frozen, select after thaw. Note selection doesn't survive a freeze.
1108     virtual void select(const TreeIter& rIter) = 0;
1109     virtual void unselect(const TreeIter& rIter) = 0;
1110     //visually indent this row as if it was at get_iter_depth() + nIndentLevel
1111     virtual void set_extra_row_indent(const TreeIter& rIter, int nIndentLevel) = 0;
1112     // col index -1 sets the first text column
1113     virtual void set_text(const TreeIter& rIter, const OUString& rStr, int col = -1) = 0;
1114     // col index -1 sets the first text column
1115     virtual void set_sensitive(const TreeIter& rIter, bool bSensitive, int col = -1) = 0;
1116     virtual void set_text_emphasis(const TreeIter& rIter, bool bOn, int col) = 0;
1117     virtual bool get_text_emphasis(const TreeIter& rIter, int col) const = 0;
1118     virtual void set_text_align(const TreeIter& rIter, double fAlign, int col) = 0;
1119     // col index -1 sets the expander toggle, enable_toggle_buttons must have been called to create that column
1120     virtual void set_toggle(const TreeIter& rIter, TriState bOn, int col = -1) = 0;
1121     // col index -1 gets the expander toggle, enable_toggle_buttons must have been called to create that column
1122     virtual TriState get_toggle(const TreeIter& rIter, int col = -1) const = 0;
1123     // col index -1 gets the first text column
1124     virtual OUString get_text(const TreeIter& rIter, int col = -1) const = 0;
1125     virtual void set_id(const TreeIter& rIter, const OUString& rId) = 0;
1126     virtual OUString get_id(const TreeIter& rIter) const = 0;
1127     // col index -1 sets the expander image
1128     virtual void set_image(const TreeIter& rIter, const OUString& rImage, int col = -1) = 0;
1129     // col index -1 sets the expander image
1130     virtual void set_image(const TreeIter& rIter, VirtualDevice& rImage, int col = -1) = 0;
1131     // col index -1 sets the expander image
1132     virtual void set_image(const TreeIter& rIter,
1133                            const css::uno::Reference<css::graphic::XGraphic>& rImage, int col = -1)
1134         = 0;
1135     virtual void set_font_color(const TreeIter& rIter, const Color& rColor) = 0;
1136     // scroll to make rIter visible, this will also expand all parent rows of rIter as necessary to
1137     // make rIter visible
1138     virtual void scroll_to_row(const TreeIter& rIter) = 0;
1139     virtual bool is_selected(const TreeIter& rIter) const = 0;
1140 
1141     virtual void move_subtree(TreeIter& rNode, const TreeIter* pNewParent, int nIndexInNewParent)
1142         = 0;
1143 
1144     // call func on each element until func returns true or we run out of elements
1145     virtual void all_foreach(const std::function<bool(TreeIter&)>& func) = 0;
1146     // call func on each selected element until func returns true or we run out of elements
1147     virtual void selected_foreach(const std::function<bool(TreeIter&)>& func) = 0;
1148     // call func on each visible element until func returns true or we run out of elements
1149     virtual void visible_foreach(const std::function<bool(TreeIter&)>& func) = 0;
1150     // clear the children of pParent (whole tree if nullptr),
1151     // then add nSourceCount rows under pParent, call func on each row
1152     // inserted with an arg of the index that this row will be when bulk insert
1153     // ends.
1154     //
1155     // this enables inserting the entries backwards in models where that is faster,
1156     //
1157     // pFixedWidths is optional, when present each matching entry col text
1158     // width will not be measured, and the fixed width used instead. Use
1159     // sparingly because wider text than the fixed width is clipped and cannot
1160     // be scrolled into view horizontally.
1161     virtual void bulk_insert_for_each(int nSourceCount,
1162                                       const std::function<void(TreeIter&, int nSourceIndex)>& func,
1163                                       const weld::TreeIter* pParent = nullptr,
1164                                       const std::vector<int>* pFixedWidths = nullptr)
1165         = 0;
1166 
1167     /* expanding on-demand node details
1168 
1169     When a node is added with children-on-demand (typically via 'insert' with
1170     bChildrenOnDemand of true), then initially in reality the
1171     children-on-demand node is given a 'placeholder' child entry to indicate
1172     the load-on-demand state.
1173 
1174     The 'placeholder' needs to be there for the expander indicator to be
1175     drawn/shown even when there are no "real" entries yet. This child doesn't
1176     exist for the purposes of any of the iterator methods, e.g. iter_has_child
1177     on an on-demand node which hasn't been expanded yet is false. Likewise the
1178     rest of the iterator methods skip over or otherwise ignore that node.
1179 
1180     Normal usage is the user clicks on the expander, the expansion mechanism
1181     removes the 'placeholder' entry (set_children_on_demand(false)) and calls
1182     any installed expanding-callback (installable via connect_expanding) which
1183     has the opportunity to populate the node with children.
1184 
1185     If you decide to directly populate the children of an on-demand node
1186     outside of the expanding-callback then you also need to explicitly remove
1187     the 'placeholder' with set_children_on_demand(false) otherwise the treeview
1188     is in an inconsistent state.  */
1189 
1190     virtual bool get_row_expanded(const TreeIter& rIter) const = 0;
1191     // expand row will first trigger the callback set via connect_expanding before expanding
1192     virtual void expand_row(const TreeIter& rIter) = 0;
1193     // collapse row will first trigger the callback set via connect_collapsing before collapsing
1194     virtual void collapse_row(const TreeIter& rIter) = 0;
1195     // set the empty node to appear as if it has children, true is equivalent
1196     // to 'insert' with a bChildrenOnDemand of true. See notes above.
1197     virtual void set_children_on_demand(const TreeIter& rIter, bool bChildrenOnDemand) = 0;
1198     // return if the node is configured to be populated on-demand
1199     virtual bool get_children_on_demand(const TreeIter& rIter) const = 0;
1200     // set if the expanders are shown or not
1201     virtual void set_show_expanders(bool bShow) = 0;
1202 
connect_expanding(const Link<const TreeIter &,bool> & rLink)1203     void connect_expanding(const Link<const TreeIter&, bool>& rLink) { m_aExpandingHdl = rLink; }
connect_collapsing(const Link<const TreeIter &,bool> & rLink)1204     void connect_collapsing(const Link<const TreeIter&, bool>& rLink) { m_aCollapsingHdl = rLink; }
1205 
1206     // rStartLink returns true to allow editing, false to disallow
1207     // rEndLink returns true to accept the edit, false to reject
connect_editing(const Link<const TreeIter &,bool> & rStartLink,const Link<const iter_string &,bool> & rEndLink)1208     virtual void connect_editing(const Link<const TreeIter&, bool>& rStartLink,
1209                                  const Link<const iter_string&, bool>& rEndLink)
1210     {
1211         assert(rStartLink.IsSet() == rEndLink.IsSet() && "should be both on or both off");
1212         m_aEditingStartedHdl = rStartLink;
1213         m_aEditingDoneHdl = rEndLink;
1214     }
1215 
1216     virtual void start_editing(const weld::TreeIter& rEntry) = 0;
1217     virtual void end_editing() = 0;
1218 
connect_visible_range_changed(const Link<TreeView &,void> & rLink)1219     virtual void connect_visible_range_changed(const Link<TreeView&, void>& rLink)
1220     {
1221         assert(!m_aVisibleRangeChangedHdl.IsSet() || !rLink.IsSet());
1222         m_aVisibleRangeChangedHdl = rLink;
1223     }
1224 
connect_popup_menu(const Link<const CommandEvent &,bool> & rLink)1225     virtual void connect_popup_menu(const Link<const CommandEvent&, bool>& rLink)
1226     {
1227         m_aPopupMenuHdl = rLink;
1228     }
1229 
1230     virtual void enable_drag_source(rtl::Reference<TransferDataContainer>& rTransferrable,
1231                                     sal_uInt8 eDNDConstants)
1232         = 0;
1233 
connect_drag_begin(const Link<bool &,bool> & rLink)1234     void connect_drag_begin(const Link<bool&, bool>& rLink) { m_aDragBeginHdl = rLink; }
1235 
1236     //all of them. Don't select when frozen, select after thaw. Note selection doesn't survive a freeze.
select_all()1237     void select_all() { unselect(-1); }
unselect_all()1238     void unselect_all() { select(-1); }
1239 
1240     // return the number of toplevel nodes
1241     virtual int n_children() const = 0;
1242 
1243     // afterwards, entries will be in default ascending sort order
1244     virtual void make_sorted() = 0;
1245     virtual void make_unsorted() = 0;
1246     virtual bool get_sort_order() const = 0;
1247     virtual void set_sort_order(bool bAscending) = 0;
1248 
1249     // TRUE ascending, FALSE, descending, INDET, neither (off)
1250     virtual void set_sort_indicator(TriState eState, int nColumn) = 0;
1251     virtual TriState get_sort_indicator(int nColumn) const = 0;
1252 
1253     virtual int get_sort_column() const = 0;
1254     virtual void set_sort_column(int nColumn) = 0;
1255 
1256     virtual void
set_sort_func(const std::function<int (const weld::TreeIter &,const weld::TreeIter &)> & func)1257     set_sort_func(const std::function<int(const weld::TreeIter&, const weld::TreeIter&)>& func)
1258     {
1259         m_aCustomSort = func;
1260     }
1261 
1262     virtual void clear() = 0;
1263     virtual int get_height_rows(int nRows) const = 0;
1264 
1265     virtual void columns_autosize() = 0;
1266     virtual void set_column_fixed_widths(const std::vector<int>& rWidths) = 0;
1267     virtual void set_column_editables(const std::vector<bool>& rEditables) = 0;
1268     virtual int get_column_width(int nCol) const = 0;
1269     virtual void set_centered_column(int nCol) = 0;
1270     virtual OUString get_column_title(int nColumn) const = 0;
1271     virtual void set_column_title(int nColumn, const OUString& rTitle) = 0;
1272 
get_checkbox_column_width() const1273     int get_checkbox_column_width() const { return get_approximate_digit_width() * 3 + 6; }
1274 
1275     virtual void set_selection_mode(SelectionMode eMode) = 0;
1276     virtual int count_selected_rows() const = 0;
1277     // remove the selected nodes
1278     virtual void remove_selection() = 0;
1279 
1280     virtual void vadjustment_set_value(int value) = 0;
1281     virtual int vadjustment_get_value() const = 0;
1282 
save_value()1283     void save_value() { m_sSavedValue = get_selected_text(); }
get_saved_value() const1284     OUString const& get_saved_value() const { return m_sSavedValue; }
get_value_changed_from_saved() const1285     bool get_value_changed_from_saved() const { return m_sSavedValue != get_selected_text(); }
1286 
1287     // for custom rendering a cell
connect_custom_get_size(const Link<get_size_args,Size> & rLink)1288     void connect_custom_get_size(const Link<get_size_args, Size>& rLink) { m_aGetSizeHdl = rLink; }
connect_custom_render(const Link<render_args,void> & rLink)1289     void connect_custom_render(const Link<render_args, void>& rLink) { m_aRenderHdl = rLink; }
1290     // call set_column_custom_renderer after setting custom callbacks
1291     virtual void set_column_custom_renderer(int nColumn, bool bEnable) = 0;
1292     // redraw all rows, typically only useful with custom rendering to redraw due to external
1293     // state change
1294     virtual void queue_draw() = 0;
1295 
1296     /* with bDnDMode false simply return the row under the point
1297      *
1298      * with bDnDMode true:
1299      * a) return the row which should be dropped on, which may
1300      *    be different from the row the mouse is over in some backends where
1301      *    positioning the mouse on the bottom half of a row indicates to drop
1302      *    after the row
1303      * b) dnd highlight the dest row
1304      */
1305     virtual bool get_dest_row_at_pos(const Point& rPos, weld::TreeIter* pResult, bool bDnDMode) = 0;
1306     virtual void unset_drag_dest_row() = 0;
1307     virtual tools::Rectangle get_row_area(const weld::TreeIter& rIter) const = 0;
1308     // for dragging and dropping between TreeViews, return the active source
1309     virtual TreeView* get_drag_source() const = 0;
1310 
1311     using Widget::set_sensitive;
1312 };
1313 
1314 class VCL_DLLPUBLIC IconView : virtual public Widget
1315 {
1316     friend class ::LOKTrigger;
1317 
1318 private:
1319     OUString m_sSavedValue;
1320 
1321 protected:
1322     Link<IconView&, void> m_aSelectionChangeHdl;
1323     Link<IconView&, bool> m_aItemActivatedHdl;
1324     Link<const CommandEvent&, bool> m_aCommandHdl;
1325 
signal_selection_changed()1326     void signal_selection_changed() { m_aSelectionChangeHdl.Call(*this); }
signal_item_activated()1327     bool signal_item_activated() { return m_aItemActivatedHdl.Call(*this); }
1328 
1329 public:
1330     virtual void insert(int pos, const OUString* pStr, const OUString* pId,
1331                         const OUString* pIconName, TreeIter* pRet)
1332         = 0;
1333 
1334     virtual void insert(int pos, const OUString* pStr, const OUString* pId,
1335                         const VirtualDevice* pIcon, TreeIter* pRet)
1336         = 0;
1337 
append(const OUString & rId,const OUString & rStr,const OUString & rImage)1338     void append(const OUString& rId, const OUString& rStr, const OUString& rImage)
1339     {
1340         insert(-1, &rStr, &rId, &rImage, nullptr);
1341     }
1342 
append(const OUString & rId,const OUString & rStr,const VirtualDevice * pImage)1343     void append(const OUString& rId, const OUString& rStr, const VirtualDevice* pImage)
1344     {
1345         insert(-1, &rStr, &rId, pImage, nullptr);
1346     }
1347 
connect_selection_changed(const Link<IconView &,void> & rLink)1348     void connect_selection_changed(const Link<IconView&, void>& rLink)
1349     {
1350         m_aSelectionChangeHdl = rLink;
1351     }
1352 
1353     /* A row is "activated" when the user double clicks a treeview row. It may
1354        also be emitted when a row is selected and Space or Enter is pressed.
1355 
1356        a return of "true" means the activation has been handled, a "false" propagates
1357        the activation to the default handler which expands/collapses the row, if possible.
1358     */
connect_item_activated(const Link<IconView &,bool> & rLink)1359     void connect_item_activated(const Link<IconView&, bool>& rLink) { m_aItemActivatedHdl = rLink; }
1360 
connect_command(const Link<const CommandEvent &,bool> & rLink)1361     void connect_command(const Link<const CommandEvent&, bool>& rLink) { m_aCommandHdl = rLink; }
1362 
1363     virtual OUString get_selected_id() const = 0;
1364 
1365     virtual void clear() = 0;
1366 
1367     virtual int count_selected_items() const = 0;
1368 
1369     virtual OUString get_selected_text() const = 0;
1370 
1371     //by index. Don't select when frozen, select after thaw. Note selection doesn't survive a freeze.
1372     virtual void select(int pos) = 0;
1373     virtual void unselect(int pos) = 0;
1374 
1375     //via iter
1376     virtual std::unique_ptr<TreeIter> make_iterator(const TreeIter* pOrig = nullptr) const = 0;
1377     virtual bool get_selected(TreeIter* pIter) const = 0;
1378     virtual bool get_cursor(TreeIter* pIter) const = 0;
1379     virtual void set_cursor(const TreeIter& rIter) = 0;
1380     virtual bool get_iter_first(TreeIter& rIter) const = 0;
1381     virtual OUString get_id(const TreeIter& rIter) const = 0;
1382     virtual void scroll_to_item(const TreeIter& rIter) = 0;
1383 
1384     // call func on each selected element until func returns true or we run out of elements
1385     virtual void selected_foreach(const std::function<bool(TreeIter&)>& func) = 0;
1386 
1387     //all of them. Don't select when frozen, select after thaw. Note selection doesn't survive a freeze.
select_all()1388     void select_all() { unselect(-1); }
unselect_all()1389     void unselect_all() { select(-1); }
1390 
1391     // return the number of toplevel nodes
1392     virtual int n_children() const = 0;
1393 
save_value()1394     void save_value() { m_sSavedValue = get_selected_text(); }
get_saved_value() const1395     OUString const& get_saved_value() const { return m_sSavedValue; }
get_value_changed_from_saved() const1396     bool get_value_changed_from_saved() const { return m_sSavedValue != get_selected_text(); }
1397 };
1398 
1399 class VCL_DLLPUBLIC Button : virtual public Widget
1400 {
1401     friend class ::LOKTrigger;
1402 
1403 protected:
1404     Link<Button&, void> m_aClickHdl;
1405 
signal_clicked()1406     void signal_clicked() { m_aClickHdl.Call(*this); }
1407 
1408 public:
1409     virtual void set_label(const OUString& rText) = 0;
1410     // pDevice, the image for the button, or nullptr to unset
1411     virtual void set_image(VirtualDevice* pDevice) = 0;
1412     virtual void set_image(const css::uno::Reference<css::graphic::XGraphic>& rImage) = 0;
1413     virtual void set_from_icon_name(const OUString& rIconName) = 0;
1414     virtual OUString get_label() const = 0;
clicked()1415     void clicked() { signal_clicked(); }
1416 
1417     // font size is in points, not pixels, e.g. see Window::[G]etPointFont
1418     virtual void set_font(const vcl::Font& rFont) = 0;
1419 
1420     /* Sometimes, a widget should behave like a button (activate on click,
1421        accept keyboard focus, etc), but look entirely different.
1422 
1423        pDevice, the custom look to use, or nullptr to unset.
1424 
1425        Typically doing this is ill advised. Consider using
1426        set_accessible_name if you do. */
1427     virtual void set_custom_button(VirtualDevice* pDevice) = 0;
1428 
connect_clicked(const Link<Button &,void> & rLink)1429     void connect_clicked(const Link<Button&, void>& rLink) { m_aClickHdl = rLink; }
1430 };
1431 
1432 class VCL_DLLPUBLIC Toggleable : virtual public Widget
1433 {
1434     friend class ::LOKTrigger;
1435 
1436 protected:
1437     Link<Toggleable&, void> m_aToggleHdl;
1438     TriState m_eSavedValue = TRISTATE_FALSE;
1439 
signal_toggled()1440     void signal_toggled() { m_aToggleHdl.Call(*this); }
1441 
1442 public:
1443     virtual void set_active(bool active) = 0;
1444     virtual bool get_active() const = 0;
1445 
1446     virtual void set_inconsistent(bool inconsistent) = 0;
1447     virtual bool get_inconsistent() const = 0;
1448 
get_state() const1449     TriState get_state() const
1450     {
1451         if (get_inconsistent())
1452             return TRISTATE_INDET;
1453         else if (get_active())
1454             return TRISTATE_TRUE;
1455         return TRISTATE_FALSE;
1456     }
1457 
set_state(TriState eState)1458     void set_state(TriState eState)
1459     {
1460         switch (eState)
1461         {
1462             case TRISTATE_INDET:
1463                 set_inconsistent(true);
1464                 break;
1465             case TRISTATE_TRUE:
1466                 set_inconsistent(false);
1467                 set_active(true);
1468                 break;
1469             case TRISTATE_FALSE:
1470                 set_inconsistent(false);
1471                 set_active(false);
1472                 break;
1473         }
1474     }
1475 
save_state()1476     void save_state() { m_eSavedValue = get_state(); }
get_saved_state() const1477     TriState get_saved_state() const { return m_eSavedValue; }
get_state_changed_from_saved() const1478     bool get_state_changed_from_saved() const { return m_eSavedValue != get_state(); }
1479 
connect_toggled(const Link<Toggleable &,void> & rLink)1480     virtual void connect_toggled(const Link<Toggleable&, void>& rLink) { m_aToggleHdl = rLink; }
1481 };
1482 
1483 class VCL_DLLPUBLIC ToggleButton : virtual public Button, virtual public Toggleable
1484 {
1485     friend class ::LOKTrigger;
1486 };
1487 
1488 struct VCL_DLLPUBLIC TriStateEnabled
1489 {
1490     TriState eState;
1491     bool bTriStateEnabled;
TriStateEnabledweld::TriStateEnabled1492     TriStateEnabled()
1493         : eState(TRISTATE_INDET)
1494         , bTriStateEnabled(true)
1495     {
1496     }
1497     void ButtonToggled(Toggleable& rToggle);
1498 };
1499 
1500 class VCL_DLLPUBLIC MenuButton : virtual public ToggleButton
1501 {
1502 protected:
1503     Link<const OString&, void> m_aSelectHdl;
1504 
signal_selected(const OString & rIdent)1505     void signal_selected(const OString& rIdent) { m_aSelectHdl.Call(rIdent); }
1506 
1507 public:
connect_selected(const Link<const OString &,void> & rLink)1508     void connect_selected(const Link<const OString&, void>& rLink) { m_aSelectHdl = rLink; }
1509 
1510     virtual void insert_item(int pos, const OUString& rId, const OUString& rStr,
1511                              const OUString* pIconName, VirtualDevice* pImageSurface,
1512                              TriState eCheckRadioFalse)
1513         = 0;
append_item(const OUString & rId,const OUString & rStr)1514     void append_item(const OUString& rId, const OUString& rStr)
1515     {
1516         insert_item(-1, rId, rStr, nullptr, nullptr, TRISTATE_INDET);
1517     }
append_item_check(const OUString & rId,const OUString & rStr)1518     void append_item_check(const OUString& rId, const OUString& rStr)
1519     {
1520         insert_item(-1, rId, rStr, nullptr, nullptr, TRISTATE_TRUE);
1521     }
append_item_radio(const OUString & rId,const OUString & rStr)1522     void append_item_radio(const OUString& rId, const OUString& rStr)
1523     {
1524         insert_item(-1, rId, rStr, nullptr, nullptr, TRISTATE_FALSE);
1525     }
append_item(const OUString & rId,const OUString & rStr,const OUString & rImage)1526     void append_item(const OUString& rId, const OUString& rStr, const OUString& rImage)
1527     {
1528         insert_item(-1, rId, rStr, &rImage, nullptr, TRISTATE_INDET);
1529     }
append_item(const OUString & rId,const OUString & rStr,VirtualDevice & rImage)1530     void append_item(const OUString& rId, const OUString& rStr, VirtualDevice& rImage)
1531     {
1532         insert_item(-1, rId, rStr, nullptr, &rImage, TRISTATE_INDET);
1533     }
1534     virtual void insert_separator(int pos, const OUString& rId) = 0;
append_separator(const OUString & rId)1535     void append_separator(const OUString& rId) { insert_separator(-1, rId); }
1536     virtual void remove_item(const OString& rId) = 0;
1537     virtual void clear() = 0;
1538     virtual void set_item_sensitive(const OString& rIdent, bool bSensitive) = 0;
1539     virtual void set_item_active(const OString& rIdent, bool bActive) = 0;
1540     virtual void set_item_label(const OString& rIdent, const OUString& rLabel) = 0;
1541     virtual OUString get_item_label(const OString& rIdent) const = 0;
1542     virtual void set_item_help_id(const OString& rIdent, const OString& rHelpId) = 0;
1543     virtual void set_item_visible(const OString& rIdent, bool bVisible) = 0;
1544     virtual OString get_item_help_id(const OString& rIdent) const = 0;
1545 
1546     virtual void set_popover(weld::Widget* pPopover) = 0;
1547 };
1548 
1549 // Similar to a MenuButton except it is split into two parts, a toggle
1550 // button at the start and a menubutton at the end
1551 class VCL_DLLPUBLIC MenuToggleButton : virtual public MenuButton
1552 {
1553 };
1554 
1555 class VCL_DLLPUBLIC CheckButton : virtual public Toggleable
1556 {
1557 public:
1558     virtual void set_label(const OUString& rText) = 0;
1559     virtual OUString get_label() const = 0;
1560     virtual void set_label_wrap(bool wrap) = 0;
1561 };
1562 
1563 class VCL_DLLPUBLIC RadioButton : virtual public CheckButton
1564 {
1565 };
1566 
1567 class VCL_DLLPUBLIC LinkButton : virtual public Widget
1568 {
1569 protected:
1570     Link<LinkButton&, bool> m_aActivateLinkHdl;
1571 
signal_activate_link()1572     bool signal_activate_link() { return m_aActivateLinkHdl.Call(*this); }
1573 
1574 public:
1575     virtual void set_label(const OUString& rText) = 0;
1576     virtual OUString get_label() const = 0;
1577     virtual void set_uri(const OUString& rUri) = 0;
1578     virtual OUString get_uri() const = 0;
1579 
connect_activate_link(const Link<LinkButton &,bool> & rLink)1580     void connect_activate_link(const Link<LinkButton&, bool>& rLink) { m_aActivateLinkHdl = rLink; }
1581 };
1582 
1583 class VCL_DLLPUBLIC Scale : virtual public Widget
1584 {
1585 protected:
1586     Link<Scale&, void> m_aValueChangedHdl;
1587 
signal_value_changed()1588     void signal_value_changed() { m_aValueChangedHdl.Call(*this); }
1589 
1590 public:
1591     virtual void set_value(int value) = 0;
1592     virtual int get_value() const = 0;
1593     virtual void set_range(int min, int max) = 0;
1594 
1595     virtual void set_increments(int step, int page) = 0;
1596     virtual void get_increments(int& step, int& page) const = 0;
1597 
connect_value_changed(const Link<Scale &,void> & rLink)1598     void connect_value_changed(const Link<Scale&, void>& rLink) { m_aValueChangedHdl = rLink; }
1599 };
1600 
1601 class VCL_DLLPUBLIC Spinner : virtual public Widget
1602 {
1603 public:
1604     virtual void start() = 0;
1605     virtual void stop() = 0;
1606 };
1607 
1608 class VCL_DLLPUBLIC ProgressBar : virtual public Widget
1609 {
1610 public:
1611     //0-100
1612     virtual void set_percentage(int value) = 0;
1613     virtual OUString get_text() const = 0;
1614     virtual void set_text(const OUString& rText) = 0;
1615 };
1616 
1617 class VCL_DLLPUBLIC Entry : virtual public Widget
1618 {
1619 private:
1620     OUString m_sSavedValue;
1621 
1622 protected:
1623     Link<Entry&, void> m_aChangeHdl;
1624     Link<OUString&, bool> m_aInsertTextHdl;
1625     Link<Entry&, void> m_aCursorPositionHdl;
1626     Link<Entry&, bool> m_aActivateHdl;
1627 
1628     friend class ::LOKTrigger;
1629 
signal_changed()1630     void signal_changed() { m_aChangeHdl.Call(*this); }
signal_cursor_position()1631     void signal_cursor_position() { m_aCursorPositionHdl.Call(*this); }
1632 
1633 public:
1634     virtual void set_text(const OUString& rText) = 0;
1635     virtual OUString get_text() const = 0;
1636     virtual void set_width_chars(int nChars) = 0;
1637     virtual int get_width_chars() const = 0;
1638     // The maximum length of the entry. Use 0 for no maximum
1639     virtual void set_max_length(int nChars) = 0;
1640     // nEndPos can be -1 in order to select all text
1641     virtual void select_region(int nStartPos, int nEndPos) = 0;
1642     // returns true if the selection has nonzero length
1643     virtual bool get_selection_bounds(int& rStartPos, int& rEndPos) = 0;
1644     virtual void replace_selection(const OUString& rText) = 0;
1645     // nCursorPos can be -1 to set to the end
1646     virtual void set_position(int nCursorPos) = 0;
1647     virtual int get_position() const = 0;
1648     virtual void set_editable(bool bEditable) = 0;
1649     virtual bool get_editable() const = 0;
1650     virtual void set_message_type(EntryMessageType eType) = 0;
1651     virtual void set_placeholder_text(const OUString& rText) = 0;
1652 
1653     virtual void set_overwrite_mode(bool bOn) = 0;
1654     virtual bool get_overwrite_mode() const = 0;
1655 
1656     // font size is in points, not pixels, e.g. see Window::[G]etPointFont
1657     virtual void set_font(const vcl::Font& rFont) = 0;
1658 
1659     /*
1660        If you want to set a warning or error state, see set_message_type
1661        instead where, if the toolkit supports it, a specific warning/error
1662        indicator is shown.
1663 
1664        This explicit text color method exists to support rendering the
1665        SvNumberformat color feature.
1666     */
1667     virtual void set_font_color(const Color& rColor) = 0;
1668 
connect_changed(const Link<Entry &,void> & rLink)1669     virtual void connect_changed(const Link<Entry&, void>& rLink) { m_aChangeHdl = rLink; }
connect_insert_text(const Link<OUString &,bool> & rLink)1670     void connect_insert_text(const Link<OUString&, bool>& rLink) { m_aInsertTextHdl = rLink; }
1671     // callback returns true to indicated no further processing of activate wanted
connect_activate(const Link<Entry &,bool> & rLink)1672     void connect_activate(const Link<Entry&, bool>& rLink) { m_aActivateHdl = rLink; }
connect_cursor_position(const Link<Entry &,void> & rLink)1673     virtual void connect_cursor_position(const Link<Entry&, void>& rLink)
1674     {
1675         m_aCursorPositionHdl = rLink;
1676     }
1677 
1678     virtual void cut_clipboard() = 0;
1679     virtual void copy_clipboard() = 0;
1680     virtual void paste_clipboard() = 0;
1681 
1682     virtual void set_alignment(TxtAlign eXAlign) = 0;
1683 
save_value()1684     void save_value() { m_sSavedValue = get_text(); }
get_saved_value() const1685     OUString const& get_saved_value() const { return m_sSavedValue; }
get_value_changed_from_saved() const1686     bool get_value_changed_from_saved() const { return m_sSavedValue != get_text(); }
1687 };
1688 
1689 class VCL_DLLPUBLIC SpinButton : virtual public Entry
1690 {
1691     friend class ::LOKTrigger;
1692 
1693 protected:
1694     Link<SpinButton&, void> m_aValueChangedHdl;
1695     Link<SpinButton&, void> m_aOutputHdl;
1696     Link<int*, bool> m_aInputHdl;
1697 
signal_value_changed()1698     void signal_value_changed() { m_aValueChangedHdl.Call(*this); }
1699 
signal_output()1700     bool signal_output()
1701     {
1702         if (!m_aOutputHdl.IsSet())
1703             return false;
1704         m_aOutputHdl.Call(*this);
1705         return true;
1706     }
1707 
signal_input(int * result)1708     TriState signal_input(int* result)
1709     {
1710         if (!m_aInputHdl.IsSet())
1711             return TRISTATE_INDET;
1712         return m_aInputHdl.Call(result) ? TRISTATE_TRUE : TRISTATE_FALSE;
1713     }
1714 
1715 public:
1716     virtual void set_value(int value) = 0;
1717     virtual int get_value() const = 0;
1718     virtual void set_range(int min, int max) = 0;
1719     virtual void get_range(int& min, int& max) const = 0;
set_min(int min)1720     void set_min(int min)
1721     {
1722         int dummy, max;
1723         get_range(dummy, max);
1724         set_range(min, max);
1725     }
set_max(int max)1726     void set_max(int max)
1727     {
1728         int min, dummy;
1729         get_range(min, dummy);
1730         set_range(min, max);
1731     }
get_min() const1732     int get_min() const
1733     {
1734         int min, dummy;
1735         get_range(min, dummy);
1736         return min;
1737     }
get_max() const1738     int get_max() const
1739     {
1740         int dummy, max;
1741         get_range(dummy, max);
1742         return max;
1743     }
1744     virtual void set_increments(int step, int page) = 0;
1745     virtual void get_increments(int& step, int& page) const = 0;
1746     virtual void set_digits(unsigned int digits) = 0;
1747     virtual unsigned int get_digits() const = 0;
1748 
connect_value_changed(const Link<SpinButton &,void> & rLink)1749     void connect_value_changed(const Link<SpinButton&, void>& rLink) { m_aValueChangedHdl = rLink; }
1750 
connect_output(const Link<SpinButton &,void> & rLink)1751     void connect_output(const Link<SpinButton&, void>& rLink) { m_aOutputHdl = rLink; }
connect_input(const Link<int *,bool> & rLink)1752     void connect_input(const Link<int*, bool>& rLink) { m_aInputHdl = rLink; }
1753 
normalize(int nValue) const1754     int normalize(int nValue) const { return (nValue * Power10(get_digits())); }
1755 
1756     int denormalize(int nValue) const;
1757 
1758     static unsigned int Power10(unsigned int n);
1759 };
1760 
1761 class EntryFormatter;
1762 
1763 // Similar to a SpinButton, but input and output formatting and range/value
1764 // are managed by a more complex Formatter which can support doubles.
1765 class VCL_DLLPUBLIC FormattedSpinButton : virtual public Entry
1766 {
1767 protected:
1768     Link<FormattedSpinButton&, void> m_aValueChangedHdl;
1769 
signal_value_changed()1770     void signal_value_changed() { m_aValueChangedHdl.Call(*this); }
1771 
1772 public:
1773     virtual Formatter& GetFormatter() = 0;
1774     // does not take ownership, and so must be deregistered if pFormatter
1775     // is destroyed
1776     virtual void SetFormatter(weld::EntryFormatter* pFormatter) = 0;
1777 
connect_value_changed(const Link<FormattedSpinButton &,void> & rLink)1778     void connect_value_changed(const Link<FormattedSpinButton&, void>& rLink)
1779     {
1780         m_aValueChangedHdl = rLink;
1781     }
1782 
1783 private:
1784     friend class EntryFormatter;
1785     virtual void sync_range_from_formatter() = 0;
1786     virtual void sync_value_from_formatter() = 0;
1787     virtual void sync_increments_from_formatter() = 0;
1788 };
1789 
1790 class VCL_DLLPUBLIC Image : virtual public Widget
1791 {
1792 public:
1793     virtual void set_from_icon_name(const OUString& rIconName) = 0;
1794     virtual void set_image(VirtualDevice* pDevice) = 0;
1795     virtual void set_image(const css::uno::Reference<css::graphic::XGraphic>& rImage) = 0;
1796 };
1797 
1798 class VCL_DLLPUBLIC Calendar : virtual public Widget
1799 {
1800 protected:
1801     Link<Calendar&, void> m_aSelectedHdl;
1802     Link<Calendar&, void> m_aActivatedHdl;
1803 
signal_selected()1804     void signal_selected() { m_aSelectedHdl.Call(*this); }
signal_activated()1805     void signal_activated() { m_aActivatedHdl.Call(*this); }
1806 
1807 public:
connect_selected(const Link<Calendar &,void> & rLink)1808     void connect_selected(const Link<Calendar&, void>& rLink) { m_aSelectedHdl = rLink; }
connect_activated(const Link<Calendar &,void> & rLink)1809     void connect_activated(const Link<Calendar&, void>& rLink) { m_aActivatedHdl = rLink; }
1810 
1811     virtual void set_date(const Date& rDate) = 0;
1812     virtual Date get_date() const = 0;
1813 };
1814 
1815 // an entry + treeview pair, where the entry autocompletes from the
1816 // treeview list, and selecting something in the list sets the
1817 // entry to that text, i.e. a visually exploded ComboBox
1818 class VCL_DLLPUBLIC EntryTreeView : virtual public ComboBox
1819 {
1820 private:
1821     DECL_DLLPRIVATE_LINK(ClickHdl, weld::TreeView&, void);
1822     DECL_DLLPRIVATE_LINK(ModifyHdl, weld::Entry&, void);
1823     void EntryModifyHdl(const weld::Entry& rEntry);
1824 
1825 protected:
1826     std::unique_ptr<Entry> m_xEntry;
1827     std::unique_ptr<TreeView> m_xTreeView;
1828 
1829 public:
1830     EntryTreeView(std::unique_ptr<Entry> xEntry, std::unique_ptr<TreeView> xTreeView);
1831 
insert_vector(const std::vector<weld::ComboBoxEntry> & rItems,bool bKeepExisting)1832     virtual void insert_vector(const std::vector<weld::ComboBoxEntry>& rItems,
1833                                bool bKeepExisting) override
1834     {
1835         m_xTreeView->freeze();
1836         if (!bKeepExisting)
1837             m_xTreeView->clear();
1838         for (const auto& rItem : rItems)
1839         {
1840             m_xTreeView->insert(-1, rItem.sString, rItem.sId.isEmpty() ? nullptr : &rItem.sId,
1841                                 rItem.sImage.isEmpty() ? nullptr : &rItem.sImage, nullptr);
1842         }
1843         m_xTreeView->thaw();
1844     }
1845 
insert(int pos,const OUString & rStr,const OUString * pId,const OUString * pIconName,VirtualDevice * pImageSurface)1846     virtual void insert(int pos, const OUString& rStr, const OUString* pId,
1847                         const OUString* pIconName, VirtualDevice* pImageSurface) override
1848     {
1849         m_xTreeView->insert(pos, rStr, pId, pIconName, pImageSurface);
1850     }
1851 
get_count() const1852     virtual int get_count() const override { return m_xTreeView->n_children(); }
clear()1853     virtual void clear() override { m_xTreeView->clear(); }
1854 
1855     //by index
get_active() const1856     virtual int get_active() const override { return m_xTreeView->get_selected_index(); }
set_active(int pos)1857     virtual void set_active(int pos) override
1858     {
1859         m_xTreeView->set_cursor(pos);
1860         m_xTreeView->select(pos);
1861         m_xEntry->set_text(m_xTreeView->get_selected_text());
1862     }
remove(int pos)1863     virtual void remove(int pos) override { m_xTreeView->remove(pos); }
1864 
1865     //by text
get_active_text() const1866     virtual OUString get_active_text() const override { return m_xEntry->get_text(); }
get_text(int pos) const1867     virtual OUString get_text(int pos) const override { return m_xTreeView->get_text(pos); }
find_text(const OUString & rStr) const1868     virtual int find_text(const OUString& rStr) const override
1869     {
1870         return m_xTreeView->find_text(rStr);
1871     }
1872 
1873     //by id
get_active_id() const1874     virtual OUString get_active_id() const override { return m_xTreeView->get_selected_id(); }
set_active_id(const OUString & rStr)1875     virtual void set_active_id(const OUString& rStr) override
1876     {
1877         m_xTreeView->select_id(rStr);
1878         m_xEntry->set_text(m_xTreeView->get_selected_text());
1879     }
get_id(int pos) const1880     virtual OUString get_id(int pos) const override { return m_xTreeView->get_id(pos); }
set_id(int pos,const OUString & rId)1881     virtual void set_id(int pos, const OUString& rId) override { m_xTreeView->set_id(pos, rId); }
find_id(const OUString & rId) const1882     virtual int find_id(const OUString& rId) const override { return m_xTreeView->find_id(rId); }
1883 
1884     //entry related
has_entry() const1885     virtual bool has_entry() const override { return true; }
set_entry_message_type(EntryMessageType eType)1886     virtual void set_entry_message_type(EntryMessageType eType) override
1887     {
1888         m_xEntry->set_message_type(eType);
1889     }
set_entry_text(const OUString & rStr)1890     virtual void set_entry_text(const OUString& rStr) override { m_xEntry->set_text(rStr); }
set_entry_width_chars(int nChars)1891     virtual void set_entry_width_chars(int nChars) override { m_xEntry->set_width_chars(nChars); }
set_entry_max_length(int nChars)1892     virtual void set_entry_max_length(int nChars) override { m_xEntry->set_max_length(nChars); }
select_entry_region(int nStartPos,int nEndPos)1893     virtual void select_entry_region(int nStartPos, int nEndPos) override
1894     {
1895         m_xEntry->select_region(nStartPos, nEndPos);
1896     }
1897     //if no text was selected, both rStartPos and rEndPos will be identical
1898     //and false will be returned
get_entry_selection_bounds(int & rStartPos,int & rEndPos)1899     virtual bool get_entry_selection_bounds(int& rStartPos, int& rEndPos) override
1900     {
1901         return m_xEntry->get_selection_bounds(rStartPos, rEndPos);
1902     }
connect_row_activated(const Link<TreeView &,bool> & rLink)1903     void connect_row_activated(const Link<TreeView&, bool>& rLink)
1904     {
1905         m_xTreeView->connect_row_activated(rLink);
1906     }
1907 
get_popup_shown() const1908     virtual bool get_popup_shown() const override { return false; }
1909 
1910     void set_height_request_by_rows(int nRows);
1911 };
1912 
1913 class VCL_DLLPUBLIC MetricSpinButton final
1914 {
1915     FieldUnit m_eSrcUnit;
1916     std::unique_ptr<weld::SpinButton> m_xSpinButton;
1917     Link<MetricSpinButton&, void> m_aValueChangedHdl;
1918 
1919     DECL_LINK(spin_button_value_changed, weld::SpinButton&, void);
1920     DECL_LINK(spin_button_output, weld::SpinButton&, void);
1921     DECL_LINK(spin_button_input, int* result, bool);
1922 
signal_value_changed()1923     void signal_value_changed() { m_aValueChangedHdl.Call(*this); }
1924 
1925     int ConvertValue(int nValue, FieldUnit eInUnit, FieldUnit eOutUnit) const;
1926     OUString format_number(int nValue) const;
1927     void update_width_chars();
1928 
1929 public:
MetricSpinButton(std::unique_ptr<SpinButton> pSpinButton,FieldUnit eSrcUnit)1930     MetricSpinButton(std::unique_ptr<SpinButton> pSpinButton, FieldUnit eSrcUnit)
1931         : m_eSrcUnit(eSrcUnit)
1932         , m_xSpinButton(std::move(pSpinButton))
1933     {
1934         update_width_chars();
1935         m_xSpinButton->connect_output(LINK(this, MetricSpinButton, spin_button_output));
1936         m_xSpinButton->connect_input(LINK(this, MetricSpinButton, spin_button_input));
1937         m_xSpinButton->connect_value_changed(
1938             LINK(this, MetricSpinButton, spin_button_value_changed));
1939         spin_button_output(*m_xSpinButton);
1940     }
1941 
1942     static OUString MetricToString(FieldUnit rUnit);
1943 
get_unit() const1944     FieldUnit get_unit() const { return m_eSrcUnit; }
1945 
1946     void set_unit(FieldUnit eUnit);
1947 
convert_value_to(int nValue,FieldUnit eValueUnit) const1948     int convert_value_to(int nValue, FieldUnit eValueUnit) const
1949     {
1950         return ConvertValue(nValue, m_eSrcUnit, eValueUnit);
1951     }
1952 
convert_value_from(int nValue,FieldUnit eValueUnit) const1953     int convert_value_from(int nValue, FieldUnit eValueUnit) const
1954     {
1955         return ConvertValue(nValue, eValueUnit, m_eSrcUnit);
1956     }
1957 
set_value(int nValue,FieldUnit eValueUnit)1958     void set_value(int nValue, FieldUnit eValueUnit)
1959     {
1960         m_xSpinButton->set_value(convert_value_from(nValue, eValueUnit));
1961     }
1962 
get_value(FieldUnit eDestUnit) const1963     int get_value(FieldUnit eDestUnit) const
1964     {
1965         return convert_value_to(m_xSpinButton->get_value(), eDestUnit);
1966     }
1967 
1968     // typically you only need to call this if set_text (e.g. with "") was
1969     // previously called to display some arbitrary text instead of the
1970     // formatted value and now you want to show it as formatted again
reformat()1971     void reformat() { spin_button_output(*m_xSpinButton); }
1972 
set_range(int min,int max,FieldUnit eValueUnit)1973     void set_range(int min, int max, FieldUnit eValueUnit)
1974     {
1975         min = convert_value_from(min, eValueUnit);
1976         max = convert_value_from(max, eValueUnit);
1977         m_xSpinButton->set_range(min, max);
1978         update_width_chars();
1979     }
1980 
get_range(int & min,int & max,FieldUnit eDestUnit) const1981     void get_range(int& min, int& max, FieldUnit eDestUnit) const
1982     {
1983         m_xSpinButton->get_range(min, max);
1984         min = convert_value_to(min, eDestUnit);
1985         max = convert_value_to(max, eDestUnit);
1986     }
1987 
set_min(int min,FieldUnit eValueUnit)1988     void set_min(int min, FieldUnit eValueUnit)
1989     {
1990         int dummy, max;
1991         get_range(dummy, max, eValueUnit);
1992         set_range(min, max, eValueUnit);
1993     }
1994 
set_max(int max,FieldUnit eValueUnit)1995     void set_max(int max, FieldUnit eValueUnit)
1996     {
1997         int min, dummy;
1998         get_range(min, dummy, eValueUnit);
1999         set_range(min, max, eValueUnit);
2000     }
2001 
get_min(FieldUnit eValueUnit) const2002     int get_min(FieldUnit eValueUnit) const
2003     {
2004         int min, dummy;
2005         get_range(min, dummy, eValueUnit);
2006         return min;
2007     }
2008 
get_max(FieldUnit eValueUnit) const2009     int get_max(FieldUnit eValueUnit) const
2010     {
2011         int dummy, max;
2012         get_range(dummy, max, eValueUnit);
2013         return max;
2014     }
2015 
set_increments(int step,int page,FieldUnit eValueUnit)2016     void set_increments(int step, int page, FieldUnit eValueUnit)
2017     {
2018         step = convert_value_from(step, eValueUnit);
2019         page = convert_value_from(page, eValueUnit);
2020         m_xSpinButton->set_increments(step, page);
2021     }
2022 
get_increments(int & step,int & page,FieldUnit eDestUnit) const2023     void get_increments(int& step, int& page, FieldUnit eDestUnit) const
2024     {
2025         m_xSpinButton->get_increments(step, page);
2026         step = convert_value_to(step, eDestUnit);
2027         page = convert_value_to(page, eDestUnit);
2028     }
2029 
connect_value_changed(const Link<MetricSpinButton &,void> & rLink)2030     void connect_value_changed(const Link<MetricSpinButton&, void>& rLink)
2031     {
2032         m_aValueChangedHdl = rLink;
2033     }
2034 
normalize(int nValue) const2035     int normalize(int nValue) const { return m_xSpinButton->normalize(nValue); }
denormalize(int nValue) const2036     int denormalize(int nValue) const { return m_xSpinButton->denormalize(nValue); }
set_sensitive(bool sensitive)2037     void set_sensitive(bool sensitive) { m_xSpinButton->set_sensitive(sensitive); }
get_sensitive() const2038     bool get_sensitive() const { return m_xSpinButton->get_sensitive(); }
get_visible() const2039     bool get_visible() const { return m_xSpinButton->get_visible(); }
grab_focus()2040     void grab_focus() { m_xSpinButton->grab_focus(); }
has_focus() const2041     bool has_focus() const { return m_xSpinButton->has_focus(); }
show()2042     void show() { m_xSpinButton->show(); }
set_visible(bool bShow)2043     void set_visible(bool bShow) { m_xSpinButton->set_visible(bShow); }
hide()2044     void hide() { m_xSpinButton->hide(); }
2045     void set_digits(unsigned int digits);
set_accessible_name(const OUString & rName)2046     void set_accessible_name(const OUString& rName) { m_xSpinButton->set_accessible_name(rName); }
get_digits() const2047     unsigned int get_digits() const { return m_xSpinButton->get_digits(); }
save_value()2048     void save_value() { m_xSpinButton->save_value(); }
get_value_changed_from_saved() const2049     bool get_value_changed_from_saved() const
2050     {
2051         return m_xSpinButton->get_value_changed_from_saved();
2052     }
set_text(const OUString & rText)2053     void set_text(const OUString& rText) { m_xSpinButton->set_text(rText); }
get_text() const2054     OUString get_text() const { return m_xSpinButton->get_text(); }
set_size_request(int nWidth,int nHeight)2055     void set_size_request(int nWidth, int nHeight)
2056     {
2057         m_xSpinButton->set_size_request(nWidth, nHeight);
2058     }
get_size_request() const2059     Size get_size_request() const { return m_xSpinButton->get_size_request(); }
get_preferred_size() const2060     Size get_preferred_size() const { return m_xSpinButton->get_preferred_size(); }
connect_focus_in(const Link<Widget &,void> & rLink)2061     void connect_focus_in(const Link<Widget&, void>& rLink)
2062     {
2063         m_xSpinButton->connect_focus_in(rLink);
2064     }
connect_focus_out(const Link<Widget &,void> & rLink)2065     void connect_focus_out(const Link<Widget&, void>& rLink)
2066     {
2067         m_xSpinButton->connect_focus_out(rLink);
2068     }
get_buildable_name() const2069     OString get_buildable_name() const { return m_xSpinButton->get_buildable_name(); }
set_help_id(const OString & rName)2070     void set_help_id(const OString& rName) { m_xSpinButton->set_help_id(rName); }
set_position(int nCursorPos)2071     void set_position(int nCursorPos) { m_xSpinButton->set_position(nCursorPos); }
2072     // set the width of the underlying widget in characters, this setting is
2073     // invalidated when changing the units, range or digits, so to have effect
2074     // must come after changing those values
set_width_chars(int nChars)2075     void set_width_chars(int nChars) { m_xSpinButton->set_width_chars(nChars); }
get_width_chars() const2076     int get_width_chars() const { return m_xSpinButton->get_width_chars(); }
get_widget()2077     weld::SpinButton& get_widget() { return *m_xSpinButton; }
2078 };
2079 
2080 enum class LabelType
2081 {
2082     Normal,
2083     Warning,
2084     Error,
2085     Title, // this is intended to be used against the background set by set_title_background
2086 };
2087 
2088 class VCL_DLLPUBLIC Label : virtual public Widget
2089 {
2090 public:
2091     virtual void set_label(const OUString& rText) = 0;
2092     virtual OUString get_label() const = 0;
2093     virtual void set_mnemonic_widget(Widget* pTarget) = 0;
2094     // font size is in points, not pixels, e.g. see Window::[G]etPointFont
2095     virtual void set_font(const vcl::Font& rFont) = 0;
2096     virtual void set_label_type(LabelType eType) = 0;
2097     /*
2098        If you want to set a warning or error state, see set_label_type
2099        instead.
2100     */
2101     virtual void set_font_color(const Color& rColor) = 0;
2102 };
2103 
2104 class VCL_DLLPUBLIC TextView : virtual public Widget
2105 {
2106     friend class ::LOKTrigger;
2107 
2108 private:
2109     OUString m_sSavedValue;
2110 
2111 protected:
2112     Link<TextView&, void> m_aChangeHdl;
2113     Link<TextView&, void> m_aVChangeHdl;
2114     Link<TextView&, void> m_aCursorPositionHdl;
2115 
signal_changed()2116     void signal_changed() { m_aChangeHdl.Call(*this); }
signal_cursor_position()2117     void signal_cursor_position() { m_aCursorPositionHdl.Call(*this); }
signal_vadjustment_changed()2118     void signal_vadjustment_changed() { m_aVChangeHdl.Call(*this); }
2119 
2120 public:
2121     virtual void set_text(const OUString& rText) = 0;
2122     virtual OUString get_text() const = 0;
2123     // if nStartPos or nEndPos is -1 the max available text pos will be used
2124     virtual void select_region(int nStartPos, int nEndPos) = 0;
2125     // returns true if the selection has nonzero length
2126     virtual bool get_selection_bounds(int& rStartPos, int& rEndPos) = 0;
2127     virtual void replace_selection(const OUString& rText) = 0;
2128     virtual void set_editable(bool bEditable) = 0;
2129     virtual bool get_editable() const = 0;
2130     virtual void set_monospace(bool bMonospace) = 0;
2131     // The maximum length of the entry. Use 0 for no maximum
2132     virtual void set_max_length(int nChars) = 0;
get_height_rows(int nRows) const2133     int get_height_rows(int nRows) const
2134     {
2135         //can improve this if needed
2136         return get_text_height() * nRows;
2137     }
2138 
2139     // font size is in points, not pixels, e.g. see Window::[G]etPointFont
2140     virtual void set_font(const vcl::Font& rFont) = 0;
2141 
2142     /*
2143        Typically you want to avoid the temptation of customizing
2144        font colors
2145     */
2146     virtual void set_font_color(const Color& rColor) = 0;
2147 
save_value()2148     void save_value() { m_sSavedValue = get_text(); }
get_value_changed_from_saved() const2149     bool get_value_changed_from_saved() const { return m_sSavedValue != get_text(); }
2150 
connect_changed(const Link<TextView &,void> & rLink)2151     void connect_changed(const Link<TextView&, void>& rLink) { m_aChangeHdl = rLink; }
connect_cursor_position(const Link<TextView &,void> & rLink)2152     virtual void connect_cursor_position(const Link<TextView&, void>& rLink)
2153     {
2154         m_aCursorPositionHdl = rLink;
2155     }
2156 
2157     // returns true if pressing up would move the cursor
2158     // doesn't matter if that move is to a previous line or to the start of the
2159     // current line just so long as the cursor would move
2160     virtual bool can_move_cursor_with_up() const = 0;
2161 
2162     // returns true if pressing down would move the cursor
2163     // doesn't matter if that move is to a next line or to the end of the
2164     // current line just so long as the cursor would move
2165     virtual bool can_move_cursor_with_down() const = 0;
2166 
2167     virtual void cut_clipboard() = 0;
2168     virtual void copy_clipboard() = 0;
2169     virtual void paste_clipboard() = 0;
2170 
2171     virtual void set_alignment(TxtAlign eXAlign) = 0;
2172 
2173     virtual int vadjustment_get_value() const = 0;
2174     virtual int vadjustment_get_upper() const = 0;
2175     virtual int vadjustment_get_lower() const = 0;
2176     virtual int vadjustment_get_page_size() const = 0;
2177     virtual void vadjustment_set_value(int value) = 0;
connect_vadjustment_changed(const Link<TextView &,void> & rLink)2178     void connect_vadjustment_changed(const Link<TextView&, void>& rLink) { m_aVChangeHdl = rLink; }
2179 };
2180 
2181 class VCL_DLLPUBLIC Expander : virtual public Widget
2182 {
2183 protected:
2184     Link<Expander&, void> m_aExpandedHdl;
2185 
signal_expanded()2186     void signal_expanded() { m_aExpandedHdl.Call(*this); }
2187 
2188 public:
2189     virtual void set_label(const OUString& rText) = 0;
2190     virtual OUString get_label() const = 0;
2191     virtual bool get_expanded() const = 0;
2192     virtual void set_expanded(bool bExpand) = 0;
2193 
connect_expanded(const Link<Expander &,void> & rLink)2194     void connect_expanded(const Link<Expander&, void>& rLink) { m_aExpandedHdl = rLink; }
2195 };
2196 
2197 class VCL_DLLPUBLIC DrawingArea : virtual public Widget
2198 {
2199 public:
2200     typedef std::pair<vcl::RenderContext&, const tools::Rectangle&> draw_args;
2201 
2202 protected:
2203     Link<draw_args, void> m_aDrawHdl;
2204     Link<Widget&, void> m_aStyleUpdatedHdl;
2205     Link<const CommandEvent&, bool> m_aCommandHdl;
2206     Link<Widget&, tools::Rectangle> m_aGetFocusRectHdl;
2207     Link<tools::Rectangle&, OUString> m_aQueryTooltipHdl;
2208     // if handler returns true, drag is disallowed
2209     Link<DrawingArea&, bool> m_aDragBeginHdl;
2210     // return position of cursor, fill OUString& with surrounding text
2211     Link<OUString&, int> m_aGetSurroundingHdl;
2212     // attempt to delete the range, return true if successful
2213     Link<const Selection&, bool> m_aDeleteSurroundingHdl;
2214 
signal_query_tooltip(tools::Rectangle & rHelpArea)2215     OUString signal_query_tooltip(tools::Rectangle& rHelpArea)
2216     {
2217         return m_aQueryTooltipHdl.Call(rHelpArea);
2218     }
2219 
signal_im_context_get_surrounding(OUString & rSurroundingText)2220     int signal_im_context_get_surrounding(OUString& rSurroundingText)
2221     {
2222         if (!m_aGetSurroundingHdl.IsSet())
2223             return -1;
2224         return m_aGetSurroundingHdl.Call(rSurroundingText);
2225     }
2226 
signal_im_context_delete_surrounding(const Selection & rRange)2227     bool signal_im_context_delete_surrounding(const Selection& rRange)
2228     {
2229         return m_aDeleteSurroundingHdl.Call(rRange);
2230     }
2231 
2232 public:
connect_draw(const Link<draw_args,void> & rLink)2233     void connect_draw(const Link<draw_args, void>& rLink) { m_aDrawHdl = rLink; }
connect_style_updated(const Link<Widget &,void> & rLink)2234     void connect_style_updated(const Link<Widget&, void>& rLink) { m_aStyleUpdatedHdl = rLink; }
connect_command(const Link<const CommandEvent &,bool> & rLink)2235     void connect_command(const Link<const CommandEvent&, bool>& rLink) { m_aCommandHdl = rLink; }
connect_focus_rect(const Link<Widget &,tools::Rectangle> & rLink)2236     void connect_focus_rect(const Link<Widget&, tools::Rectangle>& rLink)
2237     {
2238         m_aGetFocusRectHdl = rLink;
2239     }
connect_query_tooltip(const Link<tools::Rectangle &,OUString> & rLink)2240     void connect_query_tooltip(const Link<tools::Rectangle&, OUString>& rLink)
2241     {
2242         m_aQueryTooltipHdl = rLink;
2243     }
connect_drag_begin(const Link<DrawingArea &,bool> & rLink)2244     void connect_drag_begin(const Link<DrawingArea&, bool>& rLink) { m_aDragBeginHdl = rLink; }
connect_im_context_get_surrounding(const Link<OUString &,int> & rLink)2245     void connect_im_context_get_surrounding(const Link<OUString&, int>& rLink)
2246     {
2247         m_aGetSurroundingHdl = rLink;
2248     }
connect_im_context_delete_surrounding(const Link<const Selection &,bool> & rLink)2249     void connect_im_context_delete_surrounding(const Link<const Selection&, bool>& rLink)
2250     {
2251         m_aDeleteSurroundingHdl = rLink;
2252     }
2253     virtual void queue_draw() = 0;
2254     virtual void queue_draw_area(int x, int y, int width, int height) = 0;
2255 
2256     virtual void enable_drag_source(rtl::Reference<TransferDataContainer>& rTransferrable,
2257                                     sal_uInt8 eDNDConstants)
2258         = 0;
2259 
2260     virtual void set_cursor(PointerStyle ePointerStyle) = 0;
2261 
2262     virtual Point get_pointer_position() const = 0;
2263 
2264     virtual void set_input_context(const InputContext& rInputContext) = 0;
2265     virtual void im_context_set_cursor_location(const tools::Rectangle& rCursorRect,
2266                                                 int nExtTextInputWidth)
2267         = 0;
2268 
2269     // use return here just to generate matching VirtualDevices
2270     virtual OutputDevice& get_ref_device() = 0;
2271 
2272     virtual a11yref get_accessible_parent() = 0;
2273     virtual a11yrelationset get_accessible_relation_set() = 0;
2274     virtual Point get_accessible_location_on_screen() = 0;
2275 
2276 private:
2277     friend class ::LOKTrigger;
2278 
2279     virtual void click(const Point& rPos) = 0;
2280 };
2281 
2282 class VCL_DLLPUBLIC Menu
2283 {
2284 protected:
2285     Link<const OString&, void> m_aActivateHdl;
2286 
signal_activate(const OString & rIdent)2287     void signal_activate(const OString& rIdent) { m_aActivateHdl.Call(rIdent); }
2288 
2289 public:
2290     virtual OString popup_at_rect(weld::Widget* pParent, const tools::Rectangle& rRect) = 0;
2291 
connect_activate(const Link<const OString &,void> & rLink)2292     void connect_activate(const Link<const OString&, void>& rLink) { m_aActivateHdl = rLink; }
2293 
2294     virtual void set_sensitive(const OString& rIdent, bool bSensitive) = 0;
2295     virtual bool get_sensitive(const OString& rIdent) const = 0;
2296     virtual void set_label(const OString& rIdent, const OUString& rLabel) = 0;
2297     virtual OUString get_label(const OString& rIdent) const = 0;
2298     virtual void set_active(const OString& rIdent, bool bActive) = 0;
2299     virtual bool get_active(const OString& rIdent) const = 0;
2300     virtual void set_visible(const OString& rIdent, bool bVisible) = 0;
2301 
2302     virtual void insert(int pos, const OUString& rId, const OUString& rStr,
2303                         const OUString* pIconName, VirtualDevice* pImageSurface,
2304                         const css::uno::Reference<css::graphic::XGraphic>& rImage,
2305                         TriState eCheckRadioFalse)
2306         = 0;
2307 
2308     virtual void remove(const OString& rId) = 0;
2309 
2310     virtual void clear() = 0;
2311 
2312     virtual void insert_separator(int pos, const OUString& rId) = 0;
append_separator(const OUString & rId)2313     void append_separator(const OUString& rId) { insert_separator(-1, rId); }
2314 
append(const OUString & rId,const OUString & rStr)2315     void append(const OUString& rId, const OUString& rStr)
2316     {
2317         insert(-1, rId, rStr, nullptr, nullptr, nullptr, TRISTATE_INDET);
2318     }
append_check(const OUString & rId,const OUString & rStr)2319     void append_check(const OUString& rId, const OUString& rStr)
2320     {
2321         insert(-1, rId, rStr, nullptr, nullptr, nullptr, TRISTATE_TRUE);
2322     }
append_radio(const OUString & rId,const OUString & rStr)2323     void append_radio(const OUString& rId, const OUString& rStr)
2324     {
2325         insert(-1, rId, rStr, nullptr, nullptr, nullptr, TRISTATE_FALSE);
2326     }
append(const OUString & rId,const OUString & rStr,const OUString & rImage)2327     void append(const OUString& rId, const OUString& rStr, const OUString& rImage)
2328     {
2329         insert(-1, rId, rStr, &rImage, nullptr, nullptr, TRISTATE_INDET);
2330     }
append(const OUString & rId,const OUString & rStr,VirtualDevice & rImage)2331     void append(const OUString& rId, const OUString& rStr, VirtualDevice& rImage)
2332     {
2333         insert(-1, rId, rStr, nullptr, &rImage, nullptr, TRISTATE_INDET);
2334     }
2335 
2336     // return the number of toplevel nodes
2337     virtual int n_children() const = 0;
2338 
2339     virtual OString get_id(int pos) const = 0;
2340 
~Menu()2341     virtual ~Menu() {}
2342 };
2343 
2344 class VCL_DLLPUBLIC Popover : virtual public Container
2345 {
2346 private:
2347     Link<weld::Popover&, void> m_aCloseHdl;
2348 
2349 protected:
signal_closed()2350     void signal_closed() { m_aCloseHdl.Call(*this); }
2351 
2352 public:
2353     virtual void popup_at_rect(weld::Widget* pParent, const tools::Rectangle& rRect) = 0;
2354     virtual void popdown() = 0;
2355 
connect_closed(const Link<weld::Popover &,void> & rLink)2356     void connect_closed(const Link<weld::Popover&, void>& rLink) { m_aCloseHdl = rLink; }
2357 };
2358 
2359 class VCL_DLLPUBLIC Toolbar : virtual public Widget
2360 {
2361 protected:
2362     Link<const OString&, void> m_aClickHdl;
2363     Link<const OString&, void> m_aToggleMenuHdl;
2364 
2365     friend class ::LOKTrigger;
2366 
signal_clicked(const OString & rIdent)2367     void signal_clicked(const OString& rIdent) { m_aClickHdl.Call(rIdent); }
signal_toggle_menu(const OString & rIdent)2368     void signal_toggle_menu(const OString& rIdent) { m_aToggleMenuHdl.Call(rIdent); }
2369 
2370 public:
2371     virtual void set_item_sensitive(const OString& rIdent, bool bSensitive) = 0;
2372     virtual bool get_item_sensitive(const OString& rIdent) const = 0;
2373     virtual void set_item_active(const OString& rIdent, bool bActive) = 0;
2374     virtual bool get_item_active(const OString& rIdent) const = 0;
2375     virtual void set_menu_item_active(const OString& rIdent, bool bActive) = 0;
2376     virtual bool get_menu_item_active(const OString& rIdent) const = 0;
2377     virtual void set_item_menu(const OString& rIdent, weld::Menu* pMenu) = 0;
2378     virtual void set_item_popover(const OString& rIdent, weld::Widget* pPopover) = 0;
2379     virtual void set_item_visible(const OString& rIdent, bool bVisible) = 0;
2380     virtual void set_item_help_id(const OString& rIdent, const OString& rHelpId) = 0;
2381     virtual bool get_item_visible(const OString& rIdent) const = 0;
2382     virtual void set_item_label(const OString& rIdent, const OUString& rLabel) = 0;
2383     virtual OUString get_item_label(const OString& rIdent) const = 0;
2384     virtual void set_item_tooltip_text(const OString& rIdent, const OUString& rTip) = 0;
2385     virtual OUString get_item_tooltip_text(const OString& rIdent) const = 0;
2386     virtual void set_item_icon_name(const OString& rIdent, const OUString& rIconName) = 0;
2387     virtual void set_item_image(const OString& rIdent,
2388                                 const css::uno::Reference<css::graphic::XGraphic>& rIcon)
2389         = 0;
2390     virtual void set_item_image(const OString& rIdent, VirtualDevice* pDevice) = 0;
2391 
2392     virtual void insert_item(int pos, const OUString& rId) = 0;
2393     virtual void insert_separator(int pos, const OUString& rId) = 0;
append_separator(const OUString & rId)2394     void append_separator(const OUString& rId) { insert_separator(-1, rId); }
2395 
2396     virtual int get_n_items() const = 0;
2397     virtual OString get_item_ident(int nIndex) const = 0;
2398     virtual void set_item_ident(int nIndex, const OString& rIdent) = 0;
2399     virtual void set_item_label(int nIndex, const OUString& rLabel) = 0;
2400     virtual void set_item_image(int nIndex,
2401                                 const css::uno::Reference<css::graphic::XGraphic>& rIcon)
2402         = 0;
2403     virtual void set_item_tooltip_text(int nIndex, const OUString& rTip) = 0;
2404 
2405     virtual vcl::ImageType get_icon_size() const = 0;
2406     virtual void set_icon_size(vcl::ImageType eType) = 0;
2407 
2408     // return what modifiers are held
2409     virtual sal_uInt16 get_modifier_state() const = 0;
2410 
2411     // This function returns the position a new item should be inserted if dnd
2412     // is dropped at rPoint
2413     virtual int get_drop_index(const Point& rPoint) const = 0;
2414 
connect_clicked(const Link<const OString &,void> & rLink)2415     void connect_clicked(const Link<const OString&, void>& rLink) { m_aClickHdl = rLink; }
connect_menu_toggled(const Link<const OString &,void> & rLink)2416     void connect_menu_toggled(const Link<const OString&, void>& rLink) { m_aToggleMenuHdl = rLink; }
2417 };
2418 
2419 class VCL_DLLPUBLIC SizeGroup
2420 {
2421 public:
2422     virtual void add_widget(weld::Widget* pWidget) = 0;
2423     // the default mode is VclSizeGroupMode::Horizontal
2424     virtual void set_mode(VclSizeGroupMode eMode) = 0;
~SizeGroup()2425     virtual ~SizeGroup() {}
2426 };
2427 
2428 class VCL_DLLPUBLIC Builder
2429 {
2430 public:
2431     virtual std::unique_ptr<MessageDialog> weld_message_dialog(const OString& id) = 0;
2432     virtual std::unique_ptr<Dialog> weld_dialog(const OString& id) = 0;
2433     virtual std::unique_ptr<Assistant> weld_assistant(const OString& id) = 0;
2434     virtual std::unique_ptr<Widget> weld_widget(const OString& id) = 0;
2435     virtual std::unique_ptr<Container> weld_container(const OString& id) = 0;
2436     virtual std::unique_ptr<Box> weld_box(const OString& id) = 0;
2437     virtual std::unique_ptr<Paned> weld_paned(const OString& id) = 0;
2438     virtual std::unique_ptr<Button> weld_button(const OString& id) = 0;
2439     virtual std::unique_ptr<MenuButton> weld_menu_button(const OString& id) = 0;
2440     virtual std::unique_ptr<MenuToggleButton> weld_menu_toggle_button(const OString& id) = 0;
2441     virtual std::unique_ptr<Frame> weld_frame(const OString& id) = 0;
2442     /* bUserManagedScrolling of true means that the automatic scrolling of the window is disabled
2443        and the owner must specifically listen to adjustment changes and react appropriately to them.
2444     */
2445     virtual std::unique_ptr<ScrolledWindow> weld_scrolled_window(const OString& id,
2446                                                                  bool bUserManagedScrolling = false)
2447         = 0;
2448     virtual std::unique_ptr<Notebook> weld_notebook(const OString& id) = 0;
2449     virtual std::unique_ptr<ToggleButton> weld_toggle_button(const OString& id) = 0;
2450     virtual std::unique_ptr<RadioButton> weld_radio_button(const OString& id) = 0;
2451     virtual std::unique_ptr<CheckButton> weld_check_button(const OString& id) = 0;
2452     virtual std::unique_ptr<LinkButton> weld_link_button(const OString& id) = 0;
2453     virtual std::unique_ptr<SpinButton> weld_spin_button(const OString& id) = 0;
2454     virtual std::unique_ptr<MetricSpinButton> weld_metric_spin_button(const OString& id,
2455                                                                       FieldUnit eUnit)
2456         = 0;
2457     virtual std::unique_ptr<FormattedSpinButton> weld_formatted_spin_button(const OString& id) = 0;
2458     virtual std::unique_ptr<ComboBox> weld_combo_box(const OString& id) = 0;
2459     virtual std::unique_ptr<TreeView> weld_tree_view(const OString& id) = 0;
2460     virtual std::unique_ptr<IconView> weld_icon_view(const OString& id) = 0;
2461     virtual std::unique_ptr<Label> weld_label(const OString& id) = 0;
2462     virtual std::unique_ptr<TextView> weld_text_view(const OString& id) = 0;
2463     virtual std::unique_ptr<Expander> weld_expander(const OString& id) = 0;
2464     virtual std::unique_ptr<Entry> weld_entry(const OString& id) = 0;
2465     virtual std::unique_ptr<Scale> weld_scale(const OString& id) = 0;
2466     virtual std::unique_ptr<ProgressBar> weld_progress_bar(const OString& id) = 0;
2467     virtual std::unique_ptr<Spinner> weld_spinner(const OString& id) = 0;
2468     virtual std::unique_ptr<Image> weld_image(const OString& id) = 0;
2469     virtual std::unique_ptr<Calendar> weld_calendar(const OString& id) = 0;
2470     virtual std::unique_ptr<DrawingArea>
2471     weld_drawing_area(const OString& id, const a11yref& rA11yImpl = nullptr,
2472                       FactoryFunction pUITestFactoryFunction = nullptr, void* pUserData = nullptr)
2473         = 0;
2474     virtual std::unique_ptr<EntryTreeView> weld_entry_tree_view(const OString& containerid,
2475                                                                 const OString& entryid,
2476                                                                 const OString& treeviewid)
2477         = 0;
2478     virtual std::unique_ptr<Menu> weld_menu(const OString& id) = 0;
2479     virtual std::unique_ptr<Popover> weld_popover(const OString& id) = 0;
2480     virtual std::unique_ptr<Toolbar> weld_toolbar(const OString& id) = 0;
2481     virtual std::unique_ptr<SizeGroup> create_size_group() = 0;
2482     /* return a Dialog suitable to take a screenshot of containing the contents of the .ui file.
2483 
2484        If the toplevel element is a dialog, that will be returned
2485        If the toplevel is not a dialog, a dialog will be created and the contents of the .ui
2486        inserted into it
2487     */
2488     virtual std::unique_ptr<Window> create_screenshot_window() = 0;
~Builder()2489     virtual ~Builder() {}
2490 };
2491 
2492 class VCL_DLLPUBLIC DialogController : public std::enable_shared_from_this<DialogController>
2493 {
2494 public:
2495     virtual Dialog* getDialog() = 0;
getConstDialog() const2496     const Dialog* getConstDialog() const
2497     {
2498         return const_cast<DialogController*>(this)->getDialog();
2499     }
run()2500     virtual short run() { return getDialog()->run(); }
2501     static bool runAsync(const std::shared_ptr<DialogController>& rController,
2502                          const std::function<void(sal_Int32)>&);
set_title(const OUString & rTitle)2503     void set_title(const OUString& rTitle) { getDialog()->set_title(rTitle); }
get_title() const2504     OUString get_title() const { return getConstDialog()->get_title(); }
set_help_id(const OString & rHelpId)2505     void set_help_id(const OString& rHelpId) { getDialog()->set_help_id(rHelpId); }
get_help_id() const2506     OString get_help_id() const { return getConstDialog()->get_help_id(); }
response(int nResponse)2507     void response(int nResponse) { getDialog()->response(nResponse); }
2508     virtual ~DialogController() COVERITY_NOEXCEPT_FALSE;
2509 };
2510 
2511 class VCL_DLLPUBLIC GenericDialogController : public DialogController
2512 {
2513 protected:
2514     std::unique_ptr<weld::Builder> m_xBuilder;
2515     std::shared_ptr<weld::Dialog> m_xDialog;
2516 
2517 public:
2518     GenericDialogController(weld::Widget* pParent, const OUString& rUIFile,
2519                             const OString& rDialogId, bool bMobile = false);
2520     virtual Dialog* getDialog() override;
2521     virtual ~GenericDialogController() COVERITY_NOEXCEPT_FALSE override;
2522 };
2523 
2524 class VCL_DLLPUBLIC MessageDialogController : public DialogController
2525 {
2526 protected:
2527     std::unique_ptr<weld::Builder> m_xBuilder;
2528     std::unique_ptr<weld::MessageDialog> m_xDialog;
2529     std::unique_ptr<weld::Container> m_xContentArea;
2530     std::unique_ptr<weld::Widget> m_xRelocate;
2531     std::unique_ptr<weld::Container> m_xOrigParent;
2532 
2533 public:
2534     /* @param rRelocateId - optional argument of the name of a widget in the .ui file
2535                             which should be relocated into the content area of the dialog.
2536 
2537                             e.g. a checkbox for a "Never show this again" option.
2538 
2539                             This results in the named widget relocating to the same container
2540                             as the messages.  This enables aligning the extra widget with the
2541                             message labels in the content area container which doesn't
2542                             explicitly exist in the ui description, but is only implied.
2543     */
2544     MessageDialogController(weld::Widget* pParent, const OUString& rUIFile,
2545                             const OString& rDialogId, const OString& rRelocateId = OString());
2546     virtual Dialog* getDialog() override;
2547     virtual ~MessageDialogController() override;
set_primary_text(const OUString & rText)2548     void set_primary_text(const OUString& rText) { m_xDialog->set_primary_text(rText); }
get_primary_text() const2549     OUString get_primary_text() const { return m_xDialog->get_primary_text(); }
set_default_response(int nResponse)2550     void set_default_response(int nResponse) { m_xDialog->set_default_response(nResponse); }
2551 };
2552 
2553 class VCL_DLLPUBLIC AssistantController : public DialogController
2554 {
2555 protected:
2556     std::unique_ptr<weld::Builder> m_xBuilder;
2557     std::unique_ptr<weld::Assistant> m_xAssistant;
2558 
2559 public:
2560     AssistantController(weld::Widget* pParent, const OUString& rUIFile, const OString& rDialogId);
2561     virtual Dialog* getDialog() override;
2562     virtual ~AssistantController() override;
2563 };
2564 }
2565 #endif
2566 
2567 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
2568