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