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 <osl/module.hxx>
15 #include <sal/log.hxx>
16 #include <tools/resmgr.hxx>
17 #include <tools/fldunit.hxx>
18 #include <vcl/dllapi.h>
19 #include <vcl/window.hxx>
20 #include <vcl/vclptr.hxx>
26 # //some problem with MacOSX and a check define
29 #include <boost/ptr_container/ptr_map.hpp>
31 #include <com/sun/star/frame/XFrame.hpp>
32 #include <com/sun/star/uno/XComponentContext.hpp>
35 class NumericFormatter
;
42 class VclMultiLineEdit
;
43 namespace xmlreader
{ class XmlReader
; }
45 class VCL_DLLPUBLIC VclBuilder
48 typedef std::map
<OString
, OString
> stringmap
;
49 /// These functions create a new widget with parent @pParent and return it in @rRet
50 typedef void (*customMakeWidget
)(VclPtr
<vcl::Window
> &rRet
, VclPtr
<vcl::Window
> &pParent
, stringmap
&rVec
);
55 const OUString
& sUIRootDir
,
56 const OUString
& sUIFile
,
57 const OString
& sID
= OString(),
58 const css::uno::Reference
<css::frame::XFrame
> &rFrame
= css::uno::Reference
<css::frame::XFrame
>());
61 ///releases references and disposes all children.
62 void disposeBuilder();
64 //sID must exist and be of type T
65 template <typename T
> T
* get(VclPtr
<T
>& ret
, const OString
& sID
);
67 //sID may not exist, but must be of type T if it does
68 template <typename T
/*= vcl::Window if we had c++11*/> T
* get(const OString
& sID
);
70 vcl::Window
* get_widget_root();
72 PopupMenu
* get_menu(PopupMenu
*& ret
, const OString
& sID
);
75 PopupMenu
* get_menu(const OString
& sID
);
77 //given an sID return the response value for that widget
78 short get_response(const vcl::Window
*pWindow
) const;
80 OString
get_by_window(const vcl::Window
*pWindow
) const;
81 void delete_by_window(vcl::Window
*pWindow
);
83 //release ownership of pWindow, i.e. don't delete it
84 void drop_ownership(const vcl::Window
*pWindow
);
86 //apply the properties of rProps to pWindow
87 static void set_properties(vcl::Window
*pWindow
, const stringmap
&rProps
);
89 //Convert _ gtk markup to ~ vcl markup
90 static OString
convertMnemonicMarkup(const OString
&rIn
);
92 static OString
extractCustomProperty(stringmap
&rMap
);
93 static FieldUnit
detectUnit(OString
const&);
95 static bool extractDropdown(stringmap
&rMap
);
97 //add a default value of 25 width-chars to a map if width-chars not set
98 static void ensureDefaultWidthChars(VclBuilder::stringmap
&rMap
);
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 //Helpers to retrofit all the existing code to the builder
107 static void reorderWithinParent(std::vector
< vcl::Window
*>& rChilds
, bool bIsButtonBox
);
108 static void reorderWithinParent(vcl::Window
&rWindow
, sal_uInt16 nNewPosition
);
110 /// Get label of the command (like of .uno:Save) from the description service
111 static OUString
getCommandLabel(const OUString
& rCommand
, const css::uno::Reference
<css::uno::XComponentContext
>& rContext
, const OUString
& rModuleId
);
113 /// Get image of the command (like of .uno:Save) from the description service
114 static Image
getCommandImage(
115 const OUString
& rCommand
,
117 const css::uno::Reference
<css::uno::XComponentContext
>& rContext
,
118 const css::uno::Reference
<css::frame::XFrame
>& rFrame
,
119 const OUString
& rModuleId
);
121 css::uno::Reference
<css::frame::XFrame
> getFrame() { return m_xFrame
; }
124 VclBuilder(const VclBuilder
&) SAL_DELETED_FUNCTION
;
125 VclBuilder
& operator=(const VclBuilder
&) SAL_DELETED_FUNCTION
;
127 typedef boost::ptr_map
<OUString
, osl::Module
> ModuleMap
;
129 //We store these until the builder is deleted, that way we can use the
130 //ui-previewer on custom widgets and guarantee the modules they are from
131 //exist for the duration of the dialog
132 ModuleMap m_aModuleMap
;
134 //If the toplevel window has any properties which need to be set on it,
135 //but the toplevel is the owner of the builder, then its ctor
136 //has not been completed during the building, so properties for it
137 //are collected here and need to be set afterwards, e.g. during
139 stringmap m_aDeferredProperties
;
143 bool m_bVerticalOrient
;
144 sal_Int32 m_nPosition
;
145 PackingData(bool bVerticalOrient
= false, sal_Int32 nPosition
= -1)
146 : m_bVerticalOrient(bVerticalOrient
)
147 , m_nPosition(nPosition
)
155 VclPtr
<vcl::Window
> m_pWindow
;
157 PackingData m_aPackingData
;
158 WinAndId(const OString
&rId
, vcl::Window
*pWindow
, bool bVertical
)
161 , m_nResponseId(RET_CANCEL
)
162 , m_aPackingData(bVertical
)
166 std::vector
<WinAndId
> m_aChildren
;
172 MenuAndId(const OString
&rId
, PopupMenu
*pMenu
)
178 std::vector
<MenuAndId
> m_aMenus
;
184 StringPair(const OString
&rId
, const OString
&rValue
)
191 typedef StringPair RadioButtonGroupMap
;
193 struct ButtonImageWidgetMap
198 ButtonImageWidgetMap(const OString
&rId
, const OString
&rValue
, bool bRadio
)
206 typedef StringPair TextBufferMap
;
207 typedef StringPair WidgetAdjustmentMap
;
208 typedef StringPair ButtonMenuMap
;
209 typedef StringPair MnemonicWidgetMap
;
211 struct ComboBoxModelMap
215 sal_Int32 m_nActiveId
;
216 ComboBoxModelMap(const OString
&rId
, const OString
&rValue
, sal_Int32 nActiveId
)
219 , m_nActiveId(nActiveId
)
226 typedef std::vector
<OString
> row
;
227 std::vector
<row
> m_aEntries
;
230 const ListStore
* get_model_by_name(const OString
& sID
) const;
231 static void mungeModel(ListBox
&rTarget
, const ListStore
&rStore
, sal_uInt16 nActiveId
);
233 typedef stringmap TextBuffer
;
235 get_buffer_by_name(const OString
& sID
) const;
237 static void mungeTextBuffer(VclMultiLineEdit
&rTarget
, const TextBuffer
&rTextBuffer
);
239 typedef stringmap Adjustment
;
240 const Adjustment
* get_adjustment_by_name(const OString
& sID
) const;
242 static void mungeAdjustment(NumericFormatter
&rTarget
, const Adjustment
&rAdjustment
);
243 static void mungeAdjustment(DateField
&rTarget
, const Adjustment
&rAdjustment
);
244 static void mungeAdjustment(TimeField
&rTarget
, const Adjustment
&rAdjustment
);
245 static void mungeAdjustment(ScrollBar
&rTarget
, const Adjustment
&rAdjustment
);
246 static void mungeAdjustment(Slider
&rTarget
, const Adjustment
&rAdjustment
);
248 typedef std::map
<OString
, OString
> WidgetTranslations
;
249 typedef std::map
<OString
, WidgetTranslations
> Translations
;
255 stockinfo() : m_nSize(4) {}
258 typedef std::map
<OString
, stockinfo
> StockMap
;
263 std::vector
<OString
> m_aWidgets
;
264 stringmap m_aProperties
;
265 SizeGroup(const OString
&rId
)
271 typedef std::map
< VclPtr
<vcl::Window
>, stringmap
> AtkMap
;
275 std::vector
<RadioButtonGroupMap
> m_aGroupMaps
;
277 std::vector
<ComboBoxModelMap
> m_aModelMaps
;
278 std::map
<OString
, ListStore
> m_aModels
;
280 std::vector
<TextBufferMap
> m_aTextBufferMaps
;
281 std::map
<OString
, TextBuffer
> m_aTextBuffers
;
283 std::vector
<WidgetAdjustmentMap
> m_aNumericFormatterAdjustmentMaps
;
284 std::vector
<WidgetAdjustmentMap
> m_aTimeFormatterAdjustmentMaps
;
285 std::vector
<WidgetAdjustmentMap
> m_aDateFormatterAdjustmentMaps
;
286 std::vector
<WidgetAdjustmentMap
> m_aScrollAdjustmentMaps
;
287 std::vector
<WidgetAdjustmentMap
> m_aSliderAdjustmentMaps
;
289 std::map
<OString
, Adjustment
> m_aAdjustments
;
291 std::vector
<ButtonImageWidgetMap
> m_aButtonImageWidgetMaps
;
292 StockMap m_aStockMap
;
294 std::vector
<ButtonMenuMap
> m_aButtonMenuMaps
;
296 Translations m_aTranslations
;
298 std::map
< VclPtr
<vcl::Window
>, VclPtr
<vcl::Window
> > m_aRedundantParentWidgets
;
300 std::vector
<SizeGroup
> m_aSizeGroups
;
304 std::vector
<MnemonicWidgetMap
> m_aMnemonicWidgetMaps
;
306 std::vector
< VclPtr
<VclExpander
> > m_aExpanderWidgets
;
308 sal_uInt16 m_nLastToolbarId
;
313 void loadTranslations(const LanguageTag
&rLanguageTag
, const OUString
&rUri
);
314 OString
getTranslation(const OString
&rId
, const OString
&rProperty
) const;
318 ResHookProc m_pStringReplace
;
319 VclPtr
<vcl::Window
> m_pParent
;
320 bool m_bToplevelHasDeferredInit
;
321 bool m_bToplevelHasDeferredProperties
;
322 bool m_bToplevelParentFound
;
323 ParserState
*m_pParserState
;
325 vcl::Window
*get_by_name(const OString
& sID
);
326 void delete_by_name(const OString
& sID
);
328 class sortIntoBestTabTraversalOrder
329 : public std::binary_function
<const vcl::Window
*, const vcl::Window
*, bool>
332 sortIntoBestTabTraversalOrder(VclBuilder
*pBuilder
)
333 : m_pBuilder(pBuilder
) {}
335 bool operator()(const vcl::Window
*pA
, const vcl::Window
*pB
) const;
338 VclBuilder
*m_pBuilder
;
341 /// XFrame to be able to extract labels and other properties of the UNO commands (like of .uno:Bold).
342 css::uno::Reference
<css::frame::XFrame
> m_xFrame
;
345 VclPtr
<vcl::Window
> insertObject(vcl::Window
*pParent
,
346 const OString
&rClass
, const OString
&rID
,
347 stringmap
&rProps
, stringmap
&rPangoAttributes
,
348 stringmap
&rAtkProps
);
350 VclPtr
<vcl::Window
> makeObject(vcl::Window
*pParent
,
351 const OString
&rClass
, const OString
&rID
,
354 void connectNumericFormatterAdjustment(const OString
&id
, const OString
&rAdjustment
);
355 void connectTimeFormatterAdjustment(const OString
&id
, const OString
&rAdjustment
);
356 void connectDateFormatterAdjustment(const OString
&id
, const OString
&rAdjustment
);
358 bool extractGroup(const OString
&id
, stringmap
&rVec
);
359 bool extractModel(const OString
&id
, stringmap
&rVec
);
360 bool extractBuffer(const OString
&id
, stringmap
&rVec
);
361 static bool extractAdjustmentToMap(const OString
&id
, stringmap
&rVec
, std::vector
<WidgetAdjustmentMap
>& rAdjustmentMap
);
362 bool extractButtonImage(const OString
&id
, stringmap
&rMap
, bool bRadio
);
363 bool extractStock(const OString
&id
, stringmap
&rMap
);
364 void extractMnemonicWidget(const OString
&id
, stringmap
&rMap
);
366 void handleTranslations(xmlreader::XmlReader
&reader
);
368 void handleChild(vcl::Window
*pParent
, xmlreader::XmlReader
&reader
);
369 VclPtr
<vcl::Window
> handleObject(vcl::Window
*pParent
, xmlreader::XmlReader
&reader
);
370 void handlePacking(vcl::Window
*pCurrent
, vcl::Window
*pParent
, xmlreader::XmlReader
&reader
);
371 void applyPackingProperty(vcl::Window
*pCurrent
, vcl::Window
*pParent
, xmlreader::XmlReader
&reader
);
372 void collectProperty(xmlreader::XmlReader
&reader
, const OString
&rID
, stringmap
&rVec
);
373 static void collectPangoAttribute(xmlreader::XmlReader
&reader
, stringmap
&rMap
);
374 static void collectAtkAttribute(xmlreader::XmlReader
&reader
, stringmap
&rMap
);
375 static void collectAccelerator(xmlreader::XmlReader
&reader
, stringmap
&rMap
);
377 void insertMenuObject(
379 const OString
&rClass
,
384 void handleMenuChild(PopupMenu
*pParent
, xmlreader::XmlReader
&reader
);
385 void handleMenuObject(PopupMenu
*pParent
, xmlreader::XmlReader
&reader
);
387 void handleListStore(xmlreader::XmlReader
&reader
, const OString
&rID
);
388 void handleRow(xmlreader::XmlReader
&reader
, const OString
&rID
, sal_Int32 nRowIndex
);
389 void handleAdjustment(const OString
&rID
, stringmap
&rProperties
);
390 void handleTextBuffer(const OString
&rID
, stringmap
&rProperties
);
391 void handleTabChild(vcl::Window
*pParent
, xmlreader::XmlReader
&reader
);
392 void handleMenu(xmlreader::XmlReader
&reader
, const OString
&rID
);
393 std::vector
<OString
> handleItems(xmlreader::XmlReader
&reader
, const OString
&rID
);
395 void handleSizeGroup(xmlreader::XmlReader
&reader
, const OString
&rID
);
397 void handleAtkObject(xmlreader::XmlReader
&reader
, const OString
&rID
, vcl::Window
*pWindow
);
399 void handleActionWidget(xmlreader::XmlReader
&reader
);
401 PackingData
get_window_packing_data(const vcl::Window
*pWindow
) const;
402 void set_window_packing_position(const vcl::Window
*pWindow
, sal_Int32 nPosition
);
404 static vcl::Window
* prepareWidgetOwnScrolling(vcl::Window
*pParent
, WinBits
&rWinStyle
);
405 void cleanupWidgetOwnScrolling(vcl::Window
*pScrollParent
, vcl::Window
*pWindow
, stringmap
&rMap
);
407 void set_response(const OString
& sID
, short nResponse
);
410 template <typename T
>
411 inline T
* VclBuilder::get(VclPtr
<T
>& ret
, const OString
& sID
)
413 vcl::Window
*w
= get_by_name(sID
);
414 SAL_WARN_IF(!w
, "vcl.layout", "widget \"" << sID
.getStr() << "\" not found in .ui");
415 SAL_WARN_IF(!dynamic_cast<T
*>(w
),
416 "vcl.layout", ".ui widget \"" << sID
.getStr() << "\" needs to correspond to vcl type " << typeid(T
).name());
418 assert(dynamic_cast<T
*>(w
));
419 ret
= static_cast<T
*>(w
);
423 //sID may not exist, but must be of type T if it does
424 template <typename T
/*= vcl::Window if we had c++11*/>
425 inline T
* VclBuilder::get(const OString
& sID
)
427 vcl::Window
*w
= get_by_name(sID
);
428 SAL_WARN_IF(w
&& !dynamic_cast<T
*>(w
),
429 "vcl.layout", ".ui widget \"" << sID
.getStr() << "\" needs to correspond to vcl type " << typeid(T
).name());
430 assert(!w
|| dynamic_cast<T
*>(w
));
431 return static_cast<T
*>(w
);
434 inline PopupMenu
* VclBuilder::get_menu(PopupMenu
*& ret
, const OString
& sID
)
437 SAL_WARN_IF(!ret
, "vcl.layout", "menu \"" << sID
.getStr() << "\" not found in .ui");
442 //helper baseclass to ease retro fitting dialogs/tabpages that load a resource
443 //to load a .ui file instead
445 //vcl requires the Window Children of a Parent Window to be destroyed before
446 //the Parent Window. VclBuilderContainer owns the VclBuilder which owns the
447 //Children Window. So the VclBuilderContainer dtor must be called before
448 //the Parent Window dtor.
450 //i.e. class Dialog : public SystemWindow, public VclBuilderContainer
451 //not class Dialog : public VclBuilderContainer, public SystemWindow
453 //With the new 'dispose' framework, it is necessary to force the builder
454 //dispose before the Window dispose; so a Dialog::dispose() method would
455 //finish: disposeBuilder(); SystemWindow::dispose() to capture this ordering.
457 class VCL_DLLPUBLIC VclBuilderContainer
460 VclBuilderContainer();
461 virtual ~VclBuilderContainer();
462 void disposeBuilder();
464 static OUString
getUIRootDir();
465 bool hasBuilder() const { return m_pUIBuilder
!= NULL
; }
467 css::uno::Reference
<css::frame::XFrame
> getFrame() { return m_pUIBuilder
->getFrame(); }
469 template <typename T
> T
* get(VclPtr
<T
>& ret
, const OString
& sID
)
471 return m_pUIBuilder
->get
<T
>(ret
, sID
);
473 template <typename T
/*= vcl::Window if we had c++11*/> T
* get(const OString
& sID
)
475 return m_pUIBuilder
->get
<T
>(sID
);
477 PopupMenu
* get_menu(PopupMenu
*& ret
, const OString
& sID
)
479 return m_pUIBuilder
->get_menu(ret
, sID
);
481 PopupMenu
* get_menu(const OString
& sID
)
483 return m_pUIBuilder
->get_menu(sID
);
485 void setDeferredProperties()
489 m_pUIBuilder
->setDeferredProperties();
493 VclBuilder
*m_pUIBuilder
;
497 * @return true if rValue is "True", "true", "1", etc.
499 bool VCL_DLLPUBLIC
toBool(const OString
&rValue
);
503 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */