Version 5.4.3.2, tag libreoffice-5.4.3.2
[LibreOffice.git] / include / vcl / builder.hxx
blob0695af5cd25a061fde05bde477f3f39bf88cd232
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/.
8 */
10 #ifndef INCLUDED_VCL_BUILDER_HXX
11 #define INCLUDED_VCL_BUILDER_HXX
13 #include <typeinfo>
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>
21 #include <tools/wintypes.hxx>
22 #include <vcl/EnumContext.hxx>
24 #include <memory>
25 #include <map>
26 #include <set>
27 #include <stack>
28 #include <vector>
29 #ifdef check
30 # //some problem with MacOSX and a check define
31 # undef check
32 #endif
34 #include <com/sun/star/frame/XFrame.hpp>
35 #include <com/sun/star/uno/XComponentContext.hpp>
37 class ListBox;
38 class NumericFormatter;
39 class PopupMenu;
40 class ScrollBar;
41 class Slider;
42 class DateField;
43 class TimeField;
44 class VclExpander;
45 class VclMultiLineEdit;
46 namespace xmlreader { class XmlReader; }
48 class VCL_DLLPUBLIC VclBuilder
50 public:
51 typedef std::map<OString, OUString> stringmap;
52 typedef std::map<OString, std::pair<OString, OString>> accelmap;
53 /// These functions create a new widget with parent pParent and return it in rRet
54 typedef void (*customMakeWidget)(VclPtr<vcl::Window> &rRet, VclPtr<vcl::Window> &pParent, stringmap &rVec);
56 public:
57 VclBuilder(
58 vcl::Window *pParent,
59 const OUString& sUIRootDir,
60 const OUString& sUIFile,
61 const OString& sID = OString(),
62 const css::uno::Reference<css::frame::XFrame> &rFrame = css::uno::Reference<css::frame::XFrame>());
63 ~VclBuilder();
65 ///releases references and disposes all children.
66 void disposeBuilder();
68 //sID must exist and be of type T
69 template <typename T> T* get(VclPtr<T>& ret, const OString& sID);
71 //sID may not exist, but must be of type T if it does
72 template <typename T /*= vcl::Window if we had c++11*/> T* get(const OString& sID);
74 vcl::Window* get_widget_root();
76 //sID may not exist
77 PopupMenu* get_menu(const OString& sID);
79 //given an sID return the response value for that widget
80 short get_response(const vcl::Window *pWindow) const;
82 OString get_by_window(const vcl::Window *pWindow) const;
83 void delete_by_window(vcl::Window *pWindow);
85 //release ownership of pWindow, i.e. don't delete it
86 void drop_ownership(const vcl::Window *pWindow);
88 //apply the properties of rProps to pWindow
89 static void set_properties(vcl::Window *pWindow, const stringmap &rProps);
91 //Convert _ gtk markup to ~ vcl markup
92 static OUString convertMnemonicMarkup(const OUString &rIn);
94 static OUString extractCustomProperty(stringmap &rMap);
95 static FieldUnit detectUnit(OUString const&);
97 static bool extractDropdown(stringmap &rMap);
99 //add a default value of 25 width-chars to a map if width-chars not set
100 static void ensureDefaultWidthChars(VclBuilder::stringmap &rMap);
102 //see m_aDeferredProperties, you need this for toplevel dialogs
103 //which build themselves from their ctor. The properties on
104 //the top level are stored in m_aDeferredProperties and need
105 //to be applied post ctor
106 void setDeferredProperties();
108 //Helpers to retrofit all the existing code to the builder
109 static void reorderWithinParent(std::vector< vcl::Window*>& rChilds, bool bIsButtonBox);
110 static void reorderWithinParent(vcl::Window &rWindow, sal_uInt16 nNewPosition);
112 /// return UI-File name (without '.ui')
113 const OString& getUIFile() const
115 return m_sHelpRoot;
118 private:
119 VclBuilder(const VclBuilder&) = delete;
120 VclBuilder& operator=(const VclBuilder&) = delete;
122 typedef std::map<OUString, std::unique_ptr<osl::Module>> ModuleMap;
124 //We store these until the builder is deleted, that way we can use the
125 //ui-previewer on custom widgets and guarantee the modules they are from
126 //exist for the duration of the dialog
127 ModuleMap m_aModuleMap;
129 //If the toplevel window has any properties which need to be set on it,
130 //but the toplevel is the owner of the builder, then its ctor
131 //has not been completed during the building, so properties for it
132 //are collected here and need to be set afterwards, e.g. during
133 //Show or Execute
134 stringmap m_aDeferredProperties;
136 struct PackingData
138 bool m_bVerticalOrient;
139 sal_Int32 m_nPosition;
140 PackingData(bool bVerticalOrient = false)
141 : m_bVerticalOrient(bVerticalOrient)
142 , m_nPosition(-1)
147 struct WinAndId
149 OString m_sID;
150 VclPtr<vcl::Window> m_pWindow;
151 short m_nResponseId;
152 PackingData m_aPackingData;
153 WinAndId(const OString &rId, vcl::Window *pWindow, bool bVertical)
154 : m_sID(rId)
155 , m_pWindow(pWindow)
156 , m_nResponseId(RET_CANCEL)
157 , m_aPackingData(bVertical)
161 std::vector<WinAndId> m_aChildren;
163 struct MenuAndId
165 OString m_sID;
166 VclPtr<PopupMenu> m_pMenu;
167 MenuAndId(const OString &rId, PopupMenu *pMenu);
168 ~MenuAndId();
170 std::vector<MenuAndId> m_aMenus;
172 struct StringPair
174 OString m_sID;
175 OString m_sValue;
176 StringPair(const OString &rId, const OString &rValue)
177 : m_sID(rId)
178 , m_sValue(rValue)
183 struct UStringPair
185 OString m_sID;
186 OUString m_sValue;
187 UStringPair(const OString &rId, const OUString &rValue)
188 : m_sID(rId)
189 , m_sValue(rValue)
194 typedef StringPair RadioButtonGroupMap;
196 struct ButtonImageWidgetMap
198 OString m_sID;
199 OUString m_sValue;
200 bool m_bRadio;
201 ButtonImageWidgetMap(const OString &rId, const OUString &rValue, bool bRadio)
202 : m_sID(rId)
203 , m_sValue(rValue)
204 , m_bRadio(bRadio)
209 typedef UStringPair TextBufferMap;
210 typedef UStringPair WidgetAdjustmentMap;
211 typedef UStringPair ButtonMenuMap;
212 typedef UStringPair MnemonicWidgetMap;
214 struct ComboBoxModelMap
216 OString m_sID;
217 OUString m_sValue;
218 sal_Int32 m_nActiveId;
219 ComboBoxModelMap(const OString &rId, const OUString &rValue, sal_Int32 nActiveId)
220 : m_sID(rId)
221 , m_sValue(rValue)
222 , m_nActiveId(nActiveId)
227 struct ListStore
229 typedef std::vector<OUString> row;
230 std::vector<row> m_aEntries;
233 const ListStore* get_model_by_name(const OString& sID) const;
234 static void mungeModel(ListBox &rTarget, const ListStore &rStore, sal_uInt16 nActiveId);
236 typedef stringmap TextBuffer;
237 const TextBuffer* get_buffer_by_name(const OString& sID) const;
239 static void mungeTextBuffer(VclMultiLineEdit &rTarget, const TextBuffer &rTextBuffer);
241 typedef stringmap Adjustment;
242 const Adjustment* get_adjustment_by_name(const OString& sID) const;
244 static void mungeAdjustment(NumericFormatter &rTarget, const Adjustment &rAdjustment);
245 static void mungeAdjustment(DateField &rTarget, const Adjustment &rAdjustment);
246 static void mungeAdjustment(TimeField &rTarget, const Adjustment &rAdjustment);
247 static void mungeAdjustment(ScrollBar &rTarget, const Adjustment &rAdjustment);
248 static void mungeAdjustment(Slider &rTarget, const Adjustment &rAdjustment);
250 typedef std::map<OString, OString> WidgetTranslations;
251 typedef std::map<OString, WidgetTranslations> Translations;
253 struct stockinfo
255 OUString m_sStock;
256 int m_nSize;
257 stockinfo() : m_nSize(4) {}
260 typedef std::map<OString, stockinfo> StockMap;
262 struct SizeGroup
264 std::vector<OString> m_aWidgets;
265 stringmap m_aProperties;
266 SizeGroup() {}
269 typedef std::map<VclPtr<vcl::Window>, stringmap> AtkMap;
271 struct ParserState
273 std::vector<RadioButtonGroupMap> m_aGroupMaps;
275 std::vector<ComboBoxModelMap> m_aModelMaps;
276 std::map<OString, ListStore> m_aModels;
278 std::vector<TextBufferMap> m_aTextBufferMaps;
279 std::map<OString, TextBuffer> m_aTextBuffers;
281 std::vector<WidgetAdjustmentMap> m_aNumericFormatterAdjustmentMaps;
282 std::vector<WidgetAdjustmentMap> m_aTimeFormatterAdjustmentMaps;
283 std::vector<WidgetAdjustmentMap> m_aDateFormatterAdjustmentMaps;
284 std::vector<WidgetAdjustmentMap> m_aScrollAdjustmentMaps;
285 std::vector<WidgetAdjustmentMap> m_aSliderAdjustmentMaps;
287 std::map<OString, Adjustment> m_aAdjustments;
289 std::vector<ButtonImageWidgetMap> m_aButtonImageWidgetMaps;
290 StockMap m_aStockMap;
292 std::vector<ButtonMenuMap> m_aButtonMenuMaps;
294 Translations m_aTranslations;
296 std::map<VclPtr<vcl::Window>, VclPtr<vcl::Window>> m_aRedundantParentWidgets;
298 std::vector<SizeGroup> m_aSizeGroups;
300 AtkMap m_aAtkInfo;
302 std::vector<MnemonicWidgetMap> m_aMnemonicWidgetMaps;
304 std::vector< VclPtr<VclExpander> > m_aExpanderWidgets;
306 sal_uInt16 m_nLastToolbarId;
308 sal_uInt16 m_nLastMenuItemId;
310 ParserState();
313 void loadTranslations(const LanguageTag &rLanguageTag, const OUString &rUri);
314 OString getTranslation(const OString &rId, const OString &rProperty) const;
316 OString m_sID;
317 OString m_sHelpRoot;
318 ResHookProc m_pStringReplace;
319 VclPtr<vcl::Window> m_pParent;
320 bool m_bToplevelHasDeferredInit;
321 bool m_bToplevelHasDeferredProperties;
322 bool m_bToplevelParentFound;
323 std::unique_ptr<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>
331 public:
332 sortIntoBestTabTraversalOrder(VclBuilder *pBuilder)
333 : m_pBuilder(pBuilder) {}
335 bool operator()(const vcl::Window *pA, const vcl::Window *pB) const;
337 private:
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;
344 private:
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,
352 stringmap &rVec);
354 void connectNumericFormatterAdjustment(const OString &id, const OUString &rAdjustment);
355 void connectTimeFormatterAdjustment(const OString &id, const OUString &rAdjustment);
356 void connectDateFormatterAdjustment(const OString &id, const OUString &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 static std::vector<vcl::EnumContext::Context> handleStyle(xmlreader::XmlReader &reader, int &nPriority);
372 static OString getStyleClass(xmlreader::XmlReader &reader);
373 void applyPackingProperty(vcl::Window *pCurrent, vcl::Window *pParent, xmlreader::XmlReader &reader);
374 void collectProperty(xmlreader::XmlReader &reader, const OString &rID, stringmap &rVec);
375 static void collectPangoAttribute(xmlreader::XmlReader &reader, stringmap &rMap);
376 static void collectAtkAttribute(xmlreader::XmlReader &reader, stringmap &rMap);
377 static void collectAccelerator(xmlreader::XmlReader &reader, accelmap &rMap);
379 void insertMenuObject(
380 PopupMenu *pParent,
381 PopupMenu *pSubMenu,
382 const OString &rClass,
383 const OString &rID,
384 stringmap &rProps,
385 accelmap &rAccels);
387 void handleMenuChild(PopupMenu *pParent, xmlreader::XmlReader &reader);
388 void handleMenuObject(PopupMenu *pParent, xmlreader::XmlReader &reader);
390 void handleListStore(xmlreader::XmlReader &reader, const OString &rID);
391 void handleRow(xmlreader::XmlReader &reader, const OString &rID, sal_Int32 nRowIndex);
392 void handleTabChild(vcl::Window *pParent, xmlreader::XmlReader &reader);
393 void handleMenu(xmlreader::XmlReader &reader, const OString &rID);
394 std::vector<OUString> handleItems(xmlreader::XmlReader &reader, const OString &rID);
396 void handleSizeGroup(xmlreader::XmlReader &reader, const OString &rID);
398 void handleAtkObject(xmlreader::XmlReader &reader, const OString &rID, vcl::Window *pWindow);
400 void handleActionWidget(xmlreader::XmlReader &reader);
402 PackingData get_window_packing_data(const vcl::Window *pWindow) const;
403 void set_window_packing_position(const vcl::Window *pWindow, sal_Int32 nPosition);
405 static vcl::Window* prepareWidgetOwnScrolling(vcl::Window *pParent, WinBits &rWinStyle);
406 void cleanupWidgetOwnScrolling(vcl::Window *pScrollParent, vcl::Window *pWindow, stringmap &rMap);
408 void set_response(const OString& sID, short nResponse);
411 template <typename T>
412 inline T* VclBuilder::get(VclPtr<T>& ret, const OString& sID)
414 vcl::Window *w = get_by_name(sID);
415 SAL_WARN_IF(!w, "vcl.layout", "widget \"" << sID.getStr() << "\" not found in .ui");
416 SAL_WARN_IF(!dynamic_cast<T*>(w),
417 "vcl.layout", ".ui widget \"" << sID.getStr() << "\" needs to correspond to vcl type " << typeid(T).name());
418 assert(w);
419 assert(dynamic_cast<T*>(w));
420 ret = static_cast<T*>(w);
421 return ret.get();
424 //sID may not exist, but must be of type T if it does
425 template <typename T /*= vcl::Window if we had c++11*/>
426 inline T* VclBuilder::get(const OString& sID)
428 vcl::Window *w = get_by_name(sID);
429 SAL_WARN_IF(w && !dynamic_cast<T*>(w),
430 "vcl.layout", ".ui widget \"" << sID.getStr() << "\" needs to correspond to vcl type " << typeid(T).name());
431 assert(!w || dynamic_cast<T*>(w));
432 return static_cast<T*>(w);
436 //helper baseclass to ease retro fitting dialogs/tabpages that load a resource
437 //to load a .ui file instead
439 //vcl requires the Window Children of a Parent Window to be destroyed before
440 //the Parent Window. VclBuilderContainer owns the VclBuilder which owns the
441 //Children Window. So the VclBuilderContainer dtor must be called before
442 //the Parent Window dtor.
444 //i.e. class Dialog : public SystemWindow, public VclBuilderContainer
445 //not class Dialog : public VclBuilderContainer, public SystemWindow
447 //With the new 'dispose' framework, it is necessary to force the builder
448 //dispose before the Window dispose; so a Dialog::dispose() method would
449 //finish: disposeBuilder(); SystemWindow::dispose() to capture this ordering.
451 class VCL_DLLPUBLIC VclBuilderContainer
453 public:
454 VclBuilderContainer();
455 virtual ~VclBuilderContainer();
456 void disposeBuilder();
458 static OUString getUIRootDir();
459 bool hasBuilder() const { return m_pUIBuilder != nullptr; }
461 template <typename T> T* get(VclPtr<T>& ret, const OString& sID)
463 return m_pUIBuilder->get<T>(ret, sID);
465 template <typename T /*= vcl::Window if we had c++11*/> T* get(const OString & sID)
467 return m_pUIBuilder->get<T>(sID);
469 PopupMenu* get_menu(const OString & sID)
471 return m_pUIBuilder->get_menu(sID);
473 void setDeferredProperties()
475 if (!m_pUIBuilder)
476 return;
477 m_pUIBuilder->setDeferredProperties();
479 OString getUIFile() const
481 if (m_pUIBuilder)
483 return m_pUIBuilder->getUIFile();
486 return OString();
489 protected:
490 std::unique_ptr<VclBuilder> m_pUIBuilder;
494 * @return true if rValue is "True", "true", "1", etc.
496 bool VCL_DLLPUBLIC toBool(const OUString &rValue);
498 #endif
500 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */