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/.
13 #include <sal/log.hxx>
14 #include <unotools/resmgr.hxx>
15 #include <tools/fldunit.hxx>
16 #include <vcl/dllapi.h>
18 #include <vcl/menu.hxx>
19 #include <vcl/widgetbuilder.hxx>
20 #include <vcl/window.hxx>
21 #include <vcl/vclptr.hxx>
22 #include <vcl/toolboxid.hxx>
23 #include <vcl/wintypes.hxx>
24 #include <vcl/EnumContext.hxx>
28 #include <string_view>
31 # //some problem with MacOSX and a check define
41 class NumericFormatter
;
42 class SalInstanceBuilder
;
51 class VclMultiLineEdit
;
52 struct NotebookBarAddonsItem
;
53 namespace com::sun::star::frame
{ class XFrame
; }
55 /// Creates a hierarchy of vcl::Windows (widgets) from a .ui file for dialogs, sidebar, etc.
56 class VCL_DLLPUBLIC VclBuilder
: public WidgetBuilder
<vcl::Window
, VclPtr
<vcl::Window
>, PopupMenu
, VclPtr
<PopupMenu
>>
59 /// These functions create a new widget with parent pParent and return it in rRet
60 typedef void (*customMakeWidget
)(VclPtr
<vcl::Window
> &rRet
, const VclPtr
<vcl::Window
> &pParent
, stringmap
&rVec
);
63 VclBuilder(vcl::Window
* pParent
, std::u16string_view sUIRootDir
, const OUString
& sUIFile
,
65 css::uno::Reference
<css::frame::XFrame
> xFrame
66 = css::uno::Reference
<css::frame::XFrame
>(),
68 const NotebookBarAddonsItem
* pNotebookBarAddonsItem
= nullptr);
69 virtual ~VclBuilder();
70 ///releases references and disposes all children.
71 void disposeBuilder();
73 //sID may not exist, but must be of type T if it does
74 template <typename T
= vcl::Window
> T
* get(std::u16string_view sID
);
76 vcl::Window
* get_widget_root();
78 //release ownership of pWindow, i.e. don't delete it
79 void drop_ownership(const vcl::Window
*pWindow
);
81 //see m_aDeferredProperties, you need this for toplevel dialogs
82 //which build themselves from their ctor. The properties on
83 //the top level are stored in m_aDeferredProperties and need
84 //to be applied post ctor
85 void setDeferredProperties();
87 static SymbolType
mapStockToSymbol(std::u16string_view icon_name
);
90 VclBuilder(const VclBuilder
&) = delete;
91 VclBuilder
& operator=(const VclBuilder
&) = delete;
93 // owner for ListBox/ComboBox UserData
94 std::vector
<std::unique_ptr
<OUString
>> m_aUserData
;
96 //If the toplevel window has any properties which need to be set on it,
97 //but the toplevel is the owner of the builder, then its ctor
98 //has not been completed during the building, so properties for it
99 //are collected here and need to be set afterwards, e.g. during
101 stringmap m_aDeferredProperties
;
103 std::unique_ptr
<NotebookBarAddonsItem
> m_pNotebookBarAddonsItem
;
107 bool m_bVerticalOrient
;
108 sal_Int32 m_nPosition
;
109 PackingData(bool bVerticalOrient
= false)
110 : m_bVerticalOrient(bVerticalOrient
)
119 VclPtr
<vcl::Window
> m_pWindow
;
120 PackingData m_aPackingData
;
121 WinAndId(OUString sId
, vcl::Window
*pWindow
, bool bVertical
)
122 : m_sID(std::move(sId
))
124 , m_aPackingData(bVertical
)
128 std::vector
<WinAndId
> m_aChildren
;
130 struct ButtonImageWidgetMap
135 ButtonImageWidgetMap(OUString sId
, OUString sValue
, bool bRadio
)
136 : m_sID(std::move(sId
))
137 , m_sValue(std::move(sValue
))
143 typedef StringPair TextBufferMap
;
144 typedef StringPair WidgetAdjustmentMap
;
145 typedef StringPair ButtonMenuMap
;
147 struct ComboBoxModelMap
151 sal_Int32 m_nActiveId
;
152 ComboBoxModelMap(OUString sId
, OUString sValue
, sal_Int32 nActiveId
)
153 : m_sID(std::move(sId
))
154 , m_sValue(std::move(sValue
))
155 , m_nActiveId(nActiveId
)
160 void mungeModel(ListBox
&rTarget
, const ListStore
&rStore
, sal_uInt16 nActiveId
);
161 void mungeModel(ComboBox
&rTarget
, const ListStore
&rStore
, sal_uInt16 nActiveId
);
162 void mungeModel(SvTabListBox
&rTarget
, const ListStore
&rStore
, sal_uInt16 nActiveId
);
164 void insertComboBoxOrListBoxItems(vcl::Window
* pWindow
, stringmap
& rMap
,
165 const std::vector
<ComboBoxTextItem
>& rItems
) override
;
167 static void mungeTextBuffer(VclMultiLineEdit
&rTarget
, const TextBuffer
&rTextBuffer
);
169 static void mungeAdjustment(NumericFormatter
&rTarget
, const Adjustment
&rAdjustment
);
170 static void mungeAdjustment(FormattedField
&rTarget
, const Adjustment
&rAdjustment
);
171 static void mungeAdjustment(ScrollBar
&rTarget
, const Adjustment
&rAdjustment
);
172 static void mungeAdjustment(Slider
&rTarget
, const Adjustment
&rAdjustment
);
174 typedef std::map
<OUString
, int> ImageSizeMap
;
178 struct VclParserState
180 std::vector
<ComboBoxModelMap
> m_aModelMaps
;
182 std::vector
<TextBufferMap
> m_aTextBufferMaps
;
184 std::vector
<WidgetAdjustmentMap
> m_aNumericFormatterAdjustmentMaps
;
185 std::vector
<WidgetAdjustmentMap
> m_aFormattedFormatterAdjustmentMaps
;
186 std::vector
<WidgetAdjustmentMap
> m_aScrollAdjustmentMaps
;
187 std::vector
<WidgetAdjustmentMap
> m_aSliderAdjustmentMaps
;
189 std::vector
<ButtonImageWidgetMap
> m_aButtonImageWidgetMaps
;
190 ImageSizeMap m_aImageSizeMap
;
192 std::vector
<ButtonMenuMap
> m_aButtonMenuMaps
;
194 std::map
<VclPtr
<vcl::Window
>, VclPtr
<vcl::Window
>> m_aRedundantParentWidgets
;
196 std::map
<VclPtr
<vcl::Window
>, stringmap
> m_aAtkInfo
;
198 std::vector
< VclPtr
<VclExpander
> > m_aExpanderWidgets
;
200 std::vector
< VclPtr
<MessageDialog
> > m_aMessageDialogs
;
202 ToolBoxItemId m_nLastToolbarId
;
204 sal_uInt16 m_nLastMenuItemId
;
210 VclPtr
<vcl::Window
> m_pParent
;
211 bool m_bToplevelHasDeferredInit
;
212 bool m_bToplevelHasDeferredProperties
;
213 bool m_bToplevelParentFound
;
214 std::unique_ptr
<VclParserState
> m_pVclParserState
;
216 virtual void resetParserState() override
;
217 vcl::Window
*get_by_name(std::u16string_view sID
);
218 void delete_by_name(const OUString
& sID
);
220 class sortIntoBestTabTraversalOrder
223 sortIntoBestTabTraversalOrder(VclBuilder
*pBuilder
)
224 : m_pBuilder(pBuilder
) {}
226 bool operator()(const vcl::Window
*pA
, const vcl::Window
*pB
) const;
229 VclBuilder
*m_pBuilder
;
232 /// XFrame to be able to extract labels and other properties of the UNO commands (like of .uno:Bold).
233 css::uno::Reference
<css::frame::XFrame
> m_xFrame
;
236 // tweak newly inserted child depending on window type
237 void tweakInsertedChild(vcl::Window
*pParent
, vcl::Window
* pCurrentChild
,
238 std::string_view sType
, std::string_view sInternalChild
) override
;
240 VclPtr
<vcl::Window
> insertObject(vcl::Window
* pParent
, const OUString
& rClass
,
241 std::string_view sType
, const OUString
& rID
, stringmap
& rProps
,
242 stringmap
& rPangoAttributes
, stringmap
& rAtkProps
) override
;
244 VclPtr
<vcl::Window
> makeObject(vcl::Window
*pParent
,
245 const OUString
&rClass
, const OUString
&rID
,
248 void connectNumericFormatterAdjustment(const OUString
&id
, const OUString
&rAdjustment
);
249 void connectFormattedFormatterAdjustment(const OUString
&id
, const OUString
&rAdjustment
);
251 static int getImageSize(const stringmap
&rMap
);
253 void extractModel(const OUString
&id
, stringmap
&rVec
);
254 void extractBuffer(const OUString
&id
, stringmap
&rVec
);
255 static bool extractAdjustmentToMap(const OUString
&id
, stringmap
&rVec
, std::vector
<WidgetAdjustmentMap
>& rAdjustmentMap
);
256 void extractButtonImage(const OUString
&id
, stringmap
&rMap
, bool bRadio
);
258 void applyPackingProperties(vcl::Window
* pCurrent
, vcl::Window
* pParent
,
259 const stringmap
& rPackingProperties
) override
;
260 virtual void applyTabChildProperties(vcl::Window
* pParent
, const std::vector
<OUString
>& rIDs
,
261 std::vector
<vcl::EnumContext::Context
>& rContext
, stringmap
& rProperties
,
262 stringmap
& rAtkProperties
) override
;
264 void insertMenuObject(PopupMenu
* pParent
, PopupMenu
* pSubMenu
, const OUString
& rClass
,
265 const OUString
& rID
, stringmap
& rProps
, stringmap
& rAtkProps
,
266 accelmap
& rAccels
) override
;
268 // if bToolbarItem=true, pParent is the ToolBox that the item belongs to, since there's no widget for the item itself
269 void applyAtkProperties(vcl::Window
* pWindow
, const stringmap
& rProperties
,
270 bool bToolbarItem
) override
;
272 void setMnemonicWidget(const OUString
& rLabelId
, const OUString
& rMnemonicWidgetId
) override
;
273 void setRadioButtonGroup(const OUString
& rRadioButtonId
, const OUString
& rRadioGroupId
) override
;
274 void setPriority(vcl::Window
* pWindow
, int nPriority
) override
;
275 void setContext(vcl::Window
* pWindow
,
276 std::vector
<vcl::EnumContext::Context
>&& aContext
) override
;
278 virtual bool isHorizontalTabControl(vcl::Window
* pWindow
) override
;
280 virtual VclPtr
<PopupMenu
> createMenu(const OUString
& rID
) override
;
282 PackingData
get_window_packing_data(const vcl::Window
*pWindow
) const;
283 void set_window_packing_position(const vcl::Window
*pWindow
, sal_Int32 nPosition
);
285 static vcl::Window
* prepareWidgetOwnScrolling(vcl::Window
*pParent
, WinBits
&rWinStyle
);
286 void cleanupWidgetOwnScrolling(vcl::Window
*pScrollParent
, vcl::Window
*pWindow
, stringmap
&rMap
);
288 void set_response(std::u16string_view sID
, short nResponse
) override
;
290 OUString
get_by_window(const vcl::Window
*pWindow
) const;
291 void delete_by_window(vcl::Window
*pWindow
);
294 namespace BuilderUtils
296 //apply the properties of rProps to pWindow
297 void set_properties(vcl::Window
*pWindow
, const VclBuilder::stringmap
&rProps
);
299 //Convert _ gtk markup to ~ vcl markup
300 OUString
convertMnemonicMarkup(std::u16string_view rIn
);
302 OUString
extractCustomProperty(VclBuilder::stringmap
&rMap
);
304 bool extractDropdown(VclBuilder::stringmap
&rMap
);
306 //add a default value of 25 width-chars to a map if width-chars not set
307 void ensureDefaultWidthChars(VclBuilder::stringmap
&rMap
);
309 //Helpers to retrofit all the existing code to the builder
310 void reorderWithinParent(std::vector
< vcl::Window
*>& rChilds
, bool bIsButtonBox
);
311 void reorderWithinParent(vcl::Window
&rWindow
, sal_uInt16 nNewPosition
);
313 //Convert an accessibility role name to accessibility role number
314 sal_Int16
getRoleFromName(const OUString
& roleName
);
317 //sID may not exist, but must be of type T if it does
318 template <typename T
>
319 inline T
* VclBuilder::get(std::u16string_view sID
)
321 vcl::Window
*w
= get_by_name(sID
);
322 SAL_WARN_IF(w
&& !dynamic_cast<T
*>(w
), "vcl.layout",
323 ".ui widget \"" << OUStringToOString(sID
, RTL_TEXTENCODING_UTF8
)
324 << "\" needs to correspond to vcl type " << typeid(T
).name());
325 assert(!w
|| dynamic_cast<T
*>(w
));
326 return static_cast<T
*>(w
);
330 * @return true if rValue is "True", "true", "1", etc.
332 VCL_DLLPUBLIC
bool toBool(std::u16string_view rValue
);
334 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */