From 5afdcad4c0e7850b18996c549892b9360cd8973f Mon Sep 17 00:00:00 2001 From: Noel Grandin Date: Mon, 2 Aug 2021 16:06:05 +0200 Subject: Pass context and resource string down to boost::locale separately because this is often on a hot path, and we can avoid the splitting and joining of strings like this. Change-Id: I2a24a123a64b762fd0741c45eaca3ad4bdd5580d Reviewed-on: https://gerrit.libreoffice.org/c/core/+/119884 Tested-by: Jenkins Reviewed-by: Noel Grandin --- include/unotools/resmgr.hxx | 21 ++++++++++++++++++++- include/vcl/font/Feature.hxx | 11 ++++++----- unotools/source/i18n/resmgr.cxx | 29 +++++++++++++++++++++++++++++ vcl/inc/font/OpenTypeFeatureStrings.hrc | 2 +- vcl/inc/print.hrc | 4 ++-- vcl/inc/printaccessoryview.hrc | 4 ++-- vcl/inc/qt5/Qt5FilePicker.hxx | 3 ++- vcl/inc/strings.hrc | 2 +- vcl/inc/svdata.hxx | 3 ++- vcl/inc/units.hrc | 4 ++-- vcl/qt5/Qt5FilePicker.cxx | 8 ++++---- vcl/source/app/stdtext.cxx | 2 +- vcl/source/app/svapp.cxx | 2 +- vcl/source/app/svdata.cxx | 2 +- vcl/source/font/Feature.cxx | 11 ++++------- vcl/source/window/brdwin.cxx | 2 +- vcl/source/window/builder.cxx | 12 +++--------- vcl/source/window/splitwin.cxx | 2 +- vcl/unx/gtk3/fpicker/resourceprovider.cxx | 8 ++++---- 19 files changed, 87 insertions(+), 45 deletions(-) diff --git a/include/unotools/resmgr.hxx b/include/unotools/resmgr.hxx index 244963f598b1..0795c3f16704 100644 --- a/include/unotools/resmgr.hxx +++ b/include/unotools/resmgr.hxx @@ -33,7 +33,8 @@ struct UNOTOOLS_DLLPUBLIC TranslateId const char* mpContext; const char* mpId; - TranslateId() {} + TranslateId() + : mpContext(nullptr), mpId(nullptr) {} TranslateId(const char* pContext, const char* pId) : mpContext(pContext), mpId(pId) {} @@ -43,12 +44,30 @@ struct UNOTOOLS_DLLPUBLIC TranslateId bool operator!=(const TranslateId& other) const { return !operator==(other); } }; +struct UNOTOOLS_DLLPUBLIC TranslateNId +{ + const char* mpContext; + const char* mpSingular; + const char* mpPlural; + + TranslateNId() + : mpContext(nullptr), mpSingular(nullptr), mpPlural(nullptr) {} + TranslateNId(const char* pContext, const char* pSingular, const char* pPlural) + : mpContext(pContext), mpSingular(pSingular), mpPlural(pPlural) {} + + operator bool() const { return mpContext != nullptr; } + + bool operator==(const TranslateNId& other) const; + bool operator!=(const TranslateNId& other) const { return !operator==(other); } +}; + namespace Translate { UNOTOOLS_DLLPUBLIC std::locale Create(std::string_view aPrefixName, const LanguageTag& rLocale = SvtSysLocale().GetUILanguageTag()); UNOTOOLS_DLLPUBLIC OUString get(std::string_view aId, const std::locale &loc); UNOTOOLS_DLLPUBLIC OUString nget(std::string_view aId, int n, const std::locale &loc); UNOTOOLS_DLLPUBLIC OUString get(TranslateId sContextAndId, const std::locale &loc); + UNOTOOLS_DLLPUBLIC OUString nget(TranslateNId aContextSingularPlural, int n, const std::locale &loc); UNOTOOLS_DLLPUBLIC void SetReadStringHook( ResHookProc pProc ); UNOTOOLS_DLLPUBLIC ResHookProc GetReadStringHook(); UNOTOOLS_DLLPUBLIC OUString ExpandVariables(const OUString& rString); diff --git a/include/vcl/font/Feature.hxx b/include/vcl/font/Feature.hxx index 13c798fbcf32..b16843abea7d 100644 --- a/include/vcl/font/Feature.hxx +++ b/include/vcl/font/Feature.hxx @@ -12,6 +12,7 @@ #include #include +#include #include namespace vcl::font @@ -41,11 +42,11 @@ struct VCL_DLLPUBLIC FeatureParameter private: uint32_t m_nCode; OUString m_sDescription; - const char* m_pDescriptionID; + TranslateId m_pDescriptionID; public: FeatureParameter(uint32_t nCode, OUString aDescription); - FeatureParameter(uint32_t nCode, const char* pDescriptionID); + FeatureParameter(uint32_t nCode, TranslateId pDescriptionID); uint32_t getCode() const; OUString getDescription() const; @@ -55,7 +56,7 @@ class VCL_DLLPUBLIC FeatureDefinition { private: OUString m_sDescription; - const char* m_pDescriptionID; + TranslateId m_pDescriptionID; OUString m_sNumericPart; uint32_t m_nCode; uint32_t m_nDefault; @@ -70,9 +71,9 @@ public: std::vector const& rEnumParameters = std::vector{}, uint32_t nDefault = 0); - FeatureDefinition(uint32_t nCode, const char* pDescriptionID, + FeatureDefinition(uint32_t nCode, TranslateId pDescriptionID, OUString const& rNumericPart = OUString()); - FeatureDefinition(uint32_t nCode, const char* pDescriptionID, + FeatureDefinition(uint32_t nCode, TranslateId pDescriptionID, std::vector aEnumParameters); const std::vector& getEnumParameters() const; diff --git a/unotools/source/i18n/resmgr.cxx b/unotools/source/i18n/resmgr.cxx index 9d3aec3a607c..7095316859f7 100644 --- a/unotools/source/i18n/resmgr.cxx +++ b/unotools/source/i18n/resmgr.cxx @@ -313,6 +313,29 @@ namespace Translate return result; } + OUString nget(TranslateNId aContextSingularPlural, int n, const std::locale &loc) + { + //if it's a key id locale, generate it here + if (std::use_facet(loc).language() == "qtz") + { + OString sKeyId(genKeyId(OString::Concat(aContextSingularPlural.mpContext) + "|" + aContextSingularPlural.mpSingular)); + const char* pForm = n == 0 ? aContextSingularPlural.mpSingular : aContextSingularPlural.mpPlural; + return OUString::fromUtf8(sKeyId) + u"\u2016" + createFromUtf8(pForm, strlen(pForm)); + } + + //otherwise translate it + const std::string ret = boost::locale::npgettext(aContextSingularPlural.mpContext, aContextSingularPlural.mpSingular, aContextSingularPlural.mpPlural, n, loc); + OUString result(ExpandVariables(createFromUtf8(ret.data(), ret.size()))); + + if (comphelper::LibreOfficeKit::isActive()) + { + if (std::use_facet(loc).country() == "CH" && + std::use_facet(loc).language() == "de") + result = result.replaceAll(OUString::fromUtf8("\xC3\x9F"), "ss"); + } + return result; + } + static ResHookProc pImplResHookProc = nullptr; OUString ExpandVariables(const OUString& rString) @@ -338,5 +361,11 @@ bool TranslateId::operator==(const TranslateId& other) const return strcmp(mpContext, other.mpContext) == 0 && strcmp(mpId,other.mpId) == 0; } +bool TranslateNId::operator==(const TranslateNId& other) const +{ + return strcmp(mpContext, other.mpContext) == 0 + && strcmp(mpSingular, other.mpSingular) == 0 + && strcmp(mpPlural, other.mpPlural) == 0; +} /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/font/OpenTypeFeatureStrings.hrc b/vcl/inc/font/OpenTypeFeatureStrings.hrc index 9fa782b16c67..5e1960b95613 100644 --- a/vcl/inc/font/OpenTypeFeatureStrings.hrc +++ b/vcl/inc/font/OpenTypeFeatureStrings.hrc @@ -20,7 +20,7 @@ #ifndef INCLUDED_VCL_INC_FONT_OPENTYPEFEATRESTRINGS_HRC #define INCLUDED_VCL_INC_FONT_OPENTYPEFEATRESTRINGS_HRC -#define NC_(Context, String) reinterpret_cast(Context "\004" u8##String) +#define NC_(Context, String) TranslateId(Context, reinterpret_cast(u8##String)) #define STR_FONT_FEATURE_ID_AALT NC_("STR_FONT_FEATURE_ID_AALT", "Access All Alternates") #define STR_FONT_FEATURE_ID_AFRC NC_("STR_FONT_FEATURE_ID_AFRC", "Alternative (Vertical) Fractions") diff --git a/vcl/inc/print.hrc b/vcl/inc/print.hrc index 49dbcea20fa2..ddc0e3e1699a 100644 --- a/vcl/inc/print.hrc +++ b/vcl/inc/print.hrc @@ -20,9 +20,9 @@ #ifndef INCLUDED_VCL_INC_PRINT_HRC #define INCLUDED_VCL_INC_PRINT_HRC -#define NC_(Context, String) reinterpret_cast(Context "\004" u8##String) +#define NC_(Context, String) TranslateId(Context, reinterpret_cast(u8##String)) -const char* RID_STR_PAPERNAMES[] = +const TranslateId RID_STR_PAPERNAMES[] = { // To translators: This is the first entry of a sequence of paper size names NC_("RID_STR_PAPERNAMES", "A0"), diff --git a/vcl/inc/printaccessoryview.hrc b/vcl/inc/printaccessoryview.hrc index 936c5b2bcce4..c041d78c3e32 100644 --- a/vcl/inc/printaccessoryview.hrc +++ b/vcl/inc/printaccessoryview.hrc @@ -20,9 +20,9 @@ #ifndef INCLUDED_VCL_INC_PRINTACCESSORYVIEW_HRC #define INCLUDED_VCL_INC_PRINTACCESSORYVIEW_HRC -#define NC_(Context, String) reinterpret_cast(Context "\004" u8##String) +#define NC_(Context, String) TranslateId(Context, reinterpret_cast(u8##String)) -const char* SV_PRINT_NATIVE_STRINGS[] = +const TranslateId SV_PRINT_NATIVE_STRINGS[] = { NC_("SV_PRINT_NATIVE_STRINGS", "Preview"), NC_("SV_PRINT_NATIVE_STRINGS", "Page number"), diff --git a/vcl/inc/qt5/Qt5FilePicker.hxx b/vcl/inc/qt5/Qt5FilePicker.hxx index 5fef2aaeae43..4c59bd15b78e 100644 --- a/vcl/inc/qt5/Qt5FilePicker.hxx +++ b/vcl/inc/qt5/Qt5FilePicker.hxx @@ -33,6 +33,7 @@ #include #include +#include #include #include @@ -158,7 +159,7 @@ private: Qt5FilePicker(const Qt5FilePicker&) = delete; Qt5FilePicker& operator=(const Qt5FilePicker&) = delete; - static QString getResString(const char* pRedId); + static QString getResString(TranslateId pRedId); static css::uno::Any handleGetListValue(const QComboBox* pWidget, sal_Int16 nControlAction); static void handleSetListValue(QComboBox* pQComboBox, sal_Int16 nAction, const css::uno::Any& rValue); diff --git a/vcl/inc/strings.hrc b/vcl/inc/strings.hrc index 95468d1d4538..d08446ba44cf 100644 --- a/vcl/inc/strings.hrc +++ b/vcl/inc/strings.hrc @@ -20,7 +20,7 @@ #ifndef INCLUDED_VCL_INC_STRINGS_HRC #define INCLUDED_VCL_INC_STRINGS_HRC -#define NC_(Context, String) reinterpret_cast(Context "\004" u8##String) +#define NC_(Context, String) TranslateId(Context, reinterpret_cast(u8##String)) #define SV_RESID_STRING_NOSELECTIONPOSSIBLE NC_("SV_RESID_STRING_NOSELECTIONPOSSIBLE", "[No selection possible]") diff --git a/vcl/inc/svdata.hxx b/vcl/inc/svdata.hxx index 0a22d2127d2a..2f962291725b 100644 --- a/vcl/inc/svdata.hxx +++ b/vcl/inc/svdata.hxx @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -429,7 +430,7 @@ VCL_PLUGIN_PUBLIC basegfx::SystemDependentDataManager& ImplGetSystemDependentDat VCL_PLUGIN_PUBLIC vcl::Window* ImplGetDefaultWindow(); vcl::Window* ImplGetDefaultContextWindow(); const std::locale& ImplGetResLocale(); -VCL_PLUGIN_PUBLIC OUString VclResId(std::string_view aId); +VCL_PLUGIN_PUBLIC OUString VclResId(TranslateId sContextAndId); DockingManager* ImplGetDockingManager(); BlendFrameCache* ImplGetBlendFrameCache(); diff --git a/vcl/inc/units.hrc b/vcl/inc/units.hrc index 74c4496755e1..79e433f12eb2 100644 --- a/vcl/inc/units.hrc +++ b/vcl/inc/units.hrc @@ -20,9 +20,9 @@ #ifndef INCLUDED_VCL_INC_UNITS_HRC #define INCLUDED_VCL_INC_UNITS_HRC -#define NC_(Context, String) reinterpret_cast(Context "\004" u8##String) +#define NC_(Context, String) TranslateId(Context, reinterpret_cast(u8##String)) -std::pair SV_FUNIT_STRINGS[] = +std::pair SV_FUNIT_STRINGS[] = { // To translators: This is the first entry of a sequence of measurement unit names { NC_("SV_FUNIT_STRINGS", "mm"), FieldUnit::MM }, diff --git a/vcl/qt5/Qt5FilePicker.cxx b/vcl/qt5/Qt5FilePicker.cxx index 18e24580107e..9a174a08c0c6 100644 --- a/vcl/qt5/Qt5FilePicker.cxx +++ b/vcl/qt5/Qt5FilePicker.cxx @@ -576,11 +576,11 @@ OUString SAL_CALL Qt5FilePicker::getLabel(sal_Int16 controlId) return toOUString(label); } -QString Qt5FilePicker::getResString(const char* pResId) +QString Qt5FilePicker::getResString(TranslateId pResId) { QString aResString; - if (pResId == nullptr) + if (!pResId) return aResString; aResString = toQString(VclResId(pResId)); @@ -592,7 +592,7 @@ void Qt5FilePicker::addCustomControl(sal_Int16 controlId) { QWidget* widget = nullptr; QLabel* label = nullptr; - const char* resId = nullptr; + TranslateId resId; QCheckBox* pCheckbox = nullptr; switch (controlId) @@ -805,7 +805,7 @@ void SAL_CALL Qt5FilePicker::initialize(const uno::Sequence& args) static_cast(this), 1); } - const char* resId = nullptr; + TranslateId resId; switch (acceptMode) { case QFileDialog::AcceptOpen: diff --git a/vcl/source/app/stdtext.cxx b/vcl/source/app/stdtext.cxx index f5b603e009bd..bef130dc7dca 100644 --- a/vcl/source/app/stdtext.cxx +++ b/vcl/source/app/stdtext.cxx @@ -92,7 +92,7 @@ OUString GetStandardQueryBoxText() OUString GetStandardText(StandardButtonType eButton) { - static const char* aResIdAry[static_cast(StandardButtonType::Count)] = + static TranslateId aResIdAry[static_cast(StandardButtonType::Count)] = { // http://lists.freedesktop.org/archives/libreoffice/2013-January/044513.html // Under windows we don't want accelerators on ok/cancel but do on other diff --git a/vcl/source/app/svapp.cxx b/vcl/source/app/svapp.cxx index 7e1ad0865010..1a8c1d0b8e1a 100644 --- a/vcl/source/app/svapp.cxx +++ b/vcl/source/app/svapp.cxx @@ -1144,7 +1144,7 @@ OUString Application::GetAppName() enum {hwAll=0, hwEnv=1, hwUI=2}; -static OUString Localize(std::string_view aId, const bool bLocalize) +static OUString Localize(TranslateId aId, const bool bLocalize) { if (bLocalize) return VclResId(aId); diff --git a/vcl/source/app/svdata.cxx b/vcl/source/app/svdata.cxx index 8b4e5fc1662a..147d010bdd08 100644 --- a/vcl/source/app/svdata.cxx +++ b/vcl/source/app/svdata.cxx @@ -256,7 +256,7 @@ const std::locale& ImplGetResLocale() return pSVData->maResLocale; } -OUString VclResId(std::string_view aId) +OUString VclResId(TranslateId aId) { return Translate::get(aId, ImplGetResLocale()); } diff --git a/vcl/source/font/Feature.cxx b/vcl/source/font/Feature.cxx index 99a3910b81fb..3a8c20b2c915 100644 --- a/vcl/source/font/Feature.cxx +++ b/vcl/source/font/Feature.cxx @@ -62,11 +62,10 @@ FeatureSetting::FeatureSetting(OString feature) FeatureParameter::FeatureParameter(uint32_t nCode, OUString aDescription) : m_nCode(nCode) , m_sDescription(std::move(aDescription)) - , m_pDescriptionID(nullptr) { } -FeatureParameter::FeatureParameter(uint32_t nCode, const char* pDescriptionID) +FeatureParameter::FeatureParameter(uint32_t nCode, TranslateId pDescriptionID) : m_nCode(nCode) , m_pDescriptionID(pDescriptionID) { @@ -89,8 +88,7 @@ uint32_t FeatureParameter::getCode() const { return m_nCode; } // FeatureDefinition FeatureDefinition::FeatureDefinition() - : m_pDescriptionID(nullptr) - , m_nCode(0) + : m_nCode(0) , m_nDefault(0) , m_eType(FeatureParameterType::BOOL) { @@ -101,7 +99,6 @@ FeatureDefinition::FeatureDefinition(uint32_t nCode, OUString const& rDescriptio std::vector const& rEnumParameters, uint32_t nDefault) : m_sDescription(rDescription) - , m_pDescriptionID(nullptr) , m_nCode(nCode) , m_nDefault(nDefault) , m_eType(eType) @@ -109,7 +106,7 @@ FeatureDefinition::FeatureDefinition(uint32_t nCode, OUString const& rDescriptio { } -FeatureDefinition::FeatureDefinition(uint32_t nCode, const char* pDescriptionID, +FeatureDefinition::FeatureDefinition(uint32_t nCode, TranslateId pDescriptionID, OUString const& rNumericPart) : m_pDescriptionID(pDescriptionID) , m_sNumericPart(rNumericPart) @@ -119,7 +116,7 @@ FeatureDefinition::FeatureDefinition(uint32_t nCode, const char* pDescriptionID, { } -FeatureDefinition::FeatureDefinition(uint32_t nCode, const char* pDescriptionID, +FeatureDefinition::FeatureDefinition(uint32_t nCode, TranslateId pDescriptionID, std::vector aEnumParameters) : m_pDescriptionID(pDescriptionID) , m_nCode(nCode) diff --git a/vcl/source/window/brdwin.cxx b/vcl/source/window/brdwin.cxx index 0f3ee445ec33..76b07edbe9a4 100644 --- a/vcl/source/window/brdwin.cxx +++ b/vcl/source/window/brdwin.cxx @@ -288,7 +288,7 @@ OUString ImplBorderWindowView::ImplRequestHelp( ImplBorderFrameData const * pDat const Point& rPos, tools::Rectangle& rHelpRect ) { - const char* pHelpId = nullptr; + TranslateId pHelpId; OUString aHelpStr; BorderWindowHitTest nHitTest = ImplHitTest( pData, rPos ); if ( nHitTest != BorderWindowHitTest::NONE ) diff --git a/vcl/source/window/builder.cxx b/vcl/source/window/builder.cxx index 2c34c47b1d95..723c28ca640d 100644 --- a/vcl/source/window/builder.cxx +++ b/vcl/source/window/builder.cxx @@ -2963,9 +2963,7 @@ void VclBuilder::handleRow(xmlreader::XmlReader &reader, const OString &rID) OUString sFinalValue; if (bTranslated) { - if (!sContext.isEmpty()) - sValue = sContext + "\004" + sValue; - sFinalValue = Translate::get(sValue.getStr(), m_pParserState->m_aResLocale); + sFinalValue = Translate::get({sContext.getStr(), sValue.getStr()}, m_pParserState->m_aResLocale); } else sFinalValue = OUString::fromUtf8(sValue); @@ -3128,9 +3126,7 @@ std::vector VclBuilder::handleItems(xmlreader::XmlReader &read OUString sFinalValue; if (bTranslated) { - if (!sContext.isEmpty()) - sValue = sContext + "\004" + sValue; - sFinalValue = Translate::get(sValue.getStr(), m_pParserState->m_aResLocale); + sFinalValue = Translate::get({sContext.getStr(), sValue.getStr()}, m_pParserState->m_aResLocale); } else sFinalValue = OUString::fromUtf8(sValue); @@ -3943,9 +3939,7 @@ void VclBuilder::collectProperty(xmlreader::XmlReader &reader, stringmap &rMap) OUString sFinalValue; if (bTranslated) { - if (!sContext.isEmpty()) - sValue = sContext + "\004" + sValue; - sFinalValue = Translate::get(sValue.getStr(), m_pParserState->m_aResLocale); + sFinalValue = Translate::get({sContext.getStr(), sValue.getStr()}, m_pParserState->m_aResLocale); } else sFinalValue = OUString::fromUtf8(sValue); diff --git a/vcl/source/window/splitwin.cxx b/vcl/source/window/splitwin.cxx index b82769d418b0..ed32ca8f44fd 100644 --- a/vcl/source/window/splitwin.cxx +++ b/vcl/source/window/splitwin.cxx @@ -2083,7 +2083,7 @@ void SplitWindow::RequestHelp( const HelpEvent& rHEvt ) { Point aMousePosPixel = ScreenToOutputPixel( rHEvt.GetMousePosPixel() ); tools::Rectangle aHelpRect; - const char* pHelpResId = nullptr; + TranslateId pHelpResId; ImplGetFadeInRect( aHelpRect, true ); if ( aHelpRect.IsInside( aMousePosPixel ) ) diff --git a/vcl/unx/gtk3/fpicker/resourceprovider.cxx b/vcl/unx/gtk3/fpicker/resourceprovider.cxx index 95c098a73488..f656a93093a8 100644 --- a/vcl/unx/gtk3/fpicker/resourceprovider.cxx +++ b/vcl/unx/gtk3/fpicker/resourceprovider.cxx @@ -32,7 +32,7 @@ using namespace ::com::sun::star::ui::dialogs::CommonFilePickerElementIds; const struct { sal_Int32 ctrlId; - const char *resId; + TranslateId resId; } CtrlIdToResIdTable[] = { { CHECKBOX_AUTOEXTENSION, STR_FPICKER_AUTO_EXTENSION }, { CHECKBOX_PASSWORD, STR_FPICKER_PASSWORD }, @@ -57,21 +57,21 @@ const struct { FILE_PICKER_FILE_TYPE, STR_FPICKER_TYPE } }; -static const char* CtrlIdToResId( sal_Int32 aControlId ) +static TranslateId CtrlIdToResId( sal_Int32 aControlId ) { for (auto & i : CtrlIdToResIdTable) { if ( i.ctrlId == aControlId ) return i.resId; } - return nullptr; + return {}; } OUString SalGtkPicker::getResString( sal_Int32 aId ) { OUString aResString; // translate the control id to a resource id - const char *pResId = CtrlIdToResId( aId ); + TranslateId pResId = CtrlIdToResId( aId ); if (pResId) aResString = VclResId(pResId); return aResString.replace('~', '_'); -- cgit