1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_svtools.hxx" 26 27 // include --------------------------------------------------------------- 28 29 #include <tools/shl.hxx> 30 #include <tools/debug.hxx> 31 32 //#include <com/sun/star/i18n/XCharacterClassification.hpp> 33 #include <com/sun/star/i18n/DirectionProperty.hpp> 34 35 #include <i18npool/lang.h> 36 #include <i18npool/mslangid.hxx> 37 38 #include <svtools/svtools.hrc> 39 #include <svtools/svtdata.hxx> 40 #include <svtools/langtab.hxx> 41 #include <unotools/syslocale.hxx> 42 43 44 using namespace ::com::sun::star; 45 46 //------------------------------------------------------------------------ 47 48 SVT_DLLPUBLIC const String ApplyLreOrRleEmbedding( const String &rText ) 49 { 50 const sal_uInt16 nLen = rText.Len(); 51 if (nLen == 0) 52 return String(); 53 54 const sal_Unicode cLRE_Embedding = 0x202A; // the start char of an LRE embedding 55 const sal_Unicode cRLE_Embedding = 0x202B; // the start char of an RLE embedding 56 const sal_Unicode cPopDirectionalFormat = 0x202C; // the unicode PDF (POP_DIRECTIONAL_FORMAT) char that terminates an LRE/RLE embedding 57 58 // check if there are alreay embedding characters at the strings start 59 // if so change nothing 60 const sal_Unicode cChar = rText.GetBuffer()[0]; 61 if (cChar == cLRE_Embedding || cChar == cRLE_Embedding) 62 return rText; 63 64 // since we only call the function getCharacterDirection 65 // it does not matter which locale the CharClass is for. 66 // Thus we can readily make use of SvtSysLocale::GetCharClass() 67 // which should come at no cost... 68 SvtSysLocale aSysLocale; 69 const CharClass &rCharClass = aSysLocale.GetCharClass(); 70 71 // we should look for the first non-neutral LTR or RTL character 72 // and use that to determine the embedding of the whole text... 73 // Thus we can avoid to check every character of the text. 74 bool bFound = false; 75 bool bIsRtlText = false; 76 for (sal_uInt16 i = 0; i < nLen && !bFound; ++i) 77 { 78 sal_Int16 nDirection = rCharClass.getCharacterDirection( rText, i ); 79 switch (nDirection) 80 { 81 case i18n::DirectionProperty_LEFT_TO_RIGHT : 82 case i18n::DirectionProperty_LEFT_TO_RIGHT_EMBEDDING : 83 case i18n::DirectionProperty_LEFT_TO_RIGHT_OVERRIDE : 84 case i18n::DirectionProperty_EUROPEAN_NUMBER : 85 case i18n::DirectionProperty_ARABIC_NUMBER : // yes! arabic numbers are written from left to right 86 { 87 bIsRtlText = false; 88 bFound = true; 89 break; 90 } 91 92 case i18n::DirectionProperty_RIGHT_TO_LEFT : 93 case i18n::DirectionProperty_RIGHT_TO_LEFT_ARABIC : 94 case i18n::DirectionProperty_RIGHT_TO_LEFT_EMBEDDING : 95 case i18n::DirectionProperty_RIGHT_TO_LEFT_OVERRIDE : 96 { 97 bIsRtlText = true; 98 bFound = true; 99 break; 100 } 101 102 default: 103 { 104 // nothing to be done, character is considered to be neutral we need to look further ... 105 } 106 } 107 } 108 109 sal_Unicode cStart = cLRE_Embedding; // default is to use LRE embedding characters 110 if (bIsRtlText) 111 cStart = cRLE_Embedding; // then use RLE embedding 112 113 // add embedding start and end chars to the text if the direction could be determined 114 String aRes( rText ); 115 if (bFound) 116 { 117 aRes.Insert( cStart, 0 ); 118 aRes.Insert( cPopDirectionalFormat ); 119 } 120 121 return aRes; 122 } 123 124 //------------------------------------------------------------------------ 125 126 SvtLanguageTable::SvtLanguageTable() : 127 ResStringArray( SvtResId( STR_ARR_SVT_LANGUAGE_TABLE ) ) 128 { 129 } 130 131 //------------------------------------------------------------------------ 132 133 SvtLanguageTable::~SvtLanguageTable() 134 { 135 } 136 137 //------------------------------------------------------------------------ 138 139 const String& SvtLanguageTable::GetString( const LanguageType eType ) const 140 { 141 LanguageType eLang = MsLangId::getReplacementForObsoleteLanguage( eType); 142 sal_uInt32 nPos = FindIndex( eLang ); 143 144 if ( RESARRAY_INDEX_NOTFOUND != nPos && nPos < Count() ) 145 return ResStringArray::GetString( nPos ); 146 else 147 { 148 // If we knew what a simple "en" should alias to (en_US?) we could 149 // generally raise an error. 150 OSL_ENSURE( 151 eLang == LANGUAGE_ENGLISH, "language entry not found in resource" ); 152 153 nPos = FindIndex( LANGUAGE_DONTKNOW ); 154 155 if ( RESARRAY_INDEX_NOTFOUND != nPos && nPos < Count() ) 156 return ResStringArray::GetString( nPos ); 157 } 158 static String aEmptyStr; 159 return aEmptyStr; 160 } 161 162 String SvtLanguageTable::GetLanguageString( const LanguageType eType ) 163 { 164 static const SvtLanguageTable aLangTable; 165 return aLangTable.GetString( eType ); 166 } 167 168 //------------------------------------------------------------------------ 169 170 LanguageType SvtLanguageTable::GetType( const String& rStr ) const 171 { 172 LanguageType eType = LANGUAGE_DONTKNOW; 173 sal_uInt32 nCount = Count(); 174 175 for ( sal_uInt32 i = 0; i < nCount; ++i ) 176 { 177 if ( rStr == ResStringArray::GetString( i ) ) 178 { 179 eType = LanguageType( GetValue( i ) ); 180 break; 181 } 182 } 183 return eType; 184 } 185 186 //------------------------------------------------------------------------ 187 188 sal_uInt32 SvtLanguageTable::GetEntryCount() const 189 { 190 return Count(); 191 } 192 193 //------------------------------------------------------------------------ 194 195 LanguageType SvtLanguageTable::GetTypeAtIndex( sal_uInt32 nIndex ) const 196 { 197 LanguageType nType = LANGUAGE_DONTKNOW; 198 if (nIndex < Count()) 199 nType = LanguageType( GetValue( nIndex ) ); 200 return nType; 201 } 202 203 //------------------------------------------------------------------------ 204 205