Branch libreoffice-5-0-4
[LibreOffice.git] / include / vcl / builder.hxx
blob518d8a87b9ac30869efa19315acd06c23cc9c126
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 <map>
22 #include <set>
23 #include <stack>
24 #include <vector>
25 #ifdef check
26 # //some problem with MacOSX and a check define
27 # undef check
28 #endif
29 #include <boost/ptr_container/ptr_map.hpp>
31 #include <com/sun/star/frame/XFrame.hpp>
32 #include <com/sun/star/uno/XComponentContext.hpp>
34 class ListBox;
35 class NumericFormatter;
36 class PopupMenu;
37 class ScrollBar;
38 class Slider;
39 class DateField;
40 class TimeField;
41 class VclExpander;
42 class VclMultiLineEdit;
43 namespace xmlreader { class XmlReader; }
45 class VCL_DLLPUBLIC VclBuilder
47 public:
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);
52 public:
53 VclBuilder(
54 vcl::Window *pParent,
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>());
59 ~VclBuilder();
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);
74 //sID may not exist
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,
116 bool bLarge,
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; }
123 private:
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
138 //Show or Execute
139 stringmap m_aDeferredProperties;
141 struct PackingData
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)
152 struct WinAndId
154 OString m_sID;
155 VclPtr<vcl::Window> m_pWindow;
156 short m_nResponseId;
157 PackingData m_aPackingData;
158 WinAndId(const OString &rId, vcl::Window *pWindow, bool bVertical)
159 : m_sID(rId)
160 , m_pWindow(pWindow)
161 , m_nResponseId(RET_CANCEL)
162 , m_aPackingData(bVertical)
166 std::vector<WinAndId> m_aChildren;
168 struct MenuAndId
170 OString m_sID;
171 PopupMenu *m_pMenu;
172 MenuAndId(const OString &rId, PopupMenu *pMenu)
173 : m_sID(rId)
174 , m_pMenu(pMenu)
178 std::vector<MenuAndId> m_aMenus;
180 struct StringPair
182 OString m_sID;
183 OString m_sValue;
184 StringPair(const OString &rId, const OString &rValue)
185 : m_sID(rId)
186 , m_sValue(rValue)
191 typedef StringPair RadioButtonGroupMap;
193 struct ButtonImageWidgetMap
195 OString m_sID;
196 OString m_sValue;
197 bool m_bRadio;
198 ButtonImageWidgetMap(const OString &rId, const OString &rValue, bool bRadio)
199 : m_sID(rId)
200 , m_sValue(rValue)
201 , m_bRadio(bRadio)
206 typedef StringPair TextBufferMap;
207 typedef StringPair WidgetAdjustmentMap;
208 typedef StringPair ButtonMenuMap;
209 typedef StringPair MnemonicWidgetMap;
211 struct ComboBoxModelMap
213 OString m_sID;
214 OString m_sValue;
215 sal_Int32 m_nActiveId;
216 ComboBoxModelMap(const OString &rId, const OString &rValue, sal_Int32 nActiveId)
217 : m_sID(rId)
218 , m_sValue(rValue)
219 , m_nActiveId(nActiveId)
224 struct ListStore
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;
234 const 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;
251 struct stockinfo
253 OString m_sStock;
254 int m_nSize;
255 stockinfo() : m_nSize(4) {}
258 typedef std::map<OString, stockinfo> StockMap;
260 struct SizeGroup
262 OString m_sID;
263 std::vector<OString> m_aWidgets;
264 stringmap m_aProperties;
265 SizeGroup(const OString &rId)
266 : m_sID(rId)
271 typedef std::map< VclPtr<vcl::Window>, stringmap> AtkMap;
273 struct ParserState
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;
302 AtkMap m_aAtkInfo;
304 std::vector<MnemonicWidgetMap> m_aMnemonicWidgetMaps;
306 std::vector< VclPtr<VclExpander> > m_aExpanderWidgets;
308 sal_uInt16 m_nLastToolbarId;
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 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 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(
378 PopupMenu *pParent,
379 const OString &rClass,
380 const OString &rID,
381 stringmap &rProps,
382 stringmap &rAccels);
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());
417 assert(w);
418 assert(dynamic_cast<T*>(w));
419 ret = static_cast<T*>(w);
420 return ret.get();
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)
436 ret = get_menu(sID);
437 SAL_WARN_IF(!ret, "vcl.layout", "menu \"" << sID.getStr() << "\" not found in .ui");
438 assert(ret);
439 return ret;
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
459 public:
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()
487 if (!m_pUIBuilder)
488 return;
489 m_pUIBuilder->setDeferredProperties();
492 protected:
493 VclBuilder *m_pUIBuilder;
497 * @return true if rValue is "True", "true", "1", etc.
499 bool VCL_DLLPUBLIC toBool(const OString &rValue);
501 #endif
503 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */