1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
10 #ifndef INCLUDED_VCL_WELDUTILS_HXX
11 #define INCLUDED_VCL_WELDUTILS_HXX
13 #include <com/sun/star/awt/XWindow.hpp>
14 #include <com/sun/star/frame/XDispatch.hpp>
15 #include <com/sun/star/frame/XFrame.hpp>
16 #include <com/sun/star/frame/XStatusListener.hpp>
17 #include <com/sun/star/uno/Reference.hxx>
18 #include <comphelper/interfacecontainer4.hxx>
19 #include <comphelper/compbase.hxx>
20 #include <tools/time.hxx>
21 #include <vcl/dllapi.h>
22 #include <vcl/formatter.hxx>
23 #include <vcl/timer.hxx>
24 #include <vcl/transfer.hxx>
25 #include <vcl/weld.hxx>
27 class CalendarWrapper
;
36 typedef comphelper::WeakComponentImplHelper
<css::awt::XWindow
> TransportAsXWindow_Base
;
38 class VCL_DLLPUBLIC TransportAsXWindow
: public TransportAsXWindow_Base
41 weld::Widget
* m_pWeldWidget
;
42 weld::Builder
* m_pWeldWidgetBuilder
;
44 comphelper::OInterfaceContainerHelper4
<css::awt::XWindowListener
> m_aWindowListeners
;
45 comphelper::OInterfaceContainerHelper4
<css::awt::XKeyListener
> m_aKeyListeners
;
46 comphelper::OInterfaceContainerHelper4
<css::awt::XFocusListener
> m_aFocusListeners
;
47 comphelper::OInterfaceContainerHelper4
<css::awt::XMouseListener
> m_aMouseListeners
;
48 comphelper::OInterfaceContainerHelper4
<css::awt::XMouseMotionListener
> m_aMotionListeners
;
49 comphelper::OInterfaceContainerHelper4
<css::awt::XPaintListener
> m_aPaintListeners
;
52 TransportAsXWindow(weld::Widget
* pWeldWidget
, weld::Builder
* pWeldWidgetBuilder
= nullptr)
53 : m_pWeldWidget(pWeldWidget
)
54 , m_pWeldWidgetBuilder(pWeldWidgetBuilder
)
58 weld::Widget
* getWidget() const { return m_pWeldWidget
; }
60 weld::Builder
* getBuilder() const { return m_pWeldWidgetBuilder
; }
64 m_pWeldWidget
= nullptr;
65 m_pWeldWidgetBuilder
= nullptr;
69 void SAL_CALL
setPosSize(sal_Int32
, sal_Int32
, sal_Int32
, sal_Int32
, sal_Int16
) override
71 throw css::uno::RuntimeException("not implemented");
74 css::awt::Rectangle SAL_CALL
getPosSize() override
76 throw css::uno::RuntimeException("not implemented");
79 void SAL_CALL
setVisible(sal_Bool bVisible
) override
{ m_pWeldWidget
->set_visible(bVisible
); }
81 void SAL_CALL
setEnable(sal_Bool bSensitive
) override
83 m_pWeldWidget
->set_sensitive(bSensitive
);
86 void SAL_CALL
setFocus() override
{ m_pWeldWidget
->grab_focus(); }
89 addWindowListener(const css::uno::Reference
<css::awt::XWindowListener
>& rListener
) override
91 std::unique_lock
g(m_aMutex
);
92 m_aWindowListeners
.addInterface(g
, rListener
);
96 removeWindowListener(const css::uno::Reference
<css::awt::XWindowListener
>& rListener
) override
98 std::unique_lock
g(m_aMutex
);
99 m_aWindowListeners
.removeInterface(g
, rListener
);
103 addFocusListener(const css::uno::Reference
<css::awt::XFocusListener
>& rListener
) override
105 std::unique_lock
g(m_aMutex
);
106 m_aFocusListeners
.addInterface(g
, rListener
);
110 removeFocusListener(const css::uno::Reference
<css::awt::XFocusListener
>& rListener
) override
112 std::unique_lock
g(m_aMutex
);
113 m_aFocusListeners
.removeInterface(g
, rListener
);
117 addKeyListener(const css::uno::Reference
<css::awt::XKeyListener
>& rListener
) override
119 std::unique_lock
g(m_aMutex
);
120 m_aKeyListeners
.addInterface(g
, rListener
);
124 removeKeyListener(const css::uno::Reference
<css::awt::XKeyListener
>& rListener
) override
126 std::unique_lock
g(m_aMutex
);
127 m_aKeyListeners
.removeInterface(g
, rListener
);
131 addMouseListener(const css::uno::Reference
<css::awt::XMouseListener
>& rListener
) override
133 std::unique_lock
g(m_aMutex
);
134 m_aMouseListeners
.addInterface(g
, rListener
);
138 removeMouseListener(const css::uno::Reference
<css::awt::XMouseListener
>& rListener
) override
140 std::unique_lock
g(m_aMutex
);
141 m_aMouseListeners
.removeInterface(g
, rListener
);
144 void SAL_CALL
addMouseMotionListener(
145 const css::uno::Reference
<css::awt::XMouseMotionListener
>& rListener
) override
147 std::unique_lock
g(m_aMutex
);
148 m_aMotionListeners
.addInterface(g
, rListener
);
151 void SAL_CALL
removeMouseMotionListener(
152 const css::uno::Reference
<css::awt::XMouseMotionListener
>& rListener
) override
154 std::unique_lock
g(m_aMutex
);
155 m_aMotionListeners
.removeInterface(g
, rListener
);
159 addPaintListener(const css::uno::Reference
<css::awt::XPaintListener
>& rListener
) override
161 std::unique_lock
g(m_aMutex
);
162 m_aPaintListeners
.addInterface(g
, rListener
);
166 removePaintListener(const css::uno::Reference
<css::awt::XPaintListener
>& rListener
) override
168 std::unique_lock
g(m_aMutex
);
169 m_aPaintListeners
.removeInterface(g
, rListener
);
173 // don't export to avoid duplicate WeakImplHelper definitions with MSVC
174 class SAL_DLLPUBLIC_TEMPLATE WidgetStatusListener_Base
175 : public cppu::WeakImplHelper
<css::frame::XStatusListener
>
179 class VCL_DLLPUBLIC WidgetStatusListener final
: public WidgetStatusListener_Base
182 WidgetStatusListener(weld::Widget
* widget
, const OUString
& rCommand
);
185 weld::Widget
* mWidget
; /** The widget on which actions are performed */
187 /** Dispatcher. Need to keep a reference to it as long as this StatusListener exists. */
188 css::uno::Reference
<css::frame::XDispatch
> mxDispatch
;
189 css::util::URL maCommandURL
;
190 css::uno::Reference
<css::frame::XFrame
> mxFrame
;
193 SAL_DLLPRIVATE
void SAL_CALL
194 statusChanged(const css::frame::FeatureStateEvent
& rEvent
) override
;
196 SAL_DLLPRIVATE
void SAL_CALL
disposing(const css::lang::EventObject
& /*Source*/) override
;
198 const css::uno::Reference
<css::frame::XFrame
>& getFrame() const { return mxFrame
; }
200 void startListening();
205 class VCL_DLLPUBLIC EntryFormatter
: public Formatter
208 EntryFormatter(weld::Entry
& rEntry
);
209 EntryFormatter(weld::FormattedSpinButton
& rSpinButton
);
211 weld::Entry
& get_widget() { return m_rEntry
; }
213 // public Formatter overrides, drives interactions with the Entry
214 SAL_DLLPRIVATE
virtual Selection
GetEntrySelection() const override
;
215 SAL_DLLPRIVATE
virtual OUString
GetEntryText() const override
;
216 SAL_DLLPRIVATE
virtual void SetEntryText(const OUString
& rText
, const Selection
& rSel
) override
;
217 SAL_DLLPRIVATE
virtual void SetEntryTextColor(const Color
* pColor
) override
;
218 SAL_DLLPRIVATE
virtual SelectionOptions
GetEntrySelectionOptions() const override
;
219 SAL_DLLPRIVATE
virtual void FieldModified() override
;
221 // public Formatter overrides, drives optional SpinButton settings
222 SAL_DLLPRIVATE
virtual void ClearMinValue() override
;
223 SAL_DLLPRIVATE
virtual void SetMinValue(double dMin
) override
;
224 SAL_DLLPRIVATE
virtual void ClearMaxValue() override
;
225 SAL_DLLPRIVATE
virtual void SetMaxValue(double dMin
) override
;
227 SAL_DLLPRIVATE
virtual void SetSpinSize(double dStep
) override
;
229 void SetEntrySelectionOptions(SelectionOptions eOptions
) { m_eOptions
= eOptions
; }
231 /* EntryFormatter will set listeners to "changed" and "focus-out" of the
232 Entry so users that want to add their own listeners to those must set
233 them through this formatter and not directly on that entry.
235 If EntryFormatter is used with a weld::FormattedSpinButton this is
236 handled transparently by the FormattedSpinButton for the user and the
237 handlers can be set on the FormattedSpinButton
239 void connect_changed(const Link
<weld::Entry
&, void>& rLink
) { m_aModifyHdl
= rLink
; }
240 void connect_focus_out(const Link
<weld::Widget
&, void>& rLink
) { m_aFocusOutHdl
= rLink
; }
242 SAL_DLLPRIVATE
virtual ~EntryFormatter() override
;
245 weld::Entry
& m_rEntry
;
246 weld::FormattedSpinButton
* m_pSpinButton
;
247 Link
<weld::Entry
&, void> m_aModifyHdl
;
248 Link
<weld::Widget
&, void> m_aFocusOutHdl
;
249 SelectionOptions m_eOptions
;
250 DECL_DLLPRIVATE_LINK(ModifyHdl
, weld::Entry
&, void);
251 DECL_DLLPRIVATE_LINK(FocusOutHdl
, weld::Widget
&, void);
252 SAL_DLLPRIVATE
void Init();
254 // private Formatter overrides
255 SAL_DLLPRIVATE
virtual void UpdateCurrentValue(double dCurrentValue
) override
;
258 class VCL_DLLPUBLIC DoubleNumericFormatter final
: public EntryFormatter
261 DoubleNumericFormatter(weld::Entry
& rEntry
);
262 DoubleNumericFormatter(weld::FormattedSpinButton
& rSpinButton
);
264 SAL_DLLPRIVATE
virtual ~DoubleNumericFormatter() override
;
267 SAL_DLLPRIVATE
virtual bool CheckText(const OUString
& sText
) const override
;
269 SAL_DLLPRIVATE
virtual void FormatChanged(FORMAT_CHANGE_TYPE nWhat
) override
;
270 SAL_DLLPRIVATE
void ResetConformanceTester();
272 std::unique_ptr
<validation::NumberValidator
> m_pNumberValidator
;
275 class VCL_DLLPUBLIC LongCurrencyFormatter final
: public EntryFormatter
278 LongCurrencyFormatter(weld::Entry
& rEntry
);
279 LongCurrencyFormatter(weld::FormattedSpinButton
& rSpinButton
);
281 void SetUseThousandSep(bool b
);
282 void SetCurrencySymbol(const OUString
& rStr
);
284 SAL_DLLPRIVATE
virtual ~LongCurrencyFormatter() override
;
287 DECL_DLLPRIVATE_LINK(FormatOutputHdl
, LinkParamNone
*, bool);
288 DECL_DLLPRIVATE_LINK(ParseInputHdl
, sal_Int64
*, TriState
);
290 SAL_DLLPRIVATE
void Init();
292 OUString m_aCurrencySymbol
;
296 class VCL_DLLPUBLIC TimeFormatter final
: public EntryFormatter
299 TimeFormatter(weld::Entry
& rEntry
);
300 TimeFormatter(weld::FormattedSpinButton
& rSpinButton
);
302 void SetExtFormat(ExtTimeFieldFormat eFormat
);
303 void SetDuration(bool bDuration
);
304 void SetTimeFormat(TimeFieldFormat eTimeFormat
);
306 void SetMin(const tools::Time
& rNewMin
);
307 void SetMax(const tools::Time
& rNewMax
);
309 void SetTime(const tools::Time
& rNewTime
);
310 tools::Time
GetTime();
312 virtual ~TimeFormatter() override
;
315 DECL_DLLPRIVATE_LINK(FormatOutputHdl
, LinkParamNone
*, bool);
316 DECL_DLLPRIVATE_LINK(ParseInputHdl
, sal_Int64
*, TriState
);
317 DECL_DLLPRIVATE_LINK(CursorChangedHdl
, weld::Entry
&, void);
319 SAL_DLLPRIVATE
void Init();
321 SAL_DLLPRIVATE
static tools::Time
ConvertValue(int nValue
);
322 SAL_DLLPRIVATE
static int ConvertValue(const tools::Time
& rTime
);
324 SAL_DLLPRIVATE OUString
FormatNumber(int nValue
) const;
326 TimeFieldFormat m_eFormat
;
327 TimeFormat m_eTimeFormat
;
331 class VCL_DLLPUBLIC DateFormatter final
: public EntryFormatter
334 DateFormatter(weld::Entry
& rEntry
);
336 void SetMin(const Date
& rNewMin
);
337 void SetMax(const Date
& rNewMax
);
339 void SetDate(const Date
& rNewDate
);
342 void SetExtDateFormat(ExtDateFieldFormat eFormat
);
343 void SetShowDateCentury(bool bShowCentury
);
345 virtual ~DateFormatter() override
;
348 DECL_DLLPRIVATE_LINK(FormatOutputHdl
, LinkParamNone
*, bool);
349 DECL_DLLPRIVATE_LINK(ParseInputHdl
, sal_Int64
*, TriState
);
350 DECL_DLLPRIVATE_LINK(CursorChangedHdl
, weld::Entry
&, void);
352 SAL_DLLPRIVATE
void Init();
353 SAL_DLLPRIVATE CalendarWrapper
& GetCalendarWrapper() const;
355 SAL_DLLPRIVATE OUString
FormatNumber(int nValue
) const;
357 ExtDateFieldFormat m_eFormat
;
358 mutable std::unique_ptr
<CalendarWrapper
> m_xCalendarWrapper
;
361 class VCL_DLLPUBLIC PatternFormatter final
364 PatternFormatter(weld::Entry
& rEntry
);
367 weld::Entry
& get_widget() { return m_rEntry
; }
369 void SetMask(const OString
& rEditMask
, const OUString
& rLiteralMask
);
370 void SetStrictFormat(bool bStrict
);
373 /* PatternFormatter will set listeners to "changed", "focus-out", "focus-in"
374 and "key-press" of the Entry so users that want to add their own listeners
375 to those must set them through this formatter and not directly on that entry.
377 void connect_changed(const Link
<weld::Entry
&, void>& rLink
) { m_aModifyHdl
= rLink
; }
378 void connect_focus_out(const Link
<weld::Widget
&, void>& rLink
) { m_aFocusOutHdl
= rLink
; }
379 void connect_focus_in(const Link
<weld::Widget
&, void>& rLink
) { m_aFocusInHdl
= rLink
; }
380 void connect_key_press(const Link
<const KeyEvent
&, bool>& rLink
) { m_aKeyPressHdl
= rLink
; }
382 SAL_DLLPRIVATE
void Modify();
385 weld::Entry
& m_rEntry
;
386 Link
<weld::Entry
&, void> m_aModifyHdl
;
387 Link
<weld::Widget
&, void> m_aFocusInHdl
;
388 Link
<weld::Widget
&, void> m_aFocusOutHdl
;
389 Link
<const KeyEvent
&, bool> m_aKeyPressHdl
;
390 bool m_bStrictFormat
;
393 bool m_bInPattKeyInput
;
395 OUString m_aLiteralMask
;
397 SAL_DLLPRIVATE
void EntryGainFocus();
398 SAL_DLLPRIVATE
void EntryLostFocus();
399 DECL_DLLPRIVATE_LINK(ModifyHdl
, weld::Entry
&, void);
400 DECL_DLLPRIVATE_LINK(FocusInHdl
, weld::Widget
&, void);
401 DECL_DLLPRIVATE_LINK(FocusOutHdl
, weld::Widget
&, void);
402 DECL_DLLPRIVATE_LINK(KeyInputHdl
, const KeyEvent
&, bool);
405 class VCL_DLLPUBLIC ButtonPressRepeater final
406 : public std::enable_shared_from_this
<ButtonPressRepeater
>
409 weld::Button
& m_rButton
;
411 const Link
<Button
&, void> m_aLink
;
412 const Link
<const CommandEvent
&, void> m_aContextLink
;
415 DECL_DLLPRIVATE_LINK(MousePressHdl
, const MouseEvent
&, bool);
416 DECL_DLLPRIVATE_LINK(MouseReleaseHdl
, const MouseEvent
&, bool);
417 DECL_DLLPRIVATE_LINK(RepeatTimerHdl
, Timer
*, void);
420 ButtonPressRepeater(weld::Button
& rButton
, const Link
<Button
&, void>& rLink
,
421 const Link
<const CommandEvent
&, void>& rContextLink
422 = Link
<const CommandEvent
&, void>());
423 void Stop() { m_aRepeat
.Stop(); }
424 bool IsModKeyPressed() const { return m_bModKey
; }
428 If a TreeView is used as a list, rather than a tree, and DnD should just
429 reorder rows, then this can be used to implement that.
431 Because the TreeView doesn't want or need subnodes, the drop target can be
432 simply visually indicated as being between rows (the issue of a final drop
433 location of a child of the drop target doesn't arise), and the meaning of
434 what a drop before or after the last row should do is unambiguous.
436 class VCL_DLLPUBLIC ReorderingDropTarget
: public DropTargetHelper
438 weld::TreeView
& m_rTreeView
;
441 virtual sal_Int8
AcceptDrop(const AcceptDropEvent
& rEvt
) override
;
442 virtual sal_Int8
ExecuteDrop(const ExecuteDropEvent
& rEvt
) override
;
445 ReorderingDropTarget(weld::TreeView
& rTreeView
);
448 // get the row the iterator is on
449 VCL_DLLPUBLIC
size_t GetAbsPos(const weld::TreeView
& rTreeView
, const weld::TreeIter
& rIter
);
451 // an entry is visible if all parents are expanded
452 VCL_DLLPUBLIC
bool IsEntryVisible(const weld::TreeView
& rTreeView
, const weld::TreeIter
& rIter
);
454 // A Parent's Children are turned into Children of the Parent which comes next in hierarchy
455 VCL_DLLPUBLIC
void RemoveParentKeepChildren(weld::TreeView
& rTreeView
,
456 const weld::TreeIter
& rParent
);
458 // return the min height of a weld::Entry
459 VCL_DLLPUBLIC
int GetMinimumEditHeight();
461 // return the weld::Window of the SalFrame rOutWin is in, and convert rRect
462 // from relative to rOutWin to relative to that weld::Window suitable for use
463 // with popup_at_rect
464 VCL_DLLPUBLIC
weld::Window
* GetPopupParent(vcl::Window
& rOutWin
, tools::Rectangle
& rRect
);
466 // Use Application::GetDefaultDevice to set the PointFont rFont to the OutputDevice
467 VCL_DLLPUBLIC
void SetPointFont(OutputDevice
& rDevice
, const vcl::Font
& rFont
);
472 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */