Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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 : */
9 :
10 : #include <com/sun/star/frame/ModuleManager.hpp>
11 : #include <com/sun/star/frame/XModuleManager2.hpp>
12 : #include <com/sun/star/frame/theUICommandDescription.hpp>
13 : #include <com/sun/star/packages/zip/ZipFileAccess.hpp>
14 : #include <com/sun/star/ui/ImageType.hpp>
15 : #include <com/sun/star/ui/XImageManager.hpp>
16 : #include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp>
17 : #include <com/sun/star/ui/XUIConfigurationManager.hpp>
18 : #include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
19 : #include <com/sun/star/ui/theModuleUIConfigurationManagerSupplier.hpp>
20 :
21 : #include <comphelper/processfactory.hxx>
22 : #include <osl/module.hxx>
23 : #include <sal/log.hxx>
24 : #include <unotools/configmgr.hxx>
25 : #include <vcl/builder.hxx>
26 : #include <vcl/button.hxx>
27 : #include <vcl/dialog.hxx>
28 : #include <vcl/edit.hxx>
29 : #include <vcl/field.hxx>
30 : #include <vcl/fixed.hxx>
31 : #include <vcl/fixedhyper.hxx>
32 : #include <vcl/layout.hxx>
33 : #include <vcl/lstbox.hxx>
34 : #include <vcl/menubtn.hxx>
35 : #include <vcl/mnemonic.hxx>
36 : #include <vcl/prgsbar.hxx>
37 : #include <vcl/scrbar.hxx>
38 : #include <vcl/svapp.hxx>
39 : #include <vcl/tabctrl.hxx>
40 : #include <vcl/tabpage.hxx>
41 : #include <vcl/throbber.hxx>
42 : #include <vcl/toolbox.hxx>
43 : #include <vcl/vclmedit.hxx>
44 : #include <vcl/settings.hxx>
45 : #include <vcl/slider.hxx>
46 : #include <svdata.hxx>
47 : #include <svids.hrc>
48 : #include <window.h>
49 : #include <xmlreader/xmlreader.hxx>
50 :
51 : using namespace com::sun::star;
52 :
53 : #ifdef DISABLE_DYNLOADING
54 : #include <dlfcn.h>
55 : #endif
56 :
57 : namespace
58 : {
59 0 : sal_uInt16 mapStockToImageResource(const OString& sType)
60 : {
61 0 : sal_uInt16 nRet = 0;
62 0 : if (sType == "gtk-index")
63 0 : nRet = SV_RESID_BITMAP_INDEX;
64 0 : else if (sType == "gtk-refresh")
65 0 : nRet = SV_RESID_BITMAP_REFRESH;
66 0 : return nRet;
67 : }
68 :
69 0 : SymbolType mapStockToSymbol(const OString& sType)
70 : {
71 0 : SymbolType eRet = SymbolType::DONTKNOW;
72 0 : if (sType == "gtk-media-next")
73 0 : eRet = SymbolType::NEXT;
74 0 : else if (sType == "gtk-media-previous")
75 0 : eRet = SymbolType::PREV;
76 0 : else if (sType == "gtk-media-play")
77 0 : eRet = SymbolType::PLAY;
78 0 : else if (sType == "gtk-media-stop")
79 0 : eRet = SymbolType::STOP;
80 0 : else if (sType == "gtk-goto-first")
81 0 : eRet = SymbolType::FIRST;
82 0 : else if (sType == "gtk-goto-last")
83 0 : eRet = SymbolType::LAST;
84 0 : else if (sType == "gtk-go-back")
85 0 : eRet = SymbolType::ARROW_LEFT;
86 0 : else if (sType == "gtk-go-forward")
87 0 : eRet = SymbolType::ARROW_RIGHT;
88 0 : else if (sType == "gtk-go-up")
89 0 : eRet = SymbolType::ARROW_UP;
90 0 : else if (sType == "gtk-go-down")
91 0 : eRet = SymbolType::ARROW_DOWN;
92 0 : else if (sType == "gtk-missing-image")
93 0 : eRet = SymbolType::IMAGE;
94 0 : else if (sType == "gtk-help")
95 0 : eRet = SymbolType::HELP;
96 0 : else if (sType == "gtk-close")
97 0 : eRet = SymbolType::CLOSE;
98 0 : else if (mapStockToImageResource(sType))
99 0 : eRet = SymbolType::IMAGE;
100 0 : return eRet;
101 : }
102 : }
103 :
104 0 : void VclBuilder::loadTranslations(const LanguageTag &rLanguageTag, const OUString& rUri)
105 : {
106 : /* FIXME-BCP47: support language tags with
107 : * LanguageTag::getFallbackStrings() ? */
108 0 : for (int i = rLanguageTag.getCountry().isEmpty() ? 1 : 0; i < 2; ++i)
109 : {
110 0 : OUStringBuffer aTransBuf;
111 0 : sal_Int32 nLastSlash = rUri.lastIndexOf('/');
112 0 : if (nLastSlash != -1)
113 0 : aTransBuf.append(rUri.copy(0, nLastSlash));
114 : else
115 : {
116 0 : aTransBuf.append('.');
117 0 : nLastSlash = 0;
118 : }
119 0 : aTransBuf.append("/res/");
120 0 : OUString sLang(rLanguageTag.getLanguage());
121 0 : switch (i)
122 : {
123 : case 0:
124 0 : sLang = sLang + "-" + rLanguageTag.getCountry();
125 0 : break;
126 : default:
127 0 : break;
128 : }
129 0 : aTransBuf.append(sLang);
130 0 : aTransBuf.append(".zip");
131 0 : sal_Int32 nEndName = rUri.lastIndexOf('.');
132 0 : if (nEndName == -1)
133 0 : nEndName = rUri.getLength();
134 0 : OUString sZippedFile(rUri.copy(nLastSlash + 1, nEndName - nLastSlash - 1) + "/" + sLang + ".ui");
135 : try
136 : {
137 : uno::Reference<packages::zip::XZipFileAccess2> xNameAccess =
138 : packages::zip::ZipFileAccess::createWithURL(
139 0 : comphelper::getProcessComponentContext(), aTransBuf.makeStringAndClear());
140 0 : if (!xNameAccess.is())
141 0 : continue;
142 0 : uno::Reference<io::XInputStream> xInputStream(xNameAccess->getByName(sZippedFile), uno::UNO_QUERY);
143 0 : if (!xInputStream.is())
144 0 : continue;
145 0 : OStringBuffer sStr;
146 : for (;;)
147 : {
148 0 : sal_Int32 const size = 2048;
149 0 : css::uno::Sequence< sal_Int8 > data(size);
150 0 : sal_Int32 n = xInputStream->readBytes(data, size);
151 0 : sStr.append(reinterpret_cast<const sal_Char *>(data.getConstArray()), n);
152 0 : if (n < size)
153 0 : break;
154 0 : }
155 :
156 0 : xmlreader::XmlReader reader(sStr.getStr(), sStr.getLength());
157 0 : handleTranslations(reader);
158 0 : break;
159 : }
160 0 : catch (const uno::Exception &)
161 : {
162 : }
163 0 : }
164 0 : }
165 :
166 : #if defined SAL_LOG_WARN
167 : namespace
168 : {
169 : bool isButtonType(WindowType nType)
170 : {
171 : return nType == WINDOW_PUSHBUTTON ||
172 : nType == WINDOW_OKBUTTON ||
173 : nType == WINDOW_CANCELBUTTON ||
174 : nType == WINDOW_HELPBUTTON ||
175 : nType == WINDOW_IMAGEBUTTON ||
176 : nType == WINDOW_MENUBUTTON ||
177 : nType == WINDOW_MOREBUTTON ||
178 : nType == WINDOW_SPINBUTTON;
179 : }
180 : }
181 : #endif
182 :
183 1761 : VclBuilder::VclBuilder(vcl::Window *pParent, const OUString& sUIDir, const OUString& sUIFile, const OString& sID, const uno::Reference<frame::XFrame>& rFrame)
184 : : m_sID(sID)
185 : , m_sHelpRoot(OUStringToOString(sUIFile, RTL_TEXTENCODING_UTF8))
186 1761 : , m_pStringReplace(ResMgr::GetReadStringHook())
187 : , m_pParent(pParent)
188 : , m_bToplevelParentFound(false)
189 1761 : , m_pParserState(new ParserState)
190 5406 : , m_xFrame(rFrame)
191 : {
192 3542 : m_bToplevelHasDeferredInit = pParent &&
193 3522 : ((pParent->IsSystemWindow() && static_cast<SystemWindow*>(pParent)->isDeferredInit()) ||
194 3536 : (pParent->IsDockingWindow() && static_cast<DockingWindow*>(pParent)->isDeferredInit()));
195 1761 : m_bToplevelHasDeferredProperties = m_bToplevelHasDeferredInit;
196 :
197 1761 : sal_Int32 nIdx = m_sHelpRoot.lastIndexOf('.');
198 1761 : if (nIdx != -1)
199 1761 : m_sHelpRoot = m_sHelpRoot.copy(0, nIdx);
200 1761 : m_sHelpRoot = m_sHelpRoot + OString('/');
201 :
202 1761 : OUString sUri = sUIDir + sUIFile;
203 :
204 1761 : const LanguageTag& rLanguageTag = Application::GetSettings().GetUILanguageTag();
205 1761 : bool bEN_US = (rLanguageTag.getBcp47() == "en-US");
206 1761 : if (!bEN_US)
207 0 : loadTranslations(rLanguageTag, sUri);
208 :
209 : try
210 : {
211 1761 : xmlreader::XmlReader reader(sUri);
212 :
213 1638 : handleChild(pParent, reader);
214 : }
215 123 : catch (const uno::Exception &rExcept)
216 : {
217 : SAL_WARN("vcl.layout", "Unable to read .ui file: " << rExcept.Message);
218 123 : throw;
219 : }
220 :
221 : //Set Mnemonic widgets when everything has been imported
222 4412 : for (std::vector<MnemonicWidgetMap>::iterator aI = m_pParserState->m_aMnemonicWidgetMaps.begin(),
223 1638 : aEnd = m_pParserState->m_aMnemonicWidgetMaps.end(); aI != aEnd; ++aI)
224 : {
225 1136 : FixedText *pOne = get<FixedText>(aI->m_sID);
226 1136 : vcl::Window *pOther = get<vcl::Window>(aI->m_sValue);
227 : SAL_WARN_IF(!pOne || !pOther, "vcl", "missing either source " << aI->m_sID << " or target " << aI->m_sValue << " member of Mnemonic Widget Mapping");
228 1136 : if (pOne && pOther)
229 1136 : pOne->set_mnemonic_widget(pOther);
230 : }
231 :
232 : //Set a11y relations when everything has been imported
233 29460 : for (AtkMap::iterator aI = m_pParserState->m_aAtkInfo.begin(),
234 1638 : aEnd = m_pParserState->m_aAtkInfo.end(); aI != aEnd; ++aI)
235 : {
236 26184 : vcl::Window *pSource = aI->first;
237 26184 : const stringmap &rMap = aI->second;
238 :
239 52374 : for (stringmap::const_iterator aP = rMap.begin(),
240 26184 : aEndP = rMap.end(); aP != aEndP; ++aP)
241 : {
242 6 : const OString &rTarget = aP->second;
243 6 : vcl::Window *pTarget = get<vcl::Window>(rTarget);
244 : SAL_WARN_IF(!pTarget, "vcl", "missing member of a11y relation: "
245 : << rTarget.getStr());
246 6 : if (!pTarget)
247 0 : continue;
248 6 : const OString &rType = aP->first;
249 6 : if (rType == "labelled-by")
250 6 : pSource->SetAccessibleRelationLabeledBy(pTarget);
251 0 : else if (rType == "label-for")
252 0 : pSource->SetAccessibleRelationLabelFor(pTarget);
253 0 : else if (rType == "member-of")
254 0 : pSource->SetAccessibleRelationMemberOf(pTarget);
255 : else
256 : {
257 : SAL_INFO("vcl.layout", "unhandled a11y relation :" << rType.getStr());
258 : }
259 : }
260 : }
261 :
262 : //Set radiobutton groups when everything has been imported
263 3276 : for (std::vector<RadioButtonGroupMap>::iterator aI = m_pParserState->m_aGroupMaps.begin(),
264 1638 : aEnd = m_pParserState->m_aGroupMaps.end(); aI != aEnd; ++aI)
265 : {
266 0 : RadioButton *pOne = get<RadioButton>(aI->m_sID);
267 0 : RadioButton *pOther = get<RadioButton>(aI->m_sValue);
268 : SAL_WARN_IF(!pOne || !pOther, "vcl", "missing member of radiobutton group");
269 0 : if (pOne && pOther)
270 0 : pOne->group(*pOther);
271 : }
272 :
273 : //Set ComboBox models when everything has been imported
274 3276 : for (std::vector<ComboBoxModelMap>::iterator aI = m_pParserState->m_aModelMaps.begin(),
275 1638 : aEnd = m_pParserState->m_aModelMaps.end(); aI != aEnd; ++aI)
276 : {
277 0 : ListBox *pTarget = get<ListBox>(aI->m_sID);
278 0 : const ListStore *pStore = get_model_by_name(aI->m_sValue);
279 : SAL_WARN_IF(!pTarget || !pStore, "vcl", "missing elements of combobox/liststore");
280 0 : if (pTarget && pStore)
281 0 : mungeModel(*pTarget, *pStore, aI->m_nActiveId);
282 : }
283 :
284 : //Set TextView buffers when everything has been imported
285 3276 : for (std::vector<TextBufferMap>::iterator aI = m_pParserState->m_aTextBufferMaps.begin(),
286 1638 : aEnd = m_pParserState->m_aTextBufferMaps.end(); aI != aEnd; ++aI)
287 : {
288 0 : VclMultiLineEdit *pTarget = get<VclMultiLineEdit>(aI->m_sID);
289 0 : const TextBuffer *pBuffer = get_buffer_by_name(aI->m_sValue);
290 : SAL_WARN_IF(!pTarget || !pBuffer, "vcl", "missing elements of textview/textbuffer");
291 0 : if (pTarget && pBuffer)
292 0 : mungeTextBuffer(*pTarget, *pBuffer);
293 : }
294 :
295 : //Set SpinButton adjustments when everything has been imported
296 3279 : for (std::vector<WidgetAdjustmentMap>::iterator aI = m_pParserState->m_aNumericFormatterAdjustmentMaps.begin(),
297 1638 : aEnd = m_pParserState->m_aNumericFormatterAdjustmentMaps.end(); aI != aEnd; ++aI)
298 : {
299 3 : NumericFormatter *pTarget = dynamic_cast<NumericFormatter*>(get<vcl::Window>(aI->m_sID));
300 3 : const Adjustment *pAdjustment = get_adjustment_by_name(aI->m_sValue);
301 : SAL_WARN_IF(!pTarget, "vcl", "missing NumericFormatter element of spinbutton/adjustment");
302 : SAL_WARN_IF(!pAdjustment, "vcl", "missing Adjustment element of spinbutton/adjustment");
303 3 : if (pTarget && pAdjustment)
304 3 : mungeAdjustment(*pTarget, *pAdjustment);
305 : }
306 :
307 3276 : for (std::vector<WidgetAdjustmentMap>::iterator aI = m_pParserState->m_aTimeFormatterAdjustmentMaps.begin(),
308 1638 : aEnd = m_pParserState->m_aTimeFormatterAdjustmentMaps.end(); aI != aEnd; ++aI)
309 : {
310 0 : TimeField *pTarget = dynamic_cast<TimeField*>(get<vcl::Window>(aI->m_sID));
311 0 : const Adjustment *pAdjustment = get_adjustment_by_name(aI->m_sValue);
312 : SAL_WARN_IF(!pTarget || !pAdjustment, "vcl", "missing elements of spinbutton/adjustment");
313 0 : if (pTarget && pAdjustment)
314 0 : mungeAdjustment(*pTarget, *pAdjustment);
315 : }
316 :
317 3276 : for (std::vector<WidgetAdjustmentMap>::iterator aI = m_pParserState->m_aDateFormatterAdjustmentMaps.begin(),
318 1638 : aEnd = m_pParserState->m_aDateFormatterAdjustmentMaps.end(); aI != aEnd; ++aI)
319 : {
320 0 : DateField *pTarget = dynamic_cast<DateField*>(get<vcl::Window>(aI->m_sID));
321 0 : const Adjustment *pAdjustment = get_adjustment_by_name(aI->m_sValue);
322 : SAL_WARN_IF(!pTarget || !pAdjustment, "vcl", "missing elements of spinbutton/adjustment");
323 0 : if (pTarget && pAdjustment)
324 0 : mungeAdjustment(*pTarget, *pAdjustment);
325 : }
326 :
327 : //Set ScrollBar adjustments when everything has been imported
328 3276 : for (std::vector<WidgetAdjustmentMap>::iterator aI = m_pParserState->m_aScrollAdjustmentMaps.begin(),
329 1638 : aEnd = m_pParserState->m_aScrollAdjustmentMaps.end(); aI != aEnd; ++aI)
330 : {
331 0 : ScrollBar *pTarget = get<ScrollBar>(aI->m_sID);
332 0 : const Adjustment *pAdjustment = get_adjustment_by_name(aI->m_sValue);
333 : SAL_WARN_IF(!pTarget || !pAdjustment, "vcl", "missing elements of scrollbar/adjustment");
334 0 : if (pTarget && pAdjustment)
335 0 : mungeAdjustment(*pTarget, *pAdjustment);
336 : }
337 :
338 : //Set Scale(Slider) adjustments
339 1638 : std::vector<WidgetAdjustmentMap>::iterator aIterator;
340 4914 : for (aIterator = m_pParserState->m_aSliderAdjustmentMaps.begin();
341 3276 : aIterator != m_pParserState->m_aSliderAdjustmentMaps.end(); ++aIterator)
342 : {
343 0 : Slider* pTarget = dynamic_cast<Slider*>(get<vcl::Window>(aIterator->m_sID));
344 0 : const Adjustment* pAdjustment = get_adjustment_by_name(aIterator->m_sValue);
345 : SAL_WARN_IF(!pTarget || !pAdjustment, "vcl", "missing elements of scale(slider)/adjustment");
346 0 : if (pTarget && pAdjustment)
347 : {
348 0 : mungeAdjustment(*pTarget, *pAdjustment);
349 : }
350 : }
351 :
352 : //Set size-groups when all widgets have been imported
353 3615 : for (std::vector<SizeGroup>::iterator aI = m_pParserState->m_aSizeGroups.begin(),
354 1638 : aEnd = m_pParserState->m_aSizeGroups.end(); aI != aEnd; ++aI)
355 : {
356 339 : std::shared_ptr<VclSizeGroup> xGroup(std::make_shared<VclSizeGroup>());
357 :
358 1017 : for (stringmap::iterator aP = aI->m_aProperties.begin(),
359 339 : aEndP = aI->m_aProperties.end(); aP != aEndP; ++aP)
360 : {
361 339 : const OString &rKey = aP->first;
362 339 : const OString &rValue = aP->second;
363 339 : xGroup->set_property(rKey, rValue);
364 : }
365 :
366 2708 : for (std::vector<OString>::iterator aW = aI->m_aWidgets.begin(),
367 339 : aEndW = aI->m_aWidgets.end(); aW != aEndW; ++aW)
368 : {
369 2030 : vcl::Window* pWindow = get<vcl::Window>(aW->getStr());
370 2030 : pWindow->add_to_size_group(xGroup);
371 : }
372 339 : }
373 :
374 : //Set button images when everything has been imported
375 3276 : std::set<OString> aImagesToBeRemoved;
376 3285 : for (std::vector<ButtonImageWidgetMap>::iterator aI = m_pParserState->m_aButtonImageWidgetMaps.begin(),
377 1638 : aEnd = m_pParserState->m_aButtonImageWidgetMaps.end(); aI != aEnd; ++aI)
378 : {
379 9 : PushButton *pTargetButton = NULL;
380 9 : RadioButton *pTargetRadio = NULL;
381 9 : Button *pTarget = NULL;
382 :
383 9 : if (!aI->m_bRadio)
384 : {
385 9 : pTargetButton = get<PushButton>(aI->m_sID);
386 9 : pTarget = pTargetButton;
387 : }
388 : else
389 : {
390 0 : pTargetRadio = get<RadioButton>(aI->m_sID);
391 0 : pTarget = pTargetRadio;
392 : }
393 :
394 9 : FixedImage *pImage = get<FixedImage>(aI->m_sValue);
395 : SAL_WARN_IF(!pTarget || !pImage,
396 : "vcl", "missing elements of button/image/stock");
397 9 : if (!pTarget || !pImage)
398 0 : continue;
399 9 : aImagesToBeRemoved.insert(aI->m_sValue);
400 :
401 9 : VclBuilder::StockMap::iterator aFind = m_pParserState->m_aStockMap.find(aI->m_sValue);
402 9 : if (aFind == m_pParserState->m_aStockMap.end())
403 : {
404 9 : if (!aI->m_bRadio)
405 9 : pTargetButton->SetModeImage(pImage->GetImage());
406 : else
407 0 : pTargetRadio->SetModeRadioImage(pImage->GetImage());
408 : }
409 : else
410 : {
411 0 : const stockinfo &rImageInfo = aFind->second;
412 0 : SymbolType eType = mapStockToSymbol(rImageInfo.m_sStock);
413 : SAL_WARN_IF(eType == SymbolType::DONTKNOW, "vcl", "missing stock image element for button");
414 0 : if (eType == SymbolType::DONTKNOW)
415 0 : continue;
416 0 : if (!aI->m_bRadio)
417 : {
418 0 : pTargetButton->SetSymbol(eType);
419 : //fdo#76457 keep symbol images small e.g. tools->customize->menu
420 : //but images the right size. Really the PushButton::CalcMinimumSize
421 : //and PushButton::ImplDrawPushButton are the better place to handle
422 : //this, but its such a train-wreck
423 0 : if (eType != SymbolType::IMAGE)
424 0 : pTargetButton->SetStyle(pTargetButton->GetStyle() | WB_SMALLSTYLE);
425 : }
426 : else
427 : SAL_WARN_IF(eType != SymbolType::IMAGE, "vcl.layout", "inimplemented symbol type for radiobuttons");
428 0 : if (eType == SymbolType::IMAGE)
429 : {
430 0 : Bitmap aBitmap(VclResId(mapStockToImageResource(rImageInfo.m_sStock)));
431 0 : Image const aImage(aBitmap);
432 0 : if (!aI->m_bRadio)
433 0 : pTargetButton->SetModeImage(aImage);
434 : else
435 0 : pTargetRadio->SetModeRadioImage(aImage);
436 : }
437 0 : switch (rImageInfo.m_nSize)
438 : {
439 : case 1:
440 0 : pTarget->SetSmallSymbol();
441 0 : break;
442 : case 4:
443 0 : break;
444 : default:
445 : SAL_WARN("vcl.layout", "unsupported image size " << rImageInfo.m_nSize);
446 0 : break;
447 : }
448 : }
449 : }
450 :
451 : //There may be duplicate use of an Image, so we used a set to collect and
452 : //now we can remove them from the tree after their final munge
453 3285 : for (std::set<OString>::iterator aI = aImagesToBeRemoved.begin(),
454 1638 : aEnd = aImagesToBeRemoved.end(); aI != aEnd; ++aI)
455 : {
456 9 : delete_by_name(*aI);
457 : }
458 :
459 : //Set button menus when everything has been imported
460 3277 : for (std::vector<ButtonMenuMap>::iterator aI = m_pParserState->m_aButtonMenuMaps.begin(),
461 1638 : aEnd = m_pParserState->m_aButtonMenuMaps.end(); aI != aEnd; ++aI)
462 : {
463 1 : MenuButton *pTarget = get<MenuButton>(aI->m_sID);
464 1 : PopupMenu *pMenu = get_menu(aI->m_sValue);
465 : SAL_WARN_IF(!pTarget || !pMenu,
466 : "vcl", "missing elements of button/menu");
467 1 : if (!pTarget || !pMenu)
468 0 : continue;
469 1 : pTarget->SetPopupMenu(pMenu);
470 : }
471 :
472 : //Remove ScrollWindow parent widgets whose children in vcl implement scrolling
473 : //internally.
474 3276 : for (auto aI = m_pParserState->m_aRedundantParentWidgets.begin(),
475 1638 : aEnd = m_pParserState->m_aRedundantParentWidgets.end(); aI != aEnd; ++aI)
476 : {
477 0 : delete_by_window(aI->first);
478 : }
479 :
480 : //fdo#67378 merge the label into the disclosure button
481 3276 : for (auto aI = m_pParserState->m_aExpanderWidgets.begin(),
482 1638 : aEnd = m_pParserState->m_aExpanderWidgets.end(); aI != aEnd; ++aI)
483 : {
484 0 : VclExpander *pOne = *aI;
485 :
486 0 : vcl::Window *pChild = pOne->get_child();
487 0 : vcl::Window* pLabel = pOne->GetWindow(GetWindowType::LastChild);
488 0 : if (pLabel && pLabel != pChild && pLabel->GetType() == WINDOW_FIXEDTEXT)
489 : {
490 0 : FixedText *pLabelWidget = static_cast<FixedText*>(pLabel);
491 0 : pOne->set_label(pLabelWidget->GetText());
492 0 : delete_by_window(pLabel);
493 : }
494 : }
495 :
496 : //drop maps, etc. that we don't need again
497 1638 : delete m_pParserState;
498 :
499 : SAL_WARN_IF(!m_sID.isEmpty() && (!m_bToplevelParentFound && !get_by_name(m_sID)), "vcl.layout",
500 : "Requested top level widget \"" << m_sID.getStr() <<
501 1761 : "\" not found in " << sUIFile);
502 :
503 : #if defined SAL_LOG_WARN
504 : if (m_bToplevelParentFound && m_pParent->IsDialog())
505 : {
506 : int nButtons = 0;
507 : bool bHasDefButton = false;
508 : for (std::vector<WinAndId>::iterator aI = m_aChildren.begin(),
509 : aEnd = m_aChildren.end(); aI != aEnd; ++aI)
510 : {
511 : if (isButtonType(aI->m_pWindow->GetType()))
512 : {
513 : ++nButtons;
514 : if (aI->m_pWindow->GetStyle() & WB_DEFBUTTON)
515 : {
516 : bHasDefButton = true;
517 : break;
518 : }
519 : }
520 : }
521 : SAL_WARN_IF(nButtons && !bHasDefButton, "vcl.layout", "No default button defined in " << sUIFile);
522 : }
523 : #endif
524 1638 : }
525 :
526 0 : VclBuilder::~VclBuilder()
527 : {
528 0 : disposeBuilder();
529 0 : }
530 :
531 1638 : void VclBuilder::disposeBuilder()
532 : {
533 27813 : for (std::vector<WinAndId>::reverse_iterator aI = m_aChildren.rbegin(),
534 1638 : aEnd = m_aChildren.rend(); aI != aEnd; ++aI)
535 : {
536 24537 : aI->m_pWindow.disposeAndClear();
537 : }
538 1638 : m_aChildren.clear();
539 :
540 3277 : for (std::vector<MenuAndId>::reverse_iterator aI = m_aMenus.rbegin(),
541 1638 : aEnd = m_aMenus.rend(); aI != aEnd; ++aI)
542 : {
543 1 : delete aI->m_pMenu;
544 : }
545 1638 : m_aMenus.clear();
546 1638 : }
547 :
548 0 : void VclBuilder::handleTranslations(xmlreader::XmlReader &reader)
549 : {
550 0 : xmlreader::Span name;
551 : int nsId;
552 :
553 0 : OString sID, sProperty;
554 :
555 : while(true)
556 : {
557 : xmlreader::XmlReader::Result res = reader.nextItem(
558 0 : xmlreader::XmlReader::TEXT_RAW, &name, &nsId);
559 :
560 0 : if (res == xmlreader::XmlReader::RESULT_BEGIN)
561 : {
562 0 : if (name.equals("e"))
563 : {
564 0 : while (reader.nextAttribute(&nsId, &name))
565 : {
566 0 : if (name.equals("g"))
567 : {
568 0 : name = reader.getAttributeValue(false);
569 0 : sID = OString(name.begin, name.length);
570 0 : sal_Int32 nDelim = sID.indexOf(':');
571 0 : if (nDelim != -1)
572 0 : sID = sID.copy(nDelim);
573 : }
574 0 : else if (name.equals("i"))
575 : {
576 0 : name = reader.getAttributeValue(false);
577 0 : sProperty = OString(name.begin, name.length);
578 : }
579 : }
580 : }
581 : }
582 :
583 0 : if (res == xmlreader::XmlReader::RESULT_TEXT && !sID.isEmpty())
584 : {
585 0 : OString sTranslation(name.begin, name.length);
586 0 : m_pParserState->m_aTranslations[sID][sProperty] = sTranslation;
587 : }
588 :
589 0 : if (res == xmlreader::XmlReader::RESULT_END)
590 0 : sID.clear();
591 :
592 0 : if (res == xmlreader::XmlReader::RESULT_DONE)
593 0 : break;
594 0 : }
595 0 : }
596 :
597 4556 : OString VclBuilder::extractCustomProperty(VclBuilder::stringmap &rMap)
598 : {
599 4556 : OString sCustomProperty;
600 4556 : VclBuilder::stringmap::iterator aFind = rMap.find(OString("customproperty"));
601 4556 : if (aFind != rMap.end())
602 : {
603 310 : sCustomProperty = aFind->second;
604 310 : rMap.erase(aFind);
605 : }
606 4556 : return sCustomProperty;
607 : }
608 :
609 : namespace
610 : {
611 0 : bool extractDrawValue(VclBuilder::stringmap& rMap)
612 : {
613 0 : bool bDrawValue = true;
614 0 : VclBuilder::stringmap::iterator aFind = rMap.find(OString("draw_value"));
615 0 : if (aFind != rMap.end())
616 : {
617 0 : bDrawValue = toBool(aFind->second);
618 0 : rMap.erase(aFind);
619 : }
620 0 : return bDrawValue;
621 : }
622 :
623 0 : OString extractValuePos(VclBuilder::stringmap& rMap)
624 : {
625 0 : OString sRet("top");
626 0 : VclBuilder::stringmap::iterator aFind = rMap.find(OString("value_pos"));
627 0 : if (aFind != rMap.end())
628 : {
629 0 : sRet = aFind->second;
630 0 : rMap.erase(aFind);
631 : }
632 0 : return sRet;
633 : }
634 :
635 17 : OString extractTypeHint(VclBuilder::stringmap &rMap)
636 : {
637 17 : OString sRet("normal");
638 17 : VclBuilder::stringmap::iterator aFind = rMap.find(OString("type-hint"));
639 17 : if (aFind != rMap.end())
640 : {
641 17 : sRet = aFind->second;
642 17 : rMap.erase(aFind);
643 : }
644 17 : return sRet;
645 : }
646 :
647 17 : bool extractResizable(VclBuilder::stringmap &rMap)
648 : {
649 17 : bool bResizable = true;
650 17 : VclBuilder::stringmap::iterator aFind = rMap.find(OString("resizable"));
651 17 : if (aFind != rMap.end())
652 : {
653 0 : bResizable = toBool(aFind->second);
654 0 : rMap.erase(aFind);
655 : }
656 17 : return bResizable;
657 : }
658 :
659 17 : bool extractDecorated(VclBuilder::stringmap &rMap)
660 : {
661 17 : bool bDecorated = true;
662 17 : VclBuilder::stringmap::iterator aFind = rMap.find(OString("decorated"));
663 17 : if (aFind != rMap.end())
664 : {
665 0 : bDecorated = toBool(aFind->second);
666 0 : rMap.erase(aFind);
667 : }
668 17 : return bDecorated;
669 : }
670 :
671 17 : bool extractCloseable(VclBuilder::stringmap &rMap)
672 : {
673 17 : bool bCloseable = true;
674 17 : VclBuilder::stringmap::iterator aFind = rMap.find(OString("deletable"));
675 17 : if (aFind != rMap.end())
676 : {
677 0 : bCloseable = toBool(aFind->second);
678 0 : rMap.erase(aFind);
679 : }
680 17 : return bCloseable;
681 : }
682 :
683 174 : bool extractEntry(VclBuilder::stringmap &rMap)
684 : {
685 174 : bool bHasEntry = false;
686 174 : VclBuilder::stringmap::iterator aFind = rMap.find(OString("has-entry"));
687 174 : if (aFind != rMap.end())
688 : {
689 0 : bHasEntry = toBool(aFind->second);
690 0 : rMap.erase(aFind);
691 : }
692 174 : return bHasEntry;
693 : }
694 :
695 7148 : bool extractOrientation(VclBuilder::stringmap &rMap)
696 : {
697 7148 : bool bVertical = false;
698 7148 : VclBuilder::stringmap::iterator aFind = rMap.find(OString("orientation"));
699 7148 : if (aFind != rMap.end())
700 : {
701 2402 : bVertical = aFind->second.equalsIgnoreAsciiCase("vertical");
702 2402 : rMap.erase(aFind);
703 : }
704 7148 : return bVertical;
705 : }
706 :
707 605 : bool extractInconsistent(VclBuilder::stringmap &rMap)
708 : {
709 605 : bool bInconsistent = false;
710 605 : VclBuilder::stringmap::iterator aFind = rMap.find(OString("inconsistent"));
711 605 : if (aFind != rMap.end())
712 : {
713 0 : bInconsistent = toBool(aFind->second);
714 0 : rMap.erase(aFind);
715 : }
716 605 : return bInconsistent;
717 : }
718 :
719 19332 : OString extractIconName(VclBuilder::stringmap &rMap)
720 : {
721 19332 : OString sIconName;
722 19332 : VclBuilder::stringmap::iterator aFind = rMap.find(OString("icon-name"));
723 19332 : if (aFind != rMap.end())
724 : {
725 0 : sIconName = aFind->second;
726 0 : rMap.erase(aFind);
727 : }
728 19332 : return sIconName;
729 : }
730 :
731 0 : OUString getStockText(const OString &rType)
732 : {
733 0 : if (rType == "gtk-ok")
734 0 : return (VclResId(SV_BUTTONTEXT_OK).toString());
735 0 : else if (rType == "gtk-cancel")
736 0 : return (VclResId(SV_BUTTONTEXT_CANCEL).toString());
737 0 : else if (rType == "gtk-help")
738 0 : return (VclResId(SV_BUTTONTEXT_HELP).toString());
739 0 : else if (rType == "gtk-close")
740 0 : return (VclResId(SV_BUTTONTEXT_CLOSE).toString());
741 0 : else if (rType == "gtk-revert-to-saved")
742 0 : return (VclResId(SV_BUTTONTEXT_RESET).toString());
743 0 : else if (rType == "gtk-add")
744 0 : return (VclResId(SV_BUTTONTEXT_ADD).toString());
745 0 : else if (rType == "gtk-delete")
746 0 : return (VclResId(SV_BUTTONTEXT_DELETE).toString());
747 0 : else if (rType == "gtk-remove")
748 0 : return (VclResId(SV_BUTTONTEXT_REMOVE).toString());
749 0 : else if (rType == "gtk-new")
750 0 : return (VclResId(SV_BUTTONTEXT_NEW).toString());
751 0 : else if (rType == "gtk-edit")
752 0 : return (VclResId(SV_BUTTONTEXT_EDIT).toString());
753 0 : else if (rType == "gtk-apply")
754 0 : return (VclResId(SV_BUTTONTEXT_APPLY).toString());
755 0 : else if (rType == "gtk-save")
756 0 : return (VclResId(SV_BUTTONTEXT_SAVE).toString());
757 0 : else if (rType == "gtk-open")
758 0 : return (VclResId(SV_BUTTONTEXT_OPEN).toString());
759 0 : else if (rType == "gtk-undo")
760 0 : return (VclResId(SV_BUTTONTEXT_UNDO).toString());
761 0 : else if (rType == "gtk-paste")
762 0 : return (VclResId(SV_BUTTONTEXT_PASTE).toString());
763 0 : else if (rType == "gtk-media-next")
764 0 : return (VclResId(SV_BUTTONTEXT_NEXT).toString());
765 0 : else if (rType == "gtk-go-up")
766 0 : return (VclResId(SV_BUTTONTEXT_GO_UP).toString());
767 0 : else if (rType == "gtk-go-down")
768 0 : return (VclResId(SV_BUTTONTEXT_GO_DOWN).toString());
769 0 : else if (rType == "gtk-clear")
770 0 : return (VclResId(SV_BUTTONTEXT_CLEAR).toString());
771 0 : else if (rType == "gtk-media-play")
772 0 : return (VclResId(SV_BUTTONTEXT_PLAY).toString());
773 0 : else if (rType == "gtk-find")
774 0 : return (VclResId(SV_BUTTONTEXT_FIND).toString());
775 0 : else if (rType == "gtk-stop")
776 0 : return (VclResId(SV_BUTTONTEXT_STOP).toString());
777 0 : else if (rType == "gtk-connect")
778 0 : return (VclResId(SV_BUTTONTEXT_CONNECT).toString());
779 0 : else if (rType == "gtk-yes")
780 0 : return (VclResId(SV_BUTTONTEXT_YES).toString());
781 0 : else if (rType == "gtk-no")
782 0 : return (VclResId(SV_BUTTONTEXT_NO).toString());
783 : SAL_WARN("vcl.layout", "unknown stock type: " << rType.getStr());
784 0 : return OUString();
785 : }
786 :
787 11 : bool extractStock(VclBuilder::stringmap &rMap)
788 : {
789 11 : bool bIsStock = false;
790 11 : VclBuilder::stringmap::iterator aFind = rMap.find(OString("use-stock"));
791 11 : if (aFind != rMap.end())
792 : {
793 1 : bIsStock = toBool(aFind->second);
794 1 : rMap.erase(aFind);
795 : }
796 11 : return bIsStock;
797 : }
798 :
799 11 : WinBits extractRelief(VclBuilder::stringmap &rMap)
800 : {
801 11 : WinBits nBits = WB_3DLOOK;
802 11 : VclBuilder::stringmap::iterator aFind = rMap.find(OString("relief"));
803 11 : if (aFind != rMap.end())
804 : {
805 11 : if (aFind->second == "half")
806 0 : nBits = WB_FLATBUTTON | WB_BEVELBUTTON;
807 11 : else if (aFind->second == "none")
808 11 : nBits = WB_FLATBUTTON;
809 11 : rMap.erase(aFind);
810 : }
811 11 : return nBits;
812 : }
813 :
814 6 : OString extractLabel(VclBuilder::stringmap &rMap)
815 : {
816 6 : OString sType;
817 6 : VclBuilder::stringmap::iterator aFind = rMap.find(OString("label"));
818 6 : if (aFind != rMap.end())
819 : {
820 6 : sType = aFind->second;
821 6 : rMap.erase(aFind);
822 : }
823 6 : return sType;
824 : }
825 :
826 19332 : OString extractActionName(VclBuilder::stringmap &rMap)
827 : {
828 19332 : OString sActionName;
829 19332 : VclBuilder::stringmap::iterator aFind = rMap.find(OString("action-name"));
830 19332 : if (aFind != rMap.end())
831 : {
832 19332 : sActionName = aFind->second;
833 19332 : rMap.erase(aFind);
834 : }
835 19332 : return sActionName;
836 : }
837 :
838 19332 : bool extractVisible(VclBuilder::stringmap &rMap)
839 : {
840 19332 : VclBuilder::stringmap::iterator aFind = rMap.find(OString("visible"));
841 19332 : if (aFind != rMap.end())
842 : {
843 19332 : return toBool(aFind->second);
844 : }
845 0 : return false;
846 : }
847 :
848 19332 : Size extractSizeRequest(VclBuilder::stringmap &rMap)
849 : {
850 19332 : OString sWidthRequest("0");
851 38664 : OString sHeightRequest("0");
852 19332 : VclBuilder::stringmap::iterator aFind = rMap.find(OString("width-request"));
853 19332 : if (aFind != rMap.end())
854 : {
855 945 : sWidthRequest = aFind->second;
856 945 : rMap.erase(aFind);
857 : }
858 19332 : aFind = rMap.find(OString("height-request"));
859 19332 : if (aFind != rMap.end())
860 : {
861 0 : sHeightRequest = aFind->second;
862 0 : rMap.erase(aFind);
863 : }
864 38664 : return Size(sWidthRequest.toInt32(), sHeightRequest.toInt32());
865 : }
866 :
867 19332 : OString extractTooltipText(VclBuilder::stringmap &rMap)
868 : {
869 19332 : OString sTooltipText;
870 19332 : VclBuilder::stringmap::iterator aFind = rMap.find(OString("tooltip-text"));
871 19332 : if (aFind == rMap.end())
872 16023 : aFind = rMap.find(OString("tooltip-markup"));
873 19332 : if (aFind != rMap.end())
874 : {
875 3309 : sTooltipText = aFind->second;
876 3309 : rMap.erase(aFind);
877 : }
878 19332 : return sTooltipText;
879 : }
880 :
881 11 : void setupFromActionName(Button *pButton, VclBuilder::stringmap &rMap, const uno::Reference<frame::XFrame>& rFrame)
882 : {
883 11 : if (!rFrame.is())
884 22 : return;
885 :
886 0 : OUString aCommand(OStringToOUString(extractActionName(rMap), RTL_TEXTENCODING_UTF8));
887 0 : if (aCommand.isEmpty())
888 0 : return;
889 :
890 0 : uno::Reference<uno::XComponentContext> xContext(comphelper::getProcessComponentContext());
891 0 : uno::Reference<frame::XModuleManager2> xModuleManager(frame::ModuleManager::create(xContext));
892 0 : OUString aModuleId(xModuleManager->identify(rFrame));
893 :
894 0 : OUString aLabel(VclBuilder::getCommandLabel(aCommand, xContext, aModuleId));
895 0 : if (!aLabel.isEmpty())
896 0 : pButton->SetText(aLabel);
897 :
898 0 : Image aImage(VclBuilder::getCommandImage(aCommand, /* bLarge = */ false, xContext, rFrame, aModuleId));
899 0 : pButton->SetModeImage(aImage);
900 :
901 0 : pButton->SetCommandHandler(aCommand);
902 : }
903 :
904 10 : VclPtr<Button> extractStockAndBuildPushButton(vcl::Window *pParent, VclBuilder::stringmap &rMap)
905 : {
906 10 : WinBits nBits = WB_CLIPCHILDREN|WB_CENTER|WB_VCENTER;
907 :
908 10 : nBits |= extractRelief(rMap);
909 :
910 10 : bool bIsStock = extractStock(rMap);
911 :
912 10 : VclPtr<Button> xWindow;
913 :
914 10 : if (bIsStock)
915 : {
916 1 : OString sType = extractLabel(rMap);
917 1 : if (sType == "gtk-ok")
918 0 : xWindow = VclPtr<OKButton>::Create(pParent, nBits);
919 1 : else if (sType == "gtk-cancel")
920 0 : xWindow = VclPtr<CancelButton>::Create(pParent, nBits);
921 1 : else if (sType == "gtk-close")
922 0 : xWindow = VclPtr<CloseButton>::Create(pParent, nBits);
923 1 : else if (sType == "gtk-help")
924 1 : xWindow = VclPtr<HelpButton>::Create(pParent, nBits);
925 : else
926 : {
927 0 : xWindow = VclPtr<PushButton>::Create(pParent, nBits);
928 0 : xWindow->SetText(getStockText(sType));
929 1 : }
930 : }
931 :
932 10 : if (!xWindow)
933 9 : xWindow = VclPtr<PushButton>::Create(pParent, nBits);
934 10 : return xWindow;
935 : }
936 :
937 1 : VclPtr<Button> extractStockAndBuildMenuButton(vcl::Window *pParent, VclBuilder::stringmap &rMap)
938 : {
939 1 : WinBits nBits = WB_CLIPCHILDREN|WB_CENTER|WB_VCENTER|WB_3DLOOK;
940 :
941 1 : nBits |= extractRelief(rMap);
942 :
943 1 : VclPtr<Button> xWindow = VclPtr<MenuButton>::Create(pParent, nBits);
944 :
945 1 : if (extractStock(rMap))
946 : {
947 0 : xWindow->SetText(getStockText(extractLabel(rMap)));
948 : }
949 :
950 1 : return xWindow;
951 : }
952 :
953 2301 : OString extractUnit(const OString& sPattern)
954 : {
955 2301 : OString sUnit(sPattern);
956 2613 : for (sal_Int32 i = 0; i < sPattern.getLength(); ++i)
957 : {
958 621 : if (sPattern[i] != '.' && sPattern[i] != ',' && sPattern[i] != '0')
959 : {
960 309 : sUnit = sPattern.copy(i);
961 309 : break;
962 : }
963 : }
964 2301 : return sUnit;
965 : }
966 :
967 152 : int extractDecimalDigits(const OString& sPattern)
968 : {
969 152 : int nDigits = 0;
970 152 : bool bAfterPoint = false;
971 307 : for (sal_Int32 i = 0; i < sPattern.getLength(); ++i)
972 : {
973 307 : if (sPattern[i] == '.' || sPattern[i] == ',')
974 1 : bAfterPoint = true;
975 306 : else if (sPattern[i] == '0')
976 : {
977 154 : if (bAfterPoint)
978 2 : ++nDigits;
979 : }
980 : else
981 152 : break;
982 : }
983 152 : return nDigits;
984 : }
985 :
986 1999 : FieldUnit detectMetricUnit(const OString& sUnit)
987 : {
988 1999 : FieldUnit eUnit = FUNIT_NONE;
989 :
990 1999 : if (sUnit == "mm")
991 0 : eUnit = FUNIT_MM;
992 1999 : else if (sUnit == "cm")
993 0 : eUnit = FUNIT_CM;
994 1999 : else if (sUnit == "m")
995 0 : eUnit = FUNIT_M;
996 1999 : else if (sUnit == "km")
997 0 : eUnit = FUNIT_KM;
998 1999 : else if ((sUnit == "twips") || (sUnit == "twip"))
999 0 : eUnit = FUNIT_TWIP;
1000 1999 : else if (sUnit == "pt")
1001 151 : eUnit = FUNIT_POINT;
1002 1848 : else if (sUnit == "pc")
1003 0 : eUnit = FUNIT_PICA;
1004 1848 : else if (sUnit == "\"" || (sUnit == "in") || (sUnit == "inch"))
1005 4 : eUnit = FUNIT_INCH;
1006 1844 : else if ((sUnit == "'") || (sUnit == "ft") || (sUnit == "foot") || (sUnit == "feet"))
1007 0 : eUnit = FUNIT_FOOT;
1008 1844 : else if (sUnit == "mile" || (sUnit == "miles"))
1009 0 : eUnit = FUNIT_MILE;
1010 1844 : else if (sUnit == "ch")
1011 0 : eUnit = FUNIT_CHAR;
1012 1844 : else if (sUnit == "line")
1013 0 : eUnit = FUNIT_LINE;
1014 1844 : else if (sUnit == "%")
1015 2 : eUnit = FUNIT_PERCENT;
1016 1842 : else if ((sUnit == "pixels") || (sUnit == "pixel") || (sUnit == "px"))
1017 0 : eUnit = FUNIT_PIXEL;
1018 1842 : else if ((sUnit == "degrees") || (sUnit == "degree"))
1019 152 : eUnit = FUNIT_DEGREE;
1020 1690 : else if ((sUnit == "sec") || (sUnit == "seconds") || (sUnit == "second"))
1021 0 : eUnit = FUNIT_SECOND;
1022 1690 : else if ((sUnit == "ms") || (sUnit == "milliseconds") || (sUnit == "millisecond"))
1023 0 : eUnit = FUNIT_MILLISECOND;
1024 1690 : else if (sUnit != "0")
1025 1690 : eUnit = FUNIT_CUSTOM;
1026 :
1027 1999 : return eUnit;
1028 : }
1029 :
1030 17 : WinBits extractDeferredBits(VclBuilder::stringmap &rMap)
1031 : {
1032 17 : WinBits nBits = WB_3DLOOK|WB_HIDE;
1033 17 : if (extractResizable(rMap))
1034 17 : nBits |= WB_SIZEABLE;
1035 17 : if (extractCloseable(rMap))
1036 17 : nBits |= WB_CLOSEABLE;
1037 17 : OString sBorder = VclBuilder::extractCustomProperty(rMap);
1038 17 : if (!sBorder.isEmpty())
1039 0 : nBits |= WB_BORDER;
1040 17 : if (!extractDecorated(rMap))
1041 0 : nBits |= WB_OWNERDRAWDECORATION;
1042 34 : OString sType(extractTypeHint(rMap));
1043 17 : if (sType == "utility")
1044 0 : nBits |= WB_SYSTEMWINDOW | WB_DIALOGCONTROL | WB_MOVEABLE;
1045 17 : else if (sType == "popup-menu")
1046 0 : nBits |= WB_SYSTEMWINDOW | WB_DIALOGCONTROL | WB_POPUP;
1047 17 : else if (sType == "dock")
1048 17 : nBits |= WB_DOCKABLE;
1049 : else
1050 0 : nBits |= WB_MOVEABLE;
1051 34 : return nBits;
1052 : }
1053 : }
1054 :
1055 1690 : FieldUnit VclBuilder::detectUnit(OString const& rString)
1056 : {
1057 1690 : OString const unit(extractUnit(rString));
1058 1690 : return detectMetricUnit(unit);
1059 : }
1060 :
1061 0 : void VclBuilder::ensureDefaultWidthChars(VclBuilder::stringmap &rMap)
1062 : {
1063 0 : OString sWidthChars("width-chars");
1064 0 : VclBuilder::stringmap::iterator aFind = rMap.find(sWidthChars);
1065 0 : if (aFind == rMap.end())
1066 0 : rMap[sWidthChars] = "25";
1067 0 : }
1068 :
1069 0 : bool VclBuilder::extractGroup(const OString &id, stringmap &rMap)
1070 : {
1071 0 : VclBuilder::stringmap::iterator aFind = rMap.find(OString("group"));
1072 0 : if (aFind != rMap.end())
1073 : {
1074 0 : OString sID = aFind->second;
1075 0 : sal_Int32 nDelim = sID.indexOf(':');
1076 0 : if (nDelim != -1)
1077 0 : sID = sID.copy(0, nDelim);
1078 0 : m_pParserState->m_aGroupMaps.push_back(RadioButtonGroupMap(id, sID));
1079 0 : rMap.erase(aFind);
1080 0 : return true;
1081 : }
1082 0 : return false;
1083 : }
1084 :
1085 611 : void VclBuilder::connectNumericFormatterAdjustment(const OString &id, const OString &rAdjustment)
1086 : {
1087 611 : if (!rAdjustment.isEmpty())
1088 3 : m_pParserState->m_aNumericFormatterAdjustmentMaps.push_back(WidgetAdjustmentMap(id, rAdjustment));
1089 611 : }
1090 :
1091 0 : void VclBuilder::connectTimeFormatterAdjustment(const OString &id, const OString &rAdjustment)
1092 : {
1093 0 : if (!rAdjustment.isEmpty())
1094 0 : m_pParserState->m_aTimeFormatterAdjustmentMaps.push_back(WidgetAdjustmentMap(id, rAdjustment));
1095 0 : }
1096 :
1097 0 : void VclBuilder::connectDateFormatterAdjustment(const OString &id, const OString &rAdjustment)
1098 : {
1099 0 : if (!rAdjustment.isEmpty())
1100 0 : m_pParserState->m_aDateFormatterAdjustmentMaps.push_back(WidgetAdjustmentMap(id, rAdjustment));
1101 0 : }
1102 :
1103 0 : bool VclBuilder::extractAdjustmentToMap(const OString& id, VclBuilder::stringmap& rMap, std::vector<WidgetAdjustmentMap>& rAdjustmentMap)
1104 : {
1105 0 : VclBuilder::stringmap::iterator aFind = rMap.find(OString("adjustment"));
1106 0 : if (aFind != rMap.end())
1107 : {
1108 0 : rAdjustmentMap.push_back(WidgetAdjustmentMap(id, aFind->second));
1109 0 : rMap.erase(aFind);
1110 0 : return true;
1111 : }
1112 0 : return false;
1113 : }
1114 :
1115 : namespace
1116 : {
1117 154 : sal_Int32 extractActive(VclBuilder::stringmap &rMap)
1118 : {
1119 154 : sal_Int32 nActiveId = 0;
1120 154 : VclBuilder::stringmap::iterator aFind = rMap.find(OString("active"));
1121 154 : if (aFind != rMap.end())
1122 : {
1123 0 : nActiveId = aFind->second.toInt32();
1124 0 : rMap.erase(aFind);
1125 : }
1126 154 : return nActiveId;
1127 : }
1128 :
1129 1448 : bool extractSelectable(VclBuilder::stringmap &rMap)
1130 : {
1131 1448 : bool bSelectable = false;
1132 1448 : VclBuilder::stringmap::iterator aFind = rMap.find(OString("selectable"));
1133 1448 : if (aFind != rMap.end())
1134 : {
1135 0 : bSelectable = toBool(aFind->second);
1136 0 : rMap.erase(aFind);
1137 : }
1138 1448 : return bSelectable;
1139 : }
1140 :
1141 611 : OString extractAdjustment(VclBuilder::stringmap &rMap)
1142 : {
1143 611 : OString sAdjustment;
1144 611 : VclBuilder::stringmap::iterator aFind = rMap.find(OString("adjustment"));
1145 611 : if (aFind != rMap.end())
1146 : {
1147 3 : sAdjustment= aFind->second;
1148 3 : rMap.erase(aFind);
1149 3 : return sAdjustment;
1150 : }
1151 608 : return sAdjustment;
1152 : }
1153 : }
1154 :
1155 326 : bool VclBuilder::extractModel(const OString &id, stringmap &rMap)
1156 : {
1157 326 : VclBuilder::stringmap::iterator aFind = rMap.find(OString("model"));
1158 326 : if (aFind != rMap.end())
1159 : {
1160 0 : m_pParserState->m_aModelMaps.push_back(ComboBoxModelMap(id, aFind->second,
1161 0 : extractActive(rMap)));
1162 0 : rMap.erase(aFind);
1163 0 : return true;
1164 : }
1165 326 : return false;
1166 : }
1167 :
1168 326 : bool VclBuilder::extractDropdown(VclBuilder::stringmap &rMap)
1169 : {
1170 326 : bool bDropdown = true;
1171 326 : VclBuilder::stringmap::iterator aFind = rMap.find(OString("dropdown"));
1172 326 : if (aFind != rMap.end())
1173 : {
1174 0 : bDropdown = toBool(aFind->second);
1175 0 : rMap.erase(aFind);
1176 : }
1177 326 : return bDropdown;
1178 : }
1179 :
1180 0 : bool VclBuilder::extractBuffer(const OString &id, stringmap &rMap)
1181 : {
1182 0 : VclBuilder::stringmap::iterator aFind = rMap.find(OString("buffer"));
1183 0 : if (aFind != rMap.end())
1184 : {
1185 0 : m_pParserState->m_aTextBufferMaps.push_back(TextBufferMap(id, aFind->second));
1186 0 : rMap.erase(aFind);
1187 0 : return true;
1188 : }
1189 0 : return false;
1190 : }
1191 :
1192 1700 : bool VclBuilder::extractStock(const OString &id, stringmap &rMap)
1193 : {
1194 1700 : VclBuilder::stringmap::iterator aFind = rMap.find(OString("stock"));
1195 1700 : if (aFind != rMap.end())
1196 : {
1197 0 : stockinfo aInfo;
1198 0 : aInfo.m_sStock = aFind->second;
1199 0 : rMap.erase(aFind);
1200 0 : aFind = rMap.find(OString("icon-size"));
1201 0 : if (aFind != rMap.end())
1202 : {
1203 0 : aInfo.m_nSize = aFind->second.toInt32();
1204 0 : rMap.erase(aFind);
1205 : }
1206 0 : m_pParserState->m_aStockMap[id] = aInfo;
1207 0 : return true;
1208 : }
1209 1700 : return false;
1210 : }
1211 :
1212 43878 : bool VclBuilder::extractButtonImage(const OString &id, stringmap &rMap, bool bRadio)
1213 : {
1214 43878 : VclBuilder::stringmap::iterator aFind = rMap.find(OString("image"));
1215 43878 : if (aFind != rMap.end())
1216 : {
1217 9 : m_pParserState->m_aButtonImageWidgetMaps.push_back(ButtonImageWidgetMap(id, aFind->second, bRadio));
1218 9 : rMap.erase(aFind);
1219 9 : return true;
1220 : }
1221 43869 : return false;
1222 : }
1223 :
1224 1448 : void VclBuilder::extractMnemonicWidget(const OString &rLabelID, stringmap &rMap)
1225 : {
1226 1448 : VclBuilder::stringmap::iterator aFind = rMap.find(OString("mnemonic-widget"));
1227 1448 : if (aFind != rMap.end())
1228 : {
1229 1136 : OString sID = aFind->second;
1230 1136 : sal_Int32 nDelim = sID.indexOf(':');
1231 1136 : if (nDelim != -1)
1232 152 : sID = sID.copy(0, nDelim);
1233 1136 : m_pParserState->m_aMnemonicWidgetMaps.push_back(MnemonicWidgetMap(rLabelID, sID));
1234 1136 : rMap.erase(aFind);
1235 : }
1236 1448 : }
1237 :
1238 0 : vcl::Window* VclBuilder::prepareWidgetOwnScrolling(vcl::Window *pParent, WinBits &rWinStyle)
1239 : {
1240 : //For Widgets that manage their own scrolling, if one appears as a child of
1241 : //a scrolling window shoehorn that scrolling settings to this widget and
1242 : //return the real parent to use
1243 0 : if (pParent && pParent->GetType() == WINDOW_SCROLLWINDOW)
1244 : {
1245 0 : WinBits nScrollBits = pParent->GetStyle();
1246 0 : nScrollBits &= (WB_AUTOHSCROLL|WB_HSCROLL|WB_AUTOVSCROLL|WB_VSCROLL);
1247 0 : rWinStyle |= nScrollBits;
1248 0 : pParent = pParent->GetParent();
1249 : }
1250 :
1251 0 : return pParent;
1252 : }
1253 :
1254 0 : void VclBuilder::cleanupWidgetOwnScrolling(vcl::Window *pScrollParent, vcl::Window *pWindow, stringmap &rMap)
1255 : {
1256 : //remove the redundant scrolling parent
1257 0 : sal_Int32 nWidthReq = pScrollParent->get_width_request();
1258 0 : rMap[OString("width-request")] = OString::number(nWidthReq);
1259 0 : sal_Int32 nHeightReq = pScrollParent->get_height_request();
1260 0 : rMap[OString("height-request")] = OString::number(nHeightReq);
1261 :
1262 0 : m_pParserState->m_aRedundantParentWidgets[pScrollParent] = pWindow;
1263 0 : }
1264 :
1265 : #ifndef DISABLE_DYNLOADING
1266 0 : extern "C" { static void SAL_CALL thisModule() {} }
1267 : #endif
1268 :
1269 43897 : VclPtr<vcl::Window> VclBuilder::makeObject(vcl::Window *pParent, const OString &name, const OString &id,
1270 : stringmap &rMap)
1271 : {
1272 43897 : bool bIsPlaceHolder = name.isEmpty();
1273 43897 : bool bVertical = false;
1274 :
1275 43897 : if (pParent && pParent->GetType() == WINDOW_TABCONTROL)
1276 : {
1277 : //We have to add a page
1278 :
1279 : //make default pageid == position
1280 0 : TabControl *pTabControl = static_cast<TabControl*>(pParent);
1281 0 : sal_uInt16 nNewPageCount = pTabControl->GetPageCount()+1;
1282 0 : sal_uInt16 nNewPageId = nNewPageCount;
1283 0 : pTabControl->InsertPage(nNewPageId, OUString());
1284 0 : pTabControl->SetCurPageId(nNewPageId);
1285 :
1286 0 : if (!bIsPlaceHolder)
1287 : {
1288 0 : VclPtrInstance<TabPage> pPage(pTabControl);
1289 0 : pPage->Show();
1290 :
1291 : //Make up a name for it
1292 0 : OString sTabPageId = get_by_window(pParent) +
1293 0 : OString("-page") +
1294 0 : OString::number(nNewPageCount);
1295 0 : m_aChildren.push_back(WinAndId(sTabPageId, pPage, false));
1296 0 : pPage->SetHelpId(m_sHelpRoot + sTabPageId);
1297 :
1298 : //And give the page one container as a child to make it a layout enabled
1299 : //tab page
1300 0 : VclPtrInstance<VclBin> pContainer(pPage);
1301 0 : pContainer->Show();
1302 0 : m_aChildren.push_back(WinAndId(OString(), pContainer, false));
1303 0 : pContainer->SetHelpId(m_sHelpRoot + sTabPageId + OString("-bin"));
1304 0 : pParent = pContainer;
1305 :
1306 0 : pTabControl->SetTabPage(nNewPageId, pPage);
1307 : }
1308 : }
1309 :
1310 43897 : if (bIsPlaceHolder || name == "GtkTreeSelection")
1311 19 : return nullptr;
1312 :
1313 43878 : extractButtonImage(id, rMap, name == "GtkRadioButton");
1314 :
1315 43878 : VclPtr<vcl::Window> xWindow;
1316 43878 : if (name == "GtkDialog")
1317 : {
1318 0 : WinBits nBits = WB_CLIPCHILDREN|WB_MOVEABLE|WB_3DLOOK|WB_CLOSEABLE;
1319 0 : if (extractResizable(rMap))
1320 0 : nBits |= WB_SIZEABLE;
1321 0 : xWindow = VclPtr<Dialog>::Create(pParent, nBits);
1322 : }
1323 43878 : else if (name == "GtkMessageDialog")
1324 : {
1325 0 : WinBits nBits = WB_CLIPCHILDREN|WB_MOVEABLE|WB_3DLOOK|WB_CLOSEABLE;
1326 0 : if (extractResizable(rMap))
1327 0 : nBits |= WB_SIZEABLE;
1328 0 : xWindow = VclPtr<MessageDialog>::Create(pParent, nBits);
1329 : }
1330 43878 : else if (name == "GtkBox")
1331 : {
1332 7147 : bVertical = extractOrientation(rMap);
1333 7147 : if (bVertical)
1334 2402 : xWindow = VclPtr<VclVBox>::Create(pParent);
1335 : else
1336 4745 : xWindow = VclPtr<VclHBox>::Create(pParent);
1337 : }
1338 36731 : else if (name == "GtkHBox")
1339 0 : xWindow = VclPtr<VclHBox>::Create(pParent);
1340 36731 : else if (name == "GtkVBox")
1341 0 : xWindow = VclPtr<VclVBox>::Create(pParent);
1342 36731 : else if (name == "GtkButtonBox")
1343 : {
1344 0 : bVertical = extractOrientation(rMap);
1345 0 : if (bVertical)
1346 0 : xWindow = VclPtr<VclVButtonBox>::Create(pParent);
1347 : else
1348 0 : xWindow = VclPtr<VclHButtonBox>::Create(pParent);
1349 : }
1350 36731 : else if (name == "GtkHButtonBox")
1351 0 : xWindow = VclPtr<VclHButtonBox>::Create(pParent);
1352 36731 : else if (name == "GtkVButtonBox")
1353 0 : xWindow = VclPtr<VclVButtonBox>::Create(pParent);
1354 36731 : else if (name == "GtkGrid")
1355 999 : xWindow = VclPtr<VclGrid>::Create(pParent);
1356 35732 : else if (name == "GtkFrame")
1357 0 : xWindow = VclPtr<VclFrame>::Create(pParent);
1358 35732 : else if (name == "GtkExpander")
1359 : {
1360 0 : VclPtrInstance<VclExpander> pExpander(pParent);
1361 0 : m_pParserState->m_aExpanderWidgets.push_back(pExpander);
1362 0 : xWindow = pExpander;
1363 : }
1364 35732 : else if (name == "GtkAlignment")
1365 0 : xWindow = VclPtr<VclAlignment>::Create(pParent);
1366 35732 : else if (name == "GtkButton")
1367 : {
1368 11 : VclPtr<Button> xButton;
1369 22 : OString sMenu = extractCustomProperty(rMap);
1370 11 : if (sMenu.isEmpty())
1371 10 : xButton = extractStockAndBuildPushButton(pParent, rMap);
1372 : else
1373 : {
1374 1 : xButton = extractStockAndBuildMenuButton(pParent, rMap);
1375 1 : m_pParserState->m_aButtonMenuMaps.push_back(ButtonMenuMap(id, sMenu));
1376 : }
1377 11 : xButton->SetImageAlign(IMAGEALIGN_LEFT); //default to left
1378 11 : setupFromActionName(xButton, rMap, m_xFrame);
1379 22 : xWindow = xButton;
1380 : }
1381 35721 : else if (name == "GtkRadioButton")
1382 : {
1383 0 : extractGroup(id, rMap);
1384 0 : WinBits nBits = WB_CLIPCHILDREN|WB_CENTER|WB_VCENTER|WB_3DLOOK;
1385 0 : OString sWrap = extractCustomProperty(rMap);
1386 0 : if (!sWrap.isEmpty())
1387 0 : nBits |= WB_WORDBREAK;
1388 0 : VclPtr<RadioButton> xButton = VclPtr<RadioButton>::Create(pParent, nBits);
1389 0 : xButton->SetImageAlign(IMAGEALIGN_LEFT); //default to left
1390 0 : xWindow = xButton;
1391 : }
1392 35721 : else if (name == "GtkCheckButton")
1393 : {
1394 605 : WinBits nBits = WB_CLIPCHILDREN|WB_CENTER|WB_VCENTER|WB_3DLOOK;
1395 605 : OString sWrap = extractCustomProperty(rMap);
1396 605 : if (!sWrap.isEmpty())
1397 0 : nBits |= WB_WORDBREAK;
1398 : //maybe always import as TriStateBox and enable/disable tristate
1399 605 : bool bIsTriState = extractInconsistent(rMap);
1400 1210 : VclPtr<CheckBox> xCheckBox;
1401 605 : if (bIsTriState)
1402 0 : xCheckBox = VclPtr<TriStateBox>::Create(pParent, nBits);
1403 : else
1404 605 : xCheckBox = VclPtr<CheckBox>::Create(pParent, nBits);
1405 605 : if (bIsTriState)
1406 0 : xCheckBox->SetState(TRISTATE_INDET);
1407 605 : xCheckBox->SetImageAlign(IMAGEALIGN_LEFT); //default to left
1408 1210 : xWindow = xCheckBox;
1409 : }
1410 35116 : else if (name == "GtkSpinButton")
1411 : {
1412 459 : OString sAdjustment = extractAdjustment(rMap);
1413 918 : OString sPattern = extractCustomProperty(rMap);
1414 918 : OString sUnit = extractUnit(sPattern);
1415 :
1416 459 : WinBits nBits = WB_CLIPCHILDREN|WB_LEFT|WB_BORDER|WB_3DLOOK;
1417 459 : if (!id.endsWith("-nospin"))
1418 459 : nBits |= WB_SPIN | WB_REPEAT;
1419 :
1420 459 : if (sPattern.isEmpty())
1421 : {
1422 302 : connectNumericFormatterAdjustment(id, sAdjustment);
1423 : SAL_INFO("vcl.layout", "making numeric field for " << name.getStr() << " " << sUnit.getStr());
1424 302 : xWindow = VclPtr<NumericField>::Create(pParent, nBits);
1425 : }
1426 : else
1427 : {
1428 157 : if (sPattern == "hh:mm")
1429 : {
1430 0 : connectTimeFormatterAdjustment(id, sAdjustment);
1431 : SAL_INFO("vcl.layout", "making time field for " << name.getStr() << " " << sUnit.getStr());
1432 0 : xWindow = VclPtr<TimeField>::Create(pParent, nBits);
1433 : }
1434 157 : else if (sPattern == "yy:mm:dd")
1435 : {
1436 0 : connectDateFormatterAdjustment(id, sAdjustment);
1437 : SAL_INFO("vcl.layout", "making date field for " << name.getStr() << " " << sUnit.getStr());
1438 0 : xWindow = VclPtr<DateField>::Create(pParent, nBits);
1439 : }
1440 : else
1441 : {
1442 157 : connectNumericFormatterAdjustment(id, sAdjustment);
1443 157 : FieldUnit eUnit = detectMetricUnit(sUnit);
1444 : SAL_INFO("vcl.layout", "making metric field for " << name.getStr() << " " << sUnit.getStr());
1445 157 : VclPtrInstance<MetricField> xField(pParent, nBits);
1446 157 : xField->SetUnit(eUnit);
1447 157 : if (eUnit == FUNIT_CUSTOM)
1448 0 : xField->SetCustomUnitText(OStringToOUString(sUnit, RTL_TEXTENCODING_UTF8));
1449 157 : xWindow = xField;
1450 : }
1451 459 : }
1452 : }
1453 34657 : else if (name == "GtkLinkButton")
1454 0 : xWindow = VclPtr<FixedHyperlink>::Create(pParent, WB_CENTER|WB_VCENTER|WB_3DLOOK|WB_NOLABEL);
1455 34657 : else if ((name == "GtkComboBox") || (name == "GtkComboBoxText") || (name == "VclComboBoxText"))
1456 : {
1457 174 : OString sPattern = extractCustomProperty(rMap);
1458 174 : extractModel(id, rMap);
1459 :
1460 174 : WinBits nBits = WB_CLIPCHILDREN|WB_LEFT|WB_VCENTER|WB_3DLOOK;
1461 :
1462 174 : bool bDropdown = VclBuilder::extractDropdown(rMap);
1463 :
1464 174 : if (bDropdown)
1465 174 : nBits |= WB_DROPDOWN;
1466 :
1467 174 : if (!sPattern.isEmpty())
1468 : {
1469 0 : OString sAdjustment = extractAdjustment(rMap);
1470 0 : connectNumericFormatterAdjustment(id, sAdjustment);
1471 0 : OString sUnit = extractUnit(sPattern);
1472 0 : FieldUnit eUnit = detectMetricUnit(sUnit);
1473 : SAL_WARN("vcl.layout", "making metric box for type: " << name.getStr()
1474 : << " unit: " << sUnit.getStr()
1475 : << " name: " << id.getStr()
1476 : << " use a VclComboBoxNumeric instead");
1477 0 : VclPtrInstance<MetricBox> xBox(pParent, nBits);
1478 0 : xBox->EnableAutoSize(true);
1479 0 : xBox->SetUnit(eUnit);
1480 0 : xBox->SetDecimalDigits(extractDecimalDigits(sPattern));
1481 0 : if (eUnit == FUNIT_CUSTOM)
1482 0 : xBox->SetCustomUnitText(OStringToOUString(sUnit, RTL_TEXTENCODING_UTF8));
1483 0 : xWindow = xBox;
1484 : }
1485 174 : else if (extractEntry(rMap))
1486 : {
1487 0 : VclPtrInstance<ComboBox> xComboBox(pParent, nBits);
1488 0 : xComboBox->EnableAutoSize(true);
1489 0 : xWindow = xComboBox;
1490 : }
1491 : else
1492 : {
1493 174 : VclPtrInstance<ListBox> xListBox(pParent, nBits|WB_SIMPLEMODE);
1494 174 : xListBox->EnableAutoSize(true);
1495 174 : xWindow = xListBox;
1496 174 : }
1497 : }
1498 34483 : else if (name == "VclComboBoxNumeric")
1499 : {
1500 152 : OString sPattern = extractCustomProperty(rMap);
1501 304 : OString sAdjustment = extractAdjustment(rMap);
1502 152 : extractModel(id, rMap);
1503 :
1504 152 : WinBits nBits = WB_CLIPCHILDREN|WB_LEFT|WB_VCENTER|WB_3DLOOK;
1505 :
1506 152 : bool bDropdown = VclBuilder::extractDropdown(rMap);
1507 :
1508 152 : if (bDropdown)
1509 152 : nBits |= WB_DROPDOWN;
1510 :
1511 152 : if (!sPattern.isEmpty())
1512 : {
1513 152 : connectNumericFormatterAdjustment(id, sAdjustment);
1514 152 : OString sUnit = extractUnit(sPattern);
1515 152 : FieldUnit eUnit = detectMetricUnit(sUnit);
1516 : SAL_INFO("vcl.layout", "making metric box for " << name.getStr() << " " << sUnit.getStr());
1517 304 : VclPtrInstance<MetricBox> xBox(pParent, nBits);
1518 152 : xBox->EnableAutoSize(true);
1519 152 : xBox->SetUnit(eUnit);
1520 152 : xBox->SetDecimalDigits(extractDecimalDigits(sPattern));
1521 152 : if (eUnit == FUNIT_CUSTOM)
1522 0 : xBox->SetCustomUnitText(OStringToOUString(sUnit, RTL_TEXTENCODING_UTF8));
1523 304 : xWindow = xBox;
1524 : }
1525 : else
1526 : {
1527 : SAL_INFO("vcl.layout", "making numeric box for " << name.getStr());
1528 0 : connectNumericFormatterAdjustment(id, sAdjustment);
1529 0 : VclPtrInstance<NumericBox> xBox(pParent, nBits);
1530 0 : if (bDropdown)
1531 0 : xBox->EnableAutoSize(true);
1532 0 : xWindow = xBox;
1533 152 : }
1534 : }
1535 34331 : else if (name == "GtkTreeView")
1536 : {
1537 : //To-Do
1538 : //a) move svtools SvTreeViewBox into vcl
1539 : //b) make that the default target for GtkTreeView
1540 : //c) remove the non-drop down mode of ListBox and convert
1541 : // everything over to SvTreeViewBox
1542 : //d) remove the users of makeSvTreeViewBox
1543 0 : extractModel(id, rMap);
1544 0 : WinBits nWinStyle = WB_CLIPCHILDREN|WB_LEFT|WB_VCENTER|WB_3DLOOK|WB_SIMPLEMODE;
1545 0 : OString sBorder = extractCustomProperty(rMap);
1546 0 : if (!sBorder.isEmpty())
1547 0 : nWinStyle |= WB_BORDER;
1548 : //ListBox manages its own scrolling,
1549 0 : vcl::Window *pRealParent = prepareWidgetOwnScrolling(pParent, nWinStyle);
1550 0 : xWindow = VclPtr<ListBox>::Create(pRealParent, nWinStyle);
1551 0 : if (pRealParent != pParent)
1552 0 : cleanupWidgetOwnScrolling(pParent, xWindow, rMap);
1553 : }
1554 34331 : else if (name == "GtkLabel")
1555 : {
1556 1448 : WinBits nWinStyle = WB_CENTER|WB_VCENTER|WB_3DLOOK;
1557 1448 : OString sBorder = extractCustomProperty(rMap);
1558 1448 : if (!sBorder.isEmpty())
1559 0 : nWinStyle |= WB_BORDER;
1560 1448 : extractMnemonicWidget(id, rMap);
1561 1448 : if (extractSelectable(rMap))
1562 0 : xWindow = VclPtr<SelectableFixedText>::Create(pParent, nWinStyle);
1563 : else
1564 1448 : xWindow = VclPtr<FixedText>::Create(pParent, nWinStyle);
1565 : }
1566 32883 : else if (name == "GtkImage")
1567 : {
1568 1700 : extractStock(id, rMap);
1569 1700 : xWindow = VclPtr<FixedImage>::Create(pParent, WB_CENTER|WB_VCENTER|WB_3DLOOK|WB_SCALE);
1570 : //such parentless GtkImages are temps used to set icons on buttons
1571 : //default them to hidden to stop e.g. insert->index entry flicking temp
1572 : //full screen windows
1573 1700 : if (!pParent)
1574 : {
1575 0 : rMap["visible"] = "false";
1576 : }
1577 :
1578 : }
1579 31183 : else if (name == "GtkSeparator")
1580 : {
1581 1 : bVertical = extractOrientation(rMap);
1582 1 : xWindow = VclPtr<FixedLine>::Create(pParent, bVertical ? WB_VERT : WB_HORZ);
1583 : }
1584 31182 : else if (name == "GtkScrollbar")
1585 : {
1586 0 : extractAdjustmentToMap(id, rMap, m_pParserState->m_aScrollAdjustmentMaps);
1587 0 : bVertical = extractOrientation(rMap);
1588 0 : xWindow = VclPtr<ScrollBar>::Create(pParent, bVertical ? WB_VERT : WB_HORZ);
1589 : }
1590 31182 : else if (name == "GtkProgressBar")
1591 : {
1592 0 : extractAdjustmentToMap(id, rMap, m_pParserState->m_aScrollAdjustmentMaps);
1593 0 : bVertical = extractOrientation(rMap);
1594 0 : xWindow = VclPtr<ProgressBar>::Create(pParent, bVertical ? WB_VERT : WB_HORZ);
1595 : }
1596 31182 : else if (name == "GtkScrolledWindow")
1597 : {
1598 0 : xWindow = VclPtr<VclScrolledWindow>::Create(pParent);
1599 : }
1600 31182 : else if (name == "GtkViewport")
1601 : {
1602 0 : xWindow = VclPtr<VclViewport>::Create(pParent);
1603 : }
1604 31182 : else if (name == "GtkEventBox")
1605 : {
1606 0 : xWindow = VclPtr<VclEventBox>::Create(pParent);
1607 : }
1608 31182 : else if (name == "GtkEntry")
1609 : {
1610 0 : xWindow = VclPtr<Edit>::Create(pParent, WB_LEFT|WB_VCENTER|WB_BORDER|WB_3DLOOK);
1611 0 : ensureDefaultWidthChars(rMap);
1612 : }
1613 31182 : else if (name == "GtkNotebook")
1614 : {
1615 0 : xWindow = VclPtr<TabControl>::Create(pParent, WB_STDTABCONTROL|WB_3DLOOK);
1616 : }
1617 31182 : else if (name == "GtkDrawingArea")
1618 : {
1619 0 : OString sBorder = extractCustomProperty(rMap);
1620 0 : xWindow = VclPtr<vcl::Window>::Create(pParent, sBorder.isEmpty() ? 0 : WB_BORDER);
1621 : }
1622 31182 : else if (name == "GtkTextView")
1623 : {
1624 0 : extractBuffer(id, rMap);
1625 :
1626 0 : WinBits nWinStyle = WB_CLIPCHILDREN|WB_LEFT;
1627 0 : OString sBorder = extractCustomProperty(rMap);
1628 0 : if (!sBorder.isEmpty())
1629 0 : nWinStyle |= WB_BORDER;
1630 : //VclMultiLineEdit manages its own scrolling,
1631 0 : vcl::Window *pRealParent = prepareWidgetOwnScrolling(pParent, nWinStyle);
1632 0 : xWindow = VclPtr<VclMultiLineEdit>::Create(pRealParent, nWinStyle);
1633 0 : if (pRealParent != pParent)
1634 0 : cleanupWidgetOwnScrolling(pParent, xWindow, rMap);
1635 : }
1636 31182 : else if (name == "GtkSpinner")
1637 : {
1638 0 : xWindow = VclPtr<Throbber>::Create(pParent, WB_3DLOOK);
1639 : }
1640 31182 : else if (name == "GtkScale")
1641 : {
1642 0 : extractAdjustmentToMap(id, rMap, m_pParserState->m_aSliderAdjustmentMaps);
1643 0 : bool bDrawValue = extractDrawValue(rMap);
1644 0 : if (bDrawValue)
1645 : {
1646 0 : OString sValuePos = extractValuePos(rMap);
1647 0 : (void)sValuePos;
1648 : }
1649 0 : bVertical = extractOrientation(rMap);
1650 :
1651 0 : WinBits nWinStyle = bVertical ? WB_VERT : WB_HORZ;
1652 :
1653 0 : xWindow = VclPtr<Slider>::Create(pParent, nWinStyle);
1654 : }
1655 31182 : else if (name == "GtkToolbar")
1656 : {
1657 2142 : xWindow = VclPtr<ToolBox>::Create(pParent, WB_3DLOOK | WB_TABSTOP);
1658 : }
1659 29040 : else if (name == "GtkToolButton" || name == "GtkMenuToolButton")
1660 : {
1661 19332 : ToolBox *pToolBox = dynamic_cast<ToolBox*>(pParent);
1662 19332 : if (pToolBox)
1663 : {
1664 19332 : OUString aCommand(OStringToOUString(extractActionName(rMap), RTL_TEXTENCODING_UTF8));
1665 :
1666 19332 : sal_uInt16 nItemId = 0;
1667 19332 : ToolBoxItemBits nBits = ToolBoxItemBits::NONE;
1668 19332 : if (name == "GtkMenuToolButton")
1669 5753 : nBits |= ToolBoxItemBits::DROPDOWN;
1670 :
1671 19332 : if (!aCommand.isEmpty() && m_xFrame.is())
1672 : {
1673 19332 : pToolBox->InsertItem(aCommand, m_xFrame, nBits, extractSizeRequest(rMap));
1674 19332 : nItemId = pToolBox->GetItemId(aCommand);
1675 : }
1676 : else
1677 : {
1678 0 : const sal_uInt16 COMMAND_ITEMID_START = 30000;
1679 0 : nItemId = COMMAND_ITEMID_START + pToolBox->GetItemCount();
1680 : pToolBox->InsertItem(nItemId,
1681 0 : OStringToOUString(extractLabel(rMap), RTL_TEXTENCODING_UTF8), nBits);
1682 0 : pToolBox->SetItemCommand(nItemId, aCommand);
1683 0 : pToolBox->SetHelpId(nItemId, m_sHelpRoot + id);
1684 : }
1685 :
1686 38664 : OString sTooltip(extractTooltipText(rMap));
1687 19332 : if (!sTooltip.isEmpty())
1688 3309 : pToolBox->SetQuickHelpText(nItemId, OStringToOUString(sTooltip, RTL_TEXTENCODING_UTF8));
1689 :
1690 38664 : OString sIconName(extractIconName(rMap));
1691 19332 : if (!sIconName.isEmpty())
1692 0 : pToolBox->SetItemImage(nItemId, FixedImage::loadThemeImage(sIconName));
1693 :
1694 19332 : if (!extractVisible(rMap))
1695 0 : pToolBox->HideItem(nItemId);
1696 :
1697 19332 : m_pParserState->m_nLastToolbarId = nItemId;
1698 :
1699 38664 : return nullptr; // no widget to be created
1700 : }
1701 : }
1702 9708 : else if (name == "GtkSeparatorToolItem")
1703 : {
1704 0 : ToolBox *pToolBox = dynamic_cast<ToolBox*>(pParent);
1705 0 : if (pToolBox)
1706 : {
1707 0 : pToolBox->InsertSeparator();
1708 0 : return nullptr; // no widget to be created
1709 : }
1710 : }
1711 9708 : else if (name == "GtkWindow")
1712 : {
1713 0 : WinBits nBits = extractDeferredBits(rMap);
1714 0 : if (nBits & WB_DOCKABLE)
1715 0 : xWindow = VclPtr<DockingWindow>::Create(pParent, nBits|WB_MOVEABLE);
1716 : else
1717 0 : xWindow = VclPtr<FloatingWindow>::Create(pParent, nBits|WB_MOVEABLE);
1718 : }
1719 : else
1720 : {
1721 : #ifndef SAL_DLLPREFIX
1722 : #define SAL_DLLPREFIX ""
1723 : #endif
1724 9708 : sal_Int32 nDelim = name.indexOf('-');
1725 9708 : if (nDelim != -1)
1726 : {
1727 : #ifndef DISABLE_DYNLOADING
1728 9708 : OUStringBuffer sModuleBuf;
1729 9708 : sModuleBuf.append(SAL_DLLPREFIX);
1730 9708 : sModuleBuf.append(OStringToOUString(name.copy(0, nDelim), RTL_TEXTENCODING_UTF8));
1731 9708 : sModuleBuf.append(SAL_DLLEXTENSION);
1732 : #endif
1733 19416 : OUString sFunction(OStringToOUString(OString("make") + name.copy(nDelim+1), RTL_TEXTENCODING_UTF8));
1734 : #ifndef DISABLE_DYNLOADING
1735 19416 : OUString sModule = sModuleBuf.makeStringAndClear();
1736 9708 : ModuleMap::iterator aI = m_aModuleMap.find(sModule);
1737 9708 : if (aI == m_aModuleMap.end())
1738 : {
1739 1472 : osl::Module* pModule = new osl::Module;
1740 : #if ENABLE_MERGELIBS
1741 : sModuleBuf.append(SAL_DLLPREFIX);
1742 : sModuleBuf.append("mergedlo");
1743 : sModuleBuf.append(SAL_DLLEXTENSION);
1744 : OUString sMergedModule = sModuleBuf.makeStringAndClear();
1745 : pModule->loadRelative(&thisModule, sMergedModule);
1746 : if (!pModule->getFunctionSymbol(sFunction))
1747 : {
1748 : pModule->loadRelative(&thisModule, sModule);
1749 : }
1750 : #else
1751 1472 : pModule->loadRelative(&thisModule, sModule);
1752 : #endif
1753 1472 : aI = m_aModuleMap.insert(sModule, pModule).first;
1754 : }
1755 9708 : customMakeWidget pFunction = reinterpret_cast<customMakeWidget>(aI->second->getFunctionSymbol(sFunction));
1756 : #else
1757 : customMakeWidget pFunction = reinterpret_cast<customMakeWidget>(osl_getFunctionSymbol((oslModule) RTLD_DEFAULT, sFunction.pData));
1758 : #endif
1759 9708 : if (pFunction)
1760 : {
1761 9708 : VclPtr<vcl::Window> xParent(pParent);
1762 9708 : pFunction(xWindow, xParent, rMap);
1763 9708 : }
1764 : }
1765 : }
1766 : SAL_WARN_IF(!xWindow, "vcl.layout", "probably need to implement " << name.getStr() << " or add a make" << name.getStr() << " function");
1767 24546 : if (xWindow)
1768 : {
1769 24546 : xWindow->SetHelpId(m_sHelpRoot + id);
1770 : SAL_INFO("vcl.layout", "for " << name.getStr() <<
1771 : ", created " << xWindow.get() << " child of " <<
1772 : pParent << "(" << xWindow->mpWindowImpl->mpParent.get() << "/" <<
1773 : xWindow->mpWindowImpl->mpRealParent.get() << "/" <<
1774 : xWindow->mpWindowImpl->mpBorderWindow.get() << ") with helpid " <<
1775 : xWindow->GetHelpId().getStr());
1776 24546 : m_aChildren.push_back(WinAndId(id, xWindow, bVertical));
1777 : }
1778 24546 : return xWindow;
1779 : }
1780 :
1781 : namespace
1782 : {
1783 : //return true for window types which exist in vcl but are not themselves
1784 : //represented in the .ui format, i.e. only their children exist.
1785 45535 : bool isConsideredGtkPseudo(vcl::Window *pWindow)
1786 : {
1787 45535 : return pWindow->GetType() == WINDOW_TABPAGE;
1788 : }
1789 : }
1790 :
1791 : //Any properties from .ui load we couldn't set because of potential virtual methods
1792 : //during ctor are applied here
1793 70 : void VclBuilder::setDeferredProperties()
1794 : {
1795 70 : if (!m_bToplevelHasDeferredProperties)
1796 123 : return;
1797 17 : stringmap aDeferredProperties;
1798 17 : aDeferredProperties.swap(m_aDeferredProperties);
1799 17 : m_bToplevelHasDeferredProperties = false;
1800 17 : set_properties(m_pParent, aDeferredProperties);
1801 : }
1802 :
1803 26184 : void VclBuilder::set_properties(vcl::Window *pWindow, const stringmap &rProps)
1804 : {
1805 133800 : for (stringmap::const_iterator aI = rProps.begin(), aEnd = rProps.end(); aI != aEnd; ++aI)
1806 : {
1807 107616 : const OString &rKey = aI->first;
1808 107616 : const OString &rValue = aI->second;
1809 107616 : pWindow->set_property(rKey, rValue);
1810 : }
1811 26184 : }
1812 :
1813 45535 : VclPtr<vcl::Window> VclBuilder::insertObject(vcl::Window *pParent, const OString &rClass,
1814 : const OString &rID, stringmap &rProps, stringmap &rPango, stringmap &rAtk)
1815 : {
1816 45535 : VclPtr<vcl::Window> pCurrentChild;
1817 :
1818 45535 : if (m_pParent && !isConsideredGtkPseudo(m_pParent) && !m_sID.isEmpty() && rID.equals(m_sID))
1819 : {
1820 1638 : pCurrentChild = m_pParent;
1821 :
1822 : //toplevels default to resizable and apparently you can't change them
1823 : //afterwards, so we need to wait until now before we can truly
1824 : //initialize the dialog.
1825 1638 : if (pParent && pParent->IsSystemWindow())
1826 : {
1827 0 : SystemWindow *pSysWin = static_cast<SystemWindow*>(pCurrentChild.get());
1828 0 : pSysWin->doDeferredInit(extractDeferredBits(rProps));
1829 0 : m_bToplevelHasDeferredInit = false;
1830 : }
1831 1638 : else if (pParent && pParent->IsDockingWindow())
1832 : {
1833 17 : DockingWindow *pDockWin = static_cast<DockingWindow*>(pCurrentChild.get());
1834 17 : pDockWin->doDeferredInit(extractDeferredBits(rProps));
1835 17 : m_bToplevelHasDeferredInit = false;
1836 : }
1837 :
1838 1638 : if (pCurrentChild->GetHelpId().isEmpty())
1839 : {
1840 1638 : pCurrentChild->SetHelpId(m_sHelpRoot + m_sID);
1841 : SAL_INFO("vcl.layout", "for toplevel dialog " << this << " " <<
1842 : rID.getStr() << ", set helpid " <<
1843 : pCurrentChild->GetHelpId().getStr());
1844 : }
1845 1638 : m_bToplevelParentFound = true;
1846 : }
1847 : else
1848 : {
1849 : //if we're being inserting under a toplevel dialog whose init is
1850 : //deferred due to waiting to encounter it in this .ui, and it hasn't
1851 : //been seen yet, then make unattached widgets parent-less toplevels
1852 43897 : if (pParent == m_pParent.get() && m_bToplevelHasDeferredInit)
1853 0 : pParent = NULL;
1854 43897 : pCurrentChild = makeObject(pParent, rClass, rID, rProps);
1855 : }
1856 :
1857 45535 : if (pCurrentChild)
1858 : {
1859 26184 : if (pCurrentChild == m_pParent.get() && m_bToplevelHasDeferredProperties)
1860 17 : m_aDeferredProperties = rProps;
1861 : else
1862 26167 : set_properties(pCurrentChild, rProps);
1863 :
1864 26184 : for (stringmap::iterator aI = rPango.begin(), aEnd = rPango.end(); aI != aEnd; ++aI)
1865 : {
1866 0 : const OString &rKey = aI->first;
1867 0 : const OString &rValue = aI->second;
1868 0 : pCurrentChild->set_font_attribute(rKey, rValue);
1869 : }
1870 :
1871 26184 : m_pParserState->m_aAtkInfo[VclPtr<vcl::Window>(pCurrentChild)] = rAtk;
1872 : }
1873 :
1874 45535 : rProps.clear();
1875 45535 : rPango.clear();
1876 45535 : rAtk.clear();
1877 :
1878 45535 : if (!pCurrentChild)
1879 19351 : pCurrentChild = m_aChildren.empty() ? pParent : m_aChildren.back().m_pWindow.get();
1880 45535 : return pCurrentChild;
1881 : }
1882 :
1883 26687 : void VclBuilder::reorderWithinParent(vcl::Window &rWindow, sal_uInt16 nNewPosition)
1884 : {
1885 26687 : if (rWindow.mpWindowImpl->mpParent != rWindow.mpWindowImpl->mpRealParent)
1886 : {
1887 : assert(rWindow.mpWindowImpl->mpBorderWindow ==
1888 : rWindow.mpWindowImpl->mpParent);
1889 : assert(rWindow.mpWindowImpl->mpBorderWindow->mpWindowImpl->mpParent ==
1890 : rWindow.mpWindowImpl->mpRealParent);
1891 0 : reorderWithinParent(*rWindow.mpWindowImpl->mpBorderWindow, nNewPosition);
1892 26687 : return;
1893 : }
1894 26687 : rWindow.reorderWithinParent(nNewPosition);
1895 : }
1896 :
1897 0 : void VclBuilder::handleTabChild(vcl::Window *pParent, xmlreader::XmlReader &reader)
1898 : {
1899 0 : OString sID;
1900 :
1901 0 : int nLevel = 1;
1902 0 : stringmap aProperties;
1903 : while(true)
1904 : {
1905 0 : xmlreader::Span name;
1906 : int nsId;
1907 :
1908 : xmlreader::XmlReader::Result res = reader.nextItem(
1909 0 : xmlreader::XmlReader::TEXT_NONE, &name, &nsId);
1910 :
1911 0 : if (res == xmlreader::XmlReader::RESULT_BEGIN)
1912 : {
1913 0 : ++nLevel;
1914 0 : if (name.equals("object"))
1915 : {
1916 0 : while (reader.nextAttribute(&nsId, &name))
1917 : {
1918 0 : if (name.equals("id"))
1919 : {
1920 0 : name = reader.getAttributeValue(false);
1921 0 : sID = OString(name.begin, name.length);
1922 0 : sal_Int32 nDelim = sID.indexOf(':');
1923 0 : if (nDelim != -1)
1924 : {
1925 0 : OString sPattern = sID.copy(nDelim+1);
1926 0 : aProperties[OString("customproperty")] = sPattern;
1927 0 : sID = sID.copy(0, nDelim);
1928 : }
1929 : }
1930 : }
1931 : }
1932 0 : else if (name.equals("property"))
1933 0 : collectProperty(reader, sID, aProperties);
1934 : }
1935 :
1936 0 : if (res == xmlreader::XmlReader::RESULT_END)
1937 0 : --nLevel;
1938 :
1939 0 : if (!nLevel)
1940 0 : break;
1941 :
1942 0 : if (res == xmlreader::XmlReader::RESULT_DONE)
1943 0 : break;
1944 : }
1945 :
1946 0 : if (!pParent)
1947 0 : return;
1948 :
1949 0 : TabControl *pTabControl = static_cast<TabControl*>(pParent);
1950 0 : VclBuilder::stringmap::iterator aFind = aProperties.find(OString("label"));
1951 0 : if (aFind != aProperties.end())
1952 : {
1953 0 : sal_uInt16 nPageId = pTabControl->GetCurPageId();
1954 : pTabControl->SetPageText(nPageId,
1955 0 : OStringToOUString(aFind->second, RTL_TEXTENCODING_UTF8));
1956 0 : pTabControl->SetPageName(nPageId, sID);
1957 : }
1958 : else
1959 0 : pTabControl->RemovePage(pTabControl->GetCurPageId());
1960 : }
1961 :
1962 : //so that tabbing between controls goes in a visually sensible sequence
1963 : //we sort these into a best-tab-order sequence
1964 22256 : bool VclBuilder::sortIntoBestTabTraversalOrder::operator()(const vcl::Window *pA, const vcl::Window *pB) const
1965 : {
1966 : //sort child order within parent list by grid position
1967 22256 : sal_Int32 nTopA = pA->get_grid_top_attach();
1968 22256 : sal_Int32 nTopB = pB->get_grid_top_attach();
1969 22256 : if (nTopA < nTopB)
1970 1018 : return true;
1971 21238 : if (nTopA > nTopB)
1972 722 : return false;
1973 20516 : sal_Int32 nLeftA = pA->get_grid_left_attach();
1974 20516 : sal_Int32 nLeftB = pB->get_grid_left_attach();
1975 20516 : if (nLeftA < nLeftB)
1976 826 : return true;
1977 19690 : if (nLeftA > nLeftB)
1978 1514 : return false;
1979 : //sort into two groups of pack start and pack end
1980 18176 : VclPackType ePackA = pA->get_pack_type();
1981 18176 : VclPackType ePackB = pB->get_pack_type();
1982 18176 : if (ePackA < ePackB)
1983 338 : return true;
1984 17838 : if (ePackA > ePackB)
1985 3200 : return false;
1986 14638 : bool bVerticalContainer = m_pBuilder->get_window_packing_data(pA->GetParent()).m_bVerticalOrient;
1987 14638 : bool bPackA = pA->get_secondary();
1988 14638 : bool bPackB = pB->get_secondary();
1989 14638 : if (!bVerticalContainer)
1990 : {
1991 : //for horizontal boxes group secondaries before primaries
1992 5448 : if (bPackA > bPackB)
1993 0 : return true;
1994 5448 : if (bPackA < bPackB)
1995 0 : return false;
1996 : }
1997 : else
1998 : {
1999 : //for vertical boxes group secondaries after primaries
2000 9190 : if (bPackA < bPackB)
2001 0 : return true;
2002 9190 : if (bPackA > bPackB)
2003 0 : return false;
2004 : }
2005 : //honour relative box positions with pack group, (numerical order is reversed
2006 : //for VCL_PACK_END, they are packed from the end back, but here we need
2007 : //them in visual layout order so that tabbing works as expected)
2008 14638 : sal_Int32 nPackA = m_pBuilder->get_window_packing_data(pA).m_nPosition;
2009 14638 : sal_Int32 nPackB = m_pBuilder->get_window_packing_data(pB).m_nPosition;
2010 14638 : if (nPackA < nPackB)
2011 0 : return ePackA == VCL_PACK_START;
2012 14638 : if (nPackA > nPackB)
2013 14309 : return ePackA != VCL_PACK_START;
2014 : //sort labels of Frames before body
2015 329 : if (pA->GetParent() == pB->GetParent())
2016 : {
2017 329 : const VclFrame *pFrameParent = dynamic_cast<const VclFrame*>(pA->GetParent());
2018 329 : if (pFrameParent)
2019 : {
2020 0 : const vcl::Window *pLabel = pFrameParent->get_label_widget();
2021 0 : int nFramePosA = (pA == pLabel) ? 0 : 1;
2022 0 : int nFramePosB = (pB == pLabel) ? 0 : 1;
2023 0 : return nFramePosA < nFramePosB;
2024 : }
2025 : }
2026 329 : return false;
2027 : }
2028 :
2029 45531 : void VclBuilder::handleChild(vcl::Window *pParent, xmlreader::XmlReader &reader)
2030 : {
2031 45531 : vcl::Window *pCurrentChild = NULL;
2032 :
2033 45531 : xmlreader::Span name;
2034 : int nsId;
2035 91062 : OString sType, sInternalChild;
2036 :
2037 91067 : while (reader.nextAttribute(&nsId, &name))
2038 : {
2039 5 : if (name.equals("type"))
2040 : {
2041 0 : name = reader.getAttributeValue(false);
2042 0 : sType = OString(name.begin, name.length);
2043 : }
2044 5 : else if (name.equals("internal-child"))
2045 : {
2046 5 : name = reader.getAttributeValue(false);
2047 5 : sInternalChild = OString(name.begin, name.length);
2048 : }
2049 : }
2050 :
2051 45531 : if (sType.equals("tab"))
2052 : {
2053 0 : handleTabChild(pParent, reader);
2054 45531 : return;
2055 : }
2056 :
2057 45531 : int nLevel = 1;
2058 : while(true)
2059 : {
2060 : xmlreader::XmlReader::Result res = reader.nextItem(
2061 142156 : xmlreader::XmlReader::TEXT_NONE, &name, &nsId);
2062 :
2063 142156 : if (res == xmlreader::XmlReader::RESULT_BEGIN)
2064 : {
2065 93349 : if (name.equals("object") || name.equals("placeholder"))
2066 : {
2067 46221 : pCurrentChild = handleObject(pParent, reader);
2068 :
2069 46221 : bool bObjectInserted = pCurrentChild && pParent != pCurrentChild;
2070 :
2071 46221 : if (bObjectInserted)
2072 : {
2073 : //Internal-children default in glade to not having their visible bits set
2074 : //even though they are visible (generally anyway)
2075 24548 : if (!sInternalChild.isEmpty())
2076 0 : pCurrentChild->Show();
2077 :
2078 : //Select the first page if it's a notebook
2079 24548 : if (pCurrentChild->GetType() == WINDOW_TABCONTROL)
2080 : {
2081 0 : TabControl *pTabControl = static_cast<TabControl*>(pCurrentChild);
2082 0 : pTabControl->SetCurPageId(pTabControl->GetPageId(0));
2083 :
2084 : //To-Do add reorder capability to the TabControl
2085 : }
2086 : else
2087 : {
2088 : // We want to sort labels before contents of frames
2089 : // for keyboard traversal, especially if there
2090 : // are multiple widgets using the same mnemonic
2091 24548 : if (sType.equals("label"))
2092 : {
2093 0 : if (VclFrame *pFrameParent = dynamic_cast<VclFrame*>(pParent))
2094 0 : pFrameParent->designate_label(pCurrentChild);
2095 : }
2096 24548 : if (sInternalChild.startsWith("vbox") || sInternalChild.startsWith("messagedialog-vbox"))
2097 : {
2098 0 : if (Dialog *pBoxParent = dynamic_cast<Dialog*>(pParent))
2099 0 : pBoxParent->set_content_area(static_cast<VclBox*>(pCurrentChild)); // FIXME-VCLPTR
2100 : }
2101 24548 : else if (sInternalChild.startsWith("action_area") || sInternalChild.startsWith("messagedialog-action_area"))
2102 : {
2103 0 : vcl::Window *pContentArea = pCurrentChild->GetParent();
2104 0 : if (Dialog *pBoxParent = dynamic_cast<Dialog*>(pContentArea ? pContentArea->GetParent() : NULL))
2105 : {
2106 0 : pBoxParent->set_action_area(static_cast<VclButtonBox*>(pCurrentChild)); // FIXME-VCLPTR
2107 : }
2108 : }
2109 :
2110 : //To-Do make reorder a virtual in Window, move this foo
2111 : //there and see above
2112 24548 : std::vector<vcl::Window*> aChilds;
2113 51235 : for (vcl::Window* pChild = pCurrentChild->GetWindow(GetWindowType::FirstChild); pChild;
2114 26687 : pChild = pChild->GetWindow(GetWindowType::Next))
2115 : {
2116 26687 : aChilds.push_back(pChild);
2117 : }
2118 :
2119 24548 : bool bIsButtonBox = dynamic_cast<VclButtonBox*>(pCurrentChild) != NULL;
2120 :
2121 : //sort child order within parent so that tabbing
2122 : //between controls goes in a visually sensible sequence
2123 24548 : std::stable_sort(aChilds.begin(), aChilds.end(), sortIntoBestTabTraversalOrder(this));
2124 24548 : reorderWithinParent(aChilds, bIsButtonBox);
2125 : }
2126 : }
2127 : }
2128 47128 : else if (name.equals("packing"))
2129 : {
2130 43852 : handlePacking(pCurrentChild, pParent, reader);
2131 : }
2132 : else
2133 3276 : ++nLevel;
2134 : }
2135 :
2136 142156 : if (res == xmlreader::XmlReader::RESULT_END)
2137 47169 : --nLevel;
2138 :
2139 142156 : if (!nLevel)
2140 43893 : break;
2141 :
2142 98263 : if (res == xmlreader::XmlReader::RESULT_DONE)
2143 1638 : break;
2144 45531 : }
2145 : }
2146 :
2147 24548 : void VclBuilder::reorderWithinParent(std::vector<vcl::Window*>& rChilds, bool bIsButtonBox)
2148 : {
2149 51235 : for (size_t i = 0; i < rChilds.size(); ++i)
2150 : {
2151 26687 : reorderWithinParent(*rChilds[i], i);
2152 :
2153 26687 : if (!bIsButtonBox)
2154 26687 : continue;
2155 :
2156 : //The first member of the group for legacy code needs WB_GROUP set and the
2157 : //others not
2158 0 : WinBits nBits = rChilds[i]->GetStyle();
2159 0 : nBits &= ~WB_GROUP;
2160 0 : if (i == 0)
2161 0 : nBits |= WB_GROUP;
2162 0 : rChilds[i]->SetStyle(nBits);
2163 : }
2164 24548 : }
2165 :
2166 19382 : OUString VclBuilder::getCommandLabel(const OUString& rCommand, const uno::Reference<uno::XComponentContext>& rContext, const OUString& rModuleId)
2167 : {
2168 19382 : if (rCommand.isEmpty())
2169 0 : return OUString();
2170 :
2171 : try
2172 : {
2173 19382 : uno::Reference<container::XNameAccess> xUICommandLabels;
2174 21339 : uno::Reference<container::XNameAccess> xUICommandDescription(frame::theUICommandDescription::get(rContext));
2175 :
2176 19382 : if ((xUICommandDescription->getByName(rModuleId) >>= xUICommandLabels) && xUICommandLabels.is())
2177 : {
2178 19382 : uno::Sequence<beans::PropertyValue> aProperties;
2179 19382 : if (xUICommandLabels->getByName(rCommand) >>= aProperties)
2180 : {
2181 17425 : for ( sal_Int32 i = 0; i < aProperties.getLength(); i++ )
2182 : {
2183 17425 : if (aProperties[i].Name == "Label")
2184 : {
2185 17425 : OUString aLabel;
2186 17425 : if (aProperties[i].Value >>= aLabel)
2187 17425 : return aLabel;
2188 : }
2189 : }
2190 1957 : }
2191 1957 : }
2192 : }
2193 1957 : catch (uno::Exception&)
2194 : {
2195 : }
2196 :
2197 1957 : return OUString();
2198 : }
2199 :
2200 19382 : Image VclBuilder::getCommandImage(const OUString& rCommand, bool bLarge,
2201 : const uno::Reference<uno::XComponentContext>& rContext, const uno::Reference<frame::XFrame>& rFrame,
2202 : const OUString& rModuleId)
2203 : {
2204 19382 : if (rCommand.isEmpty())
2205 0 : return Image();
2206 :
2207 19382 : sal_Int16 nImageType(ui::ImageType::COLOR_NORMAL | ui::ImageType::SIZE_DEFAULT);
2208 19382 : if (bLarge)
2209 0 : nImageType |= ui::ImageType::SIZE_LARGE;
2210 :
2211 : try
2212 : {
2213 19382 : uno::Reference<frame::XController> xController(rFrame->getController());
2214 38764 : uno::Reference<frame::XModel> xModel(xController->getModel());
2215 :
2216 38764 : uno::Reference<ui::XUIConfigurationManagerSupplier> xSupplier(xModel, uno::UNO_QUERY);
2217 19382 : if (xSupplier.is())
2218 : {
2219 19382 : uno::Reference<ui::XUIConfigurationManager> xDocUICfgMgr(xSupplier->getUIConfigurationManager(), uno::UNO_QUERY);
2220 38764 : uno::Reference<ui::XImageManager> xDocImgMgr(xDocUICfgMgr->getImageManager(), uno::UNO_QUERY);
2221 :
2222 38764 : uno::Sequence< uno::Reference<graphic::XGraphic> > aGraphicSeq;
2223 38764 : uno::Sequence<OUString> aImageCmdSeq(1);
2224 19382 : aImageCmdSeq[0] = rCommand;
2225 :
2226 19382 : aGraphicSeq = xDocImgMgr->getImages( nImageType, aImageCmdSeq );
2227 38764 : uno::Reference<graphic::XGraphic> xGraphic = aGraphicSeq[0];
2228 38764 : Image aImage(xGraphic);
2229 :
2230 19382 : if (!!aImage)
2231 19382 : return aImage;
2232 19382 : }
2233 : }
2234 0 : catch (uno::Exception&)
2235 : {
2236 : }
2237 :
2238 : try {
2239 19382 : uno::Reference<ui::XModuleUIConfigurationManagerSupplier> xModuleCfgMgrSupplier(ui::theModuleUIConfigurationManagerSupplier::get(rContext));
2240 38764 : uno::Reference<ui::XUIConfigurationManager> xUICfgMgr(xModuleCfgMgrSupplier->getUIConfigurationManager(rModuleId));
2241 :
2242 38764 : uno::Sequence< uno::Reference<graphic::XGraphic> > aGraphicSeq;
2243 38764 : uno::Reference<ui::XImageManager> xModuleImageManager(xUICfgMgr->getImageManager(), uno::UNO_QUERY);
2244 :
2245 38764 : uno::Sequence<OUString> aImageCmdSeq(1);
2246 19382 : aImageCmdSeq[0] = rCommand;
2247 :
2248 19382 : aGraphicSeq = xModuleImageManager->getImages(nImageType, aImageCmdSeq);
2249 :
2250 38764 : uno::Reference<graphic::XGraphic> xGraphic(aGraphicSeq[0]);
2251 :
2252 38764 : return Image(xGraphic);
2253 : }
2254 0 : catch (uno::Exception&)
2255 : {
2256 : }
2257 :
2258 0 : return Image();
2259 : }
2260 :
2261 0 : void VclBuilder::collectPangoAttribute(xmlreader::XmlReader &reader, stringmap &rMap)
2262 : {
2263 0 : xmlreader::Span span;
2264 : int nsId;
2265 :
2266 0 : OString sProperty;
2267 0 : OString sValue;
2268 :
2269 0 : while (reader.nextAttribute(&nsId, &span))
2270 : {
2271 0 : if (span.equals("name"))
2272 : {
2273 0 : span = reader.getAttributeValue(false);
2274 0 : sProperty = OString(span.begin, span.length);
2275 : }
2276 0 : else if (span.equals("value"))
2277 : {
2278 0 : span = reader.getAttributeValue(false);
2279 0 : sValue = OString(span.begin, span.length);
2280 : }
2281 : }
2282 :
2283 0 : if (!sProperty.isEmpty())
2284 0 : rMap[sProperty] = sValue;
2285 0 : }
2286 :
2287 6 : void VclBuilder::collectAtkAttribute(xmlreader::XmlReader &reader, stringmap &rMap)
2288 : {
2289 6 : xmlreader::Span span;
2290 : int nsId;
2291 :
2292 6 : OString sProperty;
2293 12 : OString sValue;
2294 :
2295 24 : while (reader.nextAttribute(&nsId, &span))
2296 : {
2297 12 : if (span.equals("type"))
2298 : {
2299 6 : span = reader.getAttributeValue(false);
2300 6 : sProperty = OString(span.begin, span.length);
2301 : }
2302 6 : else if (span.equals("target"))
2303 : {
2304 6 : span = reader.getAttributeValue(false);
2305 6 : sValue = OString(span.begin, span.length);
2306 6 : sal_Int32 nDelim = sValue.indexOf(':');
2307 6 : if (nDelim != -1)
2308 0 : sValue = sValue.copy(0, nDelim);
2309 : }
2310 : }
2311 :
2312 6 : if (!sProperty.isEmpty())
2313 12 : rMap[sProperty] = sValue;
2314 6 : }
2315 :
2316 341 : void VclBuilder::handleAdjustment(const OString &rID, stringmap &rProperties)
2317 : {
2318 341 : m_pParserState->m_aAdjustments[rID] = rProperties;
2319 341 : }
2320 :
2321 0 : void VclBuilder::handleTextBuffer(const OString &rID, stringmap &rProperties)
2322 : {
2323 0 : m_pParserState->m_aTextBuffers[rID] = rProperties;
2324 0 : }
2325 :
2326 0 : void VclBuilder::handleRow(xmlreader::XmlReader &reader, const OString &rID, sal_Int32 nRowIndex)
2327 : {
2328 0 : int nLevel = 1;
2329 :
2330 0 : ListStore::row aRow;
2331 :
2332 : while(true)
2333 : {
2334 0 : xmlreader::Span name;
2335 : int nsId;
2336 :
2337 : xmlreader::XmlReader::Result res = reader.nextItem(
2338 0 : xmlreader::XmlReader::TEXT_NONE, &name, &nsId);
2339 :
2340 0 : if (res == xmlreader::XmlReader::RESULT_DONE)
2341 0 : break;
2342 :
2343 0 : if (res == xmlreader::XmlReader::RESULT_BEGIN)
2344 : {
2345 0 : ++nLevel;
2346 0 : if (name.equals("col"))
2347 : {
2348 0 : bool bTranslated = false;
2349 0 : OString sValue;
2350 0 : sal_uInt32 nId = 0;
2351 :
2352 0 : while (reader.nextAttribute(&nsId, &name))
2353 : {
2354 0 : if (name.equals("id"))
2355 : {
2356 0 : name = reader.getAttributeValue(false);
2357 0 : nId = OString(name.begin, name.length).toInt32();
2358 : }
2359 0 : else if (nId == 0 && name.equals("translatable") && reader.getAttributeValue(false).equals("yes"))
2360 : {
2361 0 : sValue = getTranslation(rID, OString::number(nRowIndex));
2362 0 : bTranslated = !sValue.isEmpty();
2363 : }
2364 : }
2365 :
2366 : reader.nextItem(
2367 0 : xmlreader::XmlReader::TEXT_RAW, &name, &nsId);
2368 :
2369 0 : if (!bTranslated)
2370 0 : sValue = OString(name.begin, name.length);
2371 :
2372 0 : if (aRow.size() < nId+1)
2373 0 : aRow.resize(nId+1);
2374 0 : aRow[nId] = sValue;
2375 : }
2376 : }
2377 :
2378 0 : if (res == xmlreader::XmlReader::RESULT_END)
2379 : {
2380 0 : --nLevel;
2381 : }
2382 :
2383 0 : if (!nLevel)
2384 0 : break;
2385 : }
2386 :
2387 0 : m_pParserState->m_aModels[rID].m_aEntries.push_back(aRow);
2388 0 : }
2389 :
2390 0 : void VclBuilder::handleListStore(xmlreader::XmlReader &reader, const OString &rID)
2391 : {
2392 0 : int nLevel = 1;
2393 0 : sal_Int32 nRowIndex = 0;
2394 :
2395 : while(true)
2396 : {
2397 0 : xmlreader::Span name;
2398 : int nsId;
2399 :
2400 : xmlreader::XmlReader::Result res = reader.nextItem(
2401 0 : xmlreader::XmlReader::TEXT_NONE, &name, &nsId);
2402 :
2403 0 : if (res == xmlreader::XmlReader::RESULT_DONE)
2404 0 : break;
2405 :
2406 0 : if (res == xmlreader::XmlReader::RESULT_BEGIN)
2407 : {
2408 0 : if (name.equals("row"))
2409 0 : handleRow(reader, rID, nRowIndex++);
2410 : else
2411 0 : ++nLevel;
2412 : }
2413 :
2414 0 : if (res == xmlreader::XmlReader::RESULT_END)
2415 : {
2416 0 : --nLevel;
2417 : }
2418 :
2419 0 : if (!nLevel)
2420 0 : break;
2421 0 : }
2422 0 : }
2423 :
2424 5 : void VclBuilder::handleAtkObject(xmlreader::XmlReader &reader, const OString &rID, vcl::Window *pWindow)
2425 : {
2426 : assert(pWindow);
2427 :
2428 5 : int nLevel = 1;
2429 :
2430 5 : stringmap aProperties;
2431 :
2432 : while(true)
2433 : {
2434 15 : xmlreader::Span name;
2435 : int nsId;
2436 :
2437 : xmlreader::XmlReader::Result res = reader.nextItem(
2438 15 : xmlreader::XmlReader::TEXT_NONE, &name, &nsId);
2439 :
2440 15 : if (res == xmlreader::XmlReader::RESULT_DONE)
2441 5 : break;
2442 :
2443 15 : if (res == xmlreader::XmlReader::RESULT_BEGIN)
2444 : {
2445 5 : ++nLevel;
2446 5 : if (name.equals("property"))
2447 5 : collectProperty(reader, rID, aProperties);
2448 : }
2449 :
2450 15 : if (res == xmlreader::XmlReader::RESULT_END)
2451 : {
2452 10 : --nLevel;
2453 : }
2454 :
2455 15 : if (!nLevel)
2456 5 : break;
2457 : }
2458 :
2459 10 : for (stringmap::iterator aI = aProperties.begin(), aEnd = aProperties.end(); aI != aEnd; ++aI)
2460 : {
2461 5 : const OString &rKey = aI->first;
2462 5 : const OString &rValue = aI->second;
2463 :
2464 5 : if (pWindow && rKey.match("AtkObject::"))
2465 5 : pWindow->set_property(rKey.copy(RTL_CONSTASCII_LENGTH("AtkObject::")), rValue);
2466 : else
2467 : SAL_WARN("vcl.layout", "unhandled atk prop: " << rKey.getStr());
2468 5 : }
2469 5 : }
2470 :
2471 154 : std::vector<OString> VclBuilder::handleItems(xmlreader::XmlReader &reader, const OString &rID)
2472 : {
2473 154 : int nLevel = 1;
2474 :
2475 154 : std::vector<OString> aItems;
2476 154 : sal_Int32 nItemIndex = 0;
2477 :
2478 : while(true)
2479 : {
2480 3204 : xmlreader::Span name;
2481 : int nsId;
2482 :
2483 : xmlreader::XmlReader::Result res = reader.nextItem(
2484 3204 : xmlreader::XmlReader::TEXT_NONE, &name, &nsId);
2485 :
2486 3204 : if (res == xmlreader::XmlReader::RESULT_DONE)
2487 154 : break;
2488 :
2489 3204 : if (res == xmlreader::XmlReader::RESULT_BEGIN)
2490 : {
2491 1525 : ++nLevel;
2492 1525 : if (name.equals("item"))
2493 : {
2494 1525 : bool bTranslated = false;
2495 1525 : OString sValue;
2496 :
2497 4575 : while (reader.nextAttribute(&nsId, &name))
2498 : {
2499 1525 : if (name.equals("translatable") && reader.getAttributeValue(false).equals("yes"))
2500 : {
2501 1525 : sValue = getTranslation(rID, OString::number(nItemIndex));
2502 1525 : bTranslated = !sValue.isEmpty();
2503 : }
2504 : }
2505 :
2506 : reader.nextItem(
2507 1525 : xmlreader::XmlReader::TEXT_RAW, &name, &nsId);
2508 :
2509 1525 : if (!bTranslated)
2510 1525 : sValue = OString(name.begin, name.length);
2511 :
2512 1525 : if (m_pStringReplace)
2513 : {
2514 1525 : OUString sTmp = (*m_pStringReplace)(OStringToOUString(sValue, RTL_TEXTENCODING_UTF8));
2515 1525 : sValue = OUStringToOString(sTmp, RTL_TEXTENCODING_UTF8);
2516 : }
2517 :
2518 1525 : aItems.push_back(sValue);
2519 1525 : ++nItemIndex;
2520 : }
2521 : }
2522 :
2523 3204 : if (res == xmlreader::XmlReader::RESULT_END)
2524 : {
2525 1679 : --nLevel;
2526 : }
2527 :
2528 3204 : if (!nLevel)
2529 154 : break;
2530 : }
2531 :
2532 154 : return aItems;
2533 : }
2534 :
2535 1 : void VclBuilder::handleMenu(xmlreader::XmlReader &reader, const OString &rID)
2536 : {
2537 1 : PopupMenu *pCurrentMenu = new PopupMenu;
2538 :
2539 1 : int nLevel = 1;
2540 :
2541 1 : stringmap aProperties;
2542 :
2543 : while(true)
2544 : {
2545 11 : xmlreader::Span name;
2546 : int nsId;
2547 :
2548 : xmlreader::XmlReader::Result res = reader.nextItem(
2549 11 : xmlreader::XmlReader::TEXT_NONE, &name, &nsId);
2550 :
2551 11 : if (res == xmlreader::XmlReader::RESULT_DONE)
2552 1 : break;
2553 :
2554 11 : if (res == xmlreader::XmlReader::RESULT_BEGIN)
2555 : {
2556 8 : if (name.equals("child"))
2557 : {
2558 6 : handleMenuChild(pCurrentMenu, reader);
2559 : }
2560 : else
2561 : {
2562 2 : ++nLevel;
2563 2 : if (name.equals("property"))
2564 2 : collectProperty(reader, rID, aProperties);
2565 : }
2566 : }
2567 :
2568 11 : if (res == xmlreader::XmlReader::RESULT_END)
2569 : {
2570 3 : --nLevel;
2571 : }
2572 :
2573 11 : if (!nLevel)
2574 1 : break;
2575 : }
2576 :
2577 1 : m_aMenus.push_back(MenuAndId(rID, pCurrentMenu));
2578 1 : }
2579 :
2580 6 : void VclBuilder::handleMenuChild(PopupMenu *pParent, xmlreader::XmlReader &reader)
2581 : {
2582 6 : xmlreader::Span name;
2583 : int nsId;
2584 :
2585 6 : int nLevel = 1;
2586 : while(true)
2587 : {
2588 : xmlreader::XmlReader::Result res = reader.nextItem(
2589 12 : xmlreader::XmlReader::TEXT_NONE, &name, &nsId);
2590 :
2591 12 : if (res == xmlreader::XmlReader::RESULT_BEGIN)
2592 : {
2593 6 : if (name.equals("object") || name.equals("placeholder"))
2594 : {
2595 6 : handleMenuObject(pParent, reader);
2596 : }
2597 : else
2598 0 : ++nLevel;
2599 : }
2600 :
2601 12 : if (res == xmlreader::XmlReader::RESULT_END)
2602 6 : --nLevel;
2603 :
2604 12 : if (!nLevel)
2605 6 : break;
2606 :
2607 6 : if (res == xmlreader::XmlReader::RESULT_DONE)
2608 0 : break;
2609 6 : }
2610 6 : }
2611 :
2612 6 : void VclBuilder::handleMenuObject(PopupMenu *pParent, xmlreader::XmlReader &reader)
2613 : {
2614 6 : OString sClass;
2615 12 : OString sID;
2616 12 : OString sCustomProperty;
2617 :
2618 6 : xmlreader::Span name;
2619 : int nsId;
2620 :
2621 24 : while (reader.nextAttribute(&nsId, &name))
2622 : {
2623 12 : if (name.equals("class"))
2624 : {
2625 6 : name = reader.getAttributeValue(false);
2626 6 : sClass = OString(name.begin, name.length);
2627 : }
2628 6 : else if (name.equals("id"))
2629 : {
2630 6 : name = reader.getAttributeValue(false);
2631 6 : sID = OString(name.begin, name.length);
2632 6 : sal_Int32 nDelim = sID.indexOf(':');
2633 6 : if (nDelim != -1)
2634 : {
2635 0 : sCustomProperty = sID.copy(nDelim+1);
2636 0 : sID = sID.copy(0, nDelim);
2637 : }
2638 : }
2639 : }
2640 :
2641 6 : int nLevel = 1;
2642 :
2643 12 : stringmap aProperties, aAccelerators;
2644 :
2645 6 : if (!sCustomProperty.isEmpty())
2646 0 : aProperties[OString("customproperty")] = sCustomProperty;
2647 :
2648 : while(true)
2649 : {
2650 : xmlreader::XmlReader::Result res = reader.nextItem(
2651 40 : xmlreader::XmlReader::TEXT_NONE, &name, &nsId);
2652 :
2653 40 : if (res == xmlreader::XmlReader::RESULT_DONE)
2654 0 : break;
2655 :
2656 40 : if (res == xmlreader::XmlReader::RESULT_BEGIN)
2657 : {
2658 17 : ++nLevel;
2659 17 : if (name.equals("property"))
2660 17 : collectProperty(reader, sID, aProperties);
2661 0 : else if (name.equals("accelerator"))
2662 0 : collectAccelerator(reader, aAccelerators);
2663 : }
2664 :
2665 40 : if (res == xmlreader::XmlReader::RESULT_END)
2666 : {
2667 23 : --nLevel;
2668 : }
2669 :
2670 40 : if (!nLevel)
2671 6 : break;
2672 : }
2673 :
2674 12 : insertMenuObject(pParent, sClass, sID, aProperties, aAccelerators);
2675 6 : }
2676 :
2677 339 : void VclBuilder::handleSizeGroup(xmlreader::XmlReader &reader, const OString &rID)
2678 : {
2679 339 : m_pParserState->m_aSizeGroups.push_back(SizeGroup(rID));
2680 339 : SizeGroup &rSizeGroup = m_pParserState->m_aSizeGroups.back();
2681 :
2682 339 : int nLevel = 1;
2683 :
2684 : while(true)
2685 : {
2686 5755 : xmlreader::Span name;
2687 : int nsId;
2688 :
2689 : xmlreader::XmlReader::Result res = reader.nextItem(
2690 5755 : xmlreader::XmlReader::TEXT_NONE, &name, &nsId);
2691 :
2692 5755 : if (res == xmlreader::XmlReader::RESULT_DONE)
2693 339 : break;
2694 :
2695 5755 : if (res == xmlreader::XmlReader::RESULT_BEGIN)
2696 : {
2697 2708 : ++nLevel;
2698 2708 : if (name.equals("widget"))
2699 : {
2700 6090 : while (reader.nextAttribute(&nsId, &name))
2701 : {
2702 2030 : if (name.equals("name"))
2703 : {
2704 2030 : name = reader.getAttributeValue(false);
2705 2030 : OString sWidget = OString(name.begin, name.length);
2706 2030 : sal_Int32 nDelim = sWidget.indexOf(':');
2707 2030 : if (nDelim != -1)
2708 0 : sWidget = sWidget.copy(0, nDelim);
2709 2030 : rSizeGroup.m_aWidgets.push_back(sWidget);
2710 : }
2711 : }
2712 : }
2713 : else
2714 : {
2715 678 : if (name.equals("property"))
2716 339 : collectProperty(reader, rID, rSizeGroup.m_aProperties);
2717 : }
2718 : }
2719 :
2720 5755 : if (res == xmlreader::XmlReader::RESULT_END)
2721 : {
2722 3047 : --nLevel;
2723 : }
2724 :
2725 5755 : if (!nLevel)
2726 339 : break;
2727 5416 : }
2728 339 : }
2729 :
2730 3775 : OString VclBuilder::convertMnemonicMarkup(const OString &rIn)
2731 : {
2732 3775 : OStringBuffer aRet(rIn);
2733 30197 : for (sal_Int32 nI = 0; nI < aRet.getLength(); ++nI)
2734 : {
2735 26422 : if (aRet[nI] == '_' && nI+1 < aRet.getLength())
2736 : {
2737 1760 : if (aRet[nI+1] != '_')
2738 1760 : aRet[nI] = MNEMONIC_CHAR;
2739 : else
2740 0 : aRet.remove(nI, 1);
2741 1760 : ++nI;
2742 : }
2743 : }
2744 3775 : return aRet.makeStringAndClear();
2745 : }
2746 :
2747 : namespace
2748 : {
2749 0 : vcl::KeyCode makeKeyCode(const OString &rKey)
2750 : {
2751 0 : if (rKey == "Insert")
2752 0 : return vcl::KeyCode(KEY_INSERT);
2753 0 : else if (rKey == "Delete")
2754 0 : return vcl::KeyCode(KEY_DELETE);
2755 :
2756 : assert (rKey.getLength() == 1);
2757 0 : sal_Char cChar = rKey.toChar();
2758 :
2759 0 : if (cChar >= 'a' && cChar <= 'z')
2760 0 : return vcl::KeyCode(KEY_A + (cChar - 'a'));
2761 0 : else if (cChar >= 'A' && cChar <= 'Z')
2762 0 : return vcl::KeyCode(KEY_A + (cChar - 'A'));
2763 0 : else if (cChar >= '0' && cChar <= '9')
2764 0 : return vcl::KeyCode(KEY_0 + (cChar - 'A'));
2765 :
2766 0 : return vcl::KeyCode(cChar);
2767 : }
2768 : }
2769 :
2770 6 : void VclBuilder::insertMenuObject(PopupMenu *pParent, const OString &rClass, const OString &rID,
2771 : stringmap &rProps, stringmap &rAccels)
2772 : {
2773 6 : sal_uInt16 nOldCount = pParent->GetItemCount();
2774 6 : sal_uInt16 nNewId = nOldCount + 1;
2775 :
2776 6 : if (rClass == "GtkMenuItem")
2777 : {
2778 5 : OUString sLabel(OStringToOUString(convertMnemonicMarkup(extractLabel(rProps)), RTL_TEXTENCODING_UTF8));
2779 5 : pParent->InsertItem(nNewId, sLabel, MenuItemBits::TEXT, rID);
2780 : }
2781 1 : else if (rClass == "GtkSeparatorMenuItem")
2782 : {
2783 1 : pParent->InsertSeparator(rID);
2784 : }
2785 :
2786 : SAL_WARN_IF(nOldCount == pParent->GetItemCount(), "vcl.layout", "probably need to implement " << rClass.getStr());
2787 :
2788 6 : if (nOldCount != pParent->GetItemCount())
2789 : {
2790 6 : pParent->SetHelpId(nNewId, m_sHelpRoot + rID);
2791 :
2792 18 : for (stringmap::iterator aI = rProps.begin(), aEnd = rProps.end(); aI != aEnd; ++aI)
2793 : {
2794 12 : const OString &rKey = aI->first;
2795 12 : const OString &rValue = aI->second;
2796 :
2797 12 : if (rKey == "tooltip-markup")
2798 0 : pParent->SetTipHelpText(nNewId, OStringToOUString(rValue, RTL_TEXTENCODING_UTF8));
2799 12 : else if (rKey == "tooltip-text")
2800 0 : pParent->SetTipHelpText(nNewId, OStringToOUString(rValue, RTL_TEXTENCODING_UTF8));
2801 12 : else if (rKey == "visible")
2802 6 : pParent->ShowItem(nNewId, toBool(rValue));
2803 6 : else if (rKey == "has-default" && toBool(rValue))
2804 0 : pParent->SetSelectedEntry(nNewId);
2805 : else
2806 : SAL_INFO("vcl.layout", "unhandled property: " << rKey.getStr());
2807 : }
2808 :
2809 6 : for (stringmap::iterator aI = rAccels.begin(), aEnd = rAccels.end(); aI != aEnd; ++aI)
2810 : {
2811 0 : const OString &rSignal = aI->first;
2812 0 : const OString &rValue = aI->second;
2813 :
2814 0 : if (rSignal == "activate")
2815 0 : pParent->SetAccelKey(nNewId, makeKeyCode(rValue));
2816 : else
2817 : SAL_INFO("vcl.layout", "unhandled accelerator for: " << rSignal.getStr());
2818 : }
2819 : }
2820 :
2821 6 : rProps.clear();
2822 6 : }
2823 :
2824 : /// Insert items to a ComboBox or a ListBox.
2825 : /// They have no common ancestor that would have 'InsertEntry()', so use a template.
2826 308 : template<typename T> bool insertItems(vcl::Window *pWindow, VclBuilder::stringmap &rMap, const std::vector<OString> &rItems)
2827 : {
2828 308 : T *pContainer = dynamic_cast<T*>(pWindow);
2829 308 : if (!pContainer)
2830 154 : return false;
2831 :
2832 154 : sal_uInt16 nActiveId = extractActive(rMap);
2833 1679 : for (std::vector<OString>::const_iterator aI = rItems.begin(), aEnd = rItems.end(); aI != aEnd; ++aI)
2834 1525 : pContainer->InsertEntry(OStringToOUString(*aI, RTL_TEXTENCODING_UTF8));
2835 154 : if (nActiveId < rItems.size())
2836 154 : pContainer->SelectEntryPos(nActiveId);
2837 :
2838 154 : return true;
2839 : }
2840 :
2841 46221 : VclPtr<vcl::Window> VclBuilder::handleObject(vcl::Window *pParent, xmlreader::XmlReader &reader)
2842 : {
2843 46221 : OString sClass;
2844 92442 : OString sID;
2845 92442 : OString sCustomProperty;
2846 :
2847 46221 : xmlreader::Span name;
2848 : int nsId;
2849 :
2850 184846 : while (reader.nextAttribute(&nsId, &name))
2851 : {
2852 92404 : if (name.equals("class"))
2853 : {
2854 46202 : name = reader.getAttributeValue(false);
2855 46202 : sClass = OString(name.begin, name.length);
2856 : }
2857 46202 : else if (name.equals("id"))
2858 : {
2859 46202 : name = reader.getAttributeValue(false);
2860 46202 : sID = OString(name.begin, name.length);
2861 46202 : sal_Int32 nDelim = sID.indexOf(':');
2862 46202 : if (nDelim != -1)
2863 : {
2864 314 : sCustomProperty = sID.copy(nDelim+1);
2865 314 : sID = sID.copy(0, nDelim);
2866 : }
2867 : }
2868 : }
2869 :
2870 46221 : if (sClass == "GtkListStore")
2871 : {
2872 0 : handleListStore(reader, sID);
2873 0 : return nullptr;
2874 : }
2875 46221 : else if (sClass == "GtkMenu")
2876 : {
2877 1 : handleMenu(reader, sID);
2878 1 : return nullptr;
2879 : }
2880 46220 : else if (sClass == "GtkSizeGroup")
2881 : {
2882 339 : handleSizeGroup(reader, sID);
2883 339 : return nullptr;
2884 : }
2885 45881 : else if (sClass == "AtkObject")
2886 : {
2887 5 : handleAtkObject(reader, sID, pParent);
2888 5 : return nullptr;
2889 : }
2890 :
2891 45876 : int nLevel = 1;
2892 :
2893 91752 : stringmap aProperties, aPangoAttributes, aAtkAttributes;
2894 91752 : std::vector<OString> aItems;
2895 :
2896 45876 : if (!sCustomProperty.isEmpty())
2897 310 : aProperties[OString("customproperty")] = sCustomProperty;
2898 :
2899 91752 : VclPtr<vcl::Window> pCurrentChild;
2900 : while(true)
2901 : {
2902 : xmlreader::XmlReader::Result res = reader.nextItem(
2903 527971 : xmlreader::XmlReader::TEXT_NONE, &name, &nsId);
2904 :
2905 527971 : if (res == xmlreader::XmlReader::RESULT_DONE)
2906 0 : break;
2907 :
2908 527971 : if (res == xmlreader::XmlReader::RESULT_BEGIN)
2909 : {
2910 263071 : if (name.equals("child"))
2911 : {
2912 43893 : if (!pCurrentChild)
2913 : {
2914 39888 : pCurrentChild = insertObject(pParent, sClass, sID,
2915 19944 : aProperties, aPangoAttributes, aAtkAttributes);
2916 : }
2917 43893 : handleChild(pCurrentChild, reader);
2918 : }
2919 219178 : else if (name.equals("items"))
2920 154 : aItems = handleItems(reader, sID);
2921 : else
2922 : {
2923 219024 : ++nLevel;
2924 219024 : if (name.equals("property"))
2925 219003 : collectProperty(reader, sID, aProperties);
2926 21 : else if (name.equals("attribute"))
2927 0 : collectPangoAttribute(reader, aPangoAttributes);
2928 21 : else if (name.equals("relation"))
2929 6 : collectAtkAttribute(reader, aAtkAttributes);
2930 15 : else if (name.equals("action-widget"))
2931 0 : handleActionWidget(reader);
2932 : }
2933 : }
2934 :
2935 527971 : if (res == xmlreader::XmlReader::RESULT_END)
2936 : {
2937 264900 : --nLevel;
2938 : }
2939 :
2940 527971 : if (!nLevel)
2941 45876 : break;
2942 : }
2943 :
2944 45876 : if (sClass == "GtkAdjustment")
2945 : {
2946 341 : handleAdjustment(sID, aProperties);
2947 341 : return NULL;
2948 : }
2949 45535 : else if (sClass == "GtkTextBuffer")
2950 : {
2951 0 : handleTextBuffer(sID, aProperties);
2952 0 : return NULL;
2953 : }
2954 :
2955 45535 : if (!pCurrentChild)
2956 : {
2957 51182 : pCurrentChild = insertObject(pParent, sClass, sID, aProperties,
2958 25591 : aPangoAttributes, aAtkAttributes);
2959 : }
2960 :
2961 45535 : if (!aItems.empty())
2962 : {
2963 : // try to fill-in the items
2964 154 : if (!insertItems<ComboBox>(pCurrentChild, aProperties, aItems))
2965 154 : insertItems<ListBox>(pCurrentChild, aProperties, aItems);
2966 : }
2967 :
2968 91756 : return pCurrentChild;
2969 : }
2970 :
2971 43852 : void VclBuilder::handlePacking(vcl::Window *pCurrent, vcl::Window *pParent, xmlreader::XmlReader &reader)
2972 : {
2973 43852 : xmlreader::Span name;
2974 : int nsId;
2975 :
2976 43852 : int nLevel = 1;
2977 :
2978 : while(true)
2979 : {
2980 : xmlreader::XmlReader::Result res = reader.nextItem(
2981 274326 : xmlreader::XmlReader::TEXT_NONE, &name, &nsId);
2982 :
2983 274326 : if (res == xmlreader::XmlReader::RESULT_DONE)
2984 0 : break;
2985 :
2986 274326 : if (res == xmlreader::XmlReader::RESULT_BEGIN)
2987 : {
2988 115237 : ++nLevel;
2989 115237 : if (name.equals("property"))
2990 115237 : applyPackingProperty(pCurrent, pParent, reader);
2991 : }
2992 :
2993 274326 : if (res == xmlreader::XmlReader::RESULT_END)
2994 : {
2995 159089 : --nLevel;
2996 : }
2997 :
2998 274326 : if (!nLevel)
2999 43852 : break;
3000 230474 : }
3001 43852 : }
3002 :
3003 115237 : void VclBuilder::applyPackingProperty(vcl::Window *pCurrent,
3004 : vcl::Window *pParent,
3005 : xmlreader::XmlReader &reader)
3006 : {
3007 115237 : if (!pCurrent)
3008 115237 : return;
3009 :
3010 : //ToolBoxItems are not true widgets just elements
3011 : //of the ToolBox itself
3012 115237 : ToolBox *pToolBoxParent = NULL;
3013 115237 : if (pCurrent == pParent)
3014 38664 : pToolBoxParent = dynamic_cast<ToolBox*>(pParent);
3015 :
3016 115237 : xmlreader::Span name;
3017 : int nsId;
3018 :
3019 115237 : if (pCurrent->GetType() == WINDOW_SCROLLWINDOW)
3020 : {
3021 0 : auto aFind = m_pParserState->m_aRedundantParentWidgets.find(VclPtr<vcl::Window>(pCurrent));
3022 0 : if (aFind != m_pParserState->m_aRedundantParentWidgets.end())
3023 : {
3024 0 : pCurrent = aFind->second;
3025 : assert(pCurrent);
3026 : }
3027 : }
3028 :
3029 345711 : while (reader.nextAttribute(&nsId, &name))
3030 : {
3031 115237 : if (name.equals("name"))
3032 : {
3033 115237 : name = reader.getAttributeValue(false);
3034 115237 : OString sKey(name.begin, name.length);
3035 115237 : sKey = sKey.replace('_', '-');
3036 : reader.nextItem(
3037 115237 : xmlreader::XmlReader::TEXT_RAW, &name, &nsId);
3038 172611 : OString sValue(name.begin, name.length);
3039 :
3040 115237 : if (sKey == "expand")
3041 : {
3042 38531 : bool bTrue = (!sValue.isEmpty() && (sValue[0] == 't' || sValue[0] == 'T' || sValue[0] == '1'));
3043 38531 : if (pToolBoxParent)
3044 19332 : pToolBoxParent->SetItemExpand(m_pParserState->m_nLastToolbarId, bTrue);
3045 : else
3046 19199 : pCurrent->set_expand(bTrue);
3047 38531 : continue;
3048 : }
3049 :
3050 76706 : if (pToolBoxParent)
3051 19332 : continue;
3052 :
3053 57374 : if (sKey == "fill")
3054 : {
3055 19199 : bool bTrue = (!sValue.isEmpty() && (sValue[0] == 't' || sValue[0] == 'T' || sValue[0] == '1'));
3056 19199 : pCurrent->set_fill(bTrue);
3057 : }
3058 38175 : else if (sKey == "pack-type")
3059 : {
3060 3538 : VclPackType ePackType = (!sValue.isEmpty() && (sValue[0] == 'e' || sValue[0] == 'E')) ? VCL_PACK_END : VCL_PACK_START;
3061 3538 : pCurrent->set_pack_type(ePackType);
3062 : }
3063 34637 : else if (sKey == "left-attach")
3064 : {
3065 5321 : pCurrent->set_grid_left_attach(sValue.toInt32());
3066 : }
3067 29316 : else if (sKey == "top-attach")
3068 : {
3069 5321 : pCurrent->set_grid_top_attach(sValue.toInt32());
3070 : }
3071 23995 : else if (sKey == "width")
3072 : {
3073 2567 : pCurrent->set_grid_width(sValue.toInt32());
3074 : }
3075 21428 : else if (sKey == "height")
3076 : {
3077 2229 : pCurrent->set_grid_height(sValue.toInt32());
3078 : }
3079 19199 : else if (sKey == "padding")
3080 : {
3081 0 : pCurrent->set_padding(sValue.toInt32());
3082 : }
3083 19199 : else if (sKey == "position")
3084 : {
3085 19199 : set_window_packing_position(pCurrent, sValue.toInt32());
3086 : }
3087 0 : else if (sKey == "secondary")
3088 : {
3089 0 : pCurrent->set_secondary(toBool(sValue));
3090 : }
3091 0 : else if (sKey == "non-homogeneous")
3092 : {
3093 0 : pCurrent->set_non_homogeneous(toBool(sValue));
3094 : }
3095 0 : else if (sKey == "homogeneous")
3096 : {
3097 0 : pCurrent->set_non_homogeneous(!toBool(sValue));
3098 : }
3099 : else
3100 : {
3101 : SAL_WARN("vcl.layout", "unknown packing: " << sKey.getStr());
3102 57374 : }
3103 : }
3104 : }
3105 : }
3106 :
3107 14764 : OString VclBuilder::getTranslation(const OString &rID, const OString &rProperty) const
3108 : {
3109 14764 : Translations::const_iterator aWidgetFind = m_pParserState->m_aTranslations.find(rID);
3110 14764 : if (aWidgetFind != m_pParserState->m_aTranslations.end())
3111 : {
3112 0 : const WidgetTranslations &rWidgetTranslations = aWidgetFind->second;
3113 0 : WidgetTranslations::const_iterator aPropertyFind = rWidgetTranslations.find(rProperty);
3114 0 : if (aPropertyFind != rWidgetTranslations.end())
3115 0 : return aPropertyFind->second;
3116 : }
3117 14764 : return OString();
3118 : }
3119 :
3120 219366 : void VclBuilder::collectProperty(xmlreader::XmlReader &reader, const OString &rID, stringmap &rMap)
3121 : {
3122 219366 : xmlreader::Span name;
3123 : int nsId;
3124 :
3125 219366 : OString sProperty;
3126 438732 : OString sValue;
3127 :
3128 219366 : bool bTranslated = false;
3129 :
3130 674375 : while (reader.nextAttribute(&nsId, &name))
3131 : {
3132 235643 : if (name.equals("name"))
3133 : {
3134 219366 : name = reader.getAttributeValue(false);
3135 219366 : sProperty = OString(name.begin, name.length);
3136 : }
3137 16277 : else if (name.equals("translatable") && reader.getAttributeValue(false).equals("yes"))
3138 : {
3139 13239 : sValue = getTranslation(rID, sProperty);
3140 13239 : bTranslated = !sValue.isEmpty();
3141 : }
3142 :
3143 : }
3144 :
3145 219366 : reader.nextItem(xmlreader::XmlReader::TEXT_RAW, &name, &nsId);
3146 219366 : if (!bTranslated)
3147 219366 : sValue = OString(name.begin, name.length);
3148 :
3149 219366 : if (!sProperty.isEmpty())
3150 : {
3151 219366 : sProperty = sProperty.replace('_', '-');
3152 219366 : if (m_pStringReplace)
3153 : {
3154 219366 : OUString sTmp = (*m_pStringReplace)(OStringToOUString(sValue, RTL_TEXTENCODING_UTF8));
3155 219366 : rMap[sProperty] = OUStringToOString(sTmp, RTL_TEXTENCODING_UTF8);
3156 : }
3157 : else
3158 : {
3159 0 : rMap[sProperty] = sValue;
3160 : }
3161 219366 : }
3162 219366 : }
3163 :
3164 0 : void VclBuilder::handleActionWidget(xmlreader::XmlReader &reader)
3165 : {
3166 0 : xmlreader::Span name;
3167 : int nsId;
3168 :
3169 0 : OString sResponse;
3170 :
3171 0 : while (reader.nextAttribute(&nsId, &name))
3172 : {
3173 0 : if (name.equals("response"))
3174 : {
3175 0 : name = reader.getAttributeValue(false);
3176 0 : sResponse = OString(name.begin, name.length);
3177 : }
3178 : }
3179 :
3180 0 : reader.nextItem(xmlreader::XmlReader::TEXT_RAW, &name, &nsId);
3181 0 : OString sID = OString(name.begin, name.length);
3182 0 : sal_Int32 nDelim = sID.indexOf(':');
3183 0 : if (nDelim != -1)
3184 0 : sID = sID.copy(0, nDelim);
3185 0 : set_response(sID, sResponse.toInt32());
3186 0 : }
3187 :
3188 0 : void VclBuilder::collectAccelerator(xmlreader::XmlReader &reader, stringmap &rMap)
3189 : {
3190 0 : xmlreader::Span name;
3191 : int nsId;
3192 :
3193 0 : OString sProperty;
3194 0 : OString sValue;
3195 :
3196 0 : while (reader.nextAttribute(&nsId, &name))
3197 : {
3198 0 : if (name.equals("key"))
3199 : {
3200 0 : name = reader.getAttributeValue(false);
3201 0 : sValue = OString(name.begin, name.length);
3202 : }
3203 0 : else if (name.equals("signal"))
3204 : {
3205 0 : name = reader.getAttributeValue(false);
3206 0 : sProperty = OString(name.begin, name.length);
3207 : }
3208 :
3209 : }
3210 :
3211 0 : if (!sProperty.isEmpty() && !sValue.isEmpty())
3212 : {
3213 0 : rMap[sProperty] = sValue;
3214 0 : }
3215 0 : }
3216 :
3217 0 : vcl::Window *VclBuilder::get_widget_root()
3218 : {
3219 0 : return m_aChildren.empty() ? NULL : m_aChildren[0].m_pWindow.get();
3220 : }
3221 :
3222 14349 : vcl::Window *VclBuilder::get_by_name(const OString& sID)
3223 : {
3224 197480 : for (std::vector<WinAndId>::iterator aI = m_aChildren.begin(),
3225 14349 : aEnd = m_aChildren.end(); aI != aEnd; ++aI)
3226 : {
3227 183131 : if (aI->m_sID.equals(sID))
3228 14349 : return aI->m_pWindow;
3229 : }
3230 :
3231 0 : return NULL;
3232 : }
3233 :
3234 1 : PopupMenu *VclBuilder::get_menu(const OString& sID)
3235 : {
3236 2 : for (std::vector<MenuAndId>::iterator aI = m_aMenus.begin(),
3237 1 : aEnd = m_aMenus.end(); aI != aEnd; ++aI)
3238 : {
3239 1 : if (aI->m_sID.equals(sID))
3240 1 : return aI->m_pMenu;
3241 : }
3242 :
3243 0 : return NULL;
3244 : }
3245 :
3246 0 : short VclBuilder::get_response(const vcl::Window *pWindow) const
3247 : {
3248 0 : for (std::vector<WinAndId>::const_iterator aI = m_aChildren.begin(),
3249 0 : aEnd = m_aChildren.end(); aI != aEnd; ++aI)
3250 : {
3251 0 : if (aI->m_pWindow == pWindow)
3252 : {
3253 0 : return aI->m_nResponseId;
3254 : }
3255 : }
3256 :
3257 : //how did we not find sID ?
3258 : assert(false);
3259 0 : return RET_CANCEL;
3260 : }
3261 :
3262 0 : void VclBuilder::set_response(const OString& sID, short nResponse)
3263 : {
3264 0 : for (std::vector<WinAndId>::iterator aI = m_aChildren.begin(),
3265 0 : aEnd = m_aChildren.end(); aI != aEnd; ++aI)
3266 : {
3267 0 : if (aI->m_sID.equals(sID))
3268 : {
3269 0 : aI->m_nResponseId = nResponse;
3270 0 : return;
3271 : }
3272 : }
3273 :
3274 : //how did we not find sID ?
3275 : assert(false);
3276 : }
3277 :
3278 9 : void VclBuilder::delete_by_name(const OString& sID)
3279 : {
3280 18 : for (std::vector<WinAndId>::iterator aI = m_aChildren.begin(),
3281 9 : aEnd = m_aChildren.end(); aI != aEnd; ++aI)
3282 : {
3283 9 : if (aI->m_sID.equals(sID))
3284 : {
3285 9 : aI->m_pWindow.disposeAndClear();
3286 9 : m_aChildren.erase(aI);
3287 9 : break;
3288 : }
3289 : }
3290 9 : }
3291 :
3292 0 : void VclBuilder::delete_by_window(vcl::Window *pWindow)
3293 : {
3294 0 : drop_ownership(pWindow);
3295 0 : pWindow->disposeOnce();
3296 0 : }
3297 :
3298 0 : void VclBuilder::drop_ownership(const vcl::Window *pWindow)
3299 : {
3300 0 : for (std::vector<WinAndId>::iterator aI = m_aChildren.begin(),
3301 0 : aEnd = m_aChildren.end(); aI != aEnd; ++aI)
3302 : {
3303 0 : if (aI->m_pWindow == pWindow)
3304 : {
3305 0 : m_aChildren.erase(aI);
3306 0 : break;
3307 : }
3308 : }
3309 0 : }
3310 :
3311 0 : OString VclBuilder::get_by_window(const vcl::Window *pWindow) const
3312 : {
3313 0 : for (std::vector<WinAndId>::const_iterator aI = m_aChildren.begin(),
3314 0 : aEnd = m_aChildren.end(); aI != aEnd; ++aI)
3315 : {
3316 0 : if (aI->m_pWindow == pWindow)
3317 0 : return aI->m_sID;
3318 : }
3319 :
3320 0 : return OString();
3321 : }
3322 :
3323 43914 : VclBuilder::PackingData VclBuilder::get_window_packing_data(const vcl::Window *pWindow) const
3324 : {
3325 : //We've stored the return of new Control, some of these get
3326 : //border windows placed around them which are what you get
3327 : //from GetChild, so scoot up a level if necessary to get the
3328 : //window whose position value we have
3329 : const vcl::Window *pPropHolder = pWindow->mpWindowImpl->mpClientWindow ?
3330 43914 : pWindow->mpWindowImpl->mpClientWindow : pWindow;
3331 :
3332 542635 : for (std::vector<WinAndId>::const_iterator aI = m_aChildren.begin(),
3333 43914 : aEnd = m_aChildren.end(); aI != aEnd; ++aI)
3334 : {
3335 498063 : if (aI->m_pWindow == pPropHolder)
3336 43256 : return aI->m_aPackingData;
3337 : }
3338 :
3339 658 : return PackingData();
3340 : }
3341 :
3342 19199 : void VclBuilder::set_window_packing_position(const vcl::Window *pWindow, sal_Int32 nPosition)
3343 : {
3344 284629 : for (std::vector<WinAndId>::iterator aI = m_aChildren.begin(),
3345 19199 : aEnd = m_aChildren.end(); aI != aEnd; ++aI)
3346 : {
3347 246231 : if (aI->m_pWindow == pWindow)
3348 19199 : aI->m_aPackingData.m_nPosition = nPosition;
3349 : }
3350 19199 : }
3351 :
3352 0 : const VclBuilder::ListStore *VclBuilder::get_model_by_name(const OString& sID) const
3353 : {
3354 0 : std::map<OString, ListStore>::const_iterator aI = m_pParserState->m_aModels.find(sID);
3355 0 : if (aI != m_pParserState->m_aModels.end())
3356 0 : return &(aI->second);
3357 0 : return NULL;
3358 : }
3359 :
3360 0 : const VclBuilder::TextBuffer *VclBuilder::get_buffer_by_name(const OString& sID) const
3361 : {
3362 0 : std::map<OString, TextBuffer>::const_iterator aI = m_pParserState->m_aTextBuffers.find(sID);
3363 0 : if (aI != m_pParserState->m_aTextBuffers.end())
3364 0 : return &(aI->second);
3365 0 : return NULL;
3366 : }
3367 :
3368 3 : const VclBuilder::Adjustment *VclBuilder::get_adjustment_by_name(const OString& sID) const
3369 : {
3370 3 : std::map<OString, Adjustment>::const_iterator aI = m_pParserState->m_aAdjustments.find(sID);
3371 3 : if (aI != m_pParserState->m_aAdjustments.end())
3372 3 : return &(aI->second);
3373 0 : return NULL;
3374 : }
3375 :
3376 0 : void VclBuilder::mungeModel(ListBox &rTarget, const ListStore &rStore, sal_uInt16 nActiveId)
3377 : {
3378 0 : for (std::vector<ListStore::row>::const_iterator aI = rStore.m_aEntries.begin(), aEnd = rStore.m_aEntries.end();
3379 : aI != aEnd; ++aI)
3380 : {
3381 0 : const ListStore::row &rRow = *aI;
3382 0 : sal_uInt16 nEntry = rTarget.InsertEntry(OStringToOUString(rRow[0], RTL_TEXTENCODING_UTF8));
3383 0 : if (rRow.size() > 1)
3384 : {
3385 0 : sal_IntPtr nValue = rRow[1].toInt32();
3386 0 : rTarget.SetEntryData(nEntry, reinterpret_cast<void*>(nValue));
3387 : }
3388 : }
3389 0 : if (nActiveId < rStore.m_aEntries.size())
3390 0 : rTarget.SelectEntryPos(nActiveId);
3391 0 : }
3392 :
3393 3 : void VclBuilder::mungeAdjustment(NumericFormatter &rTarget, const Adjustment &rAdjustment)
3394 : {
3395 3 : int nMul = rtl_math_pow10Exp(1, rTarget.GetDecimalDigits());
3396 :
3397 14 : for (stringmap::const_iterator aI = rAdjustment.begin(), aEnd = rAdjustment.end(); aI != aEnd; ++aI)
3398 : {
3399 11 : const OString &rKey = aI->first;
3400 11 : const OString &rValue = aI->second;
3401 :
3402 11 : if (rKey == "upper")
3403 : {
3404 3 : sal_Int64 nUpper = rValue.toDouble() * nMul;
3405 3 : rTarget.SetMax(nUpper);
3406 3 : rTarget.SetLast(nUpper);
3407 : }
3408 8 : else if (rKey == "lower")
3409 : {
3410 2 : sal_Int64 nLower = rValue.toDouble() * nMul;
3411 2 : rTarget.SetMin(nLower);
3412 2 : rTarget.SetFirst(nLower);
3413 : }
3414 6 : else if (rKey == "value")
3415 : {
3416 0 : sal_Int64 nValue = rValue.toDouble() * nMul;
3417 0 : rTarget.SetValue(nValue);
3418 : }
3419 6 : else if (rKey == "step-increment")
3420 : {
3421 3 : sal_Int64 nSpinSize = rValue.toDouble() * nMul;
3422 3 : rTarget.SetSpinSize(nSpinSize);
3423 : }
3424 : else
3425 : {
3426 : SAL_INFO("vcl.layout", "unhandled property :" << rKey.getStr());
3427 : }
3428 : }
3429 3 : }
3430 :
3431 0 : void VclBuilder::mungeAdjustment(TimeField &rTarget, const Adjustment &rAdjustment)
3432 : {
3433 0 : for (stringmap::const_iterator aI = rAdjustment.begin(), aEnd = rAdjustment.end(); aI != aEnd; ++aI)
3434 : {
3435 0 : const OString &rKey = aI->first;
3436 0 : const OString &rValue = aI->second;
3437 :
3438 0 : if (rKey == "upper")
3439 : {
3440 0 : tools::Time aUpper(rValue.toInt32());
3441 0 : rTarget.SetMax(aUpper);
3442 0 : rTarget.SetLast(aUpper);
3443 : }
3444 0 : else if (rKey == "lower")
3445 : {
3446 0 : tools::Time aLower(rValue.toInt32());
3447 0 : rTarget.SetMin(aLower);
3448 0 : rTarget.SetFirst(aLower);
3449 : }
3450 0 : else if (rKey == "value")
3451 : {
3452 0 : tools::Time aValue(rValue.toInt32());
3453 0 : rTarget.SetTime(aValue);
3454 : }
3455 : else
3456 : {
3457 : SAL_INFO("vcl.layout", "unhandled property :" << rKey.getStr());
3458 : }
3459 : }
3460 0 : }
3461 :
3462 0 : void VclBuilder::mungeAdjustment(DateField &rTarget, const Adjustment &rAdjustment)
3463 : {
3464 0 : for (stringmap::const_iterator aI = rAdjustment.begin(), aEnd = rAdjustment.end(); aI != aEnd; ++aI)
3465 : {
3466 0 : const OString &rKey = aI->first;
3467 0 : const OString &rValue = aI->second;
3468 :
3469 0 : if (rKey == "upper")
3470 : {
3471 0 : Date aUpper(rValue.toInt32());
3472 0 : rTarget.SetMax(aUpper);
3473 0 : rTarget.SetLast(aUpper);
3474 : }
3475 0 : else if (rKey == "lower")
3476 : {
3477 0 : Date aLower(rValue.toInt32());
3478 0 : rTarget.SetMin(aLower);
3479 0 : rTarget.SetFirst(aLower);
3480 : }
3481 0 : else if (rKey == "value")
3482 : {
3483 0 : Date aValue(rValue.toInt32());
3484 0 : rTarget.SetDate(aValue);
3485 : }
3486 : else
3487 : {
3488 : SAL_INFO("vcl.layout", "unhandled property :" << rKey.getStr());
3489 : }
3490 : }
3491 0 : }
3492 :
3493 0 : void VclBuilder::mungeAdjustment(ScrollBar &rTarget, const Adjustment &rAdjustment)
3494 : {
3495 0 : for (stringmap::const_iterator aI = rAdjustment.begin(), aEnd = rAdjustment.end(); aI != aEnd; ++aI)
3496 : {
3497 0 : const OString &rKey = aI->first;
3498 0 : const OString &rValue = aI->second;
3499 :
3500 0 : if (rKey == "upper")
3501 0 : rTarget.SetRangeMax(rValue.toInt32());
3502 0 : else if (rKey == "lower")
3503 0 : rTarget.SetRangeMin(rValue.toInt32());
3504 0 : else if (rKey == "value")
3505 0 : rTarget.SetThumbPos(rValue.toInt32());
3506 0 : else if (rKey == "step-increment")
3507 0 : rTarget.SetLineSize(rValue.toInt32());
3508 0 : else if (rKey == "page-increment")
3509 0 : rTarget.SetPageSize(rValue.toInt32());
3510 : else
3511 : {
3512 : SAL_INFO("vcl.layout", "unhandled property :" << rKey.getStr());
3513 : }
3514 : }
3515 0 : }
3516 :
3517 0 : void VclBuilder::mungeAdjustment(Slider& rTarget, const Adjustment& rAdjustment)
3518 : {
3519 0 : for (stringmap::const_iterator aI = rAdjustment.begin(), aEnd = rAdjustment.end(); aI != aEnd; ++aI)
3520 : {
3521 0 : const OString &rKey = aI->first;
3522 0 : const OString &rValue = aI->second;
3523 :
3524 0 : if (rKey == "upper")
3525 0 : rTarget.SetRangeMax(rValue.toInt32());
3526 0 : else if (rKey == "lower")
3527 0 : rTarget.SetRangeMin(rValue.toInt32());
3528 0 : else if (rKey == "value")
3529 0 : rTarget.SetThumbPos(rValue.toInt32());
3530 0 : else if (rKey == "step-increment")
3531 0 : rTarget.SetLineSize(rValue.toInt32());
3532 0 : else if (rKey == "page-increment")
3533 0 : rTarget.SetPageSize(rValue.toInt32());
3534 : else
3535 : {
3536 : SAL_INFO("vcl.layout", "unhandled property :" << rKey.getStr());
3537 : }
3538 : }
3539 0 : }
3540 :
3541 0 : void VclBuilder::mungeTextBuffer(VclMultiLineEdit &rTarget, const TextBuffer &rTextBuffer)
3542 : {
3543 0 : for (stringmap::const_iterator aI = rTextBuffer.begin(), aEnd = rTextBuffer.end(); aI != aEnd; ++aI)
3544 : {
3545 0 : const OString &rKey = aI->first;
3546 0 : const OString &rValue = aI->second;
3547 :
3548 0 : if (rKey == "text")
3549 0 : rTarget.SetText(OStringToOUString(rValue, RTL_TEXTENCODING_UTF8));
3550 : else
3551 : {
3552 : SAL_INFO("vcl.layout", "unhandled property :" << rKey.getStr());
3553 : }
3554 : }
3555 0 : }
3556 :
3557 1761 : VclBuilder::ParserState::ParserState()
3558 1761 : : m_nLastToolbarId(0)
3559 2562 : {}
3560 :
3561 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|