summaryrefslogtreecommitdiff
path: root/sc/source
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2020-09-08 09:48:17 +0200
committerStephan Bergmann <sbergman@redhat.com>2020-09-16 23:02:09 +0200
commite6dfaf9f44f9939abc338c83b3024108431d0f69 (patch)
tree2e220510dc589fa4ce9b205696b9d0b58d38b60a /sc/source
parenteb55bc5eae82873492cfd7577fb553b1c5abff6b (diff)
Turn OUStringLiteral into a consteval'ed, static-refcound rtl_uString
...from which an OUString can cheaply be instantiated. This is the OUString equivalent of 4b9e440c51be3e40326bc90c33ae69885bfb51e4 "Turn OStringLiteral into a consteval'ed, static-refcound rtl_String". Most remarks about that commit apply here too (this commit is just substantially bigger and a bit more complicated because there were so much more uses of OUStringLiteral than of OStringLiteral): The one downside is that OUStringLiteral now needs to be a template abstracting over the string length. But any uses for which that is a problem (e.g., as the element type of a container that would no longer be homogeneous, or in the signature of a function that shall not be turned into a template for one reason or another) can be replaced with std::u16string_view, without loss of efficiency compared to the original OUStringLiteral, and without loss of expressivity. The new OUStringLiteral ctor code would probably not be very efficient if it were ever executed at runtime, but it is intended to be only executed at compile time. Where available, C++20 "consteval" is used to statically ensure that. The intended use of the new OUStringLiteral is in all cases where an object that shall itself not be an OUString (e.g., because it shall be a global static variable for which the OUString ctor/dtor would be detrimental at library load/unload) must be converted to an OUString instance in at least one place. Other string literal abstractions could use std::u16string_view (or just plain char16_t const[N]), but interestingly OUStringLiteral might be more efficient than constexpr std::u16string_view even for such cases, as it should not need any relocations at library load time. For now, no existing uses of OUStringLiteral have been changed to some other abstraction (unless technically necessary as discussed above), and no additional places that would benefit from OUStringLiteral have been changed to use it. Global constexpr OUStringLiteral variables defined in an included file would be somewhat suboptimal, as each translation unit that uses them would create its own, unshared instance. The envisioned solution is to turn them into static data members of some class (and there may be a loplugin coming to find and fix affected places). Another approach that has been taken here in a few cases where such variables were only used in one .cxx anyway is to move their definitions from the .hxx into that one .cxx (in turn causing some files to become empty and get removed completely)---which also silenced some GCC -Werror=unused-variable if a variable from a .hxx was not used in some .cxx including it. To keep individual commits reasonably manageable, some consumers of OUStringLiteral in rtl/ustrbuf.hxx and rtl/ustring.hxx are left in a somewhat odd state for now, where they don't take advantage of OUStringLiteral's equivalence to rtl_uString, but just keep extracting its contents and copy it elsewhere. In follow-up commits, those consumers should be changed appropriately, making them treat OUStringLiteral like an rtl_uString or dropping the OUStringLiteral overload in favor of an existing (and cheap to use now) OUString overload, etc. In a similar vein, comparison operators between OUString and std::u16string_view have been added to the existing plethora of comparison operator overloads. It would be nice to eventually consolidate them, esp. with the overloads taking OUStringLiteral and/or char16_t const[N] string literals, but that appears tricky to get right without introducing new ambiguities. Also, a handful of places across the code base use comparisons between OUString and OUStringNumber, which are now ambiguous (converting the OUStringNumber to either OUString or std::u16string_view). For simplicity, those few places have manually been fixed for now by adding explicit conversion to std::u16string_view. Also some compilerplugins code needed to be adapted, and some of the compilerplugins/test cases have become irrelevant (and have been removed), as the tested code would no longer compile in the first place. sal/qa/rtl/strings/test_oustring_concat.cxx documents a workaround for GCC bug <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96878> "Failed class template argument deduction in unevaluated, parenthesized context". That place, as well as uses of OUStringLiteral in extensions/source/abpilot/fieldmappingimpl.cxx and i18npool/source/localedata/localedata.cxx, which have been replaced with OUString::Concat (and which is arguably a better choice, anyway), also caused failures with at least Clang 5.0.2 (but would not have caused failures with at least recent Clang 12 trunk, so appear to be bugs in Clang that have meanwhile been fixed). Change-Id: I34174462a28f2000cfeb2d219ffd533a767920b8 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/102222 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
Diffstat (limited to 'sc/source')
-rw-r--r--sc/source/core/data/colorscale.cxx45
-rw-r--r--sc/source/filter/excel/xlroot.cxx2
-rw-r--r--sc/source/filter/excel/xltools.cxx5
-rw-r--r--sc/source/filter/inc/xlroot.hxx4
-rw-r--r--sc/source/filter/oox/defnamesbuffer.cxx2
-rw-r--r--sc/source/ui/StatisticsDialogs/RegressionDialog.cxx11
-rw-r--r--sc/source/ui/navipi/content.cxx6
-rw-r--r--sc/source/ui/unoobj/targuno.cxx6
-rw-r--r--sc/source/ui/unoobj/textuno.cxx2
-rw-r--r--sc/source/ui/vba/vbadialog.cxx7
-rw-r--r--sc/source/ui/view/olinewin.cxx6
11 files changed, 60 insertions, 36 deletions
diff --git a/sc/source/core/data/colorscale.cxx b/sc/source/core/data/colorscale.cxx
index 16386a16370e..5287ecfdf397 100644
--- a/sc/source/core/data/colorscale.cxx
+++ b/sc/source/core/data/colorscale.cxx
@@ -22,6 +22,7 @@
#include <algorithm>
#include <cassert>
+#include <string_view>
ScFormulaListener::ScFormulaListener(ScFormulaCell* pCell):
mbDirty(false),
@@ -1228,102 +1229,102 @@ size_t ScIconSetFormat::size() const
namespace {
-const OUStringLiteral a3TrafficLights1[] = {
+const std::u16string_view a3TrafficLights1[] = {
u"" BMP_ICON_SET_CIRCLES1_RED, u"" BMP_ICON_SET_CIRCLES1_YELLOW, u"" BMP_ICON_SET_CIRCLES1_GREEN
};
-const OUStringLiteral a3TrafficLights2[] = {
+const std::u16string_view a3TrafficLights2[] = {
u"" BMP_ICON_SET_TRAFFICLIGHTS_RED, u"" BMP_ICON_SET_TRAFFICLIGHTS_YELLOW, u"" BMP_ICON_SET_TRAFFICLIGHTS_GREEN
};
-const OUStringLiteral a3Arrows[] = {
+const std::u16string_view a3Arrows[] = {
u"" BMP_ICON_SET_COLORARROWS_DOWN, u"" BMP_ICON_SET_COLORARROWS_SAME, u"" BMP_ICON_SET_COLORARROWS_UP
};
-const OUStringLiteral a3ArrowsGray[] = {
+const std::u16string_view a3ArrowsGray[] = {
u"" BMP_ICON_SET_GRAYARROWS_DOWN, u"" BMP_ICON_SET_GRAYARROWS_SAME, u"" BMP_ICON_SET_GRAYARROWS_UP
};
-const OUStringLiteral a3Flags[] = {
+const std::u16string_view a3Flags[] = {
u"" BMP_ICON_SET_FLAGS_RED, u"" BMP_ICON_SET_FLAGS_YELLOW, u"" BMP_ICON_SET_FLAGS_GREEN
};
-const OUStringLiteral a3Smilies[] = {
+const std::u16string_view a3Smilies[] = {
u"" BMP_ICON_SET_POSITIVE_YELLOW_SMILIE, u"" BMP_ICON_SET_NEUTRAL_YELLOW_SMILIE, u"" BMP_ICON_SET_NEGATIVE_YELLOW_SMILIE
};
-const OUStringLiteral a3ColorSmilies[] = {
+const std::u16string_view a3ColorSmilies[] = {
u"" BMP_ICON_SET_POSITIVE_GREEN_SMILIE, u"" BMP_ICON_SET_NEUTRAL_YELLOW_SMILIE, u"" BMP_ICON_SET_NEGATIVE_RED_SMILIE
};
-const OUStringLiteral a3Stars[] = {
+const std::u16string_view a3Stars[] = {
u"" BMP_ICON_SET_STARS_EMPTY, u"" BMP_ICON_SET_STARS_HALF, u"" BMP_ICON_SET_STARS_FULL
};
-const OUStringLiteral a3Triangles[] = {
+const std::u16string_view a3Triangles[] = {
u"" BMP_ICON_SET_TRIANGLES_DOWN, u"" BMP_ICON_SET_TRIANGLES_SAME, u"" BMP_ICON_SET_TRIANGLES_UP
};
-const OUStringLiteral a4Arrows[] = {
+const std::u16string_view a4Arrows[] = {
u"" BMP_ICON_SET_COLORARROWS_DOWN, u"" BMP_ICON_SET_COLORARROWS_SLIGHTLY_DOWN, u"" BMP_ICON_SET_COLORARROWS_SLIGHTLY_UP, u"" BMP_ICON_SET_COLORARROWS_UP
};
-const OUStringLiteral a4ArrowsGray[] = {
+const std::u16string_view a4ArrowsGray[] = {
u"" BMP_ICON_SET_GRAYARROWS_DOWN, u"" BMP_ICON_SET_GRAYARROWS_SLIGHTLY_DOWN, u"" BMP_ICON_SET_GRAYARROWS_SLIGHTLY_UP, u"" BMP_ICON_SET_GRAYARROWS_UP
};
-const OUStringLiteral a5Arrows[] = {
+const std::u16string_view a5Arrows[] = {
u"" BMP_ICON_SET_COLORARROWS_DOWN, u"" BMP_ICON_SET_COLORARROWS_SLIGHTLY_DOWN,
u"" BMP_ICON_SET_COLORARROWS_SAME, u"" BMP_ICON_SET_COLORARROWS_SLIGHTLY_UP, u"" BMP_ICON_SET_COLORARROWS_UP
};
-const OUStringLiteral a5ArrowsGray[] = {
+const std::u16string_view a5ArrowsGray[] = {
u"" BMP_ICON_SET_GRAYARROWS_DOWN, u"" BMP_ICON_SET_GRAYARROWS_SLIGHTLY_DOWN,
u"" BMP_ICON_SET_GRAYARROWS_SAME, u"" BMP_ICON_SET_GRAYARROWS_SLIGHTLY_UP, u"" BMP_ICON_SET_GRAYARROWS_UP
};
-const OUStringLiteral a4TrafficLights[] = {
+const std::u16string_view a4TrafficLights[] = {
u"" BMP_ICON_SET_CIRCLES1_GRAY, u"" BMP_ICON_SET_CIRCLES1_RED,
u"" BMP_ICON_SET_CIRCLES1_YELLOW, u"" BMP_ICON_SET_CIRCLES1_GREEN
};
-const OUStringLiteral a5Quarters[] = {
+const std::u16string_view a5Quarters[] = {
u"" BMP_ICON_SET_PIES_EMPTY, u"" BMP_ICON_SET_PIES_ONE_QUARTER, u"" BMP_ICON_SET_PIES_HALF,
u"" BMP_ICON_SET_PIES_THREE_QUARTER, u"" BMP_ICON_SET_PIES_FULL,
};
-const OUStringLiteral a5Boxes[] = {
+const std::u16string_view a5Boxes[] = {
u"" BMP_ICON_SET_SQUARES_EMPTY, u"" BMP_ICON_SET_SQUARES_ONE_QUARTER,
u"" BMP_ICON_SET_SQUARES_HALF, u"" BMP_ICON_SET_SQUARES_THREE_QUARTER,
u"" BMP_ICON_SET_SQUARES_FULL
};
-const OUStringLiteral a3Symbols1[] = {
+const std::u16string_view a3Symbols1[] = {
u"" BMP_ICON_SET_SYMBOLS1_CROSS, u"" BMP_ICON_SET_SYMBOLS1_EXCLAMATION_MARK, u"" BMP_ICON_SET_SYMBOLS1_CHECK
};
-const OUStringLiteral a3Signs[] = {
+const std::u16string_view a3Signs[] = {
u"" BMP_ICON_SET_SHAPES_DIAMOND, u"" BMP_ICON_SET_SHAPES_TRIANGLE, u"" BMP_ICON_SET_SHAPES_CIRCLE
};
-const OUStringLiteral a4RedToBlack[] = {
+const std::u16string_view a4RedToBlack[] = {
u"" BMP_ICON_SET_CIRCLES2_DARK_GRAY, u"" BMP_ICON_SET_CIRCLES2_LIGHT_GRAY,
u"" BMP_ICON_SET_CIRCLES2_LIGHT_RED, u"" BMP_ICON_SET_CIRCLES2_DARK_RED
};
-const OUStringLiteral a4Ratings[] = {
+const std::u16string_view a4Ratings[] = {
u"" BMP_ICON_SET_BARS_ONE_QUARTER, u"" BMP_ICON_SET_BARS_HALF,
u"" BMP_ICON_SET_BARS_THREE_QUARTER, u"" BMP_ICON_SET_BARS_FULL
};
-const OUStringLiteral a5Ratings[] = {
+const std::u16string_view a5Ratings[] = {
u"" BMP_ICON_SET_BARS_EMPTY, u"" BMP_ICON_SET_BARS_ONE_QUARTER, u"" BMP_ICON_SET_BARS_HALF,
u"" BMP_ICON_SET_BARS_THREE_QUARTER, u"" BMP_ICON_SET_BARS_FULL
};
struct ScIconSetBitmapMap {
ScIconSetType eType;
- const OUStringLiteral* pBitmaps;
+ const std::u16string_view* pBitmaps;
};
const ScIconSetBitmapMap aBitmapMap[] = {
diff --git a/sc/source/filter/excel/xlroot.cxx b/sc/source/filter/excel/xlroot.cxx
index 32f04f61ed40..7bc880988549 100644
--- a/sc/source/filter/excel/xlroot.cxx
+++ b/sc/source/filter/excel/xlroot.cxx
@@ -79,8 +79,6 @@ XclDebugObjCounter::~XclDebugObjCounter()
}
#endif
-const OUStringLiteral XclRootData::gaDefPassword( u"VelvetSweatshop" );
-
XclRootData::XclRootData( XclBiff eBiff, SfxMedium& rMedium,
tools::SvRef<SotStorage> const & xRootStrg, ScDocument& rDoc, rtl_TextEncoding eTextEnc, bool bExport ) :
meBiff( eBiff ),
diff --git a/sc/source/filter/excel/xltools.cxx b/sc/source/filter/excel/xltools.cxx
index 83983bb6bc4b..454de576b7bf 100644
--- a/sc/source/filter/excel/xltools.cxx
+++ b/sc/source/filter/excel/xltools.cxx
@@ -19,6 +19,8 @@
#include <algorithm>
#include <math.h>
+#include <string_view>
+
#include <sal/mathconf.h>
#include <sal/macros.h>
#include <sal/log.hxx>
@@ -632,7 +634,8 @@ bool XclTools::GetBuiltInStyleId( sal_uInt8& rnStyleId, sal_uInt8& rnLevel, cons
{
OUString aLevel = rStyleName.copy(nNextChar);
sal_Int32 nLevel = aLevel.toInt32();
- if (OUString::number(nLevel) == aLevel && nLevel > 0 && nLevel <= EXC_STYLE_LEVELCOUNT)
+ if (std::u16string_view(OUString::number(nLevel)) == aLevel
+ && nLevel > 0 && nLevel <= EXC_STYLE_LEVELCOUNT)
{
rnStyleId = nStyleId;
rnLevel = static_cast< sal_uInt8 >( nLevel - 1 );
diff --git a/sc/source/filter/inc/xlroot.hxx b/sc/source/filter/inc/xlroot.hxx
index fce08df5b0f6..781a9b6dfb07 100644
--- a/sc/source/filter/inc/xlroot.hxx
+++ b/sc/source/filter/inc/xlroot.hxx
@@ -80,7 +80,7 @@ struct XclRootData
OUString maDocUrl; /// Document URL of imported/exported file.
OUString maBasePath; /// Base path of imported/exported file (path of maDocUrl).
OUString maUserName; /// Current user name.
- static const OUStringLiteral gaDefPassword; /// The default password used for stream encryption.
+ static constexpr OUStringLiteral gaDefPassword = u"VelvetSweatshop"; /// The default password used for stream encryption.
rtl_TextEncoding meTextEnc; /// Text encoding to import/export byte strings.
LanguageType meSysLang; /// System language.
LanguageType meDocLang; /// Document language (import: from file, export: from system).
@@ -174,7 +174,7 @@ public:
const OUString& GetUserName() const { return mrData.maUserName; }
/** Returns the default password used for stream encryption. */
- static const OUStringLiteral& GetDefaultPassword() { return XclRootData::gaDefPassword; }
+ static OUString GetDefaultPassword() { return XclRootData::gaDefPassword; }
/** Requests and verifies a password from the medium or the user. */
css::uno::Sequence< css::beans::NamedValue >
RequestEncryptionData( ::comphelper::IDocPasswordVerifier& rVerifier ) const;
diff --git a/sc/source/filter/oox/defnamesbuffer.cxx b/sc/source/filter/oox/defnamesbuffer.cxx
index 6106a413aa57..467fba66e804 100644
--- a/sc/source/filter/oox/defnamesbuffer.cxx
+++ b/sc/source/filter/oox/defnamesbuffer.cxx
@@ -98,7 +98,7 @@ sal_Unicode lclGetBuiltinIdFromPrefixedName( const OUString& rModelName )
{
OUString aBaseName = lclGetBaseName( cBuiltinId );
sal_Int32 nBaseNameLen = aBaseName.getLength();
- if( (rModelName.getLength() == spcOoxPrefix.size + nBaseNameLen) && rModelName.matchIgnoreAsciiCase( aBaseName, spcOoxPrefix.size ) )
+ if( (rModelName.getLength() == spcOoxPrefix.getLength() + nBaseNameLen) && rModelName.matchIgnoreAsciiCase( aBaseName, spcOoxPrefix.getLength() ) )
return cBuiltinId;
}
}
diff --git a/sc/source/ui/StatisticsDialogs/RegressionDialog.cxx b/sc/source/ui/StatisticsDialogs/RegressionDialog.cxx
index ef5cd8f28a76..401ddf41201d 100644
--- a/sc/source/ui/StatisticsDialogs/RegressionDialog.cxx
+++ b/sc/source/ui/StatisticsDialogs/RegressionDialog.cxx
@@ -8,6 +8,10 @@
*
*/
+#include <sal/config.h>
+
+#include <string_view>
+
#include <document.hxx>
#include <reffact.hxx>
#include <TableFillingAndNavigationTools.hxx>
@@ -362,7 +366,7 @@ void ScRegressionDialog::WriteRawRegressionResults(AddressWalkerWriter& rOutput,
rTemplate.setTemplate(constTemplateLINEST[nRegressionIndex].
replaceFirst("%CALC_INTERCEPT%",
- mbCalcIntercept ? OUStringLiteral(u"TRUE") : OUStringLiteral(u"FALSE")));
+ mbCalcIntercept ? std::u16string_view(u"TRUE") : std::u16string_view(u"FALSE")));
rOutput.writeMatrixFormula(rTemplate.getTemplate(), 1 + mnNumIndependentVars, 5);
// Add LINEST result components to template
// 1. Add ranges for coefficients and standard errors for indep. vars and the intercept.
@@ -407,8 +411,9 @@ void ScRegressionDialog::WriteRegressionStatistics(AddressWalkerWriter& rOutput,
"=%SERRORY_ADDR%",
"=" + OUString::number(mnNumIndependentVars),
"=" + OUString::number(mnNumObservations),
- "=1 - (1 - %RSQUARED_ADDR%)*(%NUMOBS_ADDR% - 1)/(%NUMOBS_ADDR% - %NUMXVARS_ADDR%" +
- (mbCalcIntercept ? OUStringLiteral(u" - 1)") : OUStringLiteral(u")"))
+ OUString::Concat(
+ "=1 - (1 - %RSQUARED_ADDR%)*(%NUMOBS_ADDR% - 1)/(%NUMOBS_ADDR% - %NUMXVARS_ADDR%") +
+ (mbCalcIntercept ? std::u16string_view(u" - 1)") : std::u16string_view(u")"))
};
rTemplate.autoReplaceAddress("%NUMXVARS_ADDR%", rOutput.current(1, 2));
diff --git a/sc/source/ui/navipi/content.cxx b/sc/source/ui/navipi/content.cxx
index 6d45aed39a95..8b7d7d7d442b 100644
--- a/sc/source/ui/navipi/content.cxx
+++ b/sc/source/ui/navipi/content.cxx
@@ -17,6 +17,10 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
+#include <sal/config.h>
+
+#include <string_view>
+
#include <svx/svditer.hxx>
#include <svx/svdobj.hxx>
#include <svx/svdview.hxx>
@@ -71,7 +75,7 @@ const ScContentId pTypeList[int(ScContentId::LAST) + 1] =
ScContentId::DRAWING
};
-const OUStringLiteral aContentBmps[]=
+const std::u16string_view aContentBmps[]=
{
u"" RID_BMP_CONTENT_TABLE,
u"" RID_BMP_CONTENT_RANGENAME,
diff --git a/sc/source/ui/unoobj/targuno.cxx b/sc/source/ui/unoobj/targuno.cxx
index 4446f0fab2b1..339f3b10d60b 100644
--- a/sc/source/ui/unoobj/targuno.cxx
+++ b/sc/source/ui/unoobj/targuno.cxx
@@ -17,6 +17,10 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
+#include <sal/config.h>
+
+#include <string_view>
+
#include <toolkit/helper/vclunohelper.hxx>
#include <svl/itemprop.hxx>
#include <svl/hint.hxx>
@@ -199,7 +203,7 @@ void SAL_CALL ScLinkTargetTypeObj::setPropertyValue(const OUString& /* aProperty
//! exception?
}
-const OUStringLiteral aContentBmps[]=
+const std::u16string_view aContentBmps[]=
{
u"" RID_BMP_CONTENT_TABLE,
u"" RID_BMP_CONTENT_RANGENAME,
diff --git a/sc/source/ui/unoobj/textuno.cxx b/sc/source/ui/unoobj/textuno.cxx
index 9eea1bdb0b1f..ec41bfc8953a 100644
--- a/sc/source/ui/unoobj/textuno.cxx
+++ b/sc/source/ui/unoobj/textuno.cxx
@@ -67,7 +67,7 @@ static const SvxItemPropertySet * lcl_GetHdFtPropertySet()
// (headers/footers are in twips)
SfxItemPropertyMapEntry* pEntry = aHdFtPropertyMap_Impl;
- while (pEntry->aName.getLength())
+ while (!pEntry->aName.empty())
{
if ( ( pEntry->nWID == EE_CHAR_FONTHEIGHT ||
pEntry->nWID == EE_CHAR_FONTHEIGHT_CJK ||
diff --git a/sc/source/ui/vba/vbadialog.cxx b/sc/source/ui/vba/vbadialog.cxx
index dbb4bc543af6..afd0a561f446 100644
--- a/sc/source/ui/vba/vbadialog.cxx
+++ b/sc/source/ui/vba/vbadialog.cxx
@@ -16,6 +16,11 @@
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
+
+#include <sal/config.h>
+
+#include <string_view>
+
#include "vbadialog.hxx"
#include <sal/macros.h>
@@ -23,7 +28,7 @@
using namespace ::ooo::vba;
using namespace ::com::sun::star;
-const OUStringLiteral aStringList[]=
+const std::u16string_view aStringList[]=
{
u".uno:Open",
u".uno:FormatCellDialog",
diff --git a/sc/source/ui/view/olinewin.cxx b/sc/source/ui/view/olinewin.cxx
index c99dffe9f4fe..2925f2ded4d3 100644
--- a/sc/source/ui/view/olinewin.cxx
+++ b/sc/source/ui/view/olinewin.cxx
@@ -17,6 +17,10 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
+#include <sal/config.h>
+
+#include <string_view>
+
#include <vcl/taskpanelist.hxx>
#include <vcl/settings.hxx>
@@ -597,7 +601,7 @@ void ScOutlineWindow::HideFocus()
}
}
-const OUStringLiteral aLevelBmps[]=
+const std::u16string_view aLevelBmps[]=
{
u"" RID_BMP_LEVEL1,
u"" RID_BMP_LEVEL2,