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 <noel.grandin@collabora.co.uk>
diff --git a/include/unotools/resmgr.hxx b/include/unotools/resmgr.hxx
index 244963f..0795c3f 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 13c798f..b16843a 100644
--- a/include/vcl/font/Feature.hxx
+++ b/include/vcl/font/Feature.hxx
@@ -12,6 +12,7 @@
#include <vcl/dllapi.h>
#include <rtl/ustring.hxx>
#include <unotools/resmgr.hxx>
#include <vector>
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<FeatureParameter> const& rEnumParameters
= std::vector<FeatureParameter>{},
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<FeatureParameter> aEnumParameters);
const std::vector<FeatureParameter>& getEnumParameters() const;
diff --git a/unotools/source/i18n/resmgr.cxx b/unotools/source/i18n/resmgr.cxx
index 9d3aec3..7095316 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<boost::locale::info>(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<boost::locale::info>(loc).country() == "CH" &&
std::use_facet<boost::locale::info>(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 9fa782b..5e1960b 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<char const *>(Context "\004" u8##String)
#define NC_(Context, String) TranslateId(Context, reinterpret_cast<char const *>(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 49dbcea..ddc0e3e 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<char const *>(Context "\004" u8##String)
#define NC_(Context, String) TranslateId(Context, reinterpret_cast<char const *>(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 936c5b2..c041d78 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<char const *>(Context "\004" u8##String)
#define NC_(Context, String) TranslateId(Context, reinterpret_cast<char const *>(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 5fef2aa..4c59bd1 100644
--- a/vcl/inc/qt5/Qt5FilePicker.hxx
+++ b/vcl/inc/qt5/Qt5FilePicker.hxx
@@ -33,6 +33,7 @@
#include <osl/conditn.hxx>
#include <osl/mutex.hxx>
#include <unotools/resmgr.hxx>
#include <QtCore/QObject>
#include <QtCore/QString>
@@ -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 95468d1..d08446ba 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<char const *>(Context "\004" u8##String)
#define NC_(Context, String) TranslateId(Context, reinterpret_cast<char const *>(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 0a22d21..2f96229 100644
--- a/vcl/inc/svdata.hxx
+++ b/vcl/inc/svdata.hxx
@@ -31,6 +31,7 @@
#include <vcl/window.hxx>
#include <vcl/task.hxx>
#include <LibreOfficeKit/LibreOfficeKitTypes.h>
#include <unotools/resmgr.hxx>
#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/i18n/XCharacterClassification.hpp>
@@ -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 74c4496..79e433f 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<char const *>(Context "\004" u8##String)
#define NC_(Context, String) TranslateId(Context, reinterpret_cast<char const *>(u8##String))
std::pair<const char*, FieldUnit> SV_FUNIT_STRINGS[] =
std::pair<TranslateId, FieldUnit> 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 18e2458..9a174a0 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<uno::Any>& args)
static_cast<XFilePicker2*>(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 f5b603e..bef130d 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<int>(StandardButtonType::Count)] =
static TranslateId aResIdAry[static_cast<int>(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 7e1ad08..1a8c1d0 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 8b4e5fc..147d010 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 99a3910..3a8c20b 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<FeatureParameter> 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<FeatureParameter> aEnumParameters)
: m_pDescriptionID(pDescriptionID)
, m_nCode(nCode)
diff --git a/vcl/source/window/brdwin.cxx b/vcl/source/window/brdwin.cxx
index 0f3ee44..76b07ed 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 2c34c47..723c28c 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<ComboBoxTextItem> 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 b82769d..ed32ca8 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 95c098a7..f656a93 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('~', '_');