/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef DISABLE_DYNLOADING #include #endif bool toBool(const OString &rValue) { return (!rValue.isEmpty() && (rValue[0] == 't' || rValue[0] == 'T' || rValue[0] == '1')); } namespace { OUString mapStockToImageResource(const OUString& sType) { if (sType == "gtk-index") return OUString(SV_RESID_BITMAP_INDEX); else if (sType == "gtk-refresh") return OUString(SV_RESID_BITMAP_REFRESH); return OUString(); } SymbolType mapStockToSymbol(const OUString& sType) { SymbolType eRet = SymbolType::DONTKNOW; if (sType == "gtk-media-next") eRet = SymbolType::NEXT; else if (sType == "gtk-media-previous") eRet = SymbolType::PREV; else if (sType == "gtk-media-play") eRet = SymbolType::PLAY; else if (sType == "gtk-media-stop") eRet = SymbolType::STOP; else if (sType == "gtk-goto-first") eRet = SymbolType::FIRST; else if (sType == "gtk-goto-last") eRet = SymbolType::LAST; else if (sType == "gtk-go-back") eRet = SymbolType::ARROW_LEFT; else if (sType == "gtk-go-forward") eRet = SymbolType::ARROW_RIGHT; else if (sType == "gtk-go-up") eRet = SymbolType::ARROW_UP; else if (sType == "gtk-go-down") eRet = SymbolType::ARROW_DOWN; else if (sType == "gtk-missing-image") eRet = SymbolType::IMAGE; else if (sType == "gtk-help") eRet = SymbolType::HELP; else if (sType == "gtk-close") eRet = SymbolType::CLOSE; else if (!mapStockToImageResource(sType).isEmpty()) eRet = SymbolType::IMAGE; return eRet; } void setupFromActionName(Button *pButton, VclBuilder::stringmap &rMap, const css::uno::Reference& rFrame); } #if defined SAL_LOG_WARN namespace { bool isButtonType(WindowType nType) { return nType == WindowType::PUSHBUTTON || nType == WindowType::OKBUTTON || nType == WindowType::CANCELBUTTON || nType == WindowType::HELPBUTTON || nType == WindowType::IMAGEBUTTON || nType == WindowType::MENUBUTTON || nType == WindowType::MOREBUTTON || nType == WindowType::SPINBUTTON; } } #endif weld::Builder* Application::CreateBuilder(weld::Widget* pParent, const OUString &rUIFile) { return ImplGetSVData()->mpDefInst->CreateBuilder(pParent, VclBuilderContainer::getUIRootDir(), rUIFile); } weld::Builder* Application::CreateInterimBuilder(vcl::Window* pParent, const OUString &rUIFile) { return ImplGetSVData()->mpDefInst->CreateInterimBuilder(pParent, VclBuilderContainer::getUIRootDir(), rUIFile); } weld::MessageDialog* Application::CreateMessageDialog(weld::Widget* pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString& rPrimaryMessage) { return ImplGetSVData()->mpDefInst->CreateMessageDialog(pParent, eMessageType, eButtonType, rPrimaryMessage); } weld::Window* Application::GetFrameWeld(const css::uno::Reference& rWindow) { return ImplGetSVData()->mpDefInst->GetFrameWeld(rWindow); } namespace { const OUString MetricToString(FieldUnit rUnit) { FieldUnitStringList* pList = ImplGetFieldUnits(); if (pList) { // return unit's default string (ie, the first one ) for (auto it = pList->begin(); it != pList->end(); ++it) { if (it->second == rUnit) return it->first; } } return OUString(); } } namespace weld { IMPL_LINK_NOARG(MetricSpinButton, spin_button_value_changed, SpinButton&, void) { signal_value_changed(); } IMPL_LINK(MetricSpinButton, spin_button_output, SpinButton&, rSpinButton, void) { rSpinButton.set_text(format_number(rSpinButton.get_value())); } void MetricSpinButton::update_width_chars() { int min, max; m_xSpinButton->get_range(min, max); auto width = std::max(m_xSpinButton->get_pixel_size(format_number(min)).Width(), m_xSpinButton->get_pixel_size(format_number(max)).Width()); int chars = ceil(width / m_xSpinButton->get_approximate_digit_width()); m_xSpinButton->set_width_chars(chars); } unsigned int SpinButton::Power10(unsigned int n) { unsigned int nValue = 1; for (unsigned int i = 0; i < n; ++i) nValue *= 10; return nValue; } int SpinButton::denormalize(int nValue) const { const int nFactor = Power10(get_digits()); if ((nValue < (SAL_MIN_INT32 + nFactor)) || (nValue > (SAL_MAX_INT32 - nFactor))) { return nValue / nFactor; } const int nHalf = nFactor / 2; if (nValue < 0) return (nValue - nHalf) / nFactor; return (nValue + nHalf) / nFactor; } OUString MetricSpinButton::format_number(int nValue) const { OUString aStr; unsigned int nDecimalDigits = m_xSpinButton->get_digits(); //pawn percent off to icu to decide whether percent is separated from its number for this locale if (m_eSrcUnit == FUNIT_PERCENT) { double fValue = nValue; fValue /= SpinButton::Power10(nDecimalDigits); aStr = unicode::formatPercent(fValue, Application::GetSettings().GetUILanguageTag()); } else { const SvtSysLocale aSysLocale; const LocaleDataWrapper& rLocaleData = aSysLocale.GetLocaleData(); aStr = rLocaleData.getNum(nValue, nDecimalDigits, true, true); if (m_eSrcUnit != FUNIT_NONE && m_eSrcUnit != FUNIT_DEGREE) aStr += " "; assert(m_eSrcUnit != FUNIT_PERCENT); aStr += MetricToString(m_eSrcUnit); } return aStr; } int MetricSpinButton::ConvertValue(int nValue, FieldUnit eInUnit, FieldUnit eOutUnit) const { return MetricField::ConvertValue(nValue, 0, m_xSpinButton->get_digits(), eInUnit, eOutUnit); } IMPL_LINK(MetricSpinButton, spin_button_input, int*, result, bool) { const SvtSysLocale aSysLocale; const LocaleDataWrapper& rLocaleData = aSysLocale.GetLocaleData(); double fResult(0.0); bool bRet = MetricFormatter::TextToValue(get_text(), fResult, 0, m_xSpinButton->get_digits(), rLocaleData, m_eSrcUnit); if (bRet) *result = fResult; return bRet; } IMPL_LINK_NOARG(TimeSpinButton, spin_button_cursor_position, Entry&, void) { int nStartPos, nEndPos; m_xSpinButton->get_selection_bounds(nStartPos, nEndPos); const SvtSysLocale aSysLocale; const LocaleDataWrapper& rLocaleData = aSysLocale.GetLocaleData(); const int nTimeArea = TimeFormatter::GetTimeArea(m_eFormat, m_xSpinButton->get_text(), nEndPos, rLocaleData); int nIncrements = 1; if (nTimeArea == 1) nIncrements = 1000 * 60 * 60; else if (nTimeArea == 2) nIncrements = 1000 * 60; else if (nTimeArea == 3) nIncrements = 1000; m_xSpinButton->set_increments(nIncrements, nIncrements * 10); } IMPL_LINK_NOARG(TimeSpinButton, spin_button_value_changed, SpinButton&, void) { signal_value_changed(); } IMPL_LINK(TimeSpinButton, spin_button_output, SpinButton&, rSpinButton, void) { int nStartPos, nEndPos; rSpinButton.get_selection_bounds(nStartPos, nEndPos); rSpinButton.set_text(format_number(rSpinButton.get_value())); rSpinButton.set_position(nEndPos); } IMPL_LINK(TimeSpinButton, spin_button_input, int*, result, bool) { int nStartPos, nEndPos; m_xSpinButton->get_selection_bounds(nStartPos, nEndPos); const SvtSysLocale aSysLocale; const LocaleDataWrapper& rLocaleData = aSysLocale.GetLocaleData(); tools::Time aResult(0); bool bRet = TimeFormatter::TextToTime(m_xSpinButton->get_text(), aResult, m_eFormat, true, rLocaleData); if (bRet) *result = ConvertValue(aResult); return bRet; } void TimeSpinButton::update_width_chars() { int min, max; m_xSpinButton->get_range(min, max); auto width = std::max(m_xSpinButton->get_pixel_size(format_number(min)).Width(), m_xSpinButton->get_pixel_size(format_number(max)).Width()); int chars = ceil(width / m_xSpinButton->get_approximate_digit_width()); m_xSpinButton->set_width_chars(chars); } tools::Time TimeSpinButton::ConvertValue(int nValue) const { tools::Time aTime(0); aTime.MakeTimeFromMS(nValue); return aTime; } int TimeSpinButton::ConvertValue(const tools::Time& rTime) const { return rTime.GetMSFromTime(); } OUString TimeSpinButton::format_number(int nValue) const { const SvtSysLocale aSysLocale; const LocaleDataWrapper& rLocaleData = aSysLocale.GetLocaleData(); return TimeFormatter::FormatTime(ConvertValue(nValue), m_eFormat, TimeFormat::Hour24, true, rLocaleData); } EntryTreeView::EntryTreeView(std::unique_ptr xEntry, std::unique_ptr xTreeView) : m_xEntry(std::move(xEntry)) , m_xTreeView(std::move(xTreeView)) { m_xTreeView->connect_changed(LINK(this, EntryTreeView, ClickHdl)); m_xEntry->connect_changed(LINK(this, EntryTreeView, ModifyHdl)); } IMPL_LINK(EntryTreeView, ClickHdl, weld::TreeView&, rView, void) { m_xEntry->set_text(rView.get_selected_text()); } void EntryTreeView::EntryModifyHdl(weld::Entry& rBox) { OUString sText(rBox.get_text()); int nExists = m_xTreeView->find_text(sText); if (nExists != -1) { m_xTreeView->select(nExists); return; } m_xTreeView->select(-1); if (sText.isEmpty()) return; int nCount = m_xTreeView->n_children(); for (int i = 0; i < nCount; ++i) { if (m_xTreeView->get_text(i).startsWith(sText)) { m_xTreeView->select(i); break; } } } IMPL_LINK(EntryTreeView, ModifyHdl, weld::Entry&, rBox, void) { EntryModifyHdl(rBox); m_aChangeHdl.Call(rBox); } void EntryTreeView::set_size_request_by_digits_rows(int nDigits, int nRows) { m_xTreeView->set_size_request(m_xTreeView->get_approximate_digit_width() * nDigits, m_xTreeView->get_height_rows(nRows)); } } VclBuilder::VclBuilder(vcl::Window *pParent, const OUString& sUIDir, const OUString& sUIFile, const OString& sID, const css::uno::Reference& rFrame, bool bLegacy) : m_sID(sID) , m_sHelpRoot(OUStringToOString(sUIFile, RTL_TEXTENCODING_UTF8)) , m_pStringReplace(Translate::GetReadStringHook()) , m_pParent(pParent) , m_bToplevelParentFound(false) , m_bLegacy(bLegacy) , m_pParserState(new ParserState) , m_xFrame(rFrame) { m_bToplevelHasDeferredInit = pParent && ((pParent->IsSystemWindow() && static_cast(pParent)->isDeferredInit()) || (pParent->IsDockingWindow() && static_cast(pParent)->isDeferredInit())); m_bToplevelHasDeferredProperties = m_bToplevelHasDeferredInit; sal_Int32 nIdx = m_sHelpRoot.lastIndexOf('.'); if (nIdx != -1) m_sHelpRoot = m_sHelpRoot.copy(0, nIdx); m_sHelpRoot = m_sHelpRoot + OString('/'); OUString sUri = sUIDir + sUIFile; try { xmlreader::XmlReader reader(sUri); handleChild(pParent, reader); } catch (const css::uno::Exception &rExcept) { DBG_UNHANDLED_EXCEPTION("vcl.layout", "Unable to read .ui file"); CrashReporter::AddKeyValue("VclBuilderException", "Unable to read .ui file: " + rExcept.Message); throw; } //Set Mnemonic widgets when everything has been imported for (auto const& mnemonicWidget : m_pParserState->m_aMnemonicWidgetMaps) { FixedText *pOne = get(mnemonicWidget.m_sID); vcl::Window *pOther = get(mnemonicWidget.m_sValue.toUtf8()); SAL_WARN_IF(!pOne || !pOther, "vcl", "missing either source " << mnemonicWidget.m_sID << " or target " << mnemonicWidget.m_sValue << " member of Mnemonic Widget Mapping"); if (pOne && pOther) pOne->set_mnemonic_widget(pOther); } //Set a11y relations and role when everything has been imported for (auto const& elemAtk : m_pParserState->m_aAtkInfo) { vcl::Window *pSource = elemAtk.first; const stringmap &rMap = elemAtk.second; for (auto const& elemMap : rMap) { const OString &rType = elemMap.first; const OUString &rParam = elemMap.second; if (rType == "role") { sal_Int16 role = BuilderUtils::getRoleFromName(rParam.toUtf8()); if (role != com::sun::star::accessibility::AccessibleRole::UNKNOWN) pSource->SetAccessibleRole(role); } else { vcl::Window *pTarget = get(rParam.toUtf8()); SAL_WARN_IF(!pTarget, "vcl", "missing parameter of a11y relation: " << rParam); if (!pTarget) continue; if (rType == "labelled-by") pSource->SetAccessibleRelationLabeledBy(pTarget); else if (rType == "label-for") pSource->SetAccessibleRelationLabelFor(pTarget); else if (rType == "member-of") pSource->SetAccessibleRelationMemberOf(pTarget); else { SAL_WARN("vcl.layout", "unhandled a11y relation :" << rType); } } } } //Set radiobutton groups when everything has been imported for (auto const& elem : m_pParserState->m_aGroupMaps) { RadioButton *pOne = get(elem.m_sID); RadioButton *pOther = get(elem.m_sValue); SAL_WARN_IF(!pOne || !pOther, "vcl", "missing member of radiobutton group"); if (pOne && pOther) { if (m_bLegacy) pOne->group(*pOther); else pOther->group(*pOne); } } //Set ComboBox models when everything has been imported for (auto const& elem : m_pParserState->m_aModelMaps) { ListBox *pTarget = get(elem.m_sID); // pStore may be empty const ListStore *pStore = get_model_by_name(elem.m_sValue.toUtf8()); SAL_WARN_IF(!pTarget, "vcl", "missing elements of combobox"); if (pTarget && pStore) mungeModel(*pTarget, *pStore, elem.m_nActiveId); } //Set TextView buffers when everything has been imported for (auto const& elem : m_pParserState->m_aTextBufferMaps) { VclMultiLineEdit *pTarget = get(elem.m_sID); const TextBuffer *pBuffer = get_buffer_by_name(elem.m_sValue.toUtf8()); SAL_WARN_IF(!pTarget || !pBuffer, "vcl", "missing elements of textview/textbuffer"); if (pTarget && pBuffer) mungeTextBuffer(*pTarget, *pBuffer); } //Set SpinButton adjustments when everything has been imported for (auto const& elem : m_pParserState->m_aNumericFormatterAdjustmentMaps) { NumericFormatter *pTarget = dynamic_cast(get(elem.m_sID)); const Adjustment *pAdjustment = get_adjustment_by_name(elem.m_sValue.toUtf8()); SAL_WARN_IF(!pTarget, "vcl", "missing NumericFormatter element of spinbutton/adjustment"); SAL_WARN_IF(!pAdjustment, "vcl", "missing Adjustment element of spinbutton/adjustment"); if (pTarget && pAdjustment) mungeAdjustment(*pTarget, *pAdjustment); } for (auto const& elem : m_pParserState->m_aTimeFormatterAdjustmentMaps) { TimeField *pTarget = dynamic_cast(get(elem.m_sID)); const Adjustment *pAdjustment = get_adjustment_by_name(elem.m_sValue.toUtf8()); SAL_WARN_IF(!pTarget || !pAdjustment, "vcl", "missing elements of spinbutton/adjustment"); if (pTarget && pAdjustment) mungeAdjustment(*pTarget, *pAdjustment); } for (auto const& elem : m_pParserState->m_aDateFormatterAdjustmentMaps) { DateField *pTarget = dynamic_cast(get(elem.m_sID)); const Adjustment *pAdjustment = get_adjustment_by_name(elem.m_sValue.toUtf8()); SAL_WARN_IF(!pTarget || !pAdjustment, "vcl", "missing elements of spinbutton/adjustment"); if (pTarget && pAdjustment) mungeAdjustment(*pTarget, *pAdjustment); } //Set ScrollBar adjustments when everything has been imported for (auto const& elem : m_pParserState->m_aScrollAdjustmentMaps) { ScrollBar *pTarget = get(elem.m_sID); const Adjustment *pAdjustment = get_adjustment_by_name(elem.m_sValue.toUtf8()); SAL_WARN_IF(!pTarget || !pAdjustment, "vcl", "missing elements of scrollbar/adjustment"); if (pTarget && pAdjustment) mungeAdjustment(*pTarget, *pAdjustment); } //Set Scale(Slider) adjustments for (auto const& elem : m_pParserState->m_aSliderAdjustmentMaps) { Slider* pTarget = dynamic_cast(get(elem.m_sID)); const Adjustment* pAdjustment = get_adjustment_by_name(elem.m_sValue.toUtf8()); SAL_WARN_IF(!pTarget || !pAdjustment, "vcl", "missing elements of scale(slider)/adjustment"); if (pTarget && pAdjustment) { mungeAdjustment(*pTarget, *pAdjustment); } } //Set size-groups when all widgets have been imported for (auto const& sizeGroup : m_pParserState->m_aSizeGroups) { std::shared_ptr xGroup(std::make_shared()); for (auto const& elem : sizeGroup.m_aProperties) { const OString &rKey = elem.first; const OUString &rValue = elem.second; xGroup->set_property(rKey, rValue); } for (auto const& elem : sizeGroup.m_aWidgets) { vcl::Window* pWindow = get(elem.getStr()); pWindow->add_to_size_group(xGroup); } } //Set button images when everything has been imported std::set aImagesToBeRemoved; for (auto const& elem : m_pParserState->m_aButtonImageWidgetMaps) { PushButton *pTargetButton = nullptr; RadioButton *pTargetRadio = nullptr; Button *pTarget = nullptr; if (!elem.m_bRadio) { pTargetButton = get(elem.m_sID); pTarget = pTargetButton; } else { pTargetRadio = get(elem.m_sID); pTarget = pTargetRadio; } FixedImage *pImage = get(elem.m_sValue.toUtf8()); SAL_WARN_IF(!pTarget || !pImage, "vcl", "missing elements of button/image/stock"); if (!pTarget || !pImage) continue; aImagesToBeRemoved.insert(elem.m_sValue); VclBuilder::StockMap::iterator aFind = m_pParserState->m_aStockMap.find(elem.m_sValue.toUtf8()); if (aFind == m_pParserState->m_aStockMap.end()) { if (!elem.m_bRadio) pTargetButton->SetModeImage(pImage->GetImage()); else pTargetRadio->SetModeRadioImage(pImage->GetImage()); } else { const stockinfo &rImageInfo = aFind->second; SymbolType eType = mapStockToSymbol(rImageInfo.m_sStock); SAL_WARN_IF(eType == SymbolType::DONTKNOW, "vcl", "missing stock image element for button"); if (eType == SymbolType::DONTKNOW) continue; if (!elem.m_bRadio) { pTargetButton->SetSymbol(eType); //fdo#76457 keep symbol images small e.g. tools->customize->menu //but images the right size. Really the PushButton::CalcMinimumSize //and PushButton::ImplDrawPushButton are the better place to handle //this, but its such a train-wreck if (eType != SymbolType::IMAGE) pTargetButton->SetStyle(pTargetButton->GetStyle() | WB_SMALLSTYLE); } else SAL_WARN_IF(eType != SymbolType::IMAGE, "vcl.layout", "inimplemented symbol type for radiobuttons"); if (eType == SymbolType::IMAGE) { BitmapEx aBitmap(mapStockToImageResource(rImageInfo.m_sStock)); Image const aImage(aBitmap); if (!elem.m_bRadio) pTargetButton->SetModeImage(aImage); else pTargetRadio->SetModeRadioImage(aImage); } switch (rImageInfo.m_nSize) { case 1: pTarget->SetSmallSymbol(); break; case 4: break; default: SAL_WARN("vcl.layout", "unsupported image size " << rImageInfo.m_nSize); break; } } } //There may be duplicate use of an Image, so we used a set to collect and //now we can remove them from the tree after their final munge for (auto const& elem : aImagesToBeRemoved) { delete_by_name(elem.toUtf8()); } //Set button menus when everything has been imported for (auto const& elem : m_pParserState->m_aButtonMenuMaps) { MenuButton *pTarget = get(elem.m_sID); PopupMenu *pMenu = get_menu(elem.m_sValue.toUtf8()); SAL_WARN_IF(!pTarget || !pMenu, "vcl", "missing elements of button/menu"); if (!pTarget || !pMenu) continue; pTarget->SetPopupMenu(pMenu); } //Remove ScrollWindow parent widgets whose children in vcl implement scrolling //internally. for (auto const& elem : m_pParserState->m_aRedundantParentWidgets) { delete_by_window(elem.first); } //fdo#67378 merge the label into the disclosure button for (auto const& elem : m_pParserState->m_aExpanderWidgets) { vcl::Window *pChild = elem->get_child(); vcl::Window* pLabel = elem->GetWindow(GetWindowType::LastChild); if (pLabel && pLabel != pChild && pLabel->GetType() == WindowType::FIXEDTEXT) { FixedText *pLabelWidget = static_cast(pLabel); elem->set_label(pLabelWidget->GetText()); delete_by_window(pLabel); } } // create message dialog message area now for (auto const& elem : m_pParserState->m_aMessageDialogs) elem->create_message_area(); //drop maps, etc. that we don't need again m_pParserState.reset(); SAL_WARN_IF(!m_sID.isEmpty() && (!m_bToplevelParentFound && !get_by_name(m_sID)), "vcl.layout", "Requested top level widget \"" << m_sID << "\" not found in " << sUIFile); #if defined SAL_LOG_WARN if (m_bToplevelParentFound && m_pParent->IsDialog()) { int nButtons = 0; bool bHasDefButton = false; for (auto const& child : m_aChildren) { if (isButtonType(child.m_pWindow->GetType())) { ++nButtons; if (child.m_pWindow->GetStyle() & WB_DEFBUTTON) { bHasDefButton = true; break; } } } SAL_WARN_IF(nButtons && !bHasDefButton, "vcl.layout", "No default button defined in " << sUIFile); } #endif } VclBuilder::~VclBuilder() { disposeBuilder(); } void VclBuilder::disposeBuilder() { for (std::vector::reverse_iterator aI = m_aChildren.rbegin(), aEnd = m_aChildren.rend(); aI != aEnd; ++aI) { aI->m_pWindow.disposeAndClear(); } m_aChildren.clear(); for (std::vector::reverse_iterator aI = m_aMenus.rbegin(), aEnd = m_aMenus.rend(); aI != aEnd; ++aI) { aI->m_pMenu.disposeAndClear(); } m_aMenus.clear(); m_pParent.clear(); } namespace { bool extractDrawValue(VclBuilder::stringmap& rMap) { bool bDrawValue = true; VclBuilder::stringmap::iterator aFind = rMap.find(OString("draw_value")); if (aFind != rMap.end()) { bDrawValue = toBool(aFind->second); rMap.erase(aFind); } return bDrawValue; } OUString extractPopupMenu(VclBuilder::stringmap& rMap) { OUString sRet; VclBuilder::stringmap::iterator aFind = rMap.find(OString("popup")); if (aFind != rMap.end()) { sRet = aFind->second; rMap.erase(aFind); } return sRet; } OUString extractValuePos(VclBuilder::stringmap& rMap) { OUString sRet("top"); VclBuilder::stringmap::iterator aFind = rMap.find(OString("value_pos")); if (aFind != rMap.end()) { sRet = aFind->second; rMap.erase(aFind); } return sRet; } OUString extractTypeHint(VclBuilder::stringmap &rMap) { OUString sRet("normal"); VclBuilder::stringmap::iterator aFind = rMap.find(OString("type-hint")); if (aFind != rMap.end()) { sRet = aFind->second; rMap.erase(aFind); } return sRet; } bool extractResizable(VclBuilder::stringmap &rMap) { bool bResizable = true; VclBuilder::stringmap::iterator aFind = rMap.find(OString("resizable")); if (aFind != rMap.end()) { bResizable = toBool(aFind->second); rMap.erase(aFind); } return bResizable; } bool extractDecorated(VclBuilder::stringmap &rMap) { bool bDecorated = true; VclBuilder::stringmap::iterator aFind = rMap.find(OString("decorated")); if (aFind != rMap.end()) { bDecorated = toBool(aFind->second); rMap.erase(aFind); } return bDecorated; } bool extractCloseable(VclBuilder::stringmap &rMap) { bool bCloseable = true; VclBuilder::stringmap::iterator aFind = rMap.find(OString("deletable")); if (aFind != rMap.end()) { bCloseable = toBool(aFind->second); rMap.erase(aFind); } return bCloseable; } bool extractEntry(VclBuilder::stringmap &rMap) { bool bHasEntry = false; VclBuilder::stringmap::iterator aFind = rMap.find(OString("has-entry")); if (aFind != rMap.end()) { bHasEntry = toBool(aFind->second); rMap.erase(aFind); } return bHasEntry; } bool extractOrientation(VclBuilder::stringmap &rMap) { bool bVertical = false; VclBuilder::stringmap::iterator aFind = rMap.find(OString("orientation")); if (aFind != rMap.end()) { bVertical = aFind->second.equalsIgnoreAsciiCase("vertical"); rMap.erase(aFind); } return bVertical; } bool extractInconsistent(VclBuilder::stringmap &rMap) { bool bInconsistent = false; VclBuilder::stringmap::iterator aFind = rMap.find(OString("inconsistent")); if (aFind != rMap.end()) { bInconsistent = toBool(aFind->second); rMap.erase(aFind); } return bInconsistent; } OUString extractIconName(VclBuilder::stringmap &rMap) { OUString sIconName; VclBuilder::stringmap::iterator aFind = rMap.find(OString("icon-name")); if (aFind != rMap.end()) { sIconName = aFind->second; rMap.erase(aFind); } return sIconName; } OUString getStockText(const OUString &rType) { if (rType == "gtk-ok") return VclResId(SV_BUTTONTEXT_OK); else if (rType == "gtk-cancel") return VclResId(SV_BUTTONTEXT_CANCEL); else if (rType == "gtk-help") return VclResId(SV_BUTTONTEXT_HELP); else if (rType == "gtk-close") return VclResId(SV_BUTTONTEXT_CLOSE); else if (rType == "gtk-revert-to-saved") return VclResId(SV_BUTTONTEXT_RESET); else if (rType == "gtk-add") return VclResId(SV_BUTTONTEXT_ADD); else if (rType == "gtk-delete") return VclResId(SV_BUTTONTEXT_DELETE); else if (rType == "gtk-remove") return VclResId(SV_BUTTONTEXT_REMOVE); else if (rType == "gtk-new") return VclResId(SV_BUTTONTEXT_NEW); else if (rType == "gtk-edit") return VclResId(SV_BUTTONTEXT_EDIT); else if (rType == "gtk-apply") return VclResId(SV_BUTTONTEXT_APPLY); else if (rType == "gtk-save") return VclResId(SV_BUTTONTEXT_SAVE); else if (rType == "gtk-open") return VclResId(SV_BUTTONTEXT_OPEN); else if (rType == "gtk-undo") return VclResId(SV_BUTTONTEXT_UNDO); else if (rType == "gtk-paste") return VclResId(SV_BUTTONTEXT_PASTE); else if (rType == "gtk-media-next") return VclResId(SV_BUTTONTEXT_NEXT); else if (rType == "gtk-media-previous") return VclResId(SV_BUTTONTEXT_PREV); else if (rType == "gtk-go-up") return VclResId(SV_BUTTONTEXT_GO_UP); else if (rType == "gtk-go-down") return VclResId(SV_BUTTONTEXT_GO_DOWN); else if (rType == "gtk-clear") return VclResId(SV_BUTTONTEXT_CLEAR); else if (rType == "gtk-media-play") return VclResId(SV_BUTTONTEXT_PLAY); else if (rType == "gtk-find") return VclResId(SV_BUTTONTEXT_FIND); else if (rType == "gtk-stop") return VclResId(SV_BUTTONTEXT_STOP); else if (rType == "gtk-connect") return VclResId(SV_BUTTONTEXT_CONNECT); else if (rType == "gtk-yes") return VclResId(SV_BUTTONTEXT_YES); else if (rType == "gtk-no") return VclResId(SV_BUTTONTEXT_NO); SAL_WARN("vcl.layout", "unknown stock type: " << rType); return OUString(); } bool extractStock(VclBuilder::stringmap &rMap) { bool bIsStock = false; VclBuilder::stringmap::iterator aFind = rMap.find(OString("use-stock")); if (aFind != rMap.end()) { bIsStock = toBool(aFind->second); rMap.erase(aFind); } return bIsStock; } WinBits extractRelief(VclBuilder::stringmap &rMap) { WinBits nBits = WB_3DLOOK; VclBuilder::stringmap::iterator aFind = rMap.find(OString("relief")); if (aFind != rMap.end()) { if (aFind->second == "half") nBits = WB_FLATBUTTON | WB_BEVELBUTTON; else if (aFind->second == "none") nBits = WB_FLATBUTTON; rMap.erase(aFind); } return nBits; } OUString extractLabel(VclBuilder::stringmap &rMap) { OUString sType; VclBuilder::stringmap::iterator aFind = rMap.find(OString("label")); if (aFind != rMap.end()) { sType = aFind->second; rMap.erase(aFind); } return sType; } OUString extractActionName(VclBuilder::stringmap &rMap) { OUString sActionName; VclBuilder::stringmap::iterator aFind = rMap.find(OString("action-name")); if (aFind != rMap.end()) { sActionName = aFind->second; rMap.erase(aFind); } return sActionName; } bool extractVisible(VclBuilder::stringmap &rMap) { VclBuilder::stringmap::iterator aFind = rMap.find(OString("visible")); if (aFind != rMap.end()) { return toBool(aFind->second); } return false; } Size extractSizeRequest(VclBuilder::stringmap &rMap) { OUString sWidthRequest("0"); OUString sHeightRequest("0"); VclBuilder::stringmap::iterator aFind = rMap.find(OString("width-request")); if (aFind != rMap.end()) { sWidthRequest = aFind->second; rMap.erase(aFind); } aFind = rMap.find(OString("height-request")); if (aFind != rMap.end()) { sHeightRequest = aFind->second; rMap.erase(aFind); } return Size(sWidthRequest.toInt32(), sHeightRequest.toInt32()); } OUString extractTooltipText(VclBuilder::stringmap &rMap) { OUString sTooltipText; VclBuilder::stringmap::iterator aFind = rMap.find(OString("tooltip-text")); if (aFind == rMap.end()) aFind = rMap.find(OString("tooltip-markup")); if (aFind != rMap.end()) { sTooltipText = aFind->second; rMap.erase(aFind); } return sTooltipText; } void setupFromActionName(Button *pButton, VclBuilder::stringmap &rMap, const css::uno::Reference& rFrame) { if (!rFrame.is()) return; OUString aCommand(extractActionName(rMap)); if (aCommand.isEmpty()) return; OUString aModuleName(vcl::CommandInfoProvider::GetModuleIdentifier(rFrame)); OUString aLabel(vcl::CommandInfoProvider::GetLabelForCommand(aCommand, aModuleName)); if (!aLabel.isEmpty()) pButton->SetText(aLabel); OUString aTooltip(vcl::CommandInfoProvider::GetTooltipForCommand(aCommand, rFrame)); if (!aTooltip.isEmpty()) pButton->SetQuickHelpText(aTooltip); Image aImage(vcl::CommandInfoProvider::GetImageForCommand(aCommand, rFrame)); pButton->SetModeImage(aImage); pButton->SetCommandHandler(aCommand); } VclPtr