LibreOffice Module vcl (master) 1
builder.cxx
Go to the documentation of this file.
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 <config_feature_desktop.h>
11#include <config_options.h>
12#include <config_vclplug.h>
13
14#include <memory>
15#include <string_view>
16#include <unordered_map>
17#include <com/sun/star/accessibility/AccessibleRole.hpp>
18
19#include <comphelper/lok.hxx>
20#include <i18nutil/unicode.hxx>
21#include <jsdialog/enabled.hxx>
22#include <o3tl/string_view.hxx>
23#include <officecfg/Office/Common.hxx>
24#include <osl/module.hxx>
25#include <sal/log.hxx>
27#include <unotools/resmgr.hxx>
28#include <utility>
29#include <vcl/builder.hxx>
30#include <vcl/dialoghelper.hxx>
31#include <vcl/menu.hxx>
34#include <vcl/toolkit/edit.hxx>
35#include <vcl/toolkit/field.hxx>
36#include <vcl/fieldvalues.hxx>
38#include <vcl/toolkit/fixed.hxx>
40#include <vcl/headbar.hxx>
43#include <vcl/layout.hxx>
46#include <vcl/mnemonic.hxx>
49#include <vcl/split.hxx>
50#include <vcl/svapp.hxx>
52#include <vcl/tabctrl.hxx>
53#include <vcl/tabpage.hxx>
55#include <vcl/toolbox.hxx>
58#include <vcl/settings.hxx>
59#include <slider.hxx>
60#include <vcl/weld.hxx>
61#include <vcl/weldutils.hxx>
63#include <iconview.hxx>
64#include <svdata.hxx>
65#include <bitmaps.hlst>
66#include <managedmenubutton.hxx>
67#include <messagedialog.hxx>
68#include <ContextVBox.hxx>
69#include <DropdownBox.hxx>
70#include <IPrioritable.hxx>
71#include <OptionalBox.hxx>
73#include <PriorityHBox.hxx>
74#include <window.h>
77#include <calendar.hxx>
78#include <menutogglebutton.hxx>
79#include <salinst.hxx>
80#include <strings.hrc>
81#include <treeglue.hxx>
83#include <verticaltabctrl.hxx>
84#include <wizdlg.hxx>
85#include <tools/svlibrary.h>
87
88#if defined(DISABLE_DYNLOADING) || defined(LINUX)
89#include <dlfcn.h>
90#endif
91
92static bool toBool(std::string_view rValue)
93{
94 return (!rValue.empty() && (rValue[0] == 't' || rValue[0] == 'T' || rValue[0] == '1'));
95}
96
97namespace
98{
99 OUString mapStockToImageResource(std::u16string_view sType)
100 {
101 if (sType == u"view-refresh")
102 return SV_RESID_BITMAP_REFRESH;
103 else if (sType == u"dialog-error")
104 return IMG_ERROR;
105 else if (sType == u"list-add")
106 return IMG_ADD;
107 else if (sType == u"list-remove")
108 return IMG_REMOVE;
109 else if (sType == u"edit-copy")
110 return IMG_COPY;
111 else if (sType == u"edit-paste")
112 return IMG_PASTE;
113 else if (sType == u"document-open")
114 return IMG_OPEN;
115 else if (sType == u"open-menu-symbolic")
116 return IMG_MENU;
117 else if (sType == u"window-close-symbolic")
118 return SV_RESID_BITMAP_CLOSEDOC;
119 else if (sType == u"x-office-calendar")
120 return IMG_CALENDAR;
121 return OUString();
122 }
123
124}
125
126SymbolType VclBuilder::mapStockToSymbol(std::u16string_view sType)
127{
129 if (sType == u"media-skip-forward")
130 eRet = SymbolType::NEXT;
131 else if (sType == u"media-skip-backward")
132 eRet = SymbolType::PREV;
133 else if (sType == u"media-playback-start")
134 eRet = SymbolType::PLAY;
135 else if (sType == u"media-playback-stop")
136 eRet = SymbolType::STOP;
137 else if (sType == u"go-first")
138 eRet = SymbolType::FIRST;
139 else if (sType == u"go-last")
140 eRet = SymbolType::LAST;
141 else if (sType == u"go-previous")
143 else if (sType == u"go-next")
145 else if (sType == u"go-up")
147 else if (sType == u"go-down")
149 else if (sType == u"missing-image")
150 eRet = SymbolType::IMAGE;
151 else if (sType == u"help-browser" || sType == u"help-browser-symbolic")
152 eRet = SymbolType::HELP;
153 else if (sType == u"window-close")
154 eRet = SymbolType::CLOSE;
155 else if (sType == u"document-new")
156 eRet = SymbolType::PLUS;
157 else if (sType == u"pan-down-symbolic")
159 else if (sType == u"pan-up-symbolic")
160 eRet = SymbolType::SPIN_UP;
161 else if (!mapStockToImageResource(sType).isEmpty())
162 eRet = SymbolType::IMAGE;
163 return eRet;
164}
165
166namespace
167{
168 void setupFromActionName(Button *pButton, VclBuilder::stringmap &rMap, const css::uno::Reference<css::frame::XFrame>& rFrame);
169
170#if defined SAL_LOG_WARN
171 bool isButtonType(WindowType nType)
172 {
173 return nType == WindowType::PUSHBUTTON ||
181 }
182#endif
183
184}
185
186std::unique_ptr<weld::Builder> Application::CreateBuilder(weld::Widget* pParent, const OUString &rUIFile, bool bMobile, sal_uInt64 nLOKWindowId)
187{
189 {
191 return JSInstanceBuilder::CreateSidebarBuilder(pParent, AllSettings::GetUIRootDir(), rUIFile, nLOKWindowId);
192 else if (jsdialog::isBuilderEnabledForPopup(rUIFile))
194 else if (jsdialog::isBuilderEnabled(rUIFile, bMobile))
196 }
197
198 return ImplGetSVData()->mpDefInst->CreateBuilder(pParent, AllSettings::GetUIRootDir(), rUIFile);
199}
200
201std::unique_ptr<weld::Builder> Application::CreateInterimBuilder(vcl::Window* pParent, const OUString &rUIFile, bool bAllowCycleFocusOut, sal_uInt64 nLOKWindowId)
202{
204 {
205 // Notebookbar sub controls
207 return JSInstanceBuilder::CreateNotebookbarBuilder(pParent, AllSettings::GetUIRootDir(), rUIFile, css::uno::Reference<css::frame::XFrame>(), nLOKWindowId);
208 else if (rUIFile == u"modules/scalc/ui/inputbar.ui")
209 return JSInstanceBuilder::CreateFormulabarBuilder(pParent, AllSettings::GetUIRootDir(), rUIFile, nLOKWindowId);
210 }
211
212 return ImplGetSVData()->mpDefInst->CreateInterimBuilder(pParent, AllSettings::GetUIRootDir(), rUIFile, bAllowCycleFocusOut, nLOKWindowId);
213}
214
216 VclButtonsType eButtonType, const OUString& rPrimaryMessage,
217 const ILibreOfficeKitNotifier* pNotifier)
218{
220 return JSInstanceBuilder::CreateMessageDialog(pParent, eMessageType, eButtonType, rPrimaryMessage, pNotifier);
221 else
222 return ImplGetSVData()->mpDefInst->CreateMessageDialog(pParent, eMessageType, eButtonType, rPrimaryMessage);
223}
224
225weld::Window* Application::GetFrameWeld(const css::uno::Reference<css::awt::XWindow>& rWindow)
226{
227 return ImplGetSVData()->mpDefInst->GetFrameWeld(rWindow);
228}
229
230namespace weld
231{
233 {
234 const FieldUnitStringList& rList = ImplGetFieldUnits();
235 // return unit's default string (ie, the first one )
236 auto it = std::find_if(
237 rList.begin(), rList.end(),
238 [&rUnit](const std::pair<OUString, FieldUnit>& rItem) { return rItem.second == rUnit; });
239 if (it != rList.end())
240 return it->first;
241
242 return OUString();
243 }
244
245 IMPL_LINK_NOARG(MetricSpinButton, spin_button_value_changed, SpinButton&, void)
246 {
247 signal_value_changed();
248 }
249
250 IMPL_LINK(MetricSpinButton, spin_button_output, SpinButton&, rSpinButton, void)
251 {
252 OUString sNewText(format_number(rSpinButton.get_value()));
253 if (sNewText != rSpinButton.get_text())
254 rSpinButton.set_text(sNewText);
255 }
256
258 {
259 sal_Int64 min, max;
260 m_xSpinButton->get_range(min, max);
261 auto width = std::max(m_xSpinButton->get_pixel_size(format_number(min)).Width(),
262 m_xSpinButton->get_pixel_size(format_number(max)).Width());
263 int chars = ceil(width / m_xSpinButton->get_approximate_digit_width());
264 m_xSpinButton->set_width_chars(chars);
265 }
266
267 unsigned int SpinButton::Power10(unsigned int n)
268 {
269 unsigned int nValue = 1;
270 for (unsigned int i = 0; i < n; ++i)
271 nValue *= 10;
272 return nValue;
273 }
274
275 sal_Int64 SpinButton::denormalize(sal_Int64 nValue) const
276 {
277 const int nFactor = Power10(get_digits());
278
279 if ((nValue < (std::numeric_limits<sal_Int64>::min() + nFactor)) ||
280 (nValue > (std::numeric_limits<sal_Int64>::max() - nFactor)))
281 {
282 return nValue / nFactor;
283 }
284
285 const int nHalf = nFactor / 2;
286
287 if (nValue < 0)
288 return (nValue - nHalf) / nFactor;
289 return (nValue + nHalf) / nFactor;
290 }
291
292 OUString MetricSpinButton::format_number(sal_Int64 nValue) const
293 {
294 OUString aStr;
295
297
298 unsigned int nDecimalDigits = m_xSpinButton->get_digits();
299 //pawn percent off to icu to decide whether percent is separated from its number for this locale
300 if (m_eSrcUnit == FieldUnit::PERCENT)
301 {
302 double fValue = nValue;
303 fValue /= SpinButton::Power10(nDecimalDigits);
304 aStr = unicode::formatPercent(fValue, rLocaleData.getLanguageTag());
305 }
306 else
307 {
308 aStr = rLocaleData.getNum(nValue, nDecimalDigits, true, true);
309 OUString aSuffix = MetricToString(m_eSrcUnit);
310 if (m_eSrcUnit != FieldUnit::NONE && m_eSrcUnit != FieldUnit::DEGREE && m_eSrcUnit != FieldUnit::INCH && m_eSrcUnit != FieldUnit::FOOT)
311 aStr += " ";
312 if (m_eSrcUnit == FieldUnit::INCH)
313 {
314 OUString sDoublePrime = u"\u2033";
315 if (aSuffix != "\"" && aSuffix != sDoublePrime)
316 aStr += " ";
317 else
318 aSuffix = sDoublePrime;
319 }
320 else if (m_eSrcUnit == FieldUnit::FOOT)
321 {
322 OUString sPrime = u"\u2032";
323 if (aSuffix != "'" && aSuffix != sPrime)
324 aStr += " ";
325 else
326 aSuffix = sPrime;
327 }
328
329 assert(m_eSrcUnit != FieldUnit::PERCENT);
330 aStr += aSuffix;
331 }
332
333 return aStr;
334 }
335
336 void MetricSpinButton::set_digits(unsigned int digits)
337 {
338 int step, page;
339 get_increments(step, page, m_eSrcUnit);
340 sal_Int64 value = get_value(m_eSrcUnit);
341 m_xSpinButton->set_digits(digits);
342 set_increments(step, page, m_eSrcUnit);
345 }
346
348 {
349 if (eUnit != m_eSrcUnit)
350 {
351 int step, page;
352 get_increments(step, page, m_eSrcUnit);
353 sal_Int64 value = get_value(m_eSrcUnit);
354 m_eSrcUnit = eUnit;
355 set_increments(step, page, m_eSrcUnit);
357 spin_button_output(*m_xSpinButton);
359 }
360 }
361
362 sal_Int64 MetricSpinButton::ConvertValue(sal_Int64 nValue, FieldUnit eInUnit, FieldUnit eOutUnit) const
363 {
364 return vcl::ConvertValue(nValue, 0, m_xSpinButton->get_digits(), eInUnit, eOutUnit);
365 }
366
367 IMPL_LINK(MetricSpinButton, spin_button_input, int*, result, bool)
368 {
370 double fResult(0.0);
371 bool bRet = vcl::TextToValue(get_text(), fResult, 0, m_xSpinButton->get_digits(), rLocaleData, m_eSrcUnit);
372 if (bRet)
373 {
374 if (fResult > SAL_MAX_INT32)
375 fResult = SAL_MAX_INT32;
376 else if (fResult < SAL_MIN_INT32)
377 fResult = SAL_MIN_INT32;
378 *result = fResult;
379 }
380 return bRet;
381 }
382
383 EntryTreeView::EntryTreeView(std::unique_ptr<Entry> xEntry, std::unique_ptr<TreeView> xTreeView)
384 : m_xEntry(std::move(xEntry))
385 , m_xTreeView(std::move(xTreeView))
386 {
387 m_xTreeView->connect_changed(LINK(this, EntryTreeView, ClickHdl));
388 m_xEntry->connect_changed(LINK(this, EntryTreeView, ModifyHdl));
389 }
390
391 IMPL_LINK(EntryTreeView, ClickHdl, weld::TreeView&, rView, void)
392 {
393 m_xEntry->set_text(rView.get_selected_text());
394 m_aChangeHdl.Call(*this);
395 }
396
398 {
399 m_aChangeHdl.Call(*this);
400 }
401
403 {
404 int nHeight = nRows == -1 ? -1 : m_xTreeView->get_height_rows(nRows);
405 m_xTreeView->set_size_request(m_xTreeView->get_size_request().Width(), nHeight);
406 }
407
408 size_t GetAbsPos(const weld::TreeView& rTreeView, const weld::TreeIter& rIter)
409 {
410 size_t nAbsPos = 0;
411
412 std::unique_ptr<weld::TreeIter> xEntry(rTreeView.make_iterator(&rIter));
413 if (!rTreeView.get_iter_first(*xEntry))
414 xEntry.reset();
415
416 while (xEntry && rTreeView.iter_compare(*xEntry, rIter) != 0)
417 {
418 if (!rTreeView.iter_next(*xEntry))
419 xEntry.reset();
420 nAbsPos++;
421 }
422
423 return nAbsPos;
424 }
425
426 bool IsEntryVisible(const weld::TreeView& rTreeView, const weld::TreeIter& rIter)
427 {
428 // short circuit for the common case
429 if (rTreeView.get_iter_depth(rIter) == 0)
430 return true;
431
432 std::unique_ptr<weld::TreeIter> xEntry(rTreeView.make_iterator(&rIter));
433 bool bRetVal = false;
434 do
435 {
436 if (rTreeView.get_iter_depth(*xEntry) == 0)
437 {
438 bRetVal = true;
439 break;
440 }
441 } while (rTreeView.iter_parent(*xEntry) && rTreeView.get_row_expanded(*xEntry));
442 return bRetVal;
443 }
444}
445
446VclBuilder::VclBuilder(vcl::Window* pParent, const OUString& sUIDir, const OUString& sUIFile,
447 OUString sID, css::uno::Reference<css::frame::XFrame> xFrame,
448 bool bLegacy, const NotebookBarAddonsItem* pNotebookBarAddonsItem)
449 : m_pNotebookBarAddonsItem(pNotebookBarAddonsItem
450 ? new NotebookBarAddonsItem(*pNotebookBarAddonsItem)
451 : new NotebookBarAddonsItem{})
452 , m_sID(std::move(sID))
453 , m_sHelpRoot(sUIFile)
454 , m_pStringReplace(Translate::GetReadStringHook())
455 , m_pParent(pParent)
456 , m_bToplevelParentFound(false)
457 , m_bLegacy(bLegacy)
458 , m_pParserState(new ParserState)
459 , m_xFrame(std::move(xFrame))
460{
461 m_bToplevelHasDeferredInit = pParent &&
462 ((pParent->IsSystemWindow() && static_cast<SystemWindow*>(pParent)->isDeferredInit()) ||
463 (pParent->IsDockingWindow() && static_cast<DockingWindow*>(pParent)->isDeferredInit()));
465
466 sal_Int32 nIdx = m_sHelpRoot.lastIndexOf('.');
467 if (nIdx != -1)
468 m_sHelpRoot = m_sHelpRoot.copy(0, nIdx);
469 m_sHelpRoot += "/";
470
471 OUString sUri = sUIDir + sUIFile;
472
473 try
474 {
475 xmlreader::XmlReader reader(sUri);
476
477 handleChild(pParent, nullptr, reader);
478 }
479 catch (const css::uno::Exception &rExcept)
480 {
481 DBG_UNHANDLED_EXCEPTION("vcl.builder", "Unable to read .ui file");
482 CrashReporter::addKeyValue("VclBuilderException", "Unable to read .ui file: " + rExcept.Message, CrashReporter::Write);
483 throw;
484 }
485
486 //Set Mnemonic widgets when everything has been imported
487 for (auto const& mnemonicWidget : m_pParserState->m_aMnemonicWidgetMaps)
488 {
489 FixedText *pOne = get<FixedText>(mnemonicWidget.m_sID);
490 vcl::Window *pOther = get(mnemonicWidget.m_sValue);
491 SAL_WARN_IF(!pOne || !pOther, "vcl", "missing either source " << mnemonicWidget.m_sID
492 << " or target " << mnemonicWidget.m_sValue << " member of Mnemonic Widget Mapping");
493 if (pOne && pOther)
494 pOne->set_mnemonic_widget(pOther);
495 }
496
497 //Set a11y relations and role when everything has been imported
498 for (auto const& elemAtk : m_pParserState->m_aAtkInfo)
499 {
500 vcl::Window *pSource = elemAtk.first;
501 const stringmap &rMap = elemAtk.second;
502
503 for (auto const& [ rType, rParam ] : rMap)
504 {
505 if (rType == "role")
506 {
507 sal_Int16 role = BuilderUtils::getRoleFromName(rParam);
508 if (role != com::sun::star::accessibility::AccessibleRole::UNKNOWN)
509 pSource->SetAccessibleRole(role);
510 }
511 else
512 {
513 vcl::Window *pTarget = get(rParam);
514 SAL_WARN_IF(!pTarget, "vcl", "missing parameter of a11y relation: " << rParam);
515 if (!pTarget)
516 continue;
517 if (rType == "labelled-by")
518 pSource->SetAccessibleRelationLabeledBy(pTarget);
519 else if (rType == "label-for")
520 pSource->SetAccessibleRelationLabelFor(pTarget);
521 else
522 {
523 SAL_WARN("vcl.builder", "unhandled a11y relation :" << rType);
524 }
525 }
526 }
527 }
528
529 //Set radiobutton groups when everything has been imported
530 for (auto const& elem : m_pParserState->m_aGroupMaps)
531 {
532 RadioButton *pOne = get<RadioButton>(elem.m_sID);
533 RadioButton *pOther = get<RadioButton>(elem.m_sValue);
534 SAL_WARN_IF(!pOne || !pOther, "vcl", "missing member of radiobutton group");
535 if (pOne && pOther)
536 {
537 if (m_bLegacy)
538 pOne->group(*pOther);
539 else
540 {
541 pOther->group(*pOne);
542 std::stable_sort(pOther->m_xGroup->begin(), pOther->m_xGroup->end(), sortIntoBestTabTraversalOrder(this));
543 }
544 }
545 }
546
547#ifndef NDEBUG
549#endif
550 //Set ComboBox models when everything has been imported
551 for (auto const& elem : m_pParserState->m_aModelMaps)
552 {
553 assert(models.insert(elem.m_sValue).second && "a liststore or treestore is used in duplicate widgets");
554 vcl::Window* pTarget = get(elem.m_sID);
555 ListBox *pListBoxTarget = dynamic_cast<ListBox*>(pTarget);
556 ComboBox *pComboBoxTarget = dynamic_cast<ComboBox*>(pTarget);
557 SvTabListBox *pTreeBoxTarget = dynamic_cast<SvTabListBox*>(pTarget);
558 // pStore may be empty
559 const ListStore *pStore = get_model_by_name(elem.m_sValue);
560 SAL_WARN_IF(!pListBoxTarget && !pComboBoxTarget && !pTreeBoxTarget && !dynamic_cast<IconView*>(pTarget), "vcl", "missing elements of combobox");
561 if (pListBoxTarget && pStore)
562 mungeModel(*pListBoxTarget, *pStore, elem.m_nActiveId);
563 else if (pComboBoxTarget && pStore)
564 mungeModel(*pComboBoxTarget, *pStore, elem.m_nActiveId);
565 else if (pTreeBoxTarget && pStore)
566 mungeModel(*pTreeBoxTarget, *pStore, elem.m_nActiveId);
567 }
568
569 //Set TextView buffers when everything has been imported
570 for (auto const& elem : m_pParserState->m_aTextBufferMaps)
571 {
572 VclMultiLineEdit *pTarget = get<VclMultiLineEdit>(elem.m_sID);
573 const TextBuffer *pBuffer = get_buffer_by_name(elem.m_sValue);
574 SAL_WARN_IF(!pTarget || !pBuffer, "vcl", "missing elements of textview/textbuffer");
575 if (pTarget && pBuffer)
576 mungeTextBuffer(*pTarget, *pBuffer);
577 }
578
579 //Set SpinButton adjustments when everything has been imported
580 for (auto const& elem : m_pParserState->m_aNumericFormatterAdjustmentMaps)
581 {
582 NumericFormatter *pTarget = dynamic_cast<NumericFormatter*>(get(elem.m_sID));
583 const Adjustment *pAdjustment = get_adjustment_by_name(elem.m_sValue);
584 SAL_WARN_IF(!pTarget, "vcl", "missing NumericFormatter element of spinbutton/adjustment");
585 SAL_WARN_IF(!pAdjustment, "vcl", "missing Adjustment element of spinbutton/adjustment");
586 if (pTarget && pAdjustment)
587 mungeAdjustment(*pTarget, *pAdjustment);
588 }
589
590 for (auto const& elem : m_pParserState->m_aFormattedFormatterAdjustmentMaps)
591 {
592 FormattedField *pTarget = dynamic_cast<FormattedField*>(get(elem.m_sID));
593 const Adjustment *pAdjustment = get_adjustment_by_name(elem.m_sValue);
594 SAL_WARN_IF(!pTarget, "vcl", "missing FormattedField element of spinbutton/adjustment");
595 SAL_WARN_IF(!pAdjustment, "vcl", "missing Adjustment element of spinbutton/adjustment");
596 if (pTarget && pAdjustment)
597 mungeAdjustment(*pTarget, *pAdjustment);
598 }
599
600 //Set ScrollBar adjustments when everything has been imported
601 for (auto const& elem : m_pParserState->m_aScrollAdjustmentMaps)
602 {
603 ScrollBar *pTarget = get<ScrollBar>(elem.m_sID);
604 const Adjustment *pAdjustment = get_adjustment_by_name(elem.m_sValue);
605 SAL_WARN_IF(!pTarget || !pAdjustment, "vcl", "missing elements of scrollbar/adjustment");
606 if (pTarget && pAdjustment)
607 mungeAdjustment(*pTarget, *pAdjustment);
608 }
609
610 //Set Scale(Slider) adjustments
611 for (auto const& elem : m_pParserState->m_aSliderAdjustmentMaps)
612 {
613 Slider* pTarget = dynamic_cast<Slider*>(get(elem.m_sID));
614 const Adjustment* pAdjustment = get_adjustment_by_name(elem.m_sValue);
615 SAL_WARN_IF(!pTarget || !pAdjustment, "vcl", "missing elements of scale(slider)/adjustment");
616 if (pTarget && pAdjustment)
617 {
618 mungeAdjustment(*pTarget, *pAdjustment);
619 }
620 }
621
622 //Set size-groups when all widgets have been imported
623 for (auto const& sizeGroup : m_pParserState->m_aSizeGroups)
624 {
625 std::shared_ptr<VclSizeGroup> xGroup(std::make_shared<VclSizeGroup>());
626
627 for (auto const& [ rKey, rValue ] : sizeGroup.m_aProperties)
628 xGroup->set_property(rKey, rValue);
629
630 for (auto const& elem : sizeGroup.m_aWidgets)
631 {
632 vcl::Window* pWindow = get(elem);
633 pWindow->add_to_size_group(xGroup);
634 }
635 }
636
637 //Set button images when everything has been imported
638 std::set<OUString> aImagesToBeRemoved;
639 for (auto const& elem : m_pParserState->m_aButtonImageWidgetMaps)
640 {
641 PushButton *pTargetButton = nullptr;
642 RadioButton *pTargetRadio = nullptr;
643 Button *pTarget = nullptr;
644
645 if (!elem.m_bRadio)
646 {
647 pTargetButton = get<PushButton>(elem.m_sID);
648 pTarget = pTargetButton;
649 }
650 else
651 {
652 pTargetRadio = get<RadioButton>(elem.m_sID);
653 pTarget = pTargetRadio;
654 }
655
656 FixedImage *pImage = get<FixedImage>(elem.m_sValue);
657 SAL_WARN_IF(!pTarget || !pImage,
658 "vcl", "missing elements of button/image/stock");
659 if (!pTarget || !pImage)
660 continue;
661 aImagesToBeRemoved.insert(elem.m_sValue);
662
663 if (!elem.m_bRadio)
664 {
665 const Image& rImage = pImage->GetImage();
668 {
669 pTargetButton->SetSymbol(eSymbol);
670 //fdo#76457 keep symbol images small e.g. tools->customize->menu
671 //but images the right size. Really the PushButton::CalcMinimumSize
672 //and PushButton::ImplDrawPushButton are the better place to handle
673 //this, but its such a train-wreck
674 pTargetButton->SetStyle(pTargetButton->GetStyle() | WB_SMALLSTYLE);
675 }
676 else
677 {
678 pTargetButton->SetModeImage(rImage);
679 if (pImage->GetStyle() & WB_SMALLSTYLE)
680 {
681 Size aSz(rImage.GetSizePixel());
682 aSz.AdjustWidth(6);
683 aSz.AdjustHeight(6);
684 if (pTargetButton->get_width_request() == -1)
685 pTargetButton->set_width_request(aSz.Width());
686 if (pTargetButton->get_height_request() == -1)
687 pTargetButton->set_height_request(aSz.Height());
688 }
689 }
690 }
691 else
692 pTargetRadio->SetModeRadioImage(pImage->GetImage());
693
694 auto aFind = m_pParserState->m_aImageSizeMap.find(elem.m_sValue);
695 if (aFind != m_pParserState->m_aImageSizeMap.end())
696 {
697 switch (aFind->second)
698 {
699 case 1:
700 pTarget->SetSmallSymbol();
701 break;
702 case 2:
703 assert(pImage->GetStyle() & WB_SMALLSTYLE);
704 pTarget->SetStyle(pTarget->GetStyle() | WB_SMALLSTYLE);
705 break;
706 case 3:
707 pTarget->SetStyle(pTarget->GetStyle() | WB_SMALLSTYLE);
708 // large toolbar, make bigger than normal (4)
709 pTarget->set_width_request(pTarget->GetOptimalSize().Width() * 1.5);
710 pTarget->set_height_request(pTarget->GetOptimalSize().Height() * 1.5);
711 break;
712 case 4:
713 break;
714 default:
715 SAL_WARN("vcl.builder", "unsupported image size " << aFind->second);
716 break;
717 }
718 m_pParserState->m_aImageSizeMap.erase(aFind);
719 }
720 }
721
722 //There may be duplicate use of an Image, so we used a set to collect and
723 //now we can remove them from the tree after their final munge
724 for (auto const& elem : aImagesToBeRemoved)
725 {
726 delete_by_name(elem);
727 }
728
729 //Set button menus when everything has been imported
730 for (auto const& elem : m_pParserState->m_aButtonMenuMaps)
731 {
732 MenuButton *pTarget = get<MenuButton>(elem.m_sID);
733 PopupMenu *pMenu = get_menu(elem.m_sValue);
734 SAL_WARN_IF(!pTarget || !pMenu,
735 "vcl", "missing elements of button/menu");
736 if (!pTarget || !pMenu)
737 continue;
738 pTarget->SetPopupMenu(pMenu);
739 }
740
741 //Remove ScrollWindow parent widgets whose children in vcl implement scrolling
742 //internally.
743 for (auto const& elem : m_pParserState->m_aRedundantParentWidgets)
744 {
745 delete_by_window(elem.first);
746 }
747
748 //fdo#67378 merge the label into the disclosure button
749 for (auto const& elem : m_pParserState->m_aExpanderWidgets)
750 {
751 vcl::Window *pChild = elem->get_child();
753 if (pLabel && pLabel != pChild && pLabel->GetType() == WindowType::FIXEDTEXT)
754 {
755 FixedText *pLabelWidget = static_cast<FixedText*>(pLabel);
756 elem->set_label(pLabelWidget->GetText());
757 if (pLabelWidget->IsControlFont())
758 elem->get_label_widget()->SetControlFont(pLabelWidget->GetControlFont());
759 delete_by_window(pLabel);
760 }
761 }
762
763 // create message dialog message area now
764 for (auto const& elem : m_pParserState->m_aMessageDialogs)
765 elem->create_message_area();
766
767 //drop maps, etc. that we don't need again
768 m_pParserState.reset();
769
770 SAL_WARN_IF(!m_sID.isEmpty() && (!m_bToplevelParentFound && !get_by_name(m_sID)), "vcl.builder",
771 "Requested top level widget \"" << m_sID << "\" not found in " << sUIFile);
772
773#if defined SAL_LOG_WARN
775 {
776 int nButtons = 0;
777 bool bHasDefButton = false;
778 for (auto const& child : m_aChildren)
779 {
780 if (isButtonType(child.m_pWindow->GetType()))
781 {
782 ++nButtons;
783 if (child.m_pWindow->GetStyle() & WB_DEFBUTTON)
784 {
785 bHasDefButton = true;
786 break;
787 }
788 }
789 }
790 SAL_WARN_IF(nButtons && !bHasDefButton, "vcl.builder", "No default button defined in " << sUIFile);
791 }
792#endif
793
794 const bool bHideHelp = comphelper::LibreOfficeKit::isActive() &&
795 officecfg::Office::Common::Help::HelpRootURL::get().isEmpty();
796 if (bHideHelp)
797 {
798 if (vcl::Window *pHelpButton = get("help"))
799 pHelpButton->Hide();
800 }
801}
802
804{
806}
807
809{
810 for (std::vector<WinAndId>::reverse_iterator aI = m_aChildren.rbegin(),
811 aEnd = m_aChildren.rend(); aI != aEnd; ++aI)
812 {
813 aI->m_pWindow.disposeAndClear();
814 }
815 m_aChildren.clear();
816
817 for (std::vector<MenuAndId>::reverse_iterator aI = m_aMenus.rbegin(),
818 aEnd = m_aMenus.rend(); aI != aEnd; ++aI)
819 {
820 aI->m_pMenu.disposeAndClear();
821 }
822 m_aMenus.clear();
824}
825
826namespace
827{
828 bool extractHasFrame(VclBuilder::stringmap& rMap)
829 {
830 bool bHasFrame = true;
831 VclBuilder::stringmap::iterator aFind = rMap.find("has-frame");
832 if (aFind != rMap.end())
833 {
834 bHasFrame = toBool(aFind->second);
835 rMap.erase(aFind);
836 }
837 return bHasFrame;
838 }
839
840 bool extractDrawValue(VclBuilder::stringmap& rMap)
841 {
842 bool bDrawValue = true;
843 VclBuilder::stringmap::iterator aFind = rMap.find("draw-value");
844 if (aFind != rMap.end())
845 {
846 bDrawValue = toBool(aFind->second);
847 rMap.erase(aFind);
848 }
849 return bDrawValue;
850 }
851
852 OUString extractPopupMenu(VclBuilder::stringmap& rMap)
853 {
854 OUString sRet;
855 VclBuilder::stringmap::iterator aFind = rMap.find("popup");
856 if (aFind != rMap.end())
857 {
858 sRet = aFind->second;
859 rMap.erase(aFind);
860 }
861 return sRet;
862 }
863
864 OUString extractWidgetName(VclBuilder::stringmap& rMap)
865 {
866 OUString sRet;
867 VclBuilder::stringmap::iterator aFind = rMap.find("name");
868 if (aFind != rMap.end())
869 {
870 sRet = aFind->second;
871 rMap.erase(aFind);
872 }
873 return sRet;
874 }
875
876 OUString extractValuePos(VclBuilder::stringmap& rMap)
877 {
878 OUString sRet("top");
879 VclBuilder::stringmap::iterator aFind = rMap.find("value-pos");
880 if (aFind != rMap.end())
881 {
882 sRet = aFind->second;
883 rMap.erase(aFind);
884 }
885 return sRet;
886 }
887
888 OUString extractTypeHint(VclBuilder::stringmap &rMap)
889 {
890 OUString sRet("normal");
891 VclBuilder::stringmap::iterator aFind = rMap.find("type-hint");
892 if (aFind != rMap.end())
893 {
894 sRet = aFind->second;
895 rMap.erase(aFind);
896 }
897 return sRet;
898 }
899
900 bool extractResizable(VclBuilder::stringmap &rMap)
901 {
902 bool bResizable = true;
903 VclBuilder::stringmap::iterator aFind = rMap.find("resizable");
904 if (aFind != rMap.end())
905 {
906 bResizable = toBool(aFind->second);
907 rMap.erase(aFind);
908 }
909 return bResizable;
910 }
911
912#if HAVE_FEATURE_DESKTOP
913 bool extractModal(VclBuilder::stringmap &rMap)
914 {
915 bool bModal = false;
916 VclBuilder::stringmap::iterator aFind = rMap.find("modal");
917 if (aFind != rMap.end())
918 {
919 bModal = toBool(aFind->second);
920 rMap.erase(aFind);
921 }
922 return bModal;
923 }
924#endif
925
926 bool extractDecorated(VclBuilder::stringmap &rMap)
927 {
928 bool bDecorated = true;
929 VclBuilder::stringmap::iterator aFind = rMap.find("decorated");
930 if (aFind != rMap.end())
931 {
932 bDecorated = toBool(aFind->second);
933 rMap.erase(aFind);
934 }
935 return bDecorated;
936 }
937
938 bool extractCloseable(VclBuilder::stringmap &rMap)
939 {
940 bool bCloseable = true;
941 VclBuilder::stringmap::iterator aFind = rMap.find("deletable");
942 if (aFind != rMap.end())
943 {
944 bCloseable = toBool(aFind->second);
945 rMap.erase(aFind);
946 }
947 return bCloseable;
948 }
949
950 bool extractEntry(VclBuilder::stringmap &rMap)
951 {
952 bool bHasEntry = false;
953 VclBuilder::stringmap::iterator aFind = rMap.find("has-entry");
954 if (aFind != rMap.end())
955 {
956 bHasEntry = toBool(aFind->second);
957 rMap.erase(aFind);
958 }
959 return bHasEntry;
960 }
961
962 bool extractOrientation(VclBuilder::stringmap &rMap)
963 {
964 bool bVertical = false;
965 VclBuilder::stringmap::iterator aFind = rMap.find("orientation");
966 if (aFind != rMap.end())
967 {
968 bVertical = aFind->second.equalsIgnoreAsciiCase("vertical");
969 rMap.erase(aFind);
970 }
971 return bVertical;
972 }
973
974 bool extractVerticalTabPos(VclBuilder::stringmap &rMap)
975 {
976 bool bVertical = false;
977 VclBuilder::stringmap::iterator aFind = rMap.find("tab-pos");
978 if (aFind != rMap.end())
979 {
980 bVertical = aFind->second.equalsIgnoreAsciiCase("left") ||
981 aFind->second.equalsIgnoreAsciiCase("right");
982 rMap.erase(aFind);
983 }
984 return bVertical;
985 }
986
987 bool extractInconsistent(VclBuilder::stringmap &rMap)
988 {
989 bool bInconsistent = false;
990 VclBuilder::stringmap::iterator aFind = rMap.find("inconsistent");
991 if (aFind != rMap.end())
992 {
993 bInconsistent = toBool(aFind->second);
994 rMap.erase(aFind);
995 }
996 return bInconsistent;
997 }
998
999 OUString extractIconName(VclBuilder::stringmap &rMap)
1000 {
1001 OUString sIconName;
1002 // allow pixbuf, but prefer icon-name
1003 {
1004 VclBuilder::stringmap::iterator aFind = rMap.find("pixbuf");
1005 if (aFind != rMap.end())
1006 {
1007 sIconName = aFind->second;
1008 rMap.erase(aFind);
1009 }
1010 }
1011 {
1012 VclBuilder::stringmap::iterator aFind = rMap.find("icon-name");
1013 if (aFind != rMap.end())
1014 {
1015 sIconName = aFind->second;
1016 rMap.erase(aFind);
1017 }
1018 }
1019 if (sIconName == "missing-image")
1020 return OUString();
1021 OUString sReplace = mapStockToImageResource(sIconName);
1022 return !sReplace.isEmpty() ? sReplace : sIconName;
1023 }
1024
1025 WinBits extractRelief(VclBuilder::stringmap &rMap)
1026 {
1027 WinBits nBits = WB_3DLOOK;
1028 VclBuilder::stringmap::iterator aFind = rMap.find("relief");
1029 if (aFind != rMap.end())
1030 {
1031 assert(aFind->second != "half" && "relief of 'half' unsupported");
1032 if (aFind->second == "none")
1033 nBits = WB_FLATBUTTON;
1034 rMap.erase(aFind);
1035 }
1036 return nBits;
1037 }
1038
1039 OUString extractLabel(VclBuilder::stringmap &rMap)
1040 {
1041 OUString sType;
1042 VclBuilder::stringmap::iterator aFind = rMap.find("label");
1043 if (aFind != rMap.end())
1044 {
1045 sType = aFind->second;
1046 rMap.erase(aFind);
1047 }
1048 return sType;
1049 }
1050
1051 OUString extractActionName(VclBuilder::stringmap &rMap)
1052 {
1053 OUString sActionName;
1054 VclBuilder::stringmap::iterator aFind = rMap.find("action-name");
1055 if (aFind != rMap.end())
1056 {
1057 sActionName = aFind->second;
1058 rMap.erase(aFind);
1059 }
1060 return sActionName;
1061 }
1062
1063 bool extractVisible(VclBuilder::stringmap &rMap)
1064 {
1065 bool bRet = false;
1066 VclBuilder::stringmap::iterator aFind = rMap.find("visible");
1067 if (aFind != rMap.end())
1068 {
1069 bRet = toBool(aFind->second);
1070 rMap.erase(aFind);
1071 }
1072 return bRet;
1073 }
1074
1075 Size extractSizeRequest(VclBuilder::stringmap &rMap)
1076 {
1077 OUString sWidthRequest("0");
1078 OUString sHeightRequest("0");
1079 VclBuilder::stringmap::iterator aFind = rMap.find("width-request");
1080 if (aFind != rMap.end())
1081 {
1082 sWidthRequest = aFind->second;
1083 rMap.erase(aFind);
1084 }
1085 aFind = rMap.find("height-request");
1086 if (aFind != rMap.end())
1087 {
1088 sHeightRequest = aFind->second;
1089 rMap.erase(aFind);
1090 }
1091 return Size(sWidthRequest.toInt32(), sHeightRequest.toInt32());
1092 }
1093
1094 OUString extractTooltipText(VclBuilder::stringmap &rMap)
1095 {
1096 OUString sTooltipText;
1097 VclBuilder::stringmap::iterator aFind = rMap.find("tooltip-text");
1098 if (aFind == rMap.end())
1099 aFind = rMap.find("tooltip-markup");
1100 if (aFind != rMap.end())
1101 {
1102 sTooltipText = aFind->second;
1103 rMap.erase(aFind);
1104 }
1105 return sTooltipText;
1106 }
1107
1108 float extractAlignment(VclBuilder::stringmap &rMap)
1109 {
1110 float f = 0.0;
1111 VclBuilder::stringmap::iterator aFind = rMap.find("alignment");
1112 if (aFind != rMap.end())
1113 {
1114 f = aFind->second.toFloat();
1115 rMap.erase(aFind);
1116 }
1117 return f;
1118 }
1119
1120 OUString extractTitle(VclBuilder::stringmap &rMap)
1121 {
1122 OUString sTitle;
1123 VclBuilder::stringmap::iterator aFind = rMap.find("title");
1124 if (aFind != rMap.end())
1125 {
1126 sTitle = aFind->second;
1127 rMap.erase(aFind);
1128 }
1129 return sTitle;
1130 }
1131
1132 bool extractHeadersVisible(VclBuilder::stringmap &rMap)
1133 {
1134 bool bHeadersVisible = true;
1135 VclBuilder::stringmap::iterator aFind = rMap.find("headers-visible");
1136 if (aFind != rMap.end())
1137 {
1138 bHeadersVisible = toBool(aFind->second);
1139 rMap.erase(aFind);
1140 }
1141 return bHeadersVisible;
1142 }
1143
1144 bool extractSortIndicator(VclBuilder::stringmap &rMap)
1145 {
1146 bool bSortIndicator = false;
1147 VclBuilder::stringmap::iterator aFind = rMap.find("sort-indicator");
1148 if (aFind != rMap.end())
1149 {
1150 bSortIndicator = toBool(aFind->second);
1151 rMap.erase(aFind);
1152 }
1153 return bSortIndicator;
1154 }
1155
1156 bool extractClickable(VclBuilder::stringmap &rMap)
1157 {
1158 bool bClickable = false;
1159 VclBuilder::stringmap::iterator aFind = rMap.find("clickable");
1160 if (aFind != rMap.end())
1161 {
1162 bClickable = toBool(aFind->second);
1163 rMap.erase(aFind);
1164 }
1165 return bClickable;
1166 }
1167
1168 void setupFromActionName(Button *pButton, VclBuilder::stringmap &rMap, const css::uno::Reference<css::frame::XFrame>& rFrame)
1169 {
1170 if (!rFrame.is())
1171 return;
1172
1173 OUString aCommand(extractActionName(rMap));
1174 if (aCommand.isEmpty())
1175 return;
1176
1177 OUString aModuleName(vcl::CommandInfoProvider::GetModuleIdentifier(rFrame));
1178 auto aProperties = vcl::CommandInfoProvider::GetCommandProperties(aCommand, aModuleName);
1180 if (!aLabel.isEmpty())
1181 pButton->SetText(aLabel);
1182
1183 OUString aTooltip(vcl::CommandInfoProvider::GetTooltipForCommand(aCommand, aProperties, rFrame));
1184 if (!aTooltip.isEmpty())
1185 pButton->SetQuickHelpText(aTooltip);
1186
1187 Image aImage(vcl::CommandInfoProvider::GetImageForCommand(aCommand, rFrame));
1188 pButton->SetModeImage(aImage);
1189
1190 pButton->SetCommandHandler(aCommand, rFrame);
1191 }
1192
1193 VclPtr<Button> extractStockAndBuildPushButton(vcl::Window *pParent, VclBuilder::stringmap &rMap, bool bToggle)
1194 {
1196 if (bToggle)
1197 nBits |= WB_TOGGLE;
1198
1199 nBits |= extractRelief(rMap);
1200
1201 VclPtr<Button> xWindow = VclPtr<PushButton>::Create(pParent, nBits);
1202 return xWindow;
1203 }
1204
1205 VclPtr<MenuButton> extractStockAndBuildMenuButton(vcl::Window *pParent, VclBuilder::stringmap &rMap)
1206 {
1208
1209 nBits |= extractRelief(rMap);
1210
1211 VclPtr<MenuButton> xWindow = VclPtr<MenuButton>::Create(pParent, nBits);
1212 return xWindow;
1213 }
1214
1215 VclPtr<MenuButton> extractStockAndBuildMenuToggleButton(vcl::Window *pParent, VclBuilder::stringmap &rMap)
1216 {
1218
1219 nBits |= extractRelief(rMap);
1220
1221 VclPtr<MenuButton> xWindow = VclPtr<MenuToggleButton>::Create(pParent, nBits);
1222 return xWindow;
1223 }
1224
1225 WinBits extractDeferredBits(VclBuilder::stringmap &rMap)
1226 {
1227 WinBits nBits = WB_3DLOOK|WB_HIDE;
1228 if (extractResizable(rMap))
1229 nBits |= WB_SIZEABLE;
1230 if (extractCloseable(rMap))
1231 nBits |= WB_CLOSEABLE;
1232 if (!extractDecorated(rMap))
1233 nBits |= WB_OWNERDRAWDECORATION;
1234 OUString sType(extractTypeHint(rMap));
1235 if (sType == "utility")
1237 else if (sType == "popup-menu")
1239 else if (sType == "dock")
1240 nBits |= WB_DOCKABLE | WB_MOVEABLE;
1241 else
1242 nBits |= WB_MOVEABLE;
1243 return nBits;
1244 }
1245}
1246
1247void VclBuilder::extractGroup(const OUString &id, stringmap &rMap)
1248{
1249 VclBuilder::stringmap::iterator aFind = rMap.find("group");
1250 if (aFind != rMap.end())
1251 {
1252 OUString sID = aFind->second;
1253 sal_Int32 nDelim = sID.indexOf(':');
1254 if (nDelim != -1)
1255 sID = sID.copy(0, nDelim);
1256 m_pParserState->m_aGroupMaps.emplace_back(id, sID);
1257 rMap.erase(aFind);
1258 }
1259}
1260
1261void VclBuilder::connectNumericFormatterAdjustment(const OUString &id, const OUString &rAdjustment)
1262{
1263 if (!rAdjustment.isEmpty())
1264 m_pParserState->m_aNumericFormatterAdjustmentMaps.emplace_back(id, rAdjustment);
1265}
1266
1267void VclBuilder::connectFormattedFormatterAdjustment(const OUString &id, const OUString &rAdjustment)
1268{
1269 if (!rAdjustment.isEmpty())
1270 m_pParserState->m_aFormattedFormatterAdjustmentMaps.emplace_back(id, rAdjustment);
1271}
1272
1273bool VclBuilder::extractAdjustmentToMap(const OUString& id, VclBuilder::stringmap& rMap, std::vector<WidgetAdjustmentMap>& rAdjustmentMap)
1274{
1275 VclBuilder::stringmap::iterator aFind = rMap.find("adjustment");
1276 if (aFind != rMap.end())
1277 {
1278 rAdjustmentMap.emplace_back(id, aFind->second);
1279 rMap.erase(aFind);
1280 return true;
1281 }
1282 return false;
1283}
1284
1285namespace
1286{
1287 sal_Int32 extractActive(VclBuilder::stringmap &rMap)
1288 {
1289 sal_Int32 nActiveId = 0;
1290 VclBuilder::stringmap::iterator aFind = rMap.find("active");
1291 if (aFind != rMap.end())
1292 {
1293 nActiveId = aFind->second.toInt32();
1294 rMap.erase(aFind);
1295 }
1296 return nActiveId;
1297 }
1298
1299 bool extractSelectable(VclBuilder::stringmap &rMap)
1300 {
1301 bool bSelectable = false;
1302 VclBuilder::stringmap::iterator aFind = rMap.find("selectable");
1303 if (aFind != rMap.end())
1304 {
1305 bSelectable = toBool(aFind->second);
1306 rMap.erase(aFind);
1307 }
1308 return bSelectable;
1309 }
1310
1311 OUString extractAdjustment(VclBuilder::stringmap &rMap)
1312 {
1313 OUString sAdjustment;
1314 VclBuilder::stringmap::iterator aFind = rMap.find("adjustment");
1315 if (aFind != rMap.end())
1316 {
1317 sAdjustment= aFind->second;
1318 rMap.erase(aFind);
1319 return sAdjustment;
1320 }
1321 return sAdjustment;
1322 }
1323
1324 bool extractDrawIndicator(VclBuilder::stringmap &rMap)
1325 {
1326 bool bDrawIndicator = false;
1327 VclBuilder::stringmap::iterator aFind = rMap.find("draw-indicator");
1328 if (aFind != rMap.end())
1329 {
1330 bDrawIndicator = toBool(aFind->second);
1331 rMap.erase(aFind);
1332 }
1333 return bDrawIndicator;
1334 }
1335}
1336
1337void VclBuilder::extractModel(const OUString &id, stringmap &rMap)
1338{
1339 VclBuilder::stringmap::iterator aFind = rMap.find("model");
1340 if (aFind != rMap.end())
1341 {
1342 m_pParserState->m_aModelMaps.emplace_back(id, aFind->second,
1343 extractActive(rMap));
1344 rMap.erase(aFind);
1345 }
1346}
1347
1348void VclBuilder::extractBuffer(const OUString &id, stringmap &rMap)
1349{
1350 VclBuilder::stringmap::iterator aFind = rMap.find("buffer");
1351 if (aFind != rMap.end())
1352 {
1353 m_pParserState->m_aTextBufferMaps.emplace_back(id, aFind->second);
1354 rMap.erase(aFind);
1355 }
1356}
1357
1359{
1360 int nSize = 4;
1361 auto aFind = rMap.find("icon-size");
1362 if (aFind != rMap.end())
1363 nSize = aFind->second.toInt32();
1364 return nSize;
1365}
1366
1367void VclBuilder::extractButtonImage(const OUString &id, stringmap &rMap, bool bRadio)
1368{
1369 VclBuilder::stringmap::iterator aFind = rMap.find("image");
1370 if (aFind != rMap.end())
1371 {
1372 m_pParserState->m_aButtonImageWidgetMaps.emplace_back(id, aFind->second, bRadio);
1373 rMap.erase(aFind);
1374 }
1375}
1376
1377void VclBuilder::extractMnemonicWidget(const OUString &rLabelID, stringmap &rMap)
1378{
1379 VclBuilder::stringmap::iterator aFind = rMap.find("mnemonic-widget");
1380 if (aFind != rMap.end())
1381 {
1382 OUString sID = aFind->second;
1383 sal_Int32 nDelim = sID.indexOf(':');
1384 if (nDelim != -1)
1385 sID = sID.copy(0, nDelim);
1386 m_pParserState->m_aMnemonicWidgetMaps.emplace_back(rLabelID, sID);
1387 rMap.erase(aFind);
1388 }
1389}
1390
1392{
1393 //For Widgets that manage their own scrolling, if one appears as a child of
1394 //a scrolling window shoehorn that scrolling settings to this widget and
1395 //return the real parent to use
1396 if (pParent && pParent->GetType() == WindowType::SCROLLWINDOW)
1397 {
1398 WinBits nScrollBits = pParent->GetStyle();
1400 rWinStyle |= nScrollBits;
1401 if (static_cast<VclScrolledWindow*>(pParent)->HasVisibleBorder())
1402 rWinStyle |= WB_BORDER;
1403 pParent = pParent->GetParent();
1404 }
1405
1406 return pParent;
1407}
1408
1410{
1411 //remove the redundant scrolling parent
1412 sal_Int32 nWidthReq = pScrollParent->get_width_request();
1413 rMap["width-request"] = OUString::number(nWidthReq);
1414 sal_Int32 nHeightReq = pScrollParent->get_height_request();
1415 rMap["height-request"] = OUString::number(nHeightReq);
1416
1417 m_pParserState->m_aRedundantParentWidgets[pScrollParent] = pWindow;
1418}
1419
1420#ifndef DISABLE_DYNLOADING
1421
1422extern "C" { static void thisModule() {} }
1423
1424namespace {
1425
1426// Don't unload the module on destruction
1427class NoAutoUnloadModule : public osl::Module
1428{
1429public:
1430 ~NoAutoUnloadModule() { release(); }
1431};
1432
1433}
1434
1435typedef std::map<OUString, std::shared_ptr<NoAutoUnloadModule>> ModuleMap;
1437
1438#if ENABLE_MERGELIBS
1439static std::shared_ptr<NoAutoUnloadModule> g_pMergedLib = std::make_shared<NoAutoUnloadModule>();
1440#endif
1441
1442#ifndef SAL_DLLPREFIX
1443# define SAL_DLLPREFIX ""
1444#endif
1445
1446#endif
1447
1448namespace vcl {
1449
1451{
1452#ifndef DISABLE_DYNLOADING
1453
1454#if ENABLE_MERGELIBS
1455 g_pMergedLib->loadRelative(&thisModule, SVLIBRARY("merged"));
1456#else
1457// find -name '*ui*' | xargs grep 'class=".*lo-' |
1458// sed 's/.*class="//' | sed 's/-.*$//' | sort | uniq
1459 static const char *aWidgetLibs[] = {
1460 "sfxlo", "svtlo"
1461 };
1462 for (const auto & lib : aWidgetLibs)
1463 {
1464 std::unique_ptr<NoAutoUnloadModule> pModule(new NoAutoUnloadModule);
1465 OUString sModule = SAL_DLLPREFIX + OUString::createFromAscii(lib) + SAL_DLLEXTENSION;
1466 if (pModule->loadRelative(&thisModule, sModule))
1467 g_aModuleMap.insert(std::make_pair(sModule, std::move(pModule)));
1468 }
1469#endif // ENABLE_MERGELIBS
1470#endif // DISABLE_DYNLOADING
1471}
1472
1473}
1474
1475#if defined DISABLE_DYNLOADING && !HAVE_FEATURE_DESKTOP
1476
1477// This ifdef branch is mainly for building for the Collabora Online
1478// -based mobile apps for Android and iOS.
1479
1480extern "C" VclBuilder::customMakeWidget lo_get_custom_widget_func(const char* name);
1481
1482#elif defined EMSCRIPTEN && !ENABLE_QT5
1483
1484// This branch is mainly for building for WASM, and especially for
1485// Collabora Online in the browser, where code from core and Collabora
1486// Online is compiled to WASM and linked into a single WASM binary.
1487// (Not for Allotropia's Qt-based LibreOffice in the browser.)
1488
1489// When building core for WASM it doesn't use the same
1490// solenv/bin/native-code.py thing as the mobile apps, even if in both
1491// cases everything is linked statically. So there is no generated
1492// native-code.h, and we can't use lo_get_custom_widget_func() from
1493// that. So cheat and duplicate the code from an existing generated
1494// native-code.h. It's just a handful of lines anyway.
1495
1496extern "C" void makeNotebookbarTabControl(VclPtr<vcl::Window> &rRet, const VclPtr<vcl::Window> &pParent, VclBuilder::stringmap &rVec);
1497extern "C" void makeNotebookbarToolBox(VclPtr<vcl::Window> &rRet, const VclPtr<vcl::Window> &pParent, VclBuilder::stringmap &rVec);
1498
1499static struct { const char *name; VclBuilder::customMakeWidget func; } custom_widgets[] = {
1500 { "makeNotebookbarTabControl", makeNotebookbarTabControl },
1501 { "makeNotebookbarToolBox", makeNotebookbarToolBox },
1502};
1503
1504static VclBuilder::customMakeWidget lo_get_custom_widget_func(const char* name)
1505{
1506 for (size_t i = 0; i < sizeof(custom_widgets) / sizeof(custom_widgets[0]); i++)
1507 if (strcmp(name, custom_widgets[i].name) == 0)
1508 return custom_widgets[i].func;
1509 return nullptr;
1510}
1511
1512#endif
1513
1514namespace
1515{
1516// Takes a string like "sfxlo-NotebookbarToolBox"
1517VclBuilder::customMakeWidget GetCustomMakeWidget(const OUString& rName)
1518{
1519 const OUString name = rName == "sfxlo-SidebarToolBox" ? "sfxlo-NotebookbarToolBox" : rName;
1520 VclBuilder::customMakeWidget pFunction = nullptr;
1521 if (sal_Int32 nDelim = name.indexOf('-'); nDelim != -1)
1522 {
1523 const OUString sFunction(OUString::Concat("make") + name.subView(nDelim + 1));
1524
1525#ifndef DISABLE_DYNLOADING
1526 const OUString sModule = OUString::Concat(SAL_DLLPREFIX)
1527 + name.subView(0, nDelim)
1529 ModuleMap::iterator aI = g_aModuleMap.find(sModule);
1530 if (aI == g_aModuleMap.end())
1531 {
1532 std::shared_ptr<NoAutoUnloadModule> pModule;
1533#if ENABLE_MERGELIBS
1534 if (!g_pMergedLib->is())
1535 g_pMergedLib->loadRelative(&thisModule, SVLIBRARY("merged"));
1536 if ((pFunction = reinterpret_cast<VclBuilder::customMakeWidget>(
1537 g_pMergedLib->getFunctionSymbol(sFunction))))
1538 pModule = g_pMergedLib;
1539#endif
1540 if (!pFunction)
1541 {
1542 pModule = std::make_shared<NoAutoUnloadModule>();
1543 bool ok = pModule->loadRelative(&thisModule, sModule);
1544 if (!ok)
1545 {
1546#ifdef LINUX
1547 // in the case of preloading, we don't have eg. the
1548 // libcuilo.so, but still need to dlsym the symbols -
1549 // which are already in-process
1551 {
1552 pFunction = reinterpret_cast<VclBuilder::customMakeWidget>(dlsym(RTLD_DEFAULT, OUStringToOString(sFunction, RTL_TEXTENCODING_UTF8).getStr()));
1553 ok = !!pFunction;
1554 assert(ok && "couldn't even directly dlsym the sFunction (available via preload)");
1555 }
1556#endif
1557 assert(ok && "bad module name in .ui");
1558 }
1559 else
1560 {
1561 pFunction = reinterpret_cast<VclBuilder::customMakeWidget>(
1562 pModule->getFunctionSymbol(sFunction));
1563 }
1564 }
1565 g_aModuleMap.insert(std::make_pair(sModule, pModule));
1566 }
1567 else
1568 pFunction = reinterpret_cast<VclBuilder::customMakeWidget>(
1569 aI->second->getFunctionSymbol(sFunction));
1570#elif !HAVE_FEATURE_DESKTOP || (defined EMSCRIPTEN && !ENABLE_QT5)
1571 // This ifdef branch is mainly for building for either the
1572 // Android or iOS apps, or the Collabora Online as WASM thing.
1573 pFunction = lo_get_custom_widget_func(sFunction.toUtf8().getStr());
1574 SAL_WARN_IF(!pFunction, "vcl.builder", "Could not find " << sFunction);
1575 assert(pFunction);
1576#else
1577 pFunction = reinterpret_cast<VclBuilder::customMakeWidget>(
1578 osl_getFunctionSymbol((oslModule)RTLD_DEFAULT, sFunction.pData));
1579#endif
1580 }
1581 return pFunction;
1582}
1583}
1584
1585VclPtr<vcl::Window> VclBuilder::makeObject(vcl::Window *pParent, const OUString &name, const OUString &id,
1586 stringmap &rMap)
1587{
1588 bool bIsPlaceHolder = name.isEmpty();
1589 bool bVertical = false;
1590
1591 if (pParent && (pParent->GetType() == WindowType::TABCONTROL ||
1593 {
1594 bool bTopLevel(name == "GtkDialog" || name == "GtkMessageDialog" ||
1595 name == "GtkWindow" || name == "GtkPopover" || name == "GtkAssistant");
1596 if (!bTopLevel)
1597 {
1598 if (pParent->GetType() == WindowType::TABCONTROL)
1599 {
1600 //We have to add a page
1601 //make default pageid == position
1602 TabControl *pTabControl = static_cast<TabControl*>(pParent);
1603 sal_uInt16 nNewPageCount = pTabControl->GetPageCount()+1;
1604 sal_uInt16 nNewPageId = nNewPageCount;
1605 pTabControl->InsertPage(nNewPageId, OUString());
1606 pTabControl->SetCurPageId(nNewPageId);
1607 SAL_WARN_IF(bIsPlaceHolder, "vcl.builder", "we should have no placeholders for tabpages");
1608 if (!bIsPlaceHolder)
1609 {
1610 VclPtrInstance<TabPage> pPage(pTabControl);
1611 pPage->Show();
1612
1613 //Make up a name for it
1614 OUString sTabPageId = get_by_window(pParent) +
1615 "-page" +
1616 OUString::number(nNewPageCount);
1617 m_aChildren.emplace_back(sTabPageId, pPage, false);
1618 pPage->SetHelpId(m_sHelpRoot + sTabPageId);
1619
1620 pParent = pPage;
1621
1622 pTabControl->SetTabPage(nNewPageId, pPage);
1623 }
1624 }
1625 else
1626 {
1627 VerticalTabControl *pTabControl = static_cast<VerticalTabControl*>(pParent);
1628 SAL_WARN_IF(bIsPlaceHolder, "vcl.builder", "we should have no placeholders for tabpages");
1629 if (!bIsPlaceHolder)
1630 pParent = pTabControl->GetPageParent();
1631 }
1632 }
1633 }
1634
1635 if (bIsPlaceHolder || name == "GtkTreeSelection")
1636 return nullptr;
1637
1638 ToolBox *pToolBox = (pParent && pParent->GetType() == WindowType::TOOLBOX) ? static_cast<ToolBox*>(pParent) : nullptr;
1639
1640 extractButtonImage(id, rMap, name == "GtkRadioButton");
1641
1642 VclPtr<vcl::Window> xWindow;
1643 if (name == "GtkDialog" || name == "GtkAssistant")
1644 {
1645 // WB_ALLOWMENUBAR because we don't know in advance if we will encounter
1646 // a menubar, and menubars need a BorderWindow in the toplevel, and
1647 // such border windows need to be in created during the dialog ctor
1649 if (extractResizable(rMap))
1650 nBits |= WB_SIZEABLE;
1651 if (extractCloseable(rMap))
1652 nBits |= WB_CLOSEABLE;
1654 if (name == "GtkAssistant")
1655 xWindow = VclPtr<vcl::RoadmapWizard>::Create(pParent, nBits, eInit);
1656 else
1657 xWindow = VclPtr<Dialog>::Create(pParent, nBits, eInit);
1658#if HAVE_FEATURE_DESKTOP
1659 if (!extractModal(rMap))
1661#endif
1662 }
1663 else if (name == "GtkMessageDialog")
1664 {
1666 if (extractResizable(rMap))
1667 nBits |= WB_SIZEABLE;
1669 m_pParserState->m_aMessageDialogs.push_back(xDialog);
1670 xWindow = xDialog;
1671#if defined _WIN32
1672 xWindow->set_border_width(3);
1673#else
1674 xWindow->set_border_width(12);
1675#endif
1676 }
1677 else if (name == "GtkBox" || name == "GtkStatusbar")
1678 {
1679 bVertical = extractOrientation(rMap);
1680 if (bVertical)
1681 xWindow = VclPtr<VclVBox>::Create(pParent);
1682 else
1683 xWindow = VclPtr<VclHBox>::Create(pParent);
1684 }
1685 else if (name == "GtkPaned")
1686 {
1687 bVertical = extractOrientation(rMap);
1688 if (bVertical)
1689 xWindow = VclPtr<VclVPaned>::Create(pParent);
1690 else
1691 xWindow = VclPtr<VclHPaned>::Create(pParent);
1692 }
1693 else if (name == "GtkHBox")
1694 xWindow = VclPtr<VclHBox>::Create(pParent);
1695 else if (name == "GtkVBox")
1696 xWindow = VclPtr<VclVBox>::Create(pParent);
1697 else if (name == "GtkButtonBox")
1698 {
1699 bVertical = extractOrientation(rMap);
1700 if (bVertical)
1701 xWindow = VclPtr<VclVButtonBox>::Create(pParent);
1702 else
1703 xWindow = VclPtr<VclHButtonBox>::Create(pParent);
1704 }
1705 else if (name == "GtkHButtonBox")
1706 xWindow = VclPtr<VclHButtonBox>::Create(pParent);
1707 else if (name == "GtkVButtonBox")
1708 xWindow = VclPtr<VclVButtonBox>::Create(pParent);
1709 else if (name == "GtkGrid")
1710 xWindow = VclPtr<VclGrid>::Create(pParent);
1711 else if (name == "GtkFrame")
1712 xWindow = VclPtr<VclFrame>::Create(pParent);
1713 else if (name == "GtkExpander")
1714 {
1715 VclPtrInstance<VclExpander> pExpander(pParent);
1716 m_pParserState->m_aExpanderWidgets.push_back(pExpander);
1717 xWindow = pExpander;
1718 }
1719 else if (name == "GtkButton" || (!m_bLegacy && name == "GtkToggleButton"))
1720 {
1721 VclPtr<Button> xButton;
1722 OUString sMenu = BuilderUtils::extractCustomProperty(rMap);
1723 if (sMenu.isEmpty())
1724 xButton = extractStockAndBuildPushButton(pParent, rMap, name == "GtkToggleButton");
1725 else
1726 {
1727 assert(m_bLegacy && "use GtkMenuButton");
1728 xButton = extractStockAndBuildMenuButton(pParent, rMap);
1729 m_pParserState->m_aButtonMenuMaps.emplace_back(id, sMenu);
1730 }
1731 xButton->SetImageAlign(ImageAlign::Left); //default to left
1732 setupFromActionName(xButton, rMap, m_xFrame);
1733 xWindow = xButton;
1734 }
1735 else if (name == "GtkMenuButton")
1736 {
1737 VclPtr<MenuButton> xButton;
1738
1739 OUString sMenu = extractPopupMenu(rMap);
1740 if (!sMenu.isEmpty())
1741 m_pParserState->m_aButtonMenuMaps.emplace_back(id, sMenu);
1742
1743 OUString sType = extractWidgetName(rMap);
1744 if (sType.isEmpty())
1745 {
1746 xButton = extractStockAndBuildMenuButton(pParent, rMap);
1747 xButton->SetAccessibleRole(css::accessibility::AccessibleRole::BUTTON_MENU);
1748 }
1749 else
1750 {
1751 xButton = extractStockAndBuildMenuToggleButton(pParent, rMap);
1752 }
1753
1754 xButton->SetImageAlign(ImageAlign::Left); //default to left
1755
1756 if (!extractDrawIndicator(rMap))
1758
1759 setupFromActionName(xButton, rMap, m_xFrame);
1760 xWindow = xButton;
1761 }
1762 else if (name == "GtkToggleButton" && m_bLegacy)
1763 {
1764 VclPtr<Button> xButton;
1765 OUString sMenu = BuilderUtils::extractCustomProperty(rMap);
1766 assert(sMenu.getLength() && "not implemented yet");
1767 xButton = extractStockAndBuildMenuToggleButton(pParent, rMap);
1768 m_pParserState->m_aButtonMenuMaps.emplace_back(id, sMenu);
1769 xButton->SetImageAlign(ImageAlign::Left); //default to left
1770 setupFromActionName(xButton, rMap, m_xFrame);
1771 xWindow = xButton;
1772 }
1773 else if (name == "GtkRadioButton")
1774 {
1775 extractGroup(id, rMap);
1777 VclPtr<RadioButton> xButton = VclPtr<RadioButton>::Create(pParent, true, nBits);
1778 xButton->SetImageAlign(ImageAlign::Left); //default to left
1779 xWindow = xButton;
1780 }
1781 else if (name == "GtkCheckButton")
1782 {
1784 bool bIsTriState = extractInconsistent(rMap);
1785 VclPtr<CheckBox> xCheckBox = VclPtr<CheckBox>::Create(pParent, nBits);
1786 if (bIsTriState)
1787 {
1788 xCheckBox->EnableTriState(true);
1789 xCheckBox->SetState(TRISTATE_INDET);
1790 }
1791 xCheckBox->SetImageAlign(ImageAlign::Left); //default to left
1792
1793 xWindow = xCheckBox;
1794 }
1795 else if (name == "GtkSpinButton")
1796 {
1797 OUString sAdjustment = extractAdjustment(rMap);
1798
1800 if (extractHasFrame(rMap))
1801 nBits |= WB_BORDER;
1802
1803 connectFormattedFormatterAdjustment(id, sAdjustment);
1804 VclPtrInstance<FormattedField> xField(pParent, nBits);
1805 xField->GetFormatter().SetMinValue(0);
1806 xWindow = xField;
1807 }
1808 else if (name == "GtkLinkButton")
1810 else if (name == "GtkComboBox" || name == "GtkComboBoxText")
1811 {
1812 extractModel(id, rMap);
1813
1815
1816 bool bDropdown = BuilderUtils::extractDropdown(rMap);
1817
1818 if (bDropdown)
1819 nBits |= WB_DROPDOWN;
1820
1821 if (extractEntry(rMap))
1822 {
1823 VclPtrInstance<ComboBox> xComboBox(pParent, nBits);
1824 xComboBox->EnableAutoSize(true);
1825 xWindow = xComboBox;
1826 }
1827 else
1828 {
1829 VclPtrInstance<ListBox> xListBox(pParent, nBits|WB_SIMPLEMODE);
1830 xListBox->EnableAutoSize(true);
1831 xWindow = xListBox;
1832 }
1833 }
1834 else if (name == "VclOptionalBox" || name == "sfxlo-OptionalBox")
1835 {
1836 // tdf#135495 fallback sfxlo-OptionalBox to VclOptionalBox as a stopgap
1837 xWindow = VclPtr<OptionalBox>::Create(pParent);
1838 }
1839 else if (name == "svtlo-ManagedMenuButton")
1840 {
1841 // like tdf#135495 keep the name svtlo-ManagedMenuButton even though it's a misnomer
1842 // and is not dlsymed from the svt library
1844 OUString sMenu = BuilderUtils::extractCustomProperty(rMap);
1845 if (!sMenu.isEmpty())
1846 m_pParserState->m_aButtonMenuMaps.emplace_back(id, sMenu);
1847 setupFromActionName(static_cast<Button*>(xWindow.get()), rMap, m_xFrame);
1848 }
1849 else if (name == "sfxlo-PriorityMergedHBox")
1850 {
1851 // like tdf#135495 above, keep the sfxlo-PriorityMergedHBox even though its not in sfx anymore
1852 xWindow = VclPtr<PriorityMergedHBox>::Create(pParent);
1853 }
1854 else if (name == "sfxlo-PriorityHBox")
1855 {
1856 // like tdf#135495 above, keep the sfxlo-PriorityMergedHBox even though its not in sfx anymore
1857 xWindow = VclPtr<PriorityHBox>::Create(pParent);
1858 }
1859 else if (name == "sfxlo-DropdownBox")
1860 {
1861 // like tdf#135495 above, keep the sfxlo-PriorityMergedHBox even though its not in sfx anymore
1862 xWindow = VclPtr<DropdownBox>::Create(pParent);
1863 }
1864 else if (name == "sfxlo-ContextVBox")
1865 {
1866 // like tdf#135495 above, keep the sfxlo-PriorityMergedHBox even though its not in sfx anymore
1867 xWindow = VclPtr<ContextVBox>::Create(pParent);
1868 }
1869 else if (name == "GtkIconView")
1870 {
1871 assert(rMap.find("model") != rMap.end() && "GtkIconView must have a model");
1872
1873 //window we want to apply the packing props for this GtkIconView to
1874 VclPtr<vcl::Window> xWindowForPackingProps;
1875 extractModel(id, rMap);
1877 //IconView manages its own scrolling,
1878 vcl::Window *pRealParent = prepareWidgetOwnScrolling(pParent, nWinStyle);
1879
1880 VclPtr<IconView> xBox = VclPtr<IconView>::Create(pRealParent, nWinStyle);
1881 xWindowForPackingProps = xBox;
1882
1883 xWindow = xBox;
1884 xBox->SetNoAutoCurEntry(true);
1885 xBox->SetQuickSearch(true);
1886
1887 if (pRealParent != pParent)
1888 cleanupWidgetOwnScrolling(pParent, xWindowForPackingProps, rMap);
1889 }
1890 else if (name == "GtkTreeView")
1891 {
1892 if (!m_bLegacy)
1893 {
1894 assert(rMap.find("model") != rMap.end() && "GtkTreeView must have a model");
1895 }
1896
1897 //window we want to apply the packing props for this GtkTreeView to
1898 VclPtr<vcl::Window> xWindowForPackingProps;
1899 //To-Do
1900 //a) make SvHeaderTabListBox/SvTabListBox the default target for GtkTreeView
1901 //b) remove the non-drop down mode of ListBox and convert
1902 // everything over to SvHeaderTabListBox/SvTabListBox
1903 extractModel(id, rMap);
1905 if (m_bLegacy)
1906 {
1908 if (!sBorder.isEmpty())
1909 nWinStyle |= WB_BORDER;
1910 }
1911 else
1912 {
1913 nWinStyle |= WB_HASBUTTONS | WB_HASBUTTONSATROOT;
1914 }
1915 //ListBox/SvHeaderTabListBox manages its own scrolling,
1916 vcl::Window *pRealParent = prepareWidgetOwnScrolling(pParent, nWinStyle);
1917 if (m_bLegacy)
1918 {
1919 xWindow = VclPtr<ListBox>::Create(pRealParent, nWinStyle | WB_SIMPLEMODE);
1920 xWindowForPackingProps = xWindow;
1921 }
1922 else
1923 {
1925 bool bHeadersVisible = extractHeadersVisible(rMap);
1926 if (bHeadersVisible)
1927 {
1928 VclPtr<VclVBox> xContainer = VclPtr<VclVBox>::Create(pRealParent);
1929 OUString containerid(id + "-container");
1930 xContainer->SetHelpId(m_sHelpRoot + containerid);
1931 m_aChildren.emplace_back(containerid, xContainer, true);
1932
1934 xHeader->set_width_request(0); // let the headerbar width not affect the size request
1935 OUString headerid(id + "-header");
1936 xHeader->SetHelpId(m_sHelpRoot + headerid);
1937 m_aChildren.emplace_back(headerid, xHeader, true);
1938
1939 VclPtr<LclHeaderTabListBox> xHeaderBox = VclPtr<LclHeaderTabListBox>::Create(xContainer, nWinStyle);
1940 xHeaderBox->InitHeaderBar(xHeader);
1941 xContainer->set_expand(true);
1942 xHeader->Show();
1943 xContainer->Show();
1944 xBox = xHeaderBox;
1945 xWindowForPackingProps = xContainer;
1946 }
1947 else
1948 {
1949 xBox = VclPtr<LclTabListBox>::Create(pRealParent, nWinStyle);
1950 xWindowForPackingProps = xBox;
1951 }
1952 xWindow = xBox;
1953 xBox->SetNoAutoCurEntry(true);
1954 xBox->SetQuickSearch(true);
1955 xBox->SetSpaceBetweenEntries(3);
1956 xBox->SetEntryHeight(16);
1957 xBox->SetHighlightRange(); // select over the whole width
1958 }
1959 if (pRealParent != pParent)
1960 cleanupWidgetOwnScrolling(pParent, xWindowForPackingProps, rMap);
1961 }
1962 else if (name == "GtkTreeViewColumn")
1963 {
1964 if (!m_bLegacy)
1965 {
1966 SvHeaderTabListBox* pTreeView = dynamic_cast<SvHeaderTabListBox*>(pParent);
1967 if (HeaderBar* pHeaderBar = pTreeView ? pTreeView->GetHeaderBar() : nullptr)
1968 {
1970 if (extractClickable(rMap))
1972 if (extractSortIndicator(rMap))
1974 float fAlign = extractAlignment(rMap);
1975 if (fAlign == 0.0)
1976 nBits |= HeaderBarItemBits::LEFT;
1977 else if (fAlign == 1.0)
1978 nBits |= HeaderBarItemBits::RIGHT;
1979 else if (fAlign == 0.5)
1981 auto nItemId = pHeaderBar->GetItemCount() + 1;
1982 OUString sTitle(extractTitle(rMap));
1983 pHeaderBar->InsertItem(nItemId, sTitle, 100, nBits);
1984 }
1985 }
1986 }
1987 else if (name == "GtkLabel")
1988 {
1990 extractMnemonicWidget(id, rMap);
1991 if (extractSelectable(rMap))
1992 xWindow = VclPtr<SelectableFixedText>::Create(pParent, nWinStyle);
1993 else
1994 xWindow = VclPtr<FixedText>::Create(pParent, nWinStyle);
1995 }
1996 else if (name == "GtkImage")
1997 {
1999 OUString sIconName = extractIconName(rMap);
2000 if (!sIconName.isEmpty())
2001 xFixedImage->SetImage(FixedImage::loadThemeImage(sIconName));
2002 m_pParserState->m_aImageSizeMap[id] = getImageSize(rMap);
2003 xWindow = xFixedImage;
2004 //such parentless GtkImages are temps used to set icons on buttons
2005 //default them to hidden to stop e.g. insert->index entry flicking temp
2006 //full screen windows
2007 if (!pParent)
2008 {
2009 rMap["visible"] = "false";
2010 }
2011 }
2012 else if (name == "GtkSeparator")
2013 {
2014 bVertical = extractOrientation(rMap);
2015 xWindow = VclPtr<FixedLine>::Create(pParent, bVertical ? WB_VERT : WB_HORZ);
2016 }
2017 else if (name == "GtkScrollbar")
2018 {
2019 extractAdjustmentToMap(id, rMap, m_pParserState->m_aScrollAdjustmentMaps);
2020 bVertical = extractOrientation(rMap);
2021 xWindow = VclPtr<ScrollBar>::Create(pParent, bVertical ? WB_VERT : WB_HORZ);
2022 }
2023 else if (name == "GtkProgressBar")
2024 {
2025 extractAdjustmentToMap(id, rMap, m_pParserState->m_aScrollAdjustmentMaps);
2026 bVertical = extractOrientation(rMap);
2027 xWindow = VclPtr<ProgressBar>::Create(pParent, bVertical ? WB_VERT : WB_HORZ);
2028 }
2029 else if (name == "GtkScrolledWindow")
2030 {
2031 xWindow = VclPtr<VclScrolledWindow>::Create(pParent);
2032 }
2033 else if (name == "GtkViewport")
2034 {
2035 xWindow = VclPtr<VclViewport>::Create(pParent);
2036 }
2037 else if (name == "GtkEventBox")
2038 {
2039 xWindow = VclPtr<VclEventBox>::Create(pParent);
2040 }
2041 else if (name == "GtkEntry")
2042 {
2043 WinBits nWinStyle = WB_LEFT|WB_VCENTER|WB_3DLOOK;
2044 if (extractHasFrame(rMap))
2045 nWinStyle |= WB_BORDER;
2046 xWindow = VclPtr<Edit>::Create(pParent, nWinStyle);
2048 }
2049 else if (name == "GtkNotebook")
2050 {
2051 if (!extractVerticalTabPos(rMap))
2053 else
2054 xWindow = VclPtr<VerticalTabControl>::Create(pParent);
2055 }
2056 else if (name == "GtkDrawingArea")
2057 {
2058 xWindow = VclPtr<VclDrawingArea>::Create(pParent, WB_TABSTOP);
2059 }
2060 else if (name == "GtkTextView")
2061 {
2062 extractBuffer(id, rMap);
2063
2064 WinBits nWinStyle = WB_CLIPCHILDREN|WB_LEFT;
2065 //VclMultiLineEdit manages its own scrolling,
2066 vcl::Window *pRealParent = prepareWidgetOwnScrolling(pParent, nWinStyle);
2067 xWindow = VclPtr<VclMultiLineEdit>::Create(pRealParent, nWinStyle);
2068 if (pRealParent != pParent)
2069 cleanupWidgetOwnScrolling(pParent, xWindow, rMap);
2070 }
2071 else if (name == "GtkSpinner")
2072 {
2073 xWindow = VclPtr<Throbber>::Create(pParent, WB_3DLOOK);
2074 }
2075 else if (name == "GtkScale")
2076 {
2077 extractAdjustmentToMap(id, rMap, m_pParserState->m_aSliderAdjustmentMaps);
2078 bool bDrawValue = extractDrawValue(rMap);
2079 if (bDrawValue)
2080 {
2081 OUString sValuePos = extractValuePos(rMap);
2082 (void)sValuePos;
2083 }
2084 bVertical = extractOrientation(rMap);
2085
2086 WinBits nWinStyle = bVertical ? WB_VERT : WB_HORZ;
2087
2088 xWindow = VclPtr<Slider>::Create(pParent, nWinStyle);
2089 }
2090 else if (name == "GtkToolbar")
2091 {
2092 xWindow = VclPtr<ToolBox>::Create(pParent, WB_3DLOOK | WB_TABSTOP);
2093 }
2094 else if(name == "NotebookBarAddonsToolMergePoint")
2095 {
2096 customMakeWidget pFunction = GetCustomMakeWidget("sfxlo-NotebookbarToolBox");
2097 if(pFunction != nullptr)
2099 return nullptr;
2100 }
2101 else if (name == "GtkToolButton" || name == "GtkMenuToolButton" ||
2102 name == "GtkToggleToolButton" || name == "GtkRadioToolButton" || name == "GtkToolItem")
2103 {
2104 if (pToolBox)
2105 {
2106 OUString aCommand(extractActionName(rMap));
2107
2108 ToolBoxItemId nItemId(0);
2110 if (name == "GtkMenuToolButton")
2112 else if (name == "GtkToggleToolButton")
2114 else if (name == "GtkRadioToolButton")
2116
2117 if (!aCommand.isEmpty() && m_xFrame.is())
2118 {
2119 pToolBox->InsertItem(aCommand, m_xFrame, nBits, extractSizeRequest(rMap));
2120 nItemId = pToolBox->GetItemId(aCommand);
2121 }
2122 else
2123 {
2124 nItemId = ToolBoxItemId(pToolBox->GetItemCount() + 1);
2125 //TODO: ImplToolItems::size_type -> sal_uInt16!
2126 if (aCommand.isEmpty() && !m_bLegacy)
2127 aCommand = id;
2128 pToolBox->InsertItem(nItemId, extractLabel(rMap), aCommand, nBits);
2129 }
2130
2131 pToolBox->SetHelpId(nItemId, m_sHelpRoot + id);
2132 OUString sTooltip(extractTooltipText(rMap));
2133 if (!sTooltip.isEmpty())
2134 pToolBox->SetQuickHelpText(nItemId, sTooltip);
2135
2136 OUString sIconName(extractIconName(rMap));
2137 if (!sIconName.isEmpty())
2138 pToolBox->SetItemImage(nItemId, FixedImage::loadThemeImage(sIconName));
2139
2140 if (!extractVisible(rMap))
2141 pToolBox->HideItem(nItemId);
2142
2143 m_pParserState->m_nLastToolbarId = nItemId;
2144
2145 return nullptr; // no widget to be created
2146 }
2147 }
2148 else if (name == "GtkSeparatorToolItem")
2149 {
2150 if (pToolBox)
2151 {
2152 pToolBox->InsertSeparator();
2153 return nullptr; // no widget to be created
2154 }
2155 }
2156 else if (name == "GtkWindow")
2157 {
2158 WinBits nBits = extractDeferredBits(rMap);
2159 if (nBits & WB_DOCKABLE)
2160 xWindow = VclPtr<DockingWindow>::Create(pParent, nBits|WB_MOVEABLE);
2161 else
2162 xWindow = VclPtr<FloatingWindow>::Create(pParent, nBits|WB_MOVEABLE);
2163 }
2164 else if (name == "GtkPopover")
2165 {
2166 WinBits nBits = extractDeferredBits(rMap);
2167 xWindow = VclPtr<DockingWindow>::Create(pParent, nBits|WB_DOCKABLE|WB_MOVEABLE);
2168 }
2169 else if (name == "GtkCalendar")
2170 {
2171 WinBits nBits = extractDeferredBits(rMap);
2172 xWindow = VclPtr<Calendar>::Create(pParent, nBits);
2173 }
2174 else
2175 {
2176 if (customMakeWidget pFunction = GetCustomMakeWidget(name))
2177 {
2178 pFunction(xWindow, pParent, rMap);
2179 if (xWindow->GetType() == WindowType::PUSHBUTTON)
2180 setupFromActionName(static_cast<Button*>(xWindow.get()), rMap, m_xFrame);
2181 else if (xWindow->GetType() == WindowType::MENUBUTTON)
2182 {
2183 OUString sMenu = BuilderUtils::extractCustomProperty(rMap);
2184 if (!sMenu.isEmpty())
2185 m_pParserState->m_aButtonMenuMaps.emplace_back(id, sMenu);
2186 setupFromActionName(static_cast<Button*>(xWindow.get()), rMap, m_xFrame);
2187 }
2188 }
2189 }
2190
2191 SAL_INFO_IF(!xWindow, "vcl.builder", "probably need to implement " << name << " or add a make" << name << " function");
2192 if (xWindow)
2193 {
2194 // child windows of disabled windows are made disabled by vcl by default, we don't want that
2195 WindowImpl *pWindowImpl = xWindow->ImplGetWindowImpl();
2196 pWindowImpl->mbDisabled = false;
2197
2198 xWindow->SetHelpId(m_sHelpRoot + id);
2199 SAL_INFO("vcl.builder", "for name '" << name << "' and id '" << id <<
2200 "', created " << xWindow.get() << " child of " <<
2201 pParent << "(" << xWindow->ImplGetWindowImpl()->mpParent.get() << "/" <<
2202 xWindow->ImplGetWindowImpl()->mpRealParent.get() << "/" <<
2203 xWindow->ImplGetWindowImpl()->mpBorderWindow.get() << ") with helpid " <<
2204 xWindow->GetHelpId());
2205 m_aChildren.emplace_back(id, xWindow, bVertical);
2206
2207 // if the parent was a toolbox set it as an itemwindow for the latest itemid
2208 if (pToolBox)
2209 {
2210 Size aSize(xWindow->GetSizePixel());
2211 aSize.setHeight(xWindow->get_preferred_size().Height());
2212 xWindow->SetSizePixel(aSize);
2213 pToolBox->SetItemWindow(m_pParserState->m_nLastToolbarId, xWindow);
2214 pToolBox->SetItemExpand(m_pParserState->m_nLastToolbarId, true);
2215 }
2216 }
2217 return xWindow;
2218}
2219
2220namespace
2221{
2222 //return true for window types which exist in vcl but are not themselves
2223 //represented in the .ui format, i.e. only their children exist.
2224 bool isConsideredGtkPseudo(vcl::Window const *pWindow)
2225 {
2226 return pWindow->GetType() == WindowType::TABPAGE;
2227 }
2228}
2229
2230//Any properties from .ui load we couldn't set because of potential virtual methods
2231//during ctor are applied here
2233{
2235 return;
2236 stringmap aDeferredProperties;
2237 aDeferredProperties.swap(m_aDeferredProperties);
2239 BuilderUtils::set_properties(m_pParent, aDeferredProperties);
2240}
2241
2243{
2245 {
2246 for (auto const& [rKey, rValue] : rProps)
2247 pWindow->set_property(rKey, rValue);
2248 }
2249
2250 OUString convertMnemonicMarkup(std::u16string_view rIn)
2251 {
2252 OUStringBuffer aRet(rIn);
2253 for (sal_Int32 nI = 0; nI < aRet.getLength(); ++nI)
2254 {
2255 if (aRet[nI] == '_' && nI+1 < aRet.getLength())
2256 {
2257 if (aRet[nI+1] != '_')
2258 aRet[nI] = MNEMONIC_CHAR;
2259 else
2260 aRet.remove(nI, 1);
2261 ++nI;
2262 }
2263 }
2264 return aRet.makeStringAndClear();
2265 }
2266
2268 {
2269 OUString sCustomProperty;
2270 VclBuilder::stringmap::iterator aFind = rMap.find("customproperty");
2271 if (aFind != rMap.end())
2272 {
2273 sCustomProperty = aFind->second;
2274 rMap.erase(aFind);
2275 }
2276 return sCustomProperty;
2277 }
2278
2280 {
2281 OUString sWidthChars("width-chars");
2282 VclBuilder::stringmap::iterator aFind = rMap.find(sWidthChars);
2283 if (aFind == rMap.end())
2284 rMap[sWidthChars] = "20";
2285 }
2286
2288 {
2289 bool bDropdown = true;
2290 VclBuilder::stringmap::iterator aFind = rMap.find("dropdown");
2291 if (aFind != rMap.end())
2292 {
2293 bDropdown = toBool(aFind->second);
2294 rMap.erase(aFind);
2295 }
2296 return bDropdown;
2297 }
2298
2299 void reorderWithinParent(vcl::Window &rWindow, sal_uInt16 nNewPosition)
2300 {
2301 WindowImpl *pWindowImpl = rWindow.ImplGetWindowImpl();
2302 if (pWindowImpl->mpParent != pWindowImpl->mpRealParent)
2303 {
2304 assert(pWindowImpl->mpBorderWindow == pWindowImpl->mpParent);
2305 assert(pWindowImpl->mpBorderWindow->ImplGetWindowImpl()->mpParent == pWindowImpl->mpRealParent);
2306 reorderWithinParent(*pWindowImpl->mpBorderWindow, nNewPosition);
2307 return;
2308 }
2309 rWindow.reorderWithinParent(nNewPosition);
2310 }
2311
2312 void reorderWithinParent(std::vector<vcl::Window*>& rChilds, bool bIsButtonBox)
2313 {
2314 for (size_t i = 0; i < rChilds.size(); ++i)
2315 {
2316 reorderWithinParent(*rChilds[i], i);
2317
2318 if (!bIsButtonBox)
2319 continue;
2320
2321 //The first member of the group for legacy code needs WB_GROUP set and the
2322 //others not
2323 WinBits nBits = rChilds[i]->GetStyle();
2324 nBits &= ~WB_GROUP;
2325 if (i == 0)
2326 nBits |= WB_GROUP;
2327 rChilds[i]->SetStyle(nBits);
2328 }
2329 }
2330
2331 sal_Int16 getRoleFromName(const OUString& roleName)
2332 {
2333 using namespace com::sun::star::accessibility;
2334
2335 static const std::unordered_map<OUString, sal_Int16> aAtkRoleToAccessibleRole = {
2336 /* This is in atkobject.h's AtkRole order */
2337 { "invalid", AccessibleRole::UNKNOWN },
2338 { "accelerator label", AccessibleRole::UNKNOWN },
2339 { "alert", AccessibleRole::ALERT },
2340 { "animation", AccessibleRole::UNKNOWN },
2341 { "arrow", AccessibleRole::UNKNOWN },
2342 { "calendar", AccessibleRole::UNKNOWN },
2343 { "canvas", AccessibleRole::CANVAS },
2344 { "check box", AccessibleRole::CHECK_BOX },
2345 { "check menu item", AccessibleRole::CHECK_MENU_ITEM },
2346 { "color chooser", AccessibleRole::COLOR_CHOOSER },
2347 { "column header", AccessibleRole::COLUMN_HEADER },
2348 { "combo box", AccessibleRole::COMBO_BOX },
2349 { "date editor", AccessibleRole::DATE_EDITOR },
2350 { "desktop icon", AccessibleRole::DESKTOP_ICON },
2351 { "desktop frame", AccessibleRole::DESKTOP_PANE }, // ?
2352 { "dial", AccessibleRole::UNKNOWN },
2353 { "dialog", AccessibleRole::DIALOG },
2354 { "directory pane", AccessibleRole::DIRECTORY_PANE },
2355 { "drawing area", AccessibleRole::UNKNOWN },
2356 { "file chooser", AccessibleRole::FILE_CHOOSER },
2357 { "filler", AccessibleRole::FILLER },
2358 { "font chooser", AccessibleRole::FONT_CHOOSER },
2359 { "frame", AccessibleRole::FRAME },
2360 { "glass pane", AccessibleRole::GLASS_PANE },
2361 { "html container", AccessibleRole::UNKNOWN },
2362 { "icon", AccessibleRole::ICON },
2363 { "image", AccessibleRole::GRAPHIC },
2364 { "internal frame", AccessibleRole::INTERNAL_FRAME },
2365 { "label", AccessibleRole::LABEL },
2366 { "layered pane", AccessibleRole::LAYERED_PANE },
2367 { "list", AccessibleRole::LIST },
2368 { "list item", AccessibleRole::LIST_ITEM },
2369 { "menu", AccessibleRole::MENU },
2370 { "menu bar", AccessibleRole::MENU_BAR },
2371 { "menu item", AccessibleRole::MENU_ITEM },
2372 { "option pane", AccessibleRole::OPTION_PANE },
2373 { "page tab", AccessibleRole::PAGE_TAB },
2374 { "page tab list", AccessibleRole::PAGE_TAB_LIST },
2375 { "panel", AccessibleRole::PANEL }, // or SHAPE or TEXT_FRAME ?
2376 { "password text", AccessibleRole::PASSWORD_TEXT },
2377 { "popup menu", AccessibleRole::POPUP_MENU },
2378 { "progress bar", AccessibleRole::PROGRESS_BAR },
2379 { "push button", AccessibleRole::PUSH_BUTTON }, // or BUTTON_DROPDOWN or BUTTON_MENU
2380 { "radio button", AccessibleRole::RADIO_BUTTON },
2381 { "radio menu item", AccessibleRole::RADIO_MENU_ITEM },
2382 { "root pane", AccessibleRole::ROOT_PANE },
2383 { "row header", AccessibleRole::ROW_HEADER },
2384 { "scroll bar", AccessibleRole::SCROLL_BAR },
2385 { "scroll pane", AccessibleRole::SCROLL_PANE },
2386 { "separator", AccessibleRole::SEPARATOR },
2387 { "slider", AccessibleRole::SLIDER },
2388 { "split pane", AccessibleRole::SPLIT_PANE },
2389 { "spin button", AccessibleRole::SPIN_BOX }, // ?
2390 { "statusbar", AccessibleRole::STATUS_BAR },
2391 { "table", AccessibleRole::TABLE },
2392 { "table cell", AccessibleRole::TABLE_CELL },
2393 { "table column header", AccessibleRole::COLUMN_HEADER }, // approximate
2394 { "table row header", AccessibleRole::ROW_HEADER }, // approximate
2395 { "tear off menu item", AccessibleRole::UNKNOWN },
2396 { "terminal", AccessibleRole::UNKNOWN },
2397 { "text", AccessibleRole::TEXT },
2398 { "toggle button", AccessibleRole::TOGGLE_BUTTON },
2399 { "tool bar", AccessibleRole::TOOL_BAR },
2400 { "tool tip", AccessibleRole::TOOL_TIP },
2401 { "tree", AccessibleRole::TREE },
2402 { "tree table", AccessibleRole::TREE_TABLE },
2403 { "unknown", AccessibleRole::UNKNOWN },
2404 { "viewport", AccessibleRole::VIEW_PORT },
2405 { "window", AccessibleRole::WINDOW },
2406 { "header", AccessibleRole::HEADER },
2407 { "footer", AccessibleRole::FOOTER },
2408 { "paragraph", AccessibleRole::PARAGRAPH },
2409 { "ruler", AccessibleRole::RULER },
2410 { "application", AccessibleRole::UNKNOWN },
2411 { "autocomplete", AccessibleRole::UNKNOWN },
2412 { "edit bar", AccessibleRole::EDIT_BAR },
2413 { "embedded", AccessibleRole::EMBEDDED_OBJECT },
2414 { "entry", AccessibleRole::UNKNOWN },
2415 { "chart", AccessibleRole::CHART },
2416 { "caption", AccessibleRole::CAPTION },
2417 { "document frame", AccessibleRole::DOCUMENT },
2418 { "heading", AccessibleRole::HEADING },
2419 { "page", AccessibleRole::PAGE },
2420 { "section", AccessibleRole::SECTION },
2421 { "redundant object", AccessibleRole::UNKNOWN },
2422 { "form", AccessibleRole::FORM },
2423 { "link", AccessibleRole::HYPER_LINK },
2424 { "input method window", AccessibleRole::UNKNOWN },
2425 { "table row", AccessibleRole::UNKNOWN },
2426 { "tree item", AccessibleRole::TREE_ITEM },
2427 { "document spreadsheet", AccessibleRole::DOCUMENT_SPREADSHEET },
2428 { "document presentation", AccessibleRole::DOCUMENT_PRESENTATION },
2429 { "document text", AccessibleRole::DOCUMENT_TEXT },
2430 { "document web", AccessibleRole::DOCUMENT }, // approximate
2431 { "document email", AccessibleRole::DOCUMENT }, // approximate
2432 { "comment", AccessibleRole::COMMENT }, // or NOTE or END_NOTE or FOOTNOTE or SCROLL_PANE
2433 { "list box", AccessibleRole::UNKNOWN },
2434 { "grouping", AccessibleRole::GROUP_BOX },
2435 { "image map", AccessibleRole::IMAGE_MAP },
2436 { "notification", AccessibleRole::NOTIFICATION },
2437 { "info bar", AccessibleRole::UNKNOWN },
2438 { "level bar", AccessibleRole::UNKNOWN },
2439 { "title bar", AccessibleRole::UNKNOWN },
2440 { "block quote", AccessibleRole::UNKNOWN },
2441 { "audio", AccessibleRole::UNKNOWN },
2442 { "video", AccessibleRole::UNKNOWN },
2443 { "definition", AccessibleRole::UNKNOWN },
2444 { "article", AccessibleRole::UNKNOWN },
2445 { "landmark", AccessibleRole::UNKNOWN },
2446 { "log", AccessibleRole::UNKNOWN },
2447 { "marquee", AccessibleRole::UNKNOWN },
2448 { "math", AccessibleRole::UNKNOWN },
2449 { "rating", AccessibleRole::UNKNOWN },
2450 { "timer", AccessibleRole::UNKNOWN },
2451 { "description list", AccessibleRole::UNKNOWN },
2452 { "description term", AccessibleRole::UNKNOWN },
2453 { "description value", AccessibleRole::UNKNOWN },
2454 { "static", AccessibleRole::STATIC },
2455 { "math fraction", AccessibleRole::UNKNOWN },
2456 { "math root", AccessibleRole::UNKNOWN },
2457 { "subscript", AccessibleRole::UNKNOWN },
2458 { "superscript", AccessibleRole::UNKNOWN },
2459 { "footnote", AccessibleRole::FOOTNOTE },
2460 };
2461
2462 auto it = aAtkRoleToAccessibleRole.find(roleName);
2463 if (it == aAtkRoleToAccessibleRole.end())
2464 return AccessibleRole::UNKNOWN;
2465 return it->second;
2466 }
2467}
2468
2470 const OUString &rID, stringmap &rProps, stringmap &rPango, stringmap &rAtk)
2471{
2472 VclPtr<vcl::Window> pCurrentChild;
2473
2474 if (m_pParent && !isConsideredGtkPseudo(m_pParent) && !m_sID.isEmpty() && rID == m_sID)
2475 {
2476 pCurrentChild = m_pParent;
2477
2478 //toplevels default to resizable and apparently you can't change them
2479 //afterwards, so we need to wait until now before we can truly
2480 //initialize the dialog.
2481 if (pParent && pParent->IsSystemWindow())
2482 {
2483 SystemWindow *pSysWin = static_cast<SystemWindow*>(pCurrentChild.get());
2484 pSysWin->doDeferredInit(extractDeferredBits(rProps));
2486 }
2487 else if (pParent && pParent->IsDockingWindow())
2488 {
2489 DockingWindow *pDockWin = static_cast<DockingWindow*>(pCurrentChild.get());
2490 pDockWin->doDeferredInit(extractDeferredBits(rProps));
2492 }
2493
2494 if (pCurrentChild->GetHelpId().isEmpty())
2495 {
2496 pCurrentChild->SetHelpId(m_sHelpRoot + m_sID);
2497 SAL_INFO("vcl.builder", "for toplevel dialog " << this << " " <<
2498 rID << ", set helpid " << pCurrentChild->GetHelpId());
2499 }
2501 }
2502 else
2503 {
2504 //if we're being inserting under a toplevel dialog whose init is
2505 //deferred due to waiting to encounter it in this .ui, and it hasn't
2506 //been seen yet, then make unattached widgets parent-less toplevels
2507 if (pParent == m_pParent.get() && m_bToplevelHasDeferredInit)
2508 pParent = nullptr;
2509 pCurrentChild = makeObject(pParent, rClass, rID, rProps);
2510 }
2511
2512 if (pCurrentChild)
2513 {
2514 pCurrentChild->set_id(rID);
2515 if (pCurrentChild == m_pParent.get() && m_bToplevelHasDeferredProperties)
2516 m_aDeferredProperties = rProps;
2517 else
2518 BuilderUtils::set_properties(pCurrentChild, rProps);
2519
2520 // tdf#119827 handle size before scale so we can trivially
2521 // scale on the current font size whether size is present
2522 // or not.
2523 VclBuilder::stringmap::iterator aSize = rPango.find("size");
2524 if (aSize != rPango.end())
2525 {
2526 pCurrentChild->set_font_attribute(aSize->first, aSize->second);
2527 rPango.erase(aSize);
2528 }
2529 for (auto const& [ rKey, rValue ] : rPango)
2530 pCurrentChild->set_font_attribute(rKey, rValue);
2531
2532 m_pParserState->m_aAtkInfo[pCurrentChild] = rAtk;
2533 }
2534
2535 rProps.clear();
2536 rPango.clear();
2537 rAtk.clear();
2538
2539 if (!pCurrentChild)
2540 {
2541 bool bToolbarParent = (pParent && pParent->GetType() == WindowType::TOOLBOX);
2542 pCurrentChild = (m_aChildren.empty() || bToolbarParent) ? pParent : m_aChildren.back().m_pWindow.get();
2543 }
2544 return pCurrentChild;
2545}
2546
2548{
2549 TabControl *pTabControl = pParent && pParent->GetType() == WindowType::TABCONTROL ?
2550 static_cast<TabControl*>(pParent) : nullptr;
2551
2552 std::vector<OUString> sIDs;
2553
2554 int nLevel = 1;
2556 stringmap aAtkProperties;
2557 std::vector<vcl::EnumContext::Context> context;
2558
2559 while(true)
2560 {
2562 int nsId;
2563
2565 xmlreader::XmlReader::Text::NONE, &name, &nsId);
2566
2567 if (res == xmlreader::XmlReader::Result::Begin)
2568 {
2569 ++nLevel;
2570 if (name == "object")
2571 {
2572 while (reader.nextAttribute(&nsId, &name))
2573 {
2574 if (name == "id")
2575 {
2576 name = reader.getAttributeValue(false);
2577 OUString sID(name.begin, name.length, RTL_TEXTENCODING_UTF8);
2578 sal_Int32 nDelim = sID.indexOf(':');
2579 if (nDelim != -1)
2580 {
2581 aProperties["customproperty"] = sID.copy(nDelim + 1);
2582 sID = sID.copy(0, nDelim);
2583 }
2584 sIDs.push_back(sID);
2585 }
2586 }
2587 }
2588 else if (name == "style")
2589 {
2590 int nPriority = 0;
2591 context = handleStyle(reader, nPriority);
2592 --nLevel;
2593 }
2594 else if (name == "property")
2596 else if (pTabControl && name == "child")
2597 {
2598 // just to collect the atk properties (if any) for the label
2599 handleChild(nullptr, &aAtkProperties, reader);
2600 --nLevel;
2601 }
2602 }
2603
2604 if (res == xmlreader::XmlReader::Result::End)
2605 --nLevel;
2606
2607 if (!nLevel)
2608 break;
2609
2610 if (res == xmlreader::XmlReader::Result::Done)
2611 break;
2612 }
2613
2614 if (!pParent)
2615 return;
2616
2617 VerticalTabControl *pVerticalTabControl = pParent->GetType() == WindowType::VERTICALTABCONTROL ?
2618 static_cast<VerticalTabControl*>(pParent) : nullptr;
2619 assert(pTabControl || pVerticalTabControl);
2620 VclBuilder::stringmap::iterator aFind = aProperties.find("label");
2621 if (aFind != aProperties.end())
2622 {
2623 OUString sTooltip(extractTooltipText(aProperties));
2624 if (pTabControl)
2625 {
2626 sal_uInt16 nPageId = pTabControl->GetCurPageId();
2627 pTabControl->SetPageText(nPageId, aFind->second);
2628 pTabControl->SetPageName(nPageId, sIDs.back());
2629 pTabControl->SetHelpText(nPageId, sTooltip);
2630 if (!context.empty())
2631 {
2632 TabPage* pPage = pTabControl->GetTabPage(nPageId);
2633 pPage->SetContext(std::move(context));
2634 }
2635
2636 for (auto const& [ rKey, rValue ] : aAtkProperties)
2637 {
2638 if (rKey == "AtkObject::accessible-name")
2639 pTabControl->SetAccessibleName(nPageId, rValue);
2640 else if (rKey == "AtkObject::accessible-description")
2641 pTabControl->SetAccessibleDescription(nPageId, rValue);
2642 else
2643 SAL_INFO("vcl.builder", "unhandled atk property: " << rKey);
2644 }
2645
2646 }
2647 else
2648 {
2649 OUString sLabel(BuilderUtils::convertMnemonicMarkup(aFind->second));
2650 OUString sIconName(extractIconName(aProperties));
2651 pVerticalTabControl->InsertPage(sIDs.front(), sLabel, FixedImage::loadThemeImage(sIconName), sTooltip,
2652 pVerticalTabControl->GetPageParent()->GetWindow(GetWindowType::LastChild));
2653 }
2654 }
2655 else
2656 {
2657 if (pTabControl)
2658 pTabControl->RemovePage(pTabControl->GetCurPageId());
2659 }
2660}
2661
2662//so that tabbing between controls goes in a visually sensible sequence
2663//we sort these into a best-tab-order sequence
2665{
2666 //sort child order within parent list by grid position
2667 sal_Int32 nTopA = pA->get_grid_top_attach();
2668 sal_Int32 nTopB = pB->get_grid_top_attach();
2669 if (nTopA < nTopB)
2670 return true;
2671 if (nTopA > nTopB)
2672 return false;
2673 sal_Int32 nLeftA = pA->get_grid_left_attach();
2674 sal_Int32 nLeftB = pB->get_grid_left_attach();
2675 if (nLeftA < nLeftB)
2676 return true;
2677 if (nLeftA > nLeftB)
2678 return false;
2679 //sort into two groups of pack start and pack end
2680 VclPackType ePackA = pA->get_pack_type();
2681 VclPackType ePackB = pB->get_pack_type();
2682 if (ePackA < ePackB)
2683 return true;
2684 if (ePackA > ePackB)
2685 return false;
2686 bool bVerticalContainer = m_pBuilder->get_window_packing_data(pA->GetParent()).m_bVerticalOrient;
2687 bool bPackA = pA->get_secondary();
2688 bool bPackB = pB->get_secondary();
2689 if (!bVerticalContainer)
2690 {
2691 //for horizontal boxes group secondaries before primaries
2692 if (bPackA > bPackB)
2693 return true;
2694 if (bPackA < bPackB)
2695 return false;
2696 }
2697 else
2698 {
2699 //for vertical boxes group secondaries after primaries
2700 if (bPackA < bPackB)
2701 return true;
2702 if (bPackA > bPackB)
2703 return false;
2704 }
2705 //honour relative box positions with pack group, (numerical order is reversed
2706 //for VclPackType::End, they are packed from the end back, but here we need
2707 //them in visual layout order so that tabbing works as expected)
2708 sal_Int32 nPackA = m_pBuilder->get_window_packing_data(pA).m_nPosition;
2709 sal_Int32 nPackB = m_pBuilder->get_window_packing_data(pB).m_nPosition;
2710 if (nPackA < nPackB)
2711 return ePackA == VclPackType::Start;
2712 if (nPackA > nPackB)
2713 return ePackA != VclPackType::Start;
2714 //sort labels of Frames before body
2715 if (pA->GetParent() == pB->GetParent())
2716 {
2717 const VclFrame *pFrameParent = dynamic_cast<const VclFrame*>(pA->GetParent());
2718 if (pFrameParent)
2719 {
2720 const vcl::Window *pLabel = pFrameParent->get_label_widget();
2721 int nFramePosA = (pA == pLabel) ? 0 : 1;
2722 int nFramePosB = (pB == pLabel) ? 0 : 1;
2723 return nFramePosA < nFramePosB;
2724 }
2725 }
2726 return false;
2727}
2728
2730{
2731 vcl::Window *pCurrentChild = nullptr;
2732
2734 int nsId;
2735 OString sType, sInternalChild;
2736
2737 while (reader.nextAttribute(&nsId, &name))
2738 {
2739 if (name == "type")
2740 {
2741 name = reader.getAttributeValue(false);
2742 sType = OString(name.begin, name.length);
2743 }
2744 else if (name == "internal-child")
2745 {
2746 name = reader.getAttributeValue(false);
2747 sInternalChild = OString(name.begin, name.length);
2748 }
2749 }
2750
2751 if (sType == "tab")
2752 {
2753 handleTabChild(pParent, reader);
2754 return;
2755 }
2756
2757 int nLevel = 1;
2758 while(true)
2759 {
2761 xmlreader::XmlReader::Text::NONE, &name, &nsId);
2762
2763 if (res == xmlreader::XmlReader::Result::Begin)
2764 {
2765 if (name == "object" || name == "placeholder")
2766 {
2767 pCurrentChild = handleObject(pParent, pAtkProps, reader).get();
2768
2769 bool bObjectInserted = pCurrentChild && pParent != pCurrentChild;
2770
2771 if (bObjectInserted)
2772 {
2773 //Internal-children default in glade to not having their visible bits set
2774 //even though they are visible (generally anyway)
2775 if (!sInternalChild.isEmpty())
2776 pCurrentChild->Show();
2777
2778 //Select the first page if it's a notebook
2779 if (pCurrentChild->GetType() == WindowType::TABCONTROL)
2780 {
2781 TabControl *pTabControl = static_cast<TabControl*>(pCurrentChild);
2782 pTabControl->SetCurPageId(pTabControl->GetPageId(0));
2783
2784 //To-Do add reorder capability to the TabControl
2785 }
2786 else
2787 {
2788 // We want to sort labels before contents of frames
2789 // for keyboard traversal, especially if there
2790 // are multiple widgets using the same mnemonic
2791 if (sType == "label")
2792 {
2793 if (VclFrame *pFrameParent = dynamic_cast<VclFrame*>(pParent))
2794 pFrameParent->designate_label(pCurrentChild);
2795 }
2796 if (sInternalChild.startsWith("vbox") || sInternalChild.startsWith("messagedialog-vbox"))
2797 {
2798 if (Dialog *pBoxParent = dynamic_cast<Dialog*>(pParent))
2799 pBoxParent->set_content_area(static_cast<VclBox*>(pCurrentChild)); // FIXME-VCLPTR
2800 }
2801 else if (sInternalChild.startsWith("action_area") || sInternalChild.startsWith("messagedialog-action_area"))
2802 {
2803 vcl::Window *pContentArea = pCurrentChild->GetParent();
2804 if (Dialog *pBoxParent = dynamic_cast<Dialog*>(pContentArea ? pContentArea->GetParent() : nullptr))
2805 {
2806 pBoxParent->set_action_area(static_cast<VclButtonBox*>(pCurrentChild)); // FIXME-VCLPTR
2807 }
2808 }
2809
2810 bool bIsButtonBox = dynamic_cast<VclButtonBox*>(pCurrentChild) != nullptr;
2811
2812 //To-Do make reorder a virtual in Window, move this foo
2813 //there and see above
2814 std::vector<vcl::Window*> aChilds;
2815 for (vcl::Window* pChild = pCurrentChild->GetWindow(GetWindowType::FirstChild); pChild;
2816 pChild = pChild->GetWindow(GetWindowType::Next))
2817 {
2818 if (bIsButtonBox)
2819 {
2820 if (PushButton* pPushButton = dynamic_cast<PushButton*>(pChild))
2821 pPushButton->setAction(true);
2822 }
2823
2824 aChilds.push_back(pChild);
2825 }
2826
2827 //sort child order within parent so that tabbing
2828 //between controls goes in a visually sensible sequence
2829 std::stable_sort(aChilds.begin(), aChilds.end(), sortIntoBestTabTraversalOrder(this));
2830 BuilderUtils::reorderWithinParent(aChilds, bIsButtonBox);
2831 }
2832 }
2833 }
2834 else if (name == "packing")
2835 {
2836 handlePacking(pCurrentChild, pParent, reader);
2837 }
2838 else if (name == "interface")
2839 {
2840 while (reader.nextAttribute(&nsId, &name))
2841 {
2842 if (name == "domain")
2843 {
2844 name = reader.getAttributeValue(false);
2845 sType = OString(name.begin, name.length);
2846 m_pParserState->m_aResLocale = Translate::Create(sType);
2847 }
2848 }
2849 ++nLevel;
2850 }
2851 else
2852 ++nLevel;
2853 }
2854
2855 if (res == xmlreader::XmlReader::Result::End)
2856 --nLevel;
2857
2858 if (!nLevel)
2859 break;
2860
2861 if (res == xmlreader::XmlReader::Result::Done)
2862 break;
2863 }
2864}
2865
2867{
2868 xmlreader::Span span;
2869 int nsId;
2870
2871 OUString sProperty;
2872 OUString sValue;
2873
2874 while (reader.nextAttribute(&nsId, &span))
2875 {
2876 if (span == "name")
2877 {
2878 span = reader.getAttributeValue(false);
2879 sProperty = OUString(span.begin, span.length, RTL_TEXTENCODING_UTF8);
2880 }
2881 else if (span == "value")
2882 {
2883 span = reader.getAttributeValue(false);
2884 sValue = OUString(span.begin, span.length, RTL_TEXTENCODING_UTF8);
2885 }
2886 }
2887
2888 if (!sProperty.isEmpty())
2889 rMap[sProperty] = sValue;
2890}
2891
2893{
2894 xmlreader::Span span;
2895 int nsId;
2896
2897 OUString sProperty;
2898 OUString sValue;
2899
2900 while (reader.nextAttribute(&nsId, &span))
2901 {
2902 if (span == "type")
2903 {
2904 span = reader.getAttributeValue(false);
2905 sProperty = OUString(span.begin, span.length, RTL_TEXTENCODING_UTF8);
2906 }
2907 else if (span == "target")
2908 {
2909 span = reader.getAttributeValue(false);
2910 sValue = OUString(span.begin, span.length, RTL_TEXTENCODING_UTF8);
2911 sal_Int32 nDelim = sValue.indexOf(':');
2912 if (nDelim != -1)
2913 sValue = sValue.copy(0, nDelim);
2914 }
2915 }
2916
2917 if (!sProperty.isEmpty())
2918 rMap[sProperty] = sValue;
2919}
2920
2922{
2923 xmlreader::Span span;
2924 int nsId;
2925
2926 OUString sProperty;
2927
2928 while (reader.nextAttribute(&nsId, &span))
2929 {
2930 if (span == "type")
2931 {
2932 span = reader.getAttributeValue(false);
2933 sProperty = OUString(span.begin, span.length, RTL_TEXTENCODING_UTF8);
2934 }
2935 }
2936
2937 if (!sProperty.isEmpty())
2938 rMap["role"] = sProperty;
2939}
2940
2941void VclBuilder::handleRow(xmlreader::XmlReader &reader, const OUString &rID)
2942{
2943 int nLevel = 1;
2944
2945 ListStore::row aRow;
2946
2947 while(true)
2948 {
2950 int nsId;
2951
2953 xmlreader::XmlReader::Text::NONE, &name, &nsId);
2954
2955 if (res == xmlreader::XmlReader::Result::Done)
2956 break;
2957
2958 if (res == xmlreader::XmlReader::Result::Begin)
2959 {
2960 ++nLevel;
2961 if (name == "col")
2962 {
2963 bool bTranslated = false;
2964 sal_uInt32 nId = 0;
2965 OString sContext;
2966
2967 while (reader.nextAttribute(&nsId, &name))
2968 {
2969 if (name == "id")
2970 {
2971 name = reader.getAttributeValue(false);
2972 nId = OString(name.begin, name.length).toUInt32();
2973 }
2974 else if (nId == 0 && name == "translatable" && reader.getAttributeValue(false) == "yes")
2975 {
2976 bTranslated = true;
2977 }
2978 else if (name == "context")
2979 {
2980 name = reader.getAttributeValue(false);
2981 sContext = OString(name.begin, name.length);
2982 }
2983 }
2984
2985 (void)reader.nextItem(
2986 xmlreader::XmlReader::Text::Raw, &name, &nsId);
2987
2988 OString sValue(name.begin, name.length);
2989 OUString sFinalValue;
2990 if (bTranslated)
2991 {
2992 sFinalValue = Translate::get(TranslateId{sContext.getStr(), sValue.getStr()}, m_pParserState->m_aResLocale);
2993 }
2994 else
2995 sFinalValue = OUString::fromUtf8(sValue);
2996
2997
2998 if (aRow.size() < nId+1)
2999 aRow.resize(nId+1);
3000 aRow[nId] = sFinalValue;
3001 }
3002 }
3003
3004 if (res == xmlreader::XmlReader::Result::End)
3005 {
3006 --nLevel;
3007 }
3008
3009 if (!nLevel)
3010 break;
3011 }
3012
3013 m_pParserState->m_aModels[rID].m_aEntries.push_back(aRow);
3014}
3015
3016void VclBuilder::handleListStore(xmlreader::XmlReader &reader, const OUString &rID, std::u16string_view rClass)
3017{
3018 int nLevel = 1;
3019
3020 while(true)
3021 {
3023 int nsId;
3024
3026 xmlreader::XmlReader::Text::NONE, &name, &nsId);
3027
3028 if (res == xmlreader::XmlReader::Result::Done)
3029 break;
3030
3031 if (res == xmlreader::XmlReader::Result::Begin)
3032 {
3033 if (name == "row")
3034 {
3035 bool bNotTreeStore = rClass != u"GtkTreeStore";
3036 if (bNotTreeStore)
3037 handleRow(reader, rID);
3038 assert(bNotTreeStore && "gtk, as the time of writing, doesn't support data in GtkTreeStore serialization");
3039 }
3040 else
3041 ++nLevel;
3042 }
3043
3044 if (res == xmlreader::XmlReader::Result::End)
3045 {
3046 --nLevel;
3047 }
3048
3049 if (!nLevel)
3050 break;
3051 }
3052}
3053
3055{
3056 int nLevel = 1;
3057
3059
3060 while (true)
3061 {
3063 int nsId;
3064
3066 xmlreader::XmlReader::Text::NONE, &name, &nsId);
3067
3068 if (res == xmlreader::XmlReader::Result::Done)
3069 break;
3070
3071 if (res == xmlreader::XmlReader::Result::Begin)
3072 {
3073 ++nLevel;
3074 if (name == "property")
3076 }
3077
3078 if (res == xmlreader::XmlReader::Result::End)
3079 {
3080 --nLevel;
3081 }
3082
3083 if (!nLevel)
3084 break;
3085 }
3086
3087 return aProperties;
3088}
3089
3090void VclBuilder::applyAtkProperties(vcl::Window *pWindow, const stringmap& rProperties)
3091{
3092 assert(pWindow);
3093 for (auto const& [ rKey, rValue ] : rProperties)
3094 {
3095 if (pWindow && rKey.match("AtkObject::"))
3096 pWindow->set_property(rKey.copy(RTL_CONSTASCII_LENGTH("AtkObject::")), rValue);
3097 else
3098 SAL_WARN("vcl.builder", "unhandled atk prop: " << rKey);
3099 }
3100}
3101
3102std::vector<ComboBoxTextItem> VclBuilder::handleItems(xmlreader::XmlReader &reader) const
3103{
3104 int nLevel = 1;
3105
3106 std::vector<ComboBoxTextItem> aItems;
3107
3108 while(true)
3109 {
3111 int nsId;
3112
3114 xmlreader::XmlReader::Text::NONE, &name, &nsId);
3115
3116 if (res == xmlreader::XmlReader::Result::Done)
3117 break;
3118
3119 if (res == xmlreader::XmlReader::Result::Begin)
3120 {
3121 ++nLevel;
3122 if (name == "item")
3123 {
3124 bool bTranslated = false;
3125 OString sContext;
3126 OUString sId;
3127
3128 while (reader.nextAttribute(&nsId, &name))
3129 {
3130 if (name == "translatable" && reader.getAttributeValue(false) == "yes")
3131 {
3132 bTranslated = true;
3133 }
3134 else if (name == "context")
3135 {
3136 name = reader.getAttributeValue(false);
3137 sContext = OString(name.begin, name.length);
3138 }
3139 else if (name == "id")
3140 {
3141 name = reader.getAttributeValue(false);
3142 sId = OUString(name.begin, name.length, RTL_TEXTENCODING_UTF8);
3143 }
3144 }
3145
3146 (void)reader.nextItem(
3147 xmlreader::XmlReader::Text::Raw, &name, &nsId);
3148
3149 OString sValue(name.begin, name.length);
3150 OUString sFinalValue;
3151 if (bTranslated)
3152 {
3153 sFinalValue = Translate::get(TranslateId{sContext.getStr(), sValue.getStr()}, m_pParserState->m_aResLocale);
3154 }
3155 else
3156 sFinalValue = OUString::fromUtf8(sValue);
3157
3158 if (m_pStringReplace)
3159 sFinalValue = (*m_pStringReplace)(sFinalValue);
3160
3161 aItems.emplace_back(sFinalValue, sId);
3162 }
3163 }
3164
3165 if (res == xmlreader::XmlReader::Result::End)
3166 {
3167 --nLevel;
3168 }
3169
3170 if (!nLevel)
3171 break;
3172 }
3173
3174 return aItems;
3175}
3176
3177VclPtr<Menu> VclBuilder::handleMenu(xmlreader::XmlReader &reader, const OUString &rID, bool bMenuBar)
3178{
3179 VclPtr<Menu> pCurrentMenu;
3180 if (bMenuBar)
3181 pCurrentMenu = VclPtr<MenuBar>::Create();
3182 else
3183 pCurrentMenu = VclPtr<PopupMenu>::Create();
3184
3185 pCurrentMenu->set_id(rID);
3186
3187 int nLevel = 1;
3188
3190
3191 while(true)
3192 {
3194 int nsId;
3195
3197 xmlreader::XmlReader::Text::NONE, &name, &nsId);
3198
3199 if (res == xmlreader::XmlReader::Result::Done)
3200 break;
3201
3202 if (res == xmlreader::XmlReader::Result::Begin)
3203 {
3204 if (name == "child")
3205 {
3206 handleMenuChild(pCurrentMenu, reader);
3207 }
3208 else
3209 {
3210 ++nLevel;
3211 if (name == "property")
3213 }
3214 }
3215
3216 if (res == xmlreader::XmlReader::Result::End)
3217 {
3218 --nLevel;
3219 }
3220
3221 if (!nLevel)
3222 break;
3223 }
3224
3225 m_aMenus.emplace_back(rID, pCurrentMenu);
3226
3227 return pCurrentMenu;
3228}
3229
3231{
3233 int nsId;
3234
3235 int nLevel = 1;
3236 while(true)
3237 {
3239 xmlreader::XmlReader::Text::NONE, &name, &nsId);
3240
3241 if (res == xmlreader::XmlReader::Result::Begin)
3242 {
3243 if (name == "object" || name == "placeholder")
3244 {
3245 handleMenuObject(pParent, reader);
3246 }
3247 else
3248 ++nLevel;
3249 }
3250
3251 if (res == xmlreader::XmlReader::Result::End)
3252 --nLevel;
3253
3254 if (!nLevel)
3255 break;
3256
3257 if (res == xmlreader::XmlReader::Result::Done)
3258 break;
3259 }
3260}
3261
3263{
3264 OUString sClass;
3265 OUString sID;
3266 OUString sCustomProperty;
3267 PopupMenu *pSubMenu = nullptr;
3268
3270 int nsId;
3271
3272 while (reader.nextAttribute(&nsId, &name))
3273 {
3274 if (name == "class")
3275 {
3276 name = reader.getAttributeValue(false);
3277 sClass = OUString(name.begin, name.length, RTL_TEXTENCODING_UTF8);
3278 }
3279 else if (name == "id")
3280 {
3281 name = reader.getAttributeValue(false);
3282 sID = OUString(name.begin, name.length, RTL_TEXTENCODING_UTF8);
3283 if (m_bLegacy)
3284 {
3285 sal_Int32 nDelim = sID.indexOf(':');
3286 if (nDelim != -1)
3287 {
3288 sCustomProperty = sID.subView(nDelim+1);
3289 sID = sID.copy(0, nDelim);
3290 }
3291 }
3292 }
3293 }
3294
3295 int nLevel = 1;
3296
3298 stringmap aAtkProperties;
3299 accelmap aAccelerators;
3300
3301 if (!sCustomProperty.isEmpty())
3302 aProperties["customproperty"] = sCustomProperty;
3303
3304 while(true)
3305 {
3307 xmlreader::XmlReader::Text::NONE, &name, &nsId);
3308
3309 if (res == xmlreader::XmlReader::Result::Done)
3310 break;
3311
3312 if (res == xmlreader::XmlReader::Result::Begin)
3313 {
3314 if (name == "child")
3315 {
3316 size_t nChildMenuIdx = m_aMenus.size();
3317 handleChild(nullptr, &aAtkProperties, reader);
3318 bool bSubMenuInserted = m_aMenus.size() > nChildMenuIdx;
3319 if (bSubMenuInserted)
3320 pSubMenu = dynamic_cast<PopupMenu*>(m_aMenus[nChildMenuIdx].m_pMenu.get());
3321 }
3322 else
3323 {
3324 ++nLevel;
3325 if (name == "property")
3327 else if (name == "accelerator")
3328 collectAccelerator(reader, aAccelerators);
3329 }
3330 }
3331
3332 if (res == xmlreader::XmlReader::Result::End)
3333 {
3334 --nLevel;
3335 }
3336
3337 if (!nLevel)
3338 break;
3339 }
3340
3341 insertMenuObject(pParent, pSubMenu, sClass, sID, aProperties, aAtkProperties, aAccelerators);
3342}
3343
3345{
3346 m_pParserState->m_aSizeGroups.emplace_back();
3347 SizeGroup &rSizeGroup = m_pParserState->m_aSizeGroups.back();
3348
3349 int nLevel = 1;
3350
3351 while(true)
3352 {
3354 int nsId;
3355
3357 xmlreader::XmlReader::Text::NONE, &name, &nsId);
3358
3359 if (res == xmlreader::XmlReader::Result::Done)
3360 break;
3361
3362 if (res == xmlreader::XmlReader::Result::Begin)
3363 {
3364 ++nLevel;
3365 if (name == "widget")
3366 {
3367 while (reader.nextAttribute(&nsId, &name))
3368 {
3369 if (name == "name")
3370 {
3371 name = reader.getAttributeValue(false);
3372 OUString sWidget(name.begin, name.length, RTL_TEXTENCODING_UTF8);
3373 sal_Int32 nDelim = sWidget.indexOf(':');
3374 if (nDelim != -1)
3375 sWidget = sWidget.copy(0, nDelim);
3376 rSizeGroup.m_aWidgets.push_back(sWidget);
3377 }
3378 }
3379 }
3380 else
3381 {
3382 if (name == "property")
3383 collectProperty(reader, rSizeGroup.m_aProperties);
3384 }
3385 }
3386
3387 if (res == xmlreader::XmlReader::Result::End)
3388 {
3389 --nLevel;
3390 }
3391
3392 if (!nLevel)
3393 break;
3394 }
3395}
3396
3397namespace
3398{
3399 vcl::KeyCode makeKeyCode(const std::pair<OUString,OUString> &rKey)
3400 {
3401 bool bShift = rKey.second.indexOf("GDK_SHIFT_MASK") != -1;
3402 bool bMod1 = rKey.second.indexOf("GDK_CONTROL_MASK") != -1;
3403 bool bMod2 = rKey.second.indexOf("GDK_ALT_MASK") != -1;
3404 bool bMod3 = rKey.second.indexOf("GDK_MOD2_MASK") != -1;
3405
3406 if (rKey.first == "Insert")
3407 return vcl::KeyCode(KEY_INSERT, bShift, bMod1, bMod2, bMod3);
3408 else if (rKey.first == "Delete")
3409 return vcl::KeyCode(KEY_DELETE, bShift, bMod1, bMod2, bMod3);
3410 else if (rKey.first == "Return")
3411 return vcl::KeyCode(KEY_RETURN, bShift, bMod1, bMod2, bMod3);
3412 else if (rKey.first == "Up")
3413 return vcl::KeyCode(KEY_UP, bShift, bMod1, bMod2, bMod3);
3414 else if (rKey.first == "Down")
3415 return vcl::KeyCode(KEY_DOWN, bShift, bMod1, bMod2, bMod3);
3416 else if (rKey.first == "Left")
3417 return vcl::KeyCode(KEY_LEFT, bShift, bMod1, bMod2, bMod3);
3418 else if (rKey.first == "Right")
3419 return vcl::KeyCode(KEY_RIGHT, bShift, bMod1, bMod2, bMod3);
3420 else if (rKey.first == "asterisk")
3421 return vcl::KeyCode(KEY_MULTIPLY, bShift, bMod1, bMod2, bMod3);
3422 else if (rKey.first.getLength() > 1 && rKey.first[0] == 'F')
3423 {
3424 sal_uInt32 nIndex = o3tl::toUInt32(rKey.first.subView(1));
3425 assert(nIndex >= 1 && nIndex <= 26);
3426 return vcl::KeyCode(KEY_F1 + nIndex - 1, bShift, bMod1, bMod2, bMod3);
3427 }
3428
3429 assert (rKey.first.getLength() == 1);
3430 sal_Unicode cChar = rKey.first.toChar();
3431
3432 if (cChar >= 'a' && cChar <= 'z')
3433 return vcl::KeyCode(KEY_A + (cChar - 'a'), bShift, bMod1, bMod2, bMod3);
3434 else if (cChar >= 'A' && cChar <= 'Z')
3435 return vcl::KeyCode(KEY_A + (cChar - 'A'), bShift, bMod1, bMod2, bMod3);
3436 else if (cChar >= '0' && cChar <= '9')
3437 return vcl::KeyCode(KEY_0 + (cChar - 'A'), bShift, bMod1, bMod2, bMod3);
3438
3439 return vcl::KeyCode(cChar, bShift, bMod1, bMod2, bMod3);
3440 }
3441}
3442
3443void VclBuilder::insertMenuObject(Menu *pParent, PopupMenu *pSubMenu, const OUString &rClass, const OUString &rID,
3444 stringmap &rProps, stringmap &rAtkProps, accelmap &rAccels)
3445{
3446 sal_uInt16 nOldCount = pParent->GetItemCount();
3447 sal_uInt16 nNewId = ++m_pParserState->m_nLastMenuItemId;
3448
3449 if(rClass == "NotebookBarAddonsMenuMergePoint")
3450 {
3452 m_pParserState->m_nLastMenuItemId = pParent->GetItemCount();
3453 }
3454 else if (rClass == "GtkMenuItem")
3455 {
3456 OUString sLabel(BuilderUtils::convertMnemonicMarkup(extractLabel(rProps)));
3457 OUString aCommand(extractActionName(rProps));
3458 pParent->InsertItem(nNewId, sLabel, MenuItemBits::NONE , rID);
3459 pParent->SetItemCommand(nNewId, aCommand);
3460 if (pSubMenu)
3461 pParent->SetPopupMenu(nNewId, pSubMenu);
3462 }
3463 else if (rClass == "GtkCheckMenuItem")
3464 {
3465 OUString sLabel(BuilderUtils::convertMnemonicMarkup(extractLabel(rProps)));
3466 OUString aCommand(extractActionName(rProps));
3467 pParent->InsertItem(nNewId, sLabel, MenuItemBits::CHECKABLE, rID);
3468 pParent->SetItemCommand(nNewId, aCommand);
3469 }
3470 else if (rClass == "GtkRadioMenuItem")
3471 {
3472 OUString sLabel(BuilderUtils::convertMnemonicMarkup(extractLabel(rProps)));
3473 OUString aCommand(extractActionName(rProps));
3474 pParent->InsertItem(nNewId, sLabel, MenuItemBits::AUTOCHECK | MenuItemBits::RADIOCHECK, rID);
3475 pParent->SetItemCommand(nNewId, aCommand);
3476 }
3477 else if (rClass == "GtkSeparatorMenuItem")
3478 {
3479 pParent->InsertSeparator(rID);
3480 }
3481
3482 SAL_WARN_IF(nOldCount == pParent->GetItemCount(), "vcl.builder", "probably need to implement " << rClass);
3483
3484 if (nOldCount != pParent->GetItemCount())
3485 {
3486 pParent->SetHelpId(nNewId, m_sHelpRoot + rID);
3487 if (!extractVisible(rProps))
3488 pParent->HideItem(nNewId);
3489
3490 for (auto const& [ rKey, rValue ] : rProps)
3491 {
3492 if (rKey == "tooltip-markup")
3493 pParent->SetTipHelpText(nNewId, rValue);
3494 else if (rKey == "tooltip-text")
3495 pParent->SetTipHelpText(nNewId, rValue);
3496 else
3497 SAL_INFO("vcl.builder", "unhandled property: " << rKey);
3498 }
3499
3500 for (auto const& [ rKey, rValue ] : rAtkProps)
3501 {
3502 if (rKey == "AtkObject::accessible-name")
3503 pParent->SetAccessibleName(nNewId, rValue);
3504 else if (rKey == "AtkObject::accessible-description")
3505 pParent->SetAccessibleDescription(nNewId, rValue);
3506 else
3507 SAL_INFO("vcl.builder", "unhandled atk property: " << rKey);
3508 }
3509
3510 for (auto const& [ rSignal, rValue ] : rAccels)
3511 {
3512 if (rSignal == "activate")
3513 pParent->SetAccelKey(nNewId, makeKeyCode(rValue));
3514 else
3515 SAL_INFO("vcl.builder", "unhandled accelerator for: " << rSignal);
3516 }
3517 }
3518
3519 rProps.clear();
3520}
3521
3524template<typename T> static bool insertItems(vcl::Window *pWindow, VclBuilder::stringmap &rMap,
3525 std::vector<std::unique_ptr<OUString>>& rUserData,
3526 const std::vector<ComboBoxTextItem> &rItems)
3527{
3528 T *pContainer = dynamic_cast<T*>(pWindow);
3529 if (!pContainer)
3530 return false;
3531
3532 sal_uInt16 nActiveId = extractActive(rMap);
3533 for (auto const& item : rItems)
3534 {
3535 sal_Int32 nPos = pContainer->InsertEntry(item.m_sItem);
3536 if (!item.m_sId.isEmpty())
3537 {
3538 rUserData.emplace_back(std::make_unique<OUString>(item.m_sId));
3539 pContainer->SetEntryData(nPos, rUserData.back().get());
3540 }
3541 }
3542 if (nActiveId < rItems.size())
3543 pContainer->SelectEntryPos(nActiveId);
3544
3545 return true;
3546}
3547
3549{
3550 OUString sClass;
3551 OUString sID;
3552 OUString sCustomProperty;
3553
3555 int nsId;
3556
3557 while (reader.nextAttribute(&nsId, &name))
3558 {
3559 if (name == "class")
3560 {
3561 name = reader.getAttributeValue(false);
3562 sClass = OUString(name.begin, name.length, RTL_TEXTENCODING_UTF8);
3563 }
3564 else if (name == "id")
3565 {
3566 name = reader.getAttributeValue(false);
3567 sID = OUString(name.begin, name.length, RTL_TEXTENCODING_UTF8);
3568 if (m_bLegacy)
3569 {
3570 sal_Int32 nDelim = sID.indexOf(':');
3571 if (nDelim != -1)
3572 {
3573 sCustomProperty = sID.subView(nDelim+1);
3574 sID = sID.copy(0, nDelim);
3575 }
3576 }
3577 }
3578 }
3579
3580 if (sClass == "GtkListStore" || sClass == "GtkTreeStore")
3581 {
3582 handleListStore(reader, sID, sClass);
3583 return nullptr;
3584 }
3585 else if (sClass == "GtkMenu")
3586 {
3587 handleMenu(reader, sID, false);
3588 return nullptr;
3589 }
3590 else if (sClass == "GtkMenuBar")
3591 {
3592 VclPtr<Menu> xMenu = handleMenu(reader, sID, true);
3593 if (SystemWindow* pTopLevel = pParent ? pParent->GetSystemWindow() : nullptr)
3594 pTopLevel->SetMenuBar(dynamic_cast<MenuBar*>(xMenu.get()));
3595 return nullptr;
3596 }
3597 else if (sClass == "GtkSizeGroup")
3598 {
3599 handleSizeGroup(reader);
3600 return nullptr;
3601 }
3602 else if (sClass == "AtkObject")
3603 {
3604 assert((pParent || pAtkProps) && "must have one set");
3605 assert(!(pParent && pAtkProps) && "must not have both");
3606 auto aAtkProperties = handleAtkObject(reader);
3607 if (pParent)
3608 applyAtkProperties(pParent, aAtkProperties);
3609 if (pAtkProps)
3610 *pAtkProps = aAtkProperties;
3611 return nullptr;
3612 }
3613
3614 int nLevel = 1;
3615
3616 stringmap aProperties, aPangoAttributes;
3617 stringmap aAtkAttributes;
3618 std::vector<ComboBoxTextItem> aItems;
3619
3620 if (!sCustomProperty.isEmpty())
3621 aProperties["customproperty"] = sCustomProperty;
3622
3623 VclPtr<vcl::Window> pCurrentChild;
3624 while(true)
3625 {
3627 xmlreader::XmlReader::Text::NONE, &name, &nsId);
3628
3629 if (res == xmlreader::XmlReader::Result::Done)
3630 break;
3631
3632 if (res == xmlreader::XmlReader::Result::Begin)
3633 {
3634 if (name == "child")
3635 {
3636 if (!pCurrentChild)
3637 {
3638 pCurrentChild = insertObject(pParent, sClass, sID,
3639 aProperties, aPangoAttributes, aAtkAttributes);
3640 }
3641 handleChild(pCurrentChild, nullptr, reader);
3642 }
3643 else if (name == "items")
3644 aItems = handleItems(reader);
3645 else if (name == "style")
3646 {
3647 int nPriority = 0;
3648 std::vector<vcl::EnumContext::Context> aContext = handleStyle(reader, nPriority);
3649 if (nPriority != 0)
3650 {
3651 vcl::IPrioritable* pPrioritable = dynamic_cast<vcl::IPrioritable*>(pCurrentChild.get());
3652 SAL_WARN_IF(!pPrioritable, "vcl", "priority set for not supported item");
3653 if (pPrioritable)
3654 pPrioritable->SetPriority(nPriority);
3655 }
3656 if (!aContext.empty())
3657 {
3658 vcl::IContext* pContextControl = dynamic_cast<vcl::IContext*>(pCurrentChild.get());
3659 SAL_WARN_IF(!pContextControl, "vcl", "context set for not supported item");
3660 if (pContextControl)
3661 pContextControl->SetContext(std::move(aContext));
3662 }
3663 }
3664 else
3665 {
3666 ++nLevel;
3667 if (name == "property")
3669 else if (name == "attribute")
3670 collectPangoAttribute(reader, aPangoAttributes);
3671 else if (name == "relation")
3672 collectAtkRelationAttribute(reader, aAtkAttributes);
3673 else if (name == "role")
3674 collectAtkRoleAttribute(reader, aAtkAttributes);
3675 else if (name == "action-widget")
3676 handleActionWidget(reader);
3677 }
3678 }
3679
3680 if (res == xmlreader::XmlReader::Result::End)
3681 {
3682 --nLevel;
3683 }
3684
3685 if (!nLevel)
3686 break;
3687 }
3688
3689 if (sClass == "GtkAdjustment")
3690 {
3691 m_pParserState->m_aAdjustments[sID] = aProperties;
3692 return nullptr;
3693 }
3694 else if (sClass == "GtkTextBuffer")
3695 {
3696 m_pParserState->m_aTextBuffers[sID] = aProperties;
3697 return nullptr;
3698 }
3699
3700 if (!pCurrentChild)
3701 {
3702 pCurrentChild = insertObject(pParent, sClass, sID, aProperties,
3703 aPangoAttributes, aAtkAttributes);
3704 }
3705
3706 if (!aItems.empty())
3707 {
3708 // try to fill-in the items
3709 if (!insertItems<ComboBox>(pCurrentChild, aProperties, m_aUserData, aItems))
3710 insertItems<ListBox>(pCurrentChild, aProperties, m_aUserData, aItems);
3711 }
3712
3713 return pCurrentChild;
3714}
3715
3717{
3719 int nsId;
3720
3721 int nLevel = 1;
3722
3723 while(true)
3724 {
3726 xmlreader::XmlReader::Text::NONE, &name, &nsId);
3727
3728 if (res == xmlreader::XmlReader::Result::Done)
3729 break;
3730
3731 if (res == xmlreader::XmlReader::Result::Begin)
3732 {
3733 ++nLevel;
3734 if (name == "property")
3735 applyPackingProperty(pCurrent, pParent, reader);
3736 }
3737
3738 if (res == xmlreader::XmlReader::Result::End)
3739 {
3740 --nLevel;
3741 }
3742
3743 if (!nLevel)
3744 break;
3745 }
3746}
3747
3749 vcl::Window *pParent,
3750 xmlreader::XmlReader &reader)
3751{
3752 if (!pCurrent)
3753 return;
3754
3755 //ToolBoxItems are not true widgets just elements
3756 //of the ToolBox itself
3757 ToolBox *pToolBoxParent = nullptr;
3758 if (pCurrent == pParent)
3759 pToolBoxParent = dynamic_cast<ToolBox*>(pParent);
3760
3762 int nsId;
3763
3764 if (pCurrent->GetType() == WindowType::SCROLLWINDOW)
3765 {
3766 auto aFind = m_pParserState->m_aRedundantParentWidgets.find(VclPtr<vcl::Window>(pCurrent));
3767 if (aFind != m_pParserState->m_aRedundantParentWidgets.end())
3768 {
3769 pCurrent = aFind->second;
3770 assert(pCurrent);
3771 }
3772 }
3773
3774 while (reader.nextAttribute(&nsId, &name))
3775 {
3776 if (name == "name")
3777 {
3778 name = reader.getAttributeValue(false);
3779 OString sKey(name.begin, name.length);
3780 sKey = sKey.replace('_', '-');
3781 (void)reader.nextItem(
3782 xmlreader::XmlReader::Text::Raw, &name, &nsId);
3783 OString sValue(name.begin, name.length);
3784
3785 if (sKey == "expand" || sKey == "resize")
3786 {
3787 bool bTrue = (!sValue.isEmpty() && (sValue[0] == 't' || sValue[0] == 'T' || sValue[0] == '1'));
3788 if (pToolBoxParent)
3789 pToolBoxParent->SetItemExpand(m_pParserState->m_nLastToolbarId, bTrue);
3790 else
3791 pCurrent->set_expand(bTrue);
3792 continue;
3793 }
3794
3795 if (pToolBoxParent)
3796 continue;
3797
3798 if (sKey == "fill")
3799 {
3800 bool bTrue = (!sValue.isEmpty() && (sValue[0] == 't' || sValue[0] == 'T' || sValue[0] == '1'));
3801 pCurrent->set_fill(bTrue);
3802 }
3803 else if (sKey == "pack-type")
3804 {
3805 VclPackType ePackType = (!sValue.isEmpty() && (sValue[0] == 'e' || sValue[0] == 'E')) ? VclPackType::End : VclPackType::Start;
3806 pCurrent->set_pack_type(ePackType);
3807 }
3808 else if (sKey == "left-attach")
3809 {
3810 pCurrent->set_grid_left_attach(sValue.toInt32());
3811 }
3812 else if (sKey == "top-attach")
3813 {
3814 pCurrent->set_grid_top_attach(sValue.toInt32());
3815 }
3816 else if (sKey == "width")
3817 {
3818 pCurrent->set_grid_width(sValue.toInt32());
3819 }
3820 else if (sKey == "height")
3821 {
3822 pCurrent->set_grid_height(sValue.toInt32());
3823 }
3824 else if (sKey == "padding")
3825 {
3826 pCurrent->set_padding(sValue.toInt32());
3827 }
3828 else if (sKey == "position")
3829 {
3830 set_window_packing_position(pCurrent, sValue.toInt32());
3831 }
3832 else if (sKey == "secondary")
3833 {
3834 pCurrent->set_secondary(toBool(sValue));
3835 }
3836 else if (sKey == "non-homogeneous")
3837 {
3838 pCurrent->set_non_homogeneous(toBool(sValue));
3839 }
3840 else if (sKey == "homogeneous")
3841 {
3842 pCurrent->set_non_homogeneous(!toBool(sValue));
3843 }
3844 else
3845 {
3846 SAL_WARN_IF(sKey != "shrink", "vcl.builder", "unknown packing: " << sKey);
3847 }
3848 }
3849 }
3850}
3851
3852std::vector<vcl::EnumContext::Context> VclBuilder::handleStyle(xmlreader::XmlReader &reader, int &nPriority)
3853{
3854 std::vector<vcl::EnumContext::Context> aContext;
3855
3857 int nsId;
3858
3859 int nLevel = 1;
3860
3861 while(true)
3862 {
3864 xmlreader::XmlReader::Text::NONE, &name, &nsId);
3865
3866 if (res == xmlreader::XmlReader::Result::Done)
3867 break;
3868
3869 if (res == xmlreader::XmlReader::Result::Begin)
3870 {
3871 ++nLevel;
3872 if (name == "class")
3873 {
3874 OUString classStyle = getStyleClass(reader);
3875 OUString rest;
3876
3877 if (classStyle.startsWith("context-", &rest))
3878 {
3879 aContext.push_back(vcl::EnumContext::GetContextEnum(rest));
3880 }
3881 else if (classStyle.startsWith("priority-", &rest))
3882 {
3883 nPriority = rest.toInt32();
3884 }
3885 else if (classStyle != "small-button" && classStyle != "destructive-action" && classStyle != "suggested-action")
3886 {
3887 SAL_WARN("vcl.builder", "unknown class: " << classStyle);
3888 }
3889 }
3890 }
3891
3892 if (res == xmlreader::XmlReader::Result::End)
3893 {
3894 --nLevel;
3895 }
3896
3897 if (!nLevel)
3898 break;
3899 }
3900
3901 return aContext;
3902}
3903
3905{
3907 int nsId;
3908 OUString aRet;
3909
3910 while (reader.nextAttribute(&nsId, &name))
3911 {
3912 if (name == "name")
3913 {
3914 name = reader.getAttributeValue(false);
3915 aRet = OUString (name.begin, name.length, RTL_TEXTENCODING_UTF8);
3916 }
3917 }
3918
3919 return aRet;
3920}
3921
3923{
3925 int nsId;
3926
3927 OUString sProperty;
3928 OString sContext;
3929
3930 bool bTranslated = false;
3931
3932 while (reader.nextAttribute(&nsId, &name))
3933 {
3934 if (name == "name")
3935 {
3936 name = reader.getAttributeValue(false);
3937 sProperty = OUString(name.begin, name.length, RTL_TEXTENCODING_UTF8);
3938 }
3939 else if (name == "context")
3940 {
3941 name = reader.getAttributeValue(false);
3942 sContext = OString(name.begin, name.length);
3943 }
3944 else if (name == "translatable" && reader.getAttributeValue(false) == "yes")
3945 {
3946 bTranslated = true;
3947 }
3948 }
3949
3950 (void)reader.nextItem(xmlreader::XmlReader::Text::Raw, &name, &nsId);
3951 OString sValue(name.begin, name.length);
3952 OUString sFinalValue;
3953 if (bTranslated)
3954 {
3955 sFinalValue = Translate::get(TranslateId{sContext.getStr(), sValue.getStr()}, m_pParserState->m_aResLocale);
3956 }
3957 else
3958 sFinalValue = OUString::fromUtf8(sValue);
3959
3960 if (!sProperty.isEmpty())
3961 {
3962 sProperty = sProperty.replace('_', '-');
3963 if (m_pStringReplace)
3964 sFinalValue = (*m_pStringReplace)(sFinalValue);
3965 rMap[sProperty] = sFinalValue;
3966 }
3967}
3968
3970{
3972 int nsId;
3973
3974 OString sResponse;
3975
3976 while (reader.nextAttribute(&nsId, &name))
3977 {
3978 if (name == "response")
3979 {
3980 name = reader.getAttributeValue(false);
3981 sResponse = OString(name.begin, name.length);
3982 }
3983 }
3984
3985 (void)reader.nextItem(xmlreader::XmlReader::Text::Raw, &name, &nsId);
3986 OUString sID(name.begin, name.length, RTL_TEXTENCODING_UTF8);
3987 sal_Int32 nDelim = sID.indexOf(':');
3988 if (nDelim != -1)
3989 sID = sID.copy(0, nDelim);
3990 set_response(sID, sResponse.toInt32());
3991}
3992
3994{
3996 int nsId;
3997
3998 OUString sProperty;
3999 OUString sValue;
4000 OUString sModifiers;
4001
4002 while (reader.nextAttribute(&nsId, &name))
4003 {
4004 if (name == "key")
4005 {
4006 name = reader.getAttributeValue(false);
4007 sValue = OUString(name.begin, name.length, RTL_TEXTENCODING_UTF8);
4008 }
4009 else if (name == "signal")
4010 {
4011 name = reader.getAttributeValue(false);
4012 sProperty = OUString(name.begin, name.length, RTL_TEXTENCODING_UTF8);
4013 }
4014 else if (name == "modifiers")
4015 {
4016 name = reader.getAttributeValue(false);
4017 sModifiers = OUString(name.begin, name.length, RTL_TEXTENCODING_UTF8);
4018 }
4019 }
4020
4021 if (!sProperty.isEmpty() && !sValue.isEmpty())
4022 {
4023 rMap[sProperty] = std::make_pair(sValue, sModifiers);
4024 }
4025}
4026
4028{
4029 return m_aChildren.empty() ? nullptr : m_aChildren[0].m_pWindow.get();
4030}
4031
4032vcl::Window *VclBuilder::get_by_name(std::u16string_view sID)
4033{
4034 for (auto const& child : m_aChildren)
4035 {
4036 if (child.m_sID == sID)
4037 return child.m_pWindow;
4038 }
4039
4040 return nullptr;
4041}
4042
4043PopupMenu *VclBuilder::get_menu(std::u16string_view sID)
4044{
4045 for (auto const& menu : m_aMenus)
4046 {
4047 if (menu.m_sID == sID)
4048 return dynamic_cast<PopupMenu*>(menu.m_pMenu.get());
4049 }
4050
4051 return nullptr;
4052}
4053
4054void VclBuilder::set_response(std::u16string_view sID, short nResponse)
4055{
4056 switch (nResponse)
4057 {
4058 case -5:
4059 nResponse = RET_OK;
4060 break;
4061 case -6:
4062 nResponse = RET_CANCEL;
4063 break;
4064 case -7:
4065 nResponse = RET_CLOSE;
4066 break;
4067 case -8:
4068 nResponse = RET_YES;
4069 break;
4070 case -9:
4071 nResponse = RET_NO;
4072 break;
4073 case -11:
4074 nResponse = RET_HELP;
4075 break;
4076 default:
4077 assert(nResponse >= 100 && "keep non-canned responses in range 100+ to avoid collision with vcl RET_*");
4078 break;
4079 }
4080
4081 for (const auto & child : m_aChildren)
4082 {
4083 if (child.m_sID == sID)
4084 {
4085 PushButton* pPushButton = dynamic_cast<PushButton*>(child.m_pWindow.get());
4086 assert(pPushButton);
4087 Dialog* pDialog = pPushButton->GetParentDialog();
4088 assert(pDialog);
4089 pDialog->add_button(pPushButton, nResponse, false);
4090 return;
4091 }
4092 }
4093
4094 assert(false);
4095}
4096
4097void VclBuilder::delete_by_name(const OUString& sID)
4098{
4099 auto aI = std::find_if(m_aChildren.begin(), m_aChildren.end(),
4100 [&sID](WinAndId& rItem) { return rItem.m_sID == sID; });
4101 if (aI != m_aChildren.end())
4102 {
4103 aI->m_pWindow.disposeAndClear();
4104 m_aChildren.erase(aI);
4105 }
4106}
4107
4109{
4110 drop_ownership(pWindow);
4111 pWindow->disposeOnce();
4112}
4113
4115{
4116 auto aI = std::find_if(m_aChildren.begin(), m_aChildren.end(),
4117 [&pWindow](WinAndId& rItem) { return rItem.m_pWindow == pWindow; });
4118 if (aI != m_aChildren.end())
4119 m_aChildren.erase(aI);
4120}
4121
4122OUString VclBuilder::get_by_window(const vcl::Window *pWindow) const
4123{
4124 for (auto const& child : m_aChildren)
4125 {
4126 if (child.m_pWindow == pWindow)
4127 return child.m_sID;
4128 }
4129
4130 return {};
4131}
4132
4134{
4135 //We've stored the return of new Control, some of these get
4136 //border windows placed around them which are what you get
4137 //from GetChild, so scoot up a level if necessary to get the
4138 //window whose position value we have
4139 const vcl::Window *pPropHolder = pWindow->ImplGetWindow();
4140
4141 for (auto const& child : m_aChildren)
4142 {
4143 if (child.m_pWindow == pPropHolder)
4144 return child.m_aPackingData;
4145 }
4146
4147 return PackingData();
4148}
4149
4150void VclBuilder::set_window_packing_position(const vcl::Window *pWindow, sal_Int32 nPosition)
4151{
4152 for (auto & child : m_aChildren)
4153 {
4154 if (child.m_pWindow == pWindow)
4155 child.m_aPackingData.m_nPosition = nPosition;
4156 }
4157}
4158
4160{
4161 const auto aI = m_pParserState->m_aModels.find(sID);
4162 if (aI != m_pParserState->m_aModels.end())
4163 return &(aI->second);
4164 return nullptr;
4165}
4166
4168{
4169 const auto aI = m_pParserState->m_aTextBuffers.find(sID);
4170 if (aI != m_pParserState->m_aTextBuffers.end())
4171 return &(aI->second);
4172 return nullptr;
4173}
4174
4176{
4177 const auto aI = m_pParserState->m_aAdjustments.find(sID);
4178 if (aI != m_pParserState->m_aAdjustments.end())
4179 return &(aI->second);
4180 return nullptr;
4181}
4182
4183void VclBuilder::mungeModel(ComboBox &rTarget, const ListStore &rStore, sal_uInt16 nActiveId)
4184{
4185 for (auto const& entry : rStore.m_aEntries)
4186 {
4187 const ListStore::row &rRow = entry;
4188 sal_uInt16 nEntry = rTarget.InsertEntry(rRow[0]);
4189 if (rRow.size() > 1)
4190 {
4191 if (m_bLegacy)
4192 {
4193 sal_Int32 nValue = rRow[1].toInt32();
4194 rTarget.SetEntryData(nEntry, reinterpret_cast<void*>(nValue));
4195 }
4196 else
4197 {
4198 if (!rRow[1].isEmpty())
4199 {
4200 m_aUserData.emplace_back(std::make_unique<OUString>(rRow[1]));
4201 rTarget.SetEntryData(nEntry, m_aUserData.back().get());
4202 }
4203 }
4204 }
4205 }
4206 if (nActiveId < rStore.m_aEntries.size())
4207 rTarget.SelectEntryPos(nActiveId);
4208}
4209
4210void VclBuilder::mungeModel(ListBox &rTarget, const ListStore &rStore, sal_uInt16 nActiveId)
4211{
4212 for (auto const& entry : rStore.m_aEntries)
4213 {
4214 const ListStore::row &rRow = entry;
4215 sal_uInt16 nEntry = rTarget.InsertEntry(rRow[0]);
4216 if (rRow.size() > 1)
4217 {
4218 if (m_bLegacy)
4219 {
4220 sal_Int32 nValue = rRow[1].toInt32();
4221 rTarget.SetEntryData(nEntry, reinterpret_cast<void*>(nValue));
4222 }
4223 else
4224 {
4225 if (!rRow[1].isEmpty())
4226 {
4227 m_aUserData.emplace_back(std::make_unique<OUString>(rRow[1]));
4228 rTarget.SetEntryData(nEntry, m_aUserData.back().get());
4229 }
4230 }
4231 }
4232 }
4233 if (nActiveId < rStore.m_aEntries.size())
4234 rTarget.SelectEntryPos(nActiveId);
4235}
4236
4237void VclBuilder::mungeModel(SvTabListBox& rTarget, const ListStore &rStore, sal_uInt16 nActiveId)
4238{
4239 for (auto const& entry : rStore.m_aEntries)
4240 {
4241 const ListStore::row &rRow = entry;
4242 auto pEntry = rTarget.InsertEntry(rRow[0]);
4243 if (rRow.size() > 1)
4244 {
4245 if (m_bLegacy)
4246 {
4247 sal_Int32 nValue = rRow[1].toInt32();
4248 pEntry->SetUserData(reinterpret_cast<void*>(nValue));
4249 }
4250 else
4251 {
4252 if (!rRow[1].isEmpty())
4253 {
4254 m_aUserData.emplace_back(std::make_unique<OUString>(rRow[1]));
4255 pEntry->SetUserData(m_aUserData.back().get());
4256 }
4257 }
4258 }
4259 }
4260 if (nActiveId < rStore.m_aEntries.size())
4261 {
4262 SvTreeListEntry* pEntry = rTarget.GetEntry(nullptr, nActiveId);
4263 rTarget.Select(pEntry);
4264 }
4265}
4266
4267void VclBuilder::mungeAdjustment(NumericFormatter &rTarget, const Adjustment &rAdjustment)
4268{
4269 int nMul = rtl_math_pow10Exp(1, rTarget.GetDecimalDigits());
4270
4271 for (auto const& [ rKey, rValue ] : rAdjustment)
4272 {
4273 if (rKey == "upper")
4274 {
4275 sal_Int64 nUpper = rValue.toDouble() * nMul;
4276 rTarget.SetMax(nUpper);
4277 rTarget.SetLast(nUpper);
4278 }
4279 else if (rKey == "lower")
4280 {
4281 sal_Int64 nLower = rValue.toDouble() * nMul;
4282 rTarget.SetMin(nLower);
4283 rTarget.SetFirst(nLower);
4284 }
4285 else if (rKey == "value")
4286 {
4287 sal_Int64 nValue = rValue.toDouble() * nMul;
4288 rTarget.SetValue(nValue);
4289 }
4290 else if (rKey == "step-increment")
4291 {
4292 sal_Int64 nSpinSize = rValue.toDouble() * nMul;
4293 rTarget.SetSpinSize(nSpinSize);
4294 }
4295 else
4296 {
4297 SAL_INFO("vcl.builder", "unhandled property :" << rKey);
4298 }
4299 }
4300}
4301
4303{
4304 double nMaxValue = 0, nMinValue = 0, nValue = 0, nSpinSize = 0;
4305
4306 for (auto const& [ rKey, rValue ] : rAdjustment)
4307 {
4308 if (rKey == "upper")
4309 nMaxValue = rValue.toDouble();
4310 else if (rKey == "lower")
4311 nMinValue = rValue.toDouble();
4312 else if (rKey == "value")
4313 nValue = rValue.toDouble();
4314 else if (rKey == "step-increment")
4315 nSpinSize = rValue.toDouble();
4316 else
4317 SAL_INFO("vcl.builder", "unhandled property :" << rKey);
4318 }
4319
4320 Formatter& rFormatter = rTarget.GetFormatter();
4321 rFormatter.SetMinValue(nMinValue);
4322 rFormatter.SetMaxValue(nMaxValue);
4323 rFormatter.SetValue(nValue);
4324 rFormatter.SetSpinSize(nSpinSize);
4325}
4326
4327void VclBuilder::mungeAdjustment(ScrollBar &rTarget, const Adjustment &rAdjustment)
4328{
4329 for (auto const& [ rKey, rValue ] : rAdjustment)
4330 {
4331 if (rKey == "upper")
4332 rTarget.SetRangeMax(rValue.toInt32());
4333 else if (rKey == "lower")
4334 rTarget.SetRangeMin(rValue.toInt32());
4335 else if (rKey == "value")
4336 rTarget.SetThumbPos(rValue.toInt32());
4337 else if (rKey == "step-increment")
4338 rTarget.SetLineSize(rValue.toInt32());
4339 else if (rKey == "page-increment")
4340 rTarget.SetPageSize(rValue.toInt32());
4341 else
4342 {
4343 SAL_INFO("vcl.builder", "unhandled property :" << rKey);
4344 }
4345 }
4346}
4347
4348void VclBuilder::mungeAdjustment(Slider& rTarget, const Adjustment& rAdjustment)
4349{
4350 for (auto const& [ rKey, rValue ] : rAdjustment)
4351 {
4352 if (rKey == "upper")
4353 rTarget.SetRangeMax(rValue.toInt32());
4354 else if (rKey == "lower")
4355 rTarget.SetRangeMin(rValue.toInt32());
4356 else if (rKey == "value")
4357 rTarget.SetThumbPos(rValue.toInt32());
4358 else if (rKey == "step-increment")
4359 rTarget.SetLineSize(rValue.toInt32());
4360 else if (rKey == "page-increment")
4361 rTarget.SetPageSize(rValue.toInt32());
4362 else
4363 {
4364 SAL_INFO("vcl.builder", "unhandled property :" << rKey);
4365 }
4366 }
4367}
4368
4370{
4371 for (auto const& [ rKey, rValue ] : rTextBuffer)
4372 {
4373 if (rKey == "text")
4374 rTarget.SetText(rValue);
4375 else
4376 {
4377 SAL_INFO("vcl.builder", "unhandled property :" << rKey);
4378 }
4379 }
4380}
4381
4383 : m_nLastToolbarId(0)
4384 , m_nLastMenuItemId(0)
4385{}
4386
4388 : m_sID(std::move(aId))
4389 , m_pMenu(pMenu)
4390{}
4391
4392/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
OptionalString sType
PropertiesInfo aProperties
css::uno::Reference< css::lang::XComponent > m_xFrame
sal_uInt16 nPageId
static bool insertItems(vcl::Window *pWindow, VclBuilder::stringmap &rMap, std::vector< std::unique_ptr< OUString > > &rUserData, const std::vector< ComboBoxTextItem > &rItems)
Insert items to a ComboBox or a ListBox.
Definition: builder.cxx:3524
std::map< OUString, std::shared_ptr< NoAutoUnloadModule > > ModuleMap
Definition: builder.cxx:1435
static ModuleMap g_aModuleMap
Definition: builder.cxx:1436
#define SAL_DLLPREFIX
Definition: builder.cxx:1443
static void thisModule()
Definition: builder.cxx:1422
static bool toBool(std::string_view rValue)
Definition: builder.cxx:92
static OUString GetUIRootDir()
Definition: dialog.cxx:557
const LocaleDataWrapper & GetLocaleDataWrapper() const
static weld::Window * GetFrameWeld(const css::uno::Reference< css::awt::XWindow > &rWindow)
Definition: builder.cxx:225
static std::unique_ptr< weld::Builder > CreateInterimBuilder(vcl::Window *pParent, const OUString &rUIFile, bool bAllowCycleFocusOut, sal_uInt64 nLOKWindowId=0)
Definition: builder.cxx:201
static const AllSettings & GetSettings()
Gets the application's settings.
Definition: svapp.cxx:638
static std::unique_ptr< weld::Builder > CreateBuilder(weld::Widget *pParent, const OUString &rUIFile, bool bMobile=false, sal_uInt64 nLOKWindowId=0)
Definition: builder.cxx:186
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, const ILibreOfficeKitNotifier *pNotifier=nullptr)
Definition: builder.cxx:215
void SetSmallSymbol()
Definition: button.cxx:533
void SetImageAlign(ImageAlign eAlign)
Definition: button.cxx:153
void SetCommandHandler(const OUString &aCommand, const css::uno::Reference< css::frame::XFrame > &rFrame)
Setup handler for UNO commands so that commands like .uno:Something are handled automagically by this...
Definition: button.cxx:119
void SetModeImage(const Image &rImage)
Definition: button.cxx:133
void EnableTriState(bool bTriState=true)
Definition: button.cxx:3615
void SetState(TriState eState)
Definition: button.cxx:3593
A widget used to choose from a list of items and which has an entry.
Definition: combobox.hxx:39
virtual void SetText(const OUString &rStr) override
Definition: ctrl.cxx:98
virtual Size GetOptimalSize() const override
Definition: ctrl.cxx:369
static void addKeyValue(SAL_UNUSED_PARAMETER const OUString &, SAL_UNUSED_PARAMETER const OUString &, SAL_UNUSED_PARAMETER tAddKeyHandling)
InitFlag
Definition: dialog.hxx:44
@ NoParent
No Parent.
@ Default
Use given parent or get a default one using GetDefaultParent(...)
void add_button(PushButton *pButton, int nResponse, bool bTransferOwnership)
Definition: dialog.cxx:1456
virtual void doDeferredInit(WinBits nBits)
Definition: dockwin.cxx:363
const Image & GetImage() const
Definition: fixed.hxx:171
static Image loadThemeImage(const OUString &rFileName)
Definition: fixed.cxx:956
void SetImage(const Image &rImage)
Definition: fixed.cxx:946
void set_mnemonic_widget(vcl::Window *pWindow)
Definition: fixed.cxx:406
void SetValue(double dVal)
Definition: fmtfield.cxx:861
virtual void SetMaxValue(double dMax)
Definition: fmtfield.cxx:714
virtual void SetMinValue(double dMin)
Definition: fmtfield.cxx:704
virtual void SetSpinSize(double dStep)
Definition: formatter.hxx:227
Definition: image.hxx:40
OUString GetStock() const
Definition: Image.cxx:81
Size GetSizePixel() const
Definition: Image.cxx:88
static std::unique_ptr< JSInstanceBuilder > CreateSidebarBuilder(weld::Widget *pParent, const OUString &rUIRoot, const OUString &rUIFile, sal_uInt64 nLOKWindowId=0)
static std::unique_ptr< JSInstanceBuilder > CreateNotebookbarBuilder(vcl::Window *pParent, const OUString &rUIRoot, const OUString &rUIFile, const css::uno::Reference< css::frame::XFrame > &rFrame, sal_uInt64 nWindowId=0)
static std::unique_ptr< JSInstanceBuilder > CreateFormulabarBuilder(vcl::Window *pParent, const OUString &rUIRoot, const OUString &rUIFile, sal_uInt64 nLOKWindowId)
static std::unique_ptr< JSInstanceBuilder > CreatePopupBuilder(weld::Widget *pParent, const OUString &rUIRoot, const OUString &rUIFile)
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, const vcl::ILibreOfficeKitNotifier *pNotifier=nullptr)
static std::unique_ptr< JSInstanceBuilder > CreateDialogBuilder(weld::Widget *pParent, const OUString &rUIRoot, const OUString &rUIFile)
A widget used to choose from a list of items and which has no entry.
Definition: lstbox.hxx:83
OUString getNum(sal_Int64 nNumber, sal_uInt16 nDecimals, bool bUseThousandSep=true, bool bTrailingZeros=true) const
const LanguageTag & getLanguageTag() const
void SetPopupMenu(PopupMenu *pNewMenu)
Definition: menubtn.cxx:241
Definition: menu.hxx:116
void set_id(const OUString &rID)
Sets an ID.
Definition: menu.hxx:398
void InsertSeparator(const OUString &rIdent={}, sal_uInt16 nPos=MENU_APPEND)
Definition: menu.cxx:472
void SetHelpId(sal_uInt16 nItemId, const OUString &rHelpId)
Definition: menu.cxx:1148
void SetAccessibleName(sal_uInt16 nItemId, const OUString &rStr)
Definition: menu.cxx:2296
void SetAccessibleDescription(sal_uInt16 nItemId, const OUString &rStr)
Definition: menu.cxx:2318
void SetAccelKey(sal_uInt16 nItemId, const vcl::KeyCode &rKeyCode)
Definition: menu.cxx:785
void SetTipHelpText(sal_uInt16 nItemId, const OUString &rString)
Definition: menu.cxx:1130
void SetItemCommand(sal_uInt16 nItemId, const OUString &rCommand)
Definition: menu.cxx:1054
void SetPopupMenu(sal_uInt16 nItemId, PopupMenu *pMenu)
Definition: menu.cxx:738
void HideItem(sal_uInt16 nItemId)
Definition: menu.hxx:290
void InsertItem(sal_uInt16 nItemId, const OUString &rStr, MenuItemBits nItemBits=MenuItemBits::NONE, const OUString &rIdent={}, sal_uInt16 nPos=MENU_APPEND)
Definition: menu.cxx:432
sal_uInt16 GetItemCount() const
Definition: menu.cxx:577
void SetDropDown(PushButtonDropdownStyle nStyle)
Definition: button.cxx:1644
void SetSymbol(SymbolType eSymbol)
Definition: button.cxx:1630
std::shared_ptr< std::vector< VclPtr< RadioButton > > > m_xGroup
Definition: button.hxx:383
void group(RadioButton &rOther)
Definition: button.cxx:2274
void SetModeRadioImage(const Image &rImage)
Definition: button.cxx:2713
virtual std::unique_ptr< weld::Builder > CreateBuilder(weld::Widget *pParent, const OUString &rUIRoot, const OUString &rUIFile)
virtual weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage)
virtual std::unique_ptr< weld::Builder > CreateInterimBuilder(vcl::Window *pParent, const OUString &rUIRoot, const OUString &rUIFile, bool bAllowCycleFocusOut, sal_uInt64 nLOKWindowId=0)
virtual weld::Window * GetFrameWeld(const css::uno::Reference< css::awt::XWindow > &rWindow)
constexpr tools::Long Height() const
tools::Long AdjustHeight(tools::Long n)
tools::Long AdjustWidth(tools::Long n)
void setHeight(tools::Long nHeight)
constexpr tools::Long Width() const
HeaderBar * GetHeaderBar()
Definition: svtabbx.cxx:522
void SetSpaceBetweenEntries(short nSpace)
void SetEntryHeight(short nHeight)
void SetHighlightRange(sal_uInt16 nFirstTab=0, sal_uInt16 nLastTab=0xffff)
void SetNoAutoCurEntry(bool b)
void SetQuickSearch(bool bEnable)
virtual void doDeferredInit(WinBits nBits)
Definition: syswin.cxx:1105
sal_uInt16 GetPageCount() const
Definition: tabctrl.cxx:1777
void SetAccessibleDescription(sal_uInt16 nItemId, const OUString &rStr)
Definition: tabctrl.cxx:1978
void SetTabPage(sal_uInt16 nPageId, TabPage *pPage)
Definition: tabctrl.cxx:1881
void SetAccessibleName(sal_uInt16 nItemId, const OUString &rStr)
Definition: tabctrl.cxx:1962
void SetPageName(sal_uInt16 nPageId, const OUString &rName) const
Definition: tabctrl.cxx:1994
TabPage * GetTabPage(sal_uInt16 nPageId) const
Definition: tabctrl.cxx:1907
void SetCurPageId(sal_uInt16 nPageId)
Definition: tabctrl.cxx:1819
void InsertPage(sal_uInt16 nPageId, const OUString &rText, sal_uInt16 nPos=TAB_APPEND)
Definition: tabctrl.cxx:1638
sal_uInt16 GetCurPageId() const
Definition: tabctrl.cxx:1853
sal_uInt16 GetPageId(sal_uInt16 nPos) const
Definition: tabctrl.cxx:1782
void SetHelpText(sal_uInt16 nPageId, const OUString &rText)
Definition: tabctrl.cxx:1946
void SetPageText(sal_uInt16 nPageId, const OUString &rText)
Definition: tabctrl.cxx:1917
void RemovePage(sal_uInt16 nPageId)
Definition: tabctrl.cxx:1687
A toolbar: contains all those icons, typically below the menu bar.
Definition: toolbox.hxx:74
ToolBoxItemId GetItemId(ImplToolItems::size_type nPos) const
Definition: toolbox2.cxx:746
void SetQuickHelpText(ToolBoxItemId nItemId, const OUString &rText)
Definition: toolbox2.cxx:1321
void InsertSeparator(ImplToolItems::size_type nPos=APPEND, sal_uInt16 nPixSize=0)
Definition: toolbox2.cxx:503
ImplToolItems::size_type GetItemCount() const
Definition: toolbox2.cxx:712
void SetItemExpand(ToolBoxItemId nItemId, bool bExpand)
Definition: toolbox2.cxx:914
void SetItemWindow(ToolBoxItemId nItemId, vcl::Window *pNewWindow)
Definition: toolbox2.cxx:1058
virtual void InsertItem(const OUString &rCommand, const css::uno::Reference< css::frame::XFrame > &rFrame, ToolBoxItemBits nBits, const Size &rRequestedSize, ImplToolItems::size_type nPos=APPEND)
Insert a command (like '.uno:Save').
Definition: toolbox2.cxx:440
void HideItem(ToolBoxItemId nItemId)
Convenience method to hide items (via ShowItem).
Definition: toolbox.hxx:396
void SetHelpId(ToolBoxItemId nItemId, const OUString &rHelpId)
Definition: toolbox2.cxx:1352
void SetItemImage(ToolBoxItemId nItemId, const Image &rImage)
Definition: toolbox2.cxx:966
bool operator()(const vcl::Window *pA, const vcl::Window *pB) const
Definition: builder.cxx:2664
void delete_by_name(const OUString &sID)
Definition: builder.cxx:4097
T * get(VclPtr< T > &ret, const OUString &sID)
Definition: builder.hxx:421
static OUString getStyleClass(xmlreader::XmlReader &reader)
Definition: builder.cxx:3904
OUString m_sHelpRoot
Definition: builder.hxx:296
void set_response(std::u16string_view sID, short nResponse)
Definition: builder.cxx:4054
stringmap m_aDeferredProperties
Definition: builder.hxx:126
static std::vector< vcl::EnumContext::Context > handleStyle(xmlreader::XmlReader &reader, int &nPriority)
Definition: builder.cxx:3852
void handleActionWidget(xmlreader::XmlReader &reader)
Definition: builder.cxx:3969
static vcl::Window * prepareWidgetOwnScrolling(vcl::Window *pParent, WinBits &rWinStyle)
Definition: builder.cxx:1391
void(* customMakeWidget)(VclPtr< vcl::Window > &rRet, const VclPtr< vcl::Window > &pParent, stringmap &rVec)
These functions create a new widget with parent pParent and return it in rRet.
Definition: builder.hxx:74
PackingData get_window_packing_data(const vcl::Window *pWindow) const
Definition: builder.cxx:4133
VclPtr< vcl::Window > m_pParent
Definition: builder.hxx:298
void extractModel(const OUString &id, stringmap &rVec)
Definition: builder.cxx:1337
void mungeModel(ListBox &rTarget, const ListStore &rStore, sal_uInt16 nActiveId)
Definition: builder.cxx:4210
const ListStore * get_model_by_name(const OUString &sID) const
Definition: builder.cxx:4159
vcl::Window * get_widget_root()
Definition: builder.cxx:4027
css::uno::Reference< css::frame::XFrame > m_xFrame
XFrame to be able to extract labels and other properties of the UNO commands (like of ....
Definition: builder.hxx:321
void extractButtonImage(const OUString &id, stringmap &rMap, bool bRadio)
Definition: builder.cxx:1367
VclPtr< Menu > handleMenu(xmlreader::XmlReader &reader, const OUString &rID, bool bMenuBar)
Definition: builder.cxx:3177
VclPtr< vcl::Window > handleObject(vcl::Window *pParent, stringmap *pAtkProps, xmlreader::XmlReader &reader)
Definition: builder.cxx:3548
static void applyAtkProperties(vcl::Window *pWindow, const stringmap &rProperties)
Definition: builder.cxx:3090
VclPtr< vcl::Window > insertObject(vcl::Window *pParent, const OUString &rClass, const OUString &rID, stringmap &rProps, stringmap &rPangoAttributes, stringmap &rAtkProps)
Definition: builder.cxx:2469
static void collectAtkRelationAttribute(xmlreader::XmlReader &reader, stringmap &rMap)
Definition: builder.cxx:2892
bool m_bToplevelHasDeferredInit
Definition: builder.hxx:299
static void mungeTextBuffer(VclMultiLineEdit &rTarget, const TextBuffer &rTextBuffer)
Definition: builder.cxx:4369
void connectNumericFormatterAdjustment(const OUString &id, const OUString &rAdjustment)
Definition: builder.cxx:1261
std::vector< WinAndId > m_aChildren
Definition: builder.hxx:153
void handleRow(xmlreader::XmlReader &reader, const OUString &rID)
Definition: builder.cxx:2941
void connectFormattedFormatterAdjustment(const OUString &id, const OUString &rAdjustment)
Definition: builder.cxx:1267
bool m_bToplevelHasDeferredProperties
Definition: builder.hxx:300
void cleanupWidgetOwnScrolling(vcl::Window *pScrollParent, vcl::Window *pWindow, stringmap &rMap)
Definition: builder.cxx:1409
std::vector< std::unique_ptr< OUString > > m_aUserData
Definition: builder.hxx:119
ResHookProc m_pStringReplace
Definition: builder.hxx:297
void extractMnemonicWidget(const OUString &id, stringmap &rMap)
Definition: builder.cxx:1377
bool m_bToplevelParentFound
Definition: builder.hxx:301
void handleListStore(xmlreader::XmlReader &reader, const OUString &rID, std::u16string_view rClass)
Definition: builder.cxx:3016
void extractBuffer(const OUString &id, stringmap &rVec)
Definition: builder.cxx:1348
static void collectAccelerator(xmlreader::XmlReader &reader, accelmap &rMap)
Definition: builder.cxx:3993
std::map< OUString, OUString > stringmap
Definition: builder.hxx:71
OUString m_sID
Definition: builder.hxx:295
void set_window_packing_position(const vcl::Window *pWindow, sal_Int32 nPosition)
Definition: builder.cxx:4150
OUString get_by_window(const vcl::Window *pWindow) const
Definition: builder.cxx:4122
void collectProperty(xmlreader::XmlReader &reader, stringmap &rVec) const
Definition: builder.cxx:3922
static void collectAtkRoleAttribute(xmlreader::XmlReader &reader, stringmap &rMap)
Definition: builder.cxx:2921
void insertMenuObject(Menu *pParent, PopupMenu *pSubMenu, const OUString &rClass, const OUString &rID, stringmap &rProps, stringmap &rAtkProps, accelmap &rAccels)
Definition: builder.cxx:3443
static int getImageSize(const stringmap &rMap)
Definition: builder.cxx:1358
std::vector< MenuAndId > m_aMenus
Definition: builder.hxx:161
std::unique_ptr< ParserState > m_pParserState
Definition: builder.hxx:303
VclBuilder(vcl::Window *pParent, const OUString &sUIRootDir, const OUString &sUIFile, OUString sID={}, css::uno::Reference< css::frame::XFrame > xFrame=css::uno::Reference< css::frame::XFrame >(), bool bLegacy=true, const NotebookBarAddonsItem *pNotebookBarAddonsItem=nullptr)
Definition: builder.cxx:446
const TextBuffer * get_buffer_by_name(const OUString &sID) const
Definition: builder.cxx:4167
stringmap handleAtkObject(xmlreader::XmlReader &reader) const
Definition: builder.cxx:3054
void extractGroup(const OUString &id, stringmap &rVec)
Definition: builder.cxx:1247
const Adjustment * get_adjustment_by_name(const OUString &sID) const
Definition: builder.cxx:4175
void handleChild(vcl::Window *pParent, stringmap *pAtkProps, xmlreader::XmlReader &reader)
Definition: builder.cxx:2729
std::map< OUString, std::pair< OUString, OUString > > accelmap
Definition: builder.hxx:72
void handleMenuObject(Menu *pParent, xmlreader::XmlReader &reader)
Definition: builder.cxx:3262
void drop_ownership(const vcl::Window *pWindow)
Definition: builder.cxx:4114
void setDeferredProperties()
Definition: builder.cxx:2232
void handleSizeGroup(xmlreader::XmlReader &reader)
Definition: builder.cxx:3344
bool m_bLegacy
Definition: builder.hxx:302
void delete_by_window(vcl::Window *pWindow)
Definition: builder.cxx:4108
static void mungeAdjustment(NumericFormatter &rTarget, const Adjustment &rAdjustment)
Definition: builder.cxx:4267
stringmap Adjustment
Definition: builder.hxx:234
void applyPackingProperty(vcl::Window *pCurrent, vcl::Window *pParent, xmlreader::XmlReader &reader)
Definition: builder.cxx:3748
PopupMenu * get_menu(std::u16string_view sID)
Definition: builder.cxx:4043
static bool extractAdjustmentToMap(const OUString &id, stringmap &rVec, std::vector< WidgetAdjustmentMap > &rAdjustmentMap)
Definition: builder.cxx:1273
VclPtr< vcl::Window > makeObject(vcl::Window *pParent, const OUString &rClass, const OUString &rID, stringmap &rVec)
Definition: builder.cxx:1585
void disposeBuilder()
releases references and disposes all children.
Definition: builder.cxx:808
void handleTabChild(vcl::Window *pParent, xmlreader::XmlReader &reader)
Definition: builder.cxx:2547
static SymbolType mapStockToSymbol(std::u16string_view icon_name)
Definition: builder.cxx:126
void handleMenuChild(Menu *pParent, xmlreader::XmlReader &reader)
Definition: builder.cxx:3230
static void collectPangoAttribute(xmlreader::XmlReader &reader, stringmap &rMap)
Definition: builder.cxx:2866
void handlePacking(vcl::Window *pCurrent, vcl::Window *pParent, xmlreader::XmlReader &reader)
Definition: builder.cxx:3716
std::vector< ComboBoxTextItem > handleItems(xmlreader::XmlReader &reader) const
Definition: builder.cxx:3102
stringmap TextBuffer
Definition: builder.hxx:229
vcl::Window * get_by_name(std::u16string_view sID)
Definition: builder.cxx:4032
std::unique_ptr< NotebookBarAddonsItem > m_pNotebookBarAddonsItem
Definition: builder.hxx:128
vcl::Window * get_label_widget()
Definition: layout.cxx:1549
A construction helper for a temporary VclPtr.
Definition: vclptr.hxx:277
void clear()
Definition: vclptr.hxx:190
reference_type * get() const
Get the body.
Definition: vclptr.hxx:143
static VclPtr< reference_type > Create(Arg &&... arg)
A construction helper for VclPtr.
Definition: vclptr.hxx:127
bool HasVisibleBorder() const
Definition: layout.hxx:493
vcl::Window * GetPageParent()
void InsertPage(const OUString &rPageId, const OUString &rLabel, const Image &rImage, const OUString &rTooltip, VclPtr< vcl::Window > xPage, int nPos=-1)
Definition: ivctrl.cxx:555
bool mbDisabled
Definition: window.h:328
VclPtr< vcl::Window > mpRealParent
Definition: window.h:236
VclPtr< vcl::Window > mpBorderWindow
Definition: window.h:233
VclPtr< vcl::Window > mpParent
Definition: window.h:235
std::pair< const_iterator, bool > insert(Value &&x)
static OUString formatPercent(double dNumber, const LanguageTag &rLangTag)
static Context GetContextEnum(const OUString &rsContextName)
void SetStyle(WinBits nStyle)
Definition: window.cxx:1962
vcl::Window * GetParent() const
Definition: window2.cxx:1123
bool IsControlFont() const
Definition: window2.cxx:1093
void SetControlFont()
Definition: window2.cxx:438
WindowType GetType() const
Definition: window2.cxx:1000
void set_padding(sal_Int32 nPadding)
Definition: window2.cxx:1803
virtual void SetSizePixel(const Size &rNewSize)
Definition: window2.cxx:1288
Size get_preferred_size() const
Definition: window2.cxx:1694
vcl::Window * GetWindow(GetWindowType nType) const
Definition: stacking.cxx:1036
void set_border_width(sal_Int32 nBorderWidth)
Definition: window2.cxx:1869
void set_grid_left_attach(sal_Int32 nAttach)
Definition: window2.cxx:1839
Dialog * GetParentDialog() const
Definition: window2.cxx:1008
void set_height_request(sal_Int32 nHeightRequest)
Definition: window2.cxx:1644
void set_id(const OUString &rID)
Sets an ID.
Definition: window.cxx:3930
bool set_font_attribute(const OUString &rKey, std::u16string_view rValue)
Definition: window2.cxx:1412
VclPackType get_pack_type() const
Definition: window2.cxx:1785
void reorderWithinParent(sal_uInt16 nNewPosition)
Definition: stacking.cxx:163
void set_grid_height(sal_Int32 nRows)
Definition: window2.cxx:1851
WinBits GetStyle() const
Definition: window2.cxx:979
void Show(bool bVisible=true, ShowFlags nFlags=ShowFlags::NONE)
Definition: window.cxx:2187
const OUString & GetHelpId() const
Definition: window2.cxx:859
vcl::Font GetControlFont() const
Definition: window2.cxx:467
bool IsDialog() const
Definition: window2.cxx:1028
void set_pack_type(VclPackType ePackType)
Definition: window2.cxx:1791
bool get_secondary() const
Definition: window2.cxx:1957
SystemWindow * GetSystemWindow() const
Definition: stacking.cxx:807
void SetAccessibleRole(sal_uInt16 nRole)
bool IsDockingWindow() const
Definition: window2.cxx:942
SAL_DLLPRIVATE WindowImpl * ImplGetWindowImpl() const
Definition: window.hxx:528
sal_Int32 get_height_request() const
Definition: window2.cxx:1945
void add_to_size_group(const std::shared_ptr< VclSizeGroup > &xGroup)
Definition: window2.cxx:1981
sal_Int32 get_grid_left_attach() const
Definition: window2.cxx:1833
sal_Int32 get_grid_top_attach() const
Definition: window2.cxx:1857
void set_width_request(sal_Int32 nWidthRequest)
Definition: window2.cxx:1658
bool IsSystemWindow() const
Definition: window2.cxx:1023
virtual Size GetSizePixel() const
Definition: window.cxx:2402
sal_Int32 get_width_request() const
Definition: window2.cxx:1951
void set_secondary(bool bSecondary)
Definition: window2.cxx:1963
void set_expand(bool bExpand)
Definition: window2.cxx:1779
void set_grid_top_attach(sal_Int32 nAttach)
Definition: window2.cxx:1863
void SetQuickHelpText(const OUString &rHelpText)
Definition: window2.cxx:1252
virtual OUString GetText() const
Definition: window.cxx:3055
void set_fill(bool bFill)
Definition: window2.cxx:1815
void SetAccessibleRelationLabelFor(vcl::Window *pLabelFor)
vcl::Window * ImplGetWindow() const
if this is a proxy return the client, otherwise itself
Definition: window2.cxx:866
void set_non_homogeneous(bool bNonHomogeneous)
Definition: window2.cxx:1975
void SetType(WindowType nType)
Definition: window2.cxx:994
virtual bool set_property(const OUString &rKey, const OUString &rValue)
Definition: window2.cxx:1478
void set_grid_width(sal_Int32 nCols)
Definition: window2.cxx:1827
void SetAccessibleRelationLabeledBy(vcl::Window *pLabeledBy)
void SetHelpId(const OUString &)
Definition: window2.cxx:854
std::unique_ptr< Entry > m_xEntry
Definition: weld.hxx:1930
EntryTreeView(std::unique_ptr< Entry > xEntry, std::unique_ptr< TreeView > xTreeView)
Definition: builder.cxx:383
void set_height_request_by_rows(int nRows)
Definition: builder.cxx:402
std::unique_ptr< TreeView > m_xTreeView
Definition: weld.hxx:1931
void get_increments(int &step, int &page, FieldUnit eDestUnit) const
Definition: weld.hxx:2124
FieldUnit m_eSrcUnit
Definition: weld.hxx:2016
static OUString MetricToString(FieldUnit rUnit)
Definition: builder.cxx:232
void set_increments(int step, int page, FieldUnit eValueUnit)
Definition: weld.hxx:2117
void set_unit(FieldUnit eUnit)
Definition: builder.cxx:347
sal_Int64 ConvertValue(sal_Int64 nValue, FieldUnit eInUnit, FieldUnit eOutUnit) const
Definition: builder.cxx:362
void set_digits(unsigned int digits)
Definition: builder.cxx:336
void set_value(sal_Int64 nValue, FieldUnit eValueUnit)
Definition: weld.hxx:2059
OUString format_number(sal_Int64 nValue) const
Definition: builder.cxx:292
std::unique_ptr< weld::SpinButton > m_xSpinButton
Definition: weld.hxx:2017
sal_Int64 get_value(FieldUnit eDestUnit) const
Definition: weld.hxx:2064
sal_Int64 denormalize(sal_Int64 nValue) const
Definition: builder.cxx:275
virtual unsigned int get_digits() const =0
static unsigned int Power10(unsigned int n)
Definition: builder.cxx:267
virtual std::unique_ptr< TreeIter > make_iterator(const TreeIter *pOrig=nullptr) const =0
virtual bool get_row_expanded(const TreeIter &rIter) const =0
virtual bool get_iter_first(TreeIter &rIter) const =0
virtual bool iter_parent(TreeIter &rIter) const =0
virtual bool iter_next(TreeIter &rIter) const =0
virtual int iter_compare(const TreeIter &a, const TreeIter &b) const =0
virtual int get_iter_depth(const TreeIter &rIter) const =0
Result nextItem(Text reportText, Span *data, int *nsId)
bool nextAttribute(int *nsId, Span *localName)
Span getAttributeValue(bool fullyNormalize)
Any value
#define SAL_DLLEXTENSION
#define DBG_UNHANDLED_EXCEPTION(...)
float u
#define max(a, b)
FilterGroup & rTarget
FieldUnit
sal_Int16 nValue
TRISTATE_INDET
HeaderBarItemBits
Definition: headbar.hxx:181
#define WB_BUTTONSTYLE
Definition: headbar.hxx:177
const char sBorder[]
const char * name
sal_Int32 nIndex
sal_Int64 n
constexpr sal_uInt16 KEY_RETURN
Definition: keycodes.hxx:119
constexpr sal_uInt16 KEY_0
Definition: keycodes.hxx:45
constexpr sal_uInt16 KEY_LEFT
Definition: keycodes.hxx:112
constexpr sal_uInt16 KEY_UP
Definition: keycodes.hxx:111
constexpr sal_uInt16 KEY_F1
Definition: keycodes.hxx:83
constexpr sal_uInt16 KEY_A
Definition: keycodes.hxx:56
constexpr sal_uInt16 KEY_RIGHT
Definition: keycodes.hxx:113
constexpr sal_uInt16 KEY_DELETE
Definition: keycodes.hxx:125
constexpr sal_uInt16 KEY_DOWN
Definition: keycodes.hxx:110
constexpr sal_uInt16 KEY_INSERT
Definition: keycodes.hxx:124
constexpr sal_uInt16 KEY_MULTIPLY
Definition: keycodes.hxx:129
sal_uInt16 nPos
#define SAL_INFO_IF(condition, area, stream)
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
aStr
#define MNEMONIC_CHAR
Definition: mnemonic.hxx:48
void ensureDefaultWidthChars(VclBuilder::stringmap &rMap)
Definition: builder.cxx:2279
sal_Int16 getRoleFromName(const OUString &roleName)
Definition: builder.cxx:2331
void set_properties(vcl::Window *pWindow, const VclBuilder::stringmap &rProps)
Definition: builder.cxx:2244
OUString convertMnemonicMarkup(std::u16string_view rIn)
Definition: builder.cxx:2250
bool extractDropdown(VclBuilder::stringmap &rMap)
Definition: builder.cxx:2287
OUString extractCustomProperty(VclBuilder::stringmap &rMap)
Definition: builder.cxx:2267
void reorderWithinParent(vcl::Window &rWindow, sal_uInt16 nNewPosition)
Definition: builder.cxx:2299
void MergeNotebookBarAddons(vcl::Window *pParent, const VclBuilder::customMakeWidget &pFunction, const css::uno::Reference< css::frame::XFrame > &m_xFrame, const NotebookBarAddonsItem &aNotebookBarAddonsItem, VclBuilder::stringmap &rMap)
void MergeNotebookBarMenuAddons(Menu *pPopupMenu, sal_Int16 nItemId, const OUString &sItemIdName, NotebookBarAddonsItem &aNotebookBarAddonsItem)
ResHookProc GetReadStringHook()
std::locale Create(std::string_view aPrefixName, const LanguageTag &rLocale)
OUString get(TranslateId sContextAndId, const std::locale &loc)
int i
bool isInterimBuilderEnabledForNotebookbar(std::u16string_view rUIFile)
bool isBuilderEnabledForSidebar(std::u16string_view rUIFile)
bool isBuilderEnabled(std::u16string_view rUIFile, bool bMobile)
bool isBuilderEnabledForPopup(std::u16string_view rUIFile)
sal_uInt32 toUInt32(std::u16string_view str, sal_Int16 radix=10)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
@ eSymbol
Definition: ppdparser.hxx:44
SAL_DLLPUBLIC_EXPORT void makeNotebookbarToolBox(VclPtr< vcl::Window > &rRet, const VclPtr< vcl::Window > &pParent, VclBuilder::stringmap &rMap)
Sequence< beans::PropertyValue > GetCommandProperties(const OUString &rsCommandName, const OUString &rsModuleName)
Return a label for the given command.
OUString GetTooltipForCommand(const OUString &rsCommandName, const css::uno::Sequence< css::beans::PropertyValue > &rProperties, const Reference< frame::XFrame > &rxFrame)
OUString GetModuleIdentifier(const Reference< frame::XFrame > &rxFrame)
Image GetImageForCommand(const OUString &rsCommandName, const Reference< frame::XFrame > &rxFrame, vcl::ImageType eImageType)
OUString GetLabelForCommand(const css::uno::Sequence< css::beans::PropertyValue > &rProperties)
Return a label for the given command.
void VclBuilderPreload()
Pre-loads all modules containing UI information.
Definition: builder.cxx:1450
bool TextToValue(const OUString &rStr, double &rValue, sal_Int64 nBaseValue, sal_uInt16 nDecDigits, const LocaleDataWrapper &rLocaleDataWrapper, FieldUnit eUnit)
Definition: field.cxx:1198
sal_Int64 ConvertValue(sal_Int64 nValue, sal_Int64 mnBaseValue, sal_uInt16 nDecDigits, FieldUnit eInUnit, FieldUnit eOutUnit)
Definition: field.cxx:1027
IMPL_LINK_NOARG(HexColorControl, OnAsyncModifyHdl, void *, void)
size_t GetAbsPos(const weld::TreeView &rTreeView, const weld::TreeIter &rIter)
Definition: builder.cxx:408
bool IsEntryVisible(const weld::TreeView &rTreeView, const weld::TreeIter &rIter)
Definition: builder.cxx:426
IMPL_LINK(CustomWeld, DoResize, const Size &, rSize, void)
Definition: customweld.cxx:46
SwNodeOffset min(const SwNodeOffset &a, const SwNodeOffset &b)
sal_Int16 nId
QPRO_FUNC_TYPE nType
SalInstance * mpDefInst
Definition: svdata.hxx:389
std::vector< row > m_aEntries
Definition: builder.hxx:221
std::vector< OUString > row
Definition: builder.hxx:220
MenuAndId(OUString sId, Menu *pMenu)
Definition: builder.cxx:4387
std::vector< OUString > m_aWidgets
Definition: builder.hxx:246
stringmap m_aProperties
Definition: builder.hxx:247
char const * begin
sal_Int32 length
Reference< XFrame > xFrame
ImplSVData * ImplGetSVData()
Definition: svdata.cxx:77
const FieldUnitStringList & ImplGetFieldUnits()
Definition: svdata.cxx:266
std::vector< std::pair< OUString, FieldUnit > > FieldUnitStringList
Definition: svdata.hxx:271
#define SVLIBRARY(Base)
OUString aCommand
o3tl::strong_int< sal_uInt16, struct ToolBoxItemIdTag > ToolBoxItemId
Definition: toolboxid.hxx:14
#define SAL_MAX_INT32
#define SAL_MIN_INT32
sal_uInt16 sal_Unicode
Any result
OUString aLabel
OUString sId
SymbolType
Definition: vclenum.hxx:74
@ RET_HELP
Definition: vclenum.hxx:212
@ RET_OK
Definition: vclenum.hxx:206
@ RET_CLOSE
Definition: vclenum.hxx:211
@ RET_CANCEL
Definition: vclenum.hxx:205
@ RET_NO
Definition: vclenum.hxx:208
@ RET_YES
Definition: vclenum.hxx:207
VclMessageType
Definition: vclenum.hxx:226
VclPackType
Definition: vclenum.hxx:194
VclButtonsType
Definition: vclenum.hxx:216
ToolBoxItemBits
Definition: vclenum.hxx:51
sal_Int64 WinBits
Definition: wintypes.hxx:109
WinBits const WB_CLOSEABLE
Definition: wintypes.hxx:123
WinBits const WB_VCENTER
Definition: wintypes.hxx:150
WinBits const WB_MOVEABLE
Definition: wintypes.hxx:122
WinBits const WB_VERT
Definition: wintypes.hxx:145
WinBits const WB_DIALOGCONTROL
Definition: wintypes.hxx:113
WinBits const WB_OWNERDRAWDECORATION
Definition: wintypes.hxx:173
WinBits const WB_DOCKABLE
Definition: wintypes.hxx:162
WinBits const WB_CENTER
Definition: wintypes.hxx:147
WinBits const WB_DROPDOWN
Definition: wintypes.hxx:159
WinBits const WB_STDTABCONTROL
Definition: wintypes.hxx:219
WinBits const WB_SCALE
Definition: wintypes.hxx:204
WindowType
Definition: wintypes.hxx:27
@ VERTICALTABCONTROL
WinBits const WB_POPUP
Definition: wintypes.hxx:175
WinBits const WB_SIZEABLE
Definition: wintypes.hxx:117
WinBits const WB_SYSTEMWINDOW
Definition: wintypes.hxx:126
WinBits const WB_NOLABEL
Definition: wintypes.hxx:157
WinBits const WB_TOGGLE
Definition: wintypes.hxx:185
WinBits const WB_REPEAT
Definition: wintypes.hxx:154
WinBits const WB_SIMPLEMODE
Definition: wintypes.hxx:201
WinBits const WB_AUTOVSCROLL
Definition: wintypes.hxx:163
WinBits const WB_3DLOOK
Definition: wintypes.hxx:118
WinBits const WB_AUTOHSCROLL
Definition: wintypes.hxx:161
WinBits const WB_GROUP
Definition: wintypes.hxx:142
WinBits const WB_HASBUTTONS
Definition: wintypes.hxx:223
WinBits const WB_FLATBUTTON
Definition: wintypes.hxx:186
WinBits const WB_HORZ
Definition: wintypes.hxx:144
WinBits const WB_HASBUTTONSATROOT
Definition: wintypes.hxx:226
WinBits const WB_BORDER
Definition: wintypes.hxx:115
WinBits const WB_SMALLSTYLE
Definition: wintypes.hxx:184
WinBits const WB_SPIN
Definition: wintypes.hxx:153
WinBits const WB_DEFBUTTON
Definition: wintypes.hxx:181
WinBits const WB_VSCROLL
Definition: wintypes.hxx:178
WinBits const WB_ALLOWMENUBAR
Definition: wintypes.hxx:119
WinBits const WB_TABSTOP
Definition: wintypes.hxx:140
WinBits const WB_CLIPCHILDREN
Definition: wintypes.hxx:112
WinBits const WB_HIDE
Definition: wintypes.hxx:160
WinBits const WB_LEFT
Definition: wintypes.hxx:146
WinBits const WB_HSCROLL
Definition: wintypes.hxx:177