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