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_BUILDER_HXX
11 #define INCLUDED_VCL_BUILDER_HXX
14 #include <sal/log.hxx>
15 #include <unotools/resmgr.hxx>
16 #include <tools/fldunit.hxx>
17 #include <vcl/dllapi.h>
19 #include <vcl/window.hxx>
20 #include <vcl/vclptr.hxx>
21 #include <vcl/toolboxid.hxx>
22 #include <vcl/wintypes.hxx>
23 #include <vcl/EnumContext.hxx>
27 #include <string_view>
30 # //some problem with MacOSX and a check define
40 class NumericFormatter
;
42 class SalInstanceBuilder
;
51 class VclMultiLineEdit
;
52 struct NotebookBarAddonsItem
;
53 namespace xmlreader
{ class XmlReader
; }
54 namespace com::sun::star::frame
{ class XFrame
; }
56 struct ComboBoxTextItem
60 ComboBoxTextItem(OUString sItem
, OUString sId
)
61 : m_sItem(std::move(sItem
))
62 , m_sId(std::move(sId
))
67 /// Creates a hierarchy of vcl::Windows (widgets) from a .ui file for dialogs, sidebar, etc.
68 class VCL_DLLPUBLIC VclBuilder
71 typedef std::map
<OUString
, OUString
> stringmap
;
72 typedef std::map
<OUString
, std::pair
<OUString
, OUString
>> accelmap
;
73 /// These functions create a new widget with parent pParent and return it in rRet
74 typedef void (*customMakeWidget
)(VclPtr
<vcl::Window
> &rRet
, const VclPtr
<vcl::Window
> &pParent
, stringmap
&rVec
);
77 VclBuilder(vcl::Window
* pParent
, const OUString
& sUIRootDir
, const OUString
& sUIFile
,
79 css::uno::Reference
<css::frame::XFrame
> xFrame
80 = css::uno::Reference
<css::frame::XFrame
>(),
82 const NotebookBarAddonsItem
* pNotebookBarAddonsItem
= nullptr);
84 ///releases references and disposes all children.
85 void disposeBuilder();
86 //sID must exist and be of type T
87 template <typename T
> T
* get(VclPtr
<T
>& ret
, const OUString
& sID
);
89 //sID may not exist, but must be of type T if it does
90 template <typename T
= vcl::Window
> T
* get(const OUString
& sID
);
92 vcl::Window
* get_widget_root();
95 PopupMenu
* get_menu(std::u16string_view sID
);
97 //release ownership of pWindow, i.e. don't delete it
98 void drop_ownership(const vcl::Window
*pWindow
);
100 //see m_aDeferredProperties, you need this for toplevel dialogs
101 //which build themselves from their ctor. The properties on
102 //the top level are stored in m_aDeferredProperties and need
103 //to be applied post ctor
104 void setDeferredProperties();
106 /// return UI-File name (without '.ui')
107 const OUString
& getUIFile() const
112 static SymbolType
mapStockToSymbol(std::u16string_view icon_name
);
115 VclBuilder(const VclBuilder
&) = delete;
116 VclBuilder
& operator=(const VclBuilder
&) = delete;
118 // owner for ListBox/ComboBox UserData
119 std::vector
<std::unique_ptr
<OUString
>> m_aUserData
;
121 //If the toplevel window has any properties which need to be set on it,
122 //but the toplevel is the owner of the builder, then its ctor
123 //has not been completed during the building, so properties for it
124 //are collected here and need to be set afterwards, e.g. during
126 stringmap m_aDeferredProperties
;
128 std::unique_ptr
<NotebookBarAddonsItem
> m_pNotebookBarAddonsItem
;
132 bool m_bVerticalOrient
;
133 sal_Int32 m_nPosition
;
134 PackingData(bool bVerticalOrient
= false)
135 : m_bVerticalOrient(bVerticalOrient
)
144 VclPtr
<vcl::Window
> m_pWindow
;
145 PackingData m_aPackingData
;
146 WinAndId(OUString sId
, vcl::Window
*pWindow
, bool bVertical
)
147 : m_sID(std::move(sId
))
149 , m_aPackingData(bVertical
)
153 std::vector
<WinAndId
> m_aChildren
;
158 VclPtr
<Menu
> m_pMenu
;
159 MenuAndId(OUString sId
, Menu
*pMenu
);
161 std::vector
<MenuAndId
> m_aMenus
;
167 StringPair(OUString sId
, OUString sValue
)
168 : m_sID(std::move(sId
))
169 , m_sValue(std::move(sValue
))
178 UStringPair(OUString sId
, OUString sValue
)
179 : m_sID(std::move(sId
))
180 , m_sValue(std::move(sValue
))
185 typedef StringPair RadioButtonGroupMap
;
187 struct ButtonImageWidgetMap
192 ButtonImageWidgetMap(OUString sId
, OUString sValue
, bool bRadio
)
193 : m_sID(std::move(sId
))
194 , m_sValue(std::move(sValue
))
200 typedef UStringPair TextBufferMap
;
201 typedef UStringPair WidgetAdjustmentMap
;
202 typedef UStringPair ButtonMenuMap
;
203 typedef UStringPair MnemonicWidgetMap
;
205 struct ComboBoxModelMap
209 sal_Int32 m_nActiveId
;
210 ComboBoxModelMap(OUString sId
, OUString sValue
, sal_Int32 nActiveId
)
211 : m_sID(std::move(sId
))
212 , m_sValue(std::move(sValue
))
213 , m_nActiveId(nActiveId
)
220 typedef std::vector
<OUString
> row
;
221 std::vector
<row
> m_aEntries
;
224 const ListStore
* get_model_by_name(const OUString
& sID
) const;
225 void mungeModel(ListBox
&rTarget
, const ListStore
&rStore
, sal_uInt16 nActiveId
);
226 void mungeModel(ComboBox
&rTarget
, const ListStore
&rStore
, sal_uInt16 nActiveId
);
227 void mungeModel(SvTabListBox
&rTarget
, const ListStore
&rStore
, sal_uInt16 nActiveId
);
229 typedef stringmap TextBuffer
;
230 const TextBuffer
* get_buffer_by_name(const OUString
& sID
) const;
232 static void mungeTextBuffer(VclMultiLineEdit
&rTarget
, const TextBuffer
&rTextBuffer
);
234 typedef stringmap Adjustment
;
235 const Adjustment
* get_adjustment_by_name(const OUString
& sID
) const;
237 static void mungeAdjustment(NumericFormatter
&rTarget
, const Adjustment
&rAdjustment
);
238 static void mungeAdjustment(FormattedField
&rTarget
, const Adjustment
&rAdjustment
);
239 static void mungeAdjustment(ScrollBar
&rTarget
, const Adjustment
&rAdjustment
);
240 static void mungeAdjustment(Slider
&rTarget
, const Adjustment
&rAdjustment
);
242 typedef std::map
<OUString
, int> ImageSizeMap
;
246 std::vector
<OUString
> m_aWidgets
;
247 stringmap m_aProperties
;
254 std::locale m_aResLocale
;
256 std::vector
<RadioButtonGroupMap
> m_aGroupMaps
;
258 std::vector
<ComboBoxModelMap
> m_aModelMaps
;
259 std::map
<OUString
, ListStore
> m_aModels
;
261 std::vector
<TextBufferMap
> m_aTextBufferMaps
;
262 std::map
<OUString
, TextBuffer
> m_aTextBuffers
;
264 std::vector
<WidgetAdjustmentMap
> m_aNumericFormatterAdjustmentMaps
;
265 std::vector
<WidgetAdjustmentMap
> m_aFormattedFormatterAdjustmentMaps
;
266 std::vector
<WidgetAdjustmentMap
> m_aScrollAdjustmentMaps
;
267 std::vector
<WidgetAdjustmentMap
> m_aSliderAdjustmentMaps
;
269 std::map
<OUString
, Adjustment
> m_aAdjustments
;
271 std::vector
<ButtonImageWidgetMap
> m_aButtonImageWidgetMaps
;
272 ImageSizeMap m_aImageSizeMap
;
274 std::vector
<ButtonMenuMap
> m_aButtonMenuMaps
;
276 std::map
<VclPtr
<vcl::Window
>, VclPtr
<vcl::Window
>> m_aRedundantParentWidgets
;
278 std::vector
<SizeGroup
> m_aSizeGroups
;
280 std::map
<VclPtr
<vcl::Window
>, stringmap
> m_aAtkInfo
;
282 std::vector
<MnemonicWidgetMap
> m_aMnemonicWidgetMaps
;
284 std::vector
< VclPtr
<VclExpander
> > m_aExpanderWidgets
;
286 std::vector
< VclPtr
<MessageDialog
> > m_aMessageDialogs
;
288 ToolBoxItemId m_nLastToolbarId
;
290 sal_uInt16 m_nLastMenuItemId
;
296 OUString m_sHelpRoot
;
297 ResHookProc m_pStringReplace
;
298 VclPtr
<vcl::Window
> m_pParent
;
299 bool m_bToplevelHasDeferredInit
;
300 bool m_bToplevelHasDeferredProperties
;
301 bool m_bToplevelParentFound
;
303 std::unique_ptr
<ParserState
> m_pParserState
;
305 vcl::Window
*get_by_name(std::u16string_view sID
);
306 void delete_by_name(const OUString
& sID
);
308 class sortIntoBestTabTraversalOrder
311 sortIntoBestTabTraversalOrder(VclBuilder
*pBuilder
)
312 : m_pBuilder(pBuilder
) {}
314 bool operator()(const vcl::Window
*pA
, const vcl::Window
*pB
) const;
317 VclBuilder
*m_pBuilder
;
320 /// XFrame to be able to extract labels and other properties of the UNO commands (like of .uno:Bold).
321 css::uno::Reference
<css::frame::XFrame
> m_xFrame
;
324 VclPtr
<vcl::Window
> insertObject(vcl::Window
*pParent
,
325 const OUString
&rClass
, const OUString
&rID
,
326 stringmap
&rProps
, stringmap
&rPangoAttributes
,
327 stringmap
&rAtkProps
);
329 VclPtr
<vcl::Window
> makeObject(vcl::Window
*pParent
,
330 const OUString
&rClass
, const OUString
&rID
,
333 void connectNumericFormatterAdjustment(const OUString
&id
, const OUString
&rAdjustment
);
334 void connectFormattedFormatterAdjustment(const OUString
&id
, const OUString
&rAdjustment
);
336 static int getImageSize(const stringmap
&rMap
);
338 void extractGroup(const OUString
&id
, stringmap
&rVec
);
339 void extractModel(const OUString
&id
, stringmap
&rVec
);
340 void extractBuffer(const OUString
&id
, stringmap
&rVec
);
341 static bool extractAdjustmentToMap(const OUString
&id
, stringmap
&rVec
, std::vector
<WidgetAdjustmentMap
>& rAdjustmentMap
);
342 void extractButtonImage(const OUString
&id
, stringmap
&rMap
, bool bRadio
);
343 void extractMnemonicWidget(const OUString
&id
, stringmap
&rMap
);
345 // either pParent or pAtkProps must be set, pParent for a child of a widget, pAtkProps for
346 // collecting the atk info for a GtkMenuItem
347 void handleChild(vcl::Window
*pParent
, stringmap
*pAtkProps
, xmlreader::XmlReader
&reader
);
348 VclPtr
<vcl::Window
> handleObject(vcl::Window
*pParent
, stringmap
*pAtkProps
, xmlreader::XmlReader
&reader
);
349 void handlePacking(vcl::Window
*pCurrent
, vcl::Window
*pParent
, xmlreader::XmlReader
&reader
);
350 static std::vector
<vcl::EnumContext::Context
> handleStyle(xmlreader::XmlReader
&reader
, int &nPriority
);
351 static OUString
getStyleClass(xmlreader::XmlReader
&reader
);
352 void applyPackingProperty(vcl::Window
*pCurrent
, vcl::Window
*pParent
, xmlreader::XmlReader
&reader
);
353 void collectProperty(xmlreader::XmlReader
&reader
, stringmap
&rVec
) const;
354 static void collectPangoAttribute(xmlreader::XmlReader
&reader
, stringmap
&rMap
);
355 static void collectAtkRelationAttribute(xmlreader::XmlReader
&reader
, stringmap
&rMap
);
356 static void collectAtkRoleAttribute(xmlreader::XmlReader
&reader
, stringmap
&rMap
);
357 static void collectAccelerator(xmlreader::XmlReader
&reader
, accelmap
&rMap
);
359 void insertMenuObject(
362 const OUString
&rClass
,
365 stringmap
&rAtkProps
,
368 void handleMenuChild(Menu
*pParent
, xmlreader::XmlReader
&reader
);
369 void handleMenuObject(Menu
*pParent
, xmlreader::XmlReader
&reader
);
371 void handleListStore(xmlreader::XmlReader
&reader
, const OUString
&rID
, std::u16string_view rClass
);
372 void handleRow(xmlreader::XmlReader
&reader
, const OUString
&rID
);
373 void handleTabChild(vcl::Window
*pParent
, xmlreader::XmlReader
&reader
);
374 VclPtr
<Menu
> handleMenu(xmlreader::XmlReader
&reader
, const OUString
&rID
, bool bMenuBar
);
375 std::vector
<ComboBoxTextItem
> handleItems(xmlreader::XmlReader
&reader
) const;
377 void handleSizeGroup(xmlreader::XmlReader
&reader
);
379 stringmap
handleAtkObject(xmlreader::XmlReader
&reader
) const;
381 static void applyAtkProperties(vcl::Window
*pWindow
, const stringmap
& rProperties
);
383 void handleActionWidget(xmlreader::XmlReader
&reader
);
385 PackingData
get_window_packing_data(const vcl::Window
*pWindow
) const;
386 void set_window_packing_position(const vcl::Window
*pWindow
, sal_Int32 nPosition
);
388 static vcl::Window
* prepareWidgetOwnScrolling(vcl::Window
*pParent
, WinBits
&rWinStyle
);
389 void cleanupWidgetOwnScrolling(vcl::Window
*pScrollParent
, vcl::Window
*pWindow
, stringmap
&rMap
);
391 void set_response(std::u16string_view sID
, short nResponse
);
393 OUString
get_by_window(const vcl::Window
*pWindow
) const;
394 void delete_by_window(vcl::Window
*pWindow
);
397 namespace BuilderUtils
399 //apply the properties of rProps to pWindow
400 VCL_DLLPUBLIC
void set_properties(vcl::Window
*pWindow
, const VclBuilder::stringmap
&rProps
);
402 //Convert _ gtk markup to ~ vcl markup
403 VCL_DLLPUBLIC OUString
convertMnemonicMarkup(std::u16string_view rIn
);
405 VCL_DLLPUBLIC OUString
extractCustomProperty(VclBuilder::stringmap
&rMap
);
407 VCL_DLLPUBLIC
bool extractDropdown(VclBuilder::stringmap
&rMap
);
409 //add a default value of 25 width-chars to a map if width-chars not set
410 VCL_DLLPUBLIC
void ensureDefaultWidthChars(VclBuilder::stringmap
&rMap
);
412 //Helpers to retrofit all the existing code to the builder
413 VCL_DLLPUBLIC
void reorderWithinParent(std::vector
< vcl::Window
*>& rChilds
, bool bIsButtonBox
);
414 VCL_DLLPUBLIC
void reorderWithinParent(vcl::Window
&rWindow
, sal_uInt16 nNewPosition
);
416 //Convert an accessibility role name to accessibility role number
417 VCL_DLLPUBLIC sal_Int16
getRoleFromName(const OUString
& roleName
);
420 template <typename T
>
421 inline T
* VclBuilder::get(VclPtr
<T
>& ret
, const OUString
& sID
)
423 vcl::Window
*w
= get_by_name(sID
);
424 SAL_WARN_IF(!w
, "vcl.layout", "widget \"" << sID
<< "\" not found in .ui");
425 SAL_WARN_IF(!dynamic_cast<T
*>(w
),
426 "vcl.layout", ".ui widget \"" << sID
<< "\" needs to correspond to vcl type " << typeid(T
).name());
428 assert(dynamic_cast<T
*>(w
));
429 ret
= static_cast<T
*>(w
);
433 //sID may not exist, but must be of type T if it does
434 template <typename T
>
435 inline T
* VclBuilder::get(const OUString
& sID
)
437 vcl::Window
*w
= get_by_name(sID
);
438 SAL_WARN_IF(w
&& !dynamic_cast<T
*>(w
),
439 "vcl.layout", ".ui widget \"" << sID
<< "\" needs to correspond to vcl type " << typeid(T
).name());
440 assert(!w
|| dynamic_cast<T
*>(w
));
441 return static_cast<T
*>(w
);
445 * @return true if rValue is "True", "true", "1", etc.
447 VCL_DLLPUBLIC
bool toBool(std::u16string_view rValue
);
451 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */