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