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