Index: formula/inc/formula/compiler.hrc =================================================================== --- formula/inc/formula/compiler.hrc (revision 1389681) +++ formula/inc/formula/compiler.hrc (working copy) @@ -393,9 +393,13 @@ #define SC_OPCODE_SUM_IFS 397 #define SC_OPCODE_AVERAGE_IFS 398 #define SC_OPCODE_COUNT_IFS 399 -#define SC_OPCODE_STOP_2_PAR 400 +#define SC_OPCODE_LENB 400 +#define SC_OPCODE_RIGHTB 401 +#define SC_OPCODE_LEFTB 402 +#define SC_OPCODE_MIDB 403 +#define SC_OPCODE_STOP_2_PAR 404 -#define SC_OPCODE_LAST_OPCODE_ID 399 /* last OpCode */ +#define SC_OPCODE_LAST_OPCODE_ID 403 /* last OpCode */ /*** Interna ***/ #define SC_OPCODE_INTERNAL_BEGIN 9999 Index: formula/inc/formula/opcode.hxx =================================================================== --- formula/inc/formula/opcode.hxx (revision 1389681) +++ formula/inc/formula/opcode.hxx (working copy) @@ -299,6 +299,10 @@ ocSubstitute = SC_OPCODE_SUBSTITUTE, ocRept = SC_OPCODE_REPT, ocConcat = SC_OPCODE_CONCAT, + ocLenB = SC_OPCODE_LENB, + ocRightB = SC_OPCODE_RIGHTB, + ocLeftB = SC_OPCODE_LEFTB, + ocMidB = SC_OPCODE_MIDB, // Matrix functions ocMatValue = SC_OPCODE_MAT_VALUE, ocMatDet = SC_OPCODE_MAT_DET, Index: formula/source/core/resource/core_resource.src =================================================================== --- formula/source/core/resource/core_resource.src (revision 1389681) +++ formula/source/core/resource/core_resource.src (working copy) @@ -261,6 +261,10 @@ String SC_OPCODE_RIGHT { Text = "RIGHT" ; }; String SC_OPCODE_SEARCH { Text = "SEARCH" ; }; String SC_OPCODE_MID { Text = "MID" ; }; + String SC_OPCODE_LENB { Text = "LENB" ; }; + String SC_OPCODE_RIGHTB { Text = "RIGHTB" ; }; + String SC_OPCODE_LEFTB { Text = "LEFTB" ; }; + String SC_OPCODE_MIDB { Text = "MIDB" ; }; String SC_OPCODE_TEXT { Text = "TEXT" ; }; String SC_OPCODE_SUBSTITUTE { Text = "SUBSTITUTE" ; }; String SC_OPCODE_REPT { Text = "REPT" ; }; @@ -594,6 +598,10 @@ String SC_OPCODE_RIGHT { Text = "RIGHT" ; }; String SC_OPCODE_SEARCH { Text = "SEARCH" ; }; String SC_OPCODE_MID { Text = "MID" ; }; + String SC_OPCODE_LENB { Text = "LENB" ; }; + String SC_OPCODE_RIGHTB { Text = "RIGHTB" ; }; + String SC_OPCODE_LEFTB { Text = "LEFTB" ; }; + String SC_OPCODE_MIDB { Text = "MIDB" ; }; String SC_OPCODE_TEXT { Text = "TEXT" ; }; String SC_OPCODE_SUBSTITUTE { Text = "SUBSTITUTE" ; }; String SC_OPCODE_REPT { Text = "REPT" ; }; @@ -1554,6 +1562,22 @@ { Text [ en-US ] = "MID" ; }; + String SC_OPCODE_LENB + { + Text [ en-US ] = "LENB" ; + }; + String SC_OPCODE_RIGHTB + { + Text [ en-US ] = "RIGHTB" ; + }; + String SC_OPCODE_LEFTB + { + Text [ en-US ] = "LEFTB" ; + }; + String SC_OPCODE_MIDB + { + Text [ en-US ] = "MIDB" ; + }; String SC_OPCODE_TEXT { Text [ en-US ] = "TEXT" ; Index: oox/source/xls/formulabase.cxx =================================================================== --- oox/source/xls/formulabase.cxx (revision 1389681) +++ oox/source/xls/formulabase.cxx (working copy) @@ -442,10 +442,10 @@ { 0/*"FIND"*/, "FINDB", 205, 205, 2, 3, V, { VR }, 0 }, { 0/*"SEARCH"*/, "SEARCHB", 206, 206, 2, 3, V, { VR }, 0 }, { 0/*"REPLACE"*/, "REPLACEB", 207, 207, 4, 4, V, { VR }, 0 }, - { 0/*"LEFT"*/, "LEFTB", 208, 208, 1, 2, V, { VR }, 0 }, - { 0/*"RIGHT"*/, "RIGHTB", 209, 209, 1, 2, V, { VR }, 0 }, - { 0/*"MID"*/, "MIDB", 210, 210, 3, 3, V, { VR }, 0 }, - { 0/*"LEN"*/, "LENB", 211, 211, 1, 1, V, { VR }, 0 }, + { "LEFTB", "LEFTB", 208, 208, 1, 2, V, { VR }, 0 }, + { "RIGHTB", "RIGHTB", 209, 209, 1, 2, V, { VR }, 0 }, + { "MIDB", "MIDB", 210, 210, 3, 3, V, { VR }, 0 }, + { "LENB", "LENB", 211, 211, 1, 1, V, { VR }, 0 }, { "ROUNDUP", "ROUNDUP", 212, 212, 2, 2, V, { VR }, 0 }, { "ROUNDDOWN", "ROUNDDOWN", 213, 213, 2, 2, V, { VR }, 0 }, { "ASC", "ASC", 214, 214, 1, 1, V, { VR }, 0 }, Index: sc/inc/helpids.h =================================================================== --- sc/inc/helpids.h (revision 1389681) +++ sc/inc/helpids.h (working copy) @@ -687,6 +687,10 @@ #define HID_FUNC_LINKS "SC_HID_FUNC_LINKS" #define HID_FUNC_RECHTS "SC_HID_FUNC_RECHTS" #define HID_FUNC_TEIL "SC_HID_FUNC_TEIL" +#define HID_FUNC_LENB "SC_HID_FUNC_LENB" +#define HID_FUNC_RIGHTB "SC_HID_FUNC_RIGHTB" +#define HID_FUNC_LEFTB "SC_HID_FUNC_LEFTB" +#define HID_FUNC_MIDB "SC_HID_FUNC_MIDB" #define HID_FUNC_WIEDERHOLEN "SC_HID_FUNC_WIEDERHOLEN" #define HID_FUNC_WECHSELN "SC_HID_FUNC_WECHSELN" #define HID_FUNC_BASIS "SC_HID_FUNC_BASIS" @@ -699,3 +703,4 @@ #define HID_FUNC_UNICODE "SC_HID_FUNC_UNICODE" #define HID_FUNC_UNICHAR "SC_HID_FUNC_UNICHAR" #define HID_FUNC_NUMBERVALUE "SC_HID_FUNC_NUMBERVALUE" + Index: sc/source/core/inc/interpre.hxx =================================================================== --- sc/source/core/inc/interpre.hxx (revision 1389681) +++ sc/source/core/inc/interpre.hxx (working copy) @@ -787,6 +787,10 @@ void ScSlope(); void ScTrend(); void ScInfo(); +void ScLenB(); +void ScRightB(); +void ScLeftB(); +void ScMidB(); //------------------------ Functions in interpr6.cxx ------------------------- Index: sc/source/core/tool/interpr1.cxx =================================================================== --- sc/source/core/tool/interpr1.cxx (revision 1389681) +++ sc/source/core/tool/interpr1.cxx (working copy) @@ -40,6 +40,7 @@ #include #include #include +#include #include "interpre.hxx" #include "patattr.hxx" @@ -7632,7 +7633,183 @@ } } +typedef struct { + UBlockCode from; + UBlockCode to; +} UBlockScript; +static UBlockScript scriptList[] = { + {UBLOCK_HANGUL_JAMO, UBLOCK_HANGUL_JAMO}, + {UBLOCK_CJK_RADICALS_SUPPLEMENT, UBLOCK_HANGUL_SYLLABLES}, + {UBLOCK_CJK_COMPATIBILITY_IDEOGRAPHS,UBLOCK_CJK_RADICALS_SUPPLEMENT }, + {UBLOCK_IDEOGRAPHIC_DESCRIPTION_CHARACTERS,UBLOCK_CJK_COMPATIBILITY_IDEOGRAPHS}, + {UBLOCK_CJK_COMPATIBILITY_FORMS, UBLOCK_CJK_COMPATIBILITY_FORMS}, + {UBLOCK_HALFWIDTH_AND_FULLWIDTH_FORMS, UBLOCK_HALFWIDTH_AND_FULLWIDTH_FORMS}, + {UBLOCK_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B, UBLOCK_CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT}, + {UBLOCK_CJK_STROKES, UBLOCK_CJK_STROKES} +}; +#define scriptListCount sizeof (scriptList) / sizeof (UBlockScript) +bool SAL_CALL lcl_getScriptClass(sal_uInt32 currentChar) +{ + // for the locale of ja-JP, character U+0x005c and U+0x20ac should be ScriptType::Asian + if( (currentChar == 0x005c || currentChar == 0x20ac) && + (MsLangId::getSystemLanguage() == LANGUAGE_JAPANESE) ) + return true; + sal_uInt16 i; + static sal_Int16 nRet = 0; + UBlockCode block = (UBlockCode)ublock_getCode((sal_uInt32)currentChar); + for ( i = 0; i < scriptListCount; i++) { + if (block <= scriptList[i].to) break; + } + nRet = (i < scriptListCount && block >= scriptList[i].from); + return nRet; +} +bool IsDBCS(sal_Unicode ch) +{ + return lcl_getScriptClass(ch); +} +sal_Int32 getLengthB(String &str) +{ + sal_Int32 index = 0; + sal_Int32 length = 0; + if(0 == str.Len()) + return 0; + while(index < str.Len()){ + if(IsDBCS(str.GetChar(index))) + length += 2; + else + length++; + index++; + } + return length; +} +void ScInterpreter::ScLenB() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "luzhang", "ScInterpreter::ScLenB" ); + String aStr( GetString() ); + PushDouble( getLengthB(aStr) ); +} +void lcl_RightB(String &aStr, sal_Int32 n) +{ + if( n < getLengthB(aStr) ) + { + sal_Int32 index = aStr.Len(); + while(index-- >= 0) + { + if(0 == n) + { + aStr.Erase( 0, index + 1); + break; + } + if(-1 == n) + { + aStr.Erase( 0, index + 2 ); + aStr.InsertAscii(" ", 0); + break; + } + if(IsDBCS(aStr.GetChar(index))) + n -= 2; + else + n--; + } + } +} +void ScInterpreter::ScRightB() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "luzhang", "ScInterpreter::ScRightB" ); + sal_uInt8 nParamCount = GetByte(); + if ( MustHaveParamCount( nParamCount, 1, 2 ) ) + { + sal_Int32 n; + if (nParamCount == 2) + { + double nVal = ::rtl::math::approxFloor(GetDouble()); + if ( nVal < 0.0 || nVal > STRING_MAXLEN ) + { + PushIllegalArgument(); + return ; + } + else + n = (xub_StrLen) nVal; + } + else + n = 1; + String aStr( GetString() ); + lcl_RightB(aStr, n); + PushString( aStr ); + } +} +void lcl_LeftB(String &aStr, sal_Int32 n) +{ + if( n < getLengthB(aStr) ) + { + sal_Int32 index = -1; + while(index++ < aStr.Len()) + { + if(0 == n) + { + aStr.Erase( index ); + break; + } + if(-1 == n) + { + aStr.Erase( index - 1 ); + aStr.InsertAscii(" "); + break; + } + if(IsDBCS(aStr.GetChar(index))) + n -= 2; + else + n--; + } + } +} +void ScInterpreter::ScLeftB() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "luzhang", "ScInterpreter::ScLeftB" ); + sal_uInt8 nParamCount = GetByte(); + if ( MustHaveParamCount( nParamCount, 1, 2 ) ) + { + sal_Int32 n; + if (nParamCount == 2) + { + double nVal = ::rtl::math::approxFloor(GetDouble()); + if ( nVal < 0.0 || nVal > STRING_MAXLEN ) + { + PushIllegalArgument(); + return ; + } + else + n = (xub_StrLen) nVal; + } + else + n = 1; + String aStr( GetString() ); + lcl_LeftB(aStr, n); + PushString( aStr ); + } +} +void ScInterpreter::ScMidB() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "luzhang", "ScInterpreter::ScMidB" ); + if ( MustHaveParamCount( GetByte(), 3 ) ) + { + double fAnz = ::rtl::math::approxFloor(GetDouble()); + double fAnfang = ::rtl::math::approxFloor(GetDouble()); + String rStr( GetString() ); + if (fAnfang < 1.0 || fAnz < 0.0 || fAnfang > double(STRING_MAXLEN) || fAnz > double(STRING_MAXLEN)) + PushIllegalArgument(); + else + { + + lcl_LeftB(rStr, (xub_StrLen)fAnfang + (xub_StrLen)fAnz - 1); + sal_Int32 nCnt = getLengthB(rStr) - (xub_StrLen)fAnfang + 1; + lcl_RightB(rStr, nCnt>0 ? nCnt:0); + PushString(rStr); + } + } +} + void ScInterpreter::ScRight() { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScRight" ); Index: sc/source/core/tool/interpr4.cxx =================================================================== --- sc/source/core/tool/interpr4.cxx (revision 1389681) +++ sc/source/core/tool/interpr4.cxx (working copy) @@ -3759,6 +3759,10 @@ case ocGetPivotData : ScGetPivotData(); break; case ocJis : ScJis(); break; case ocAsc : ScAsc(); break; + case ocLenB : ScLenB(); break; + case ocRightB : ScRightB(); break; + case ocLeftB : ScLeftB(); break; + case ocMidB : ScMidB(); break; case ocUnicode : ScUnicode(); break; case ocUnichar : ScUnichar(); break; case ocTTT : ScTTT(); break; Index: sc/source/filter/excel/xlformula.cxx =================================================================== --- sc/source/filter/excel/xlformula.cxx (revision 1389681) +++ sc/source/filter/excel/xlformula.cxx (working copy) @@ -208,6 +208,10 @@ { ocIsLogical, 198, 1, 1, V, { VR }, 0, 0 }, { ocDBCount2, 199, 3, 3, V, { RO, RR }, 0, 0 }, { ocCurrency, 204, 1, 2, V, { VR }, EXC_FUNCFLAG_IMPORTONLY, 0 }, + { ocLeftB, 208, 1, 2, V, { VR }, 0, 0 }, + { ocRightB, 209, 1, 2, V, { VR }, 0, 0 }, + { ocMidB, 210, 3, 3, V, { VR }, 0, 0 }, + { ocLenB, 211, 1, 1, V, { VR }, 0, 0 }, { ocRoundUp, 212, 2, 2, V, { VR }, 0, 0 }, { ocRoundDown, 213, 2, 2, V, { VR }, 0, 0 }, { ocExternal, 255, 1, MX, R, { RO_E, RO }, EXC_FUNCFLAG_IMPORTONLY, 0 } Index: sc/source/ui/src/scfuncs.src =================================================================== --- sc/source/ui/src/scfuncs.src (revision 1389681) +++ sc/source/ui/src/scfuncs.src (working copy) @@ -9217,6 +9217,130 @@ Text [ en-US ] = "Defines the character used as the decimal point." ; }; }; + Resource SC_OPCODE_LENB + { + String 1 // Description + { + Text [ en-US ] = "Calculates length of a text string, with DBCS" ; + }; + ExtraData = + { + 0; + ID_FUNCTION_GRP_TEXT; + U2S( HID_FUNC_LENB ); + 1; 0; + 0; + }; + String 2 // Name of Parameter 1 + { + Text [ en-US ] = "text" ; + }; + String 3 // Description of Parameter 1 + { + Text [ en-US ] = "The text in which the length is to be determined." ; + }; + }; + Resource SC_OPCODE_RIGHTB + { + String 1 // Description + { + Text [ en-US ] = "Returns the last character or characters of a text,with DBCS" ; + }; + ExtraData = + { + 0; + ID_FUNCTION_GRP_TEXT; + U2S( HID_FUNC_RIGHTB ); + 2; 0; 1; + 0; + }; + String 2 // Name of Parameter 1 + { + Text [ en-US ] = "text" ; + }; + String 3 // Description of Parameter 1 + { + Text [ en-US ] = "The text in which the end partial words are to be determined." ; + }; + String 4 // Name of Parameter 2 + { + Text [ en-US ] = "number" ; + }; + String 5 // Description of Parameter 2 + { + Text [ en-US ] = "The number of characters for the end text." ; + }; + }; + Resource SC_OPCODE_LEFTB + { + String 1 // Description + { + Text [ en-US ] = "Returns the first character or characters of a text,with DBCS" ; + }; + ExtraData = + { + 0; + ID_FUNCTION_GRP_TEXT; + U2S( HID_FUNC_LEFTB ); + 2; 0; 1; + 0; + }; + String 2 // Name of Parameter 1 + { + Text [ en-US ] = "text" ; + }; + String 3 // Description of Parameter 1 + { + Text [ en-US ] = "The text where the initial partial words are to be determined." ; + }; + String 4 // Name of Parameter 2 + { + Text [ en-US ] = "number" ; + }; + String 5 // Description of Parameter 2 + { + Text [ en-US ] = "The number of characters for the start text." ; + }; + }; + Resource SC_OPCODE_MIDB + { + String 1 // Description + { + Text [ en-US ] = "Returns a partial text string of a text, with DBCS" ; + }; + ExtraData = + { + 0; + ID_FUNCTION_GRP_TEXT; + U2S( HID_FUNC_MIDB ); + 3; 0; 0; 0; + 0; + }; + String 2 // Name of Parameter 1 + { + Text [ en-US ] = "text" ; + }; + String 3 // Description of Parameter 1 + { + Text [ en-US ] = "The text in which partial words are to be determined." ; + }; + String 4 // Name of Parameter 2 + { + Text [ en-US ] = "start" ; + }; + String 5 // Description of Parameter 2 + { + Text [ en-US ] = "The position from which the part word is to be determined." ; + }; + String 6 // Name of Parameter 3 + { + Text [ en-US ] = "number" ; + }; + String 7 // Description of Parameter 3 + { + Text [ en-US ] = "The number of characters for the text." ; + }; + }; }; #if defined(U2S) Index: sc/util/hidother.src =================================================================== --- sc/util/hidother.src (revision 1389681) +++ sc/util/hidother.src (working copy) @@ -345,6 +345,10 @@ hidspecial HID_FUNC_LINKS { HelpID = HID_FUNC_LINKS; }; hidspecial HID_FUNC_RECHTS { HelpID = HID_FUNC_RECHTS; }; hidspecial HID_FUNC_TEIL { HelpID = HID_FUNC_TEIL; }; +hidspecial HID_FUNC_LENB { HelpID = HID_FUNC_LENB; }; +hidspecial HID_FUNC_RIGHTB { HelpID = HID_FUNC_RIGHTB; }; +hidspecial HID_FUNC_LEFTB { HelpID = HID_FUNC_LEFTB; }; +hidspecial HID_FUNC_MIDB { HelpID = HID_FUNC_MIDB; }; hidspecial HID_FUNC_WIEDERHOLEN { HelpID = HID_FUNC_WIEDERHOLEN; }; hidspecial HID_FUNC_WECHSELN { HelpID = HID_FUNC_WECHSELN; }; hidspecial HID_FUNC_BASIS { HelpID = HID_FUNC_BASIS; }; Index: sc/util/makefile.mk =================================================================== --- sc/util/makefile.mk (revision 1389681) +++ sc/util/makefile.mk (working copy) @@ -92,7 +92,10 @@ $(XMLOFFLIB) \ $(AVMEDIALIB) \ $(FORLIB) \ - $(FORUILIB) + $(FORUILIB) \ + $(ICUINLIB) \ + $(ICUUCLIB) \ + $(ICUDATALIB) SHL1LIBS=$(LIB3TARGET) $(LIB4TARGET)