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