xref: /trunk/main/svtools/source/misc/langtab.cxx (revision 353566969a66957f00012e88c396ae18ac1cc883)
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 // MARKER(update_precomp.py): autogen include statement, do not remove
23 #include "precompiled_svtools.hxx"
24 
25 // include ---------------------------------------------------------------
26 
27 #include <tools/shl.hxx>
28 #include <tools/debug.hxx>
29 
30 //#include <com/sun/star/i18n/XCharacterClassification.hpp>
31 #include <com/sun/star/i18n/DirectionProperty.hpp>
32 
33 #include <i18npool/lang.h>
34 #include <i18npool/mslangid.hxx>
35 
36 #include <svtools/svtools.hrc>
37 #include <svtools/svtdata.hxx>
38 #include <svtools/langtab.hxx>
39 #include <unotools/syslocale.hxx>
40 
41 
42 using namespace ::com::sun::star;
43 
44 //------------------------------------------------------------------------
45 
ApplyLreOrRleEmbedding(const String & rText)46 SVT_DLLPUBLIC const String ApplyLreOrRleEmbedding( const String &rText )
47 {
48     const sal_uInt16 nLen = rText.Len();
49     if (nLen == 0)
50         return String();
51 
52     const sal_Unicode cLRE_Embedding  = 0x202A;      // the start char of an LRE embedding
53     const sal_Unicode cRLE_Embedding  = 0x202B;      // the start char of an RLE embedding
54     const sal_Unicode cPopDirectionalFormat = 0x202C;   // the unicode PDF (POP_DIRECTIONAL_FORMAT) char that terminates an LRE/RLE embedding
55 
56     // check if there are already embedding characters at the strings start
57     // if so change nothing
58     const sal_Unicode cChar = rText.GetBuffer()[0];
59     if (cChar == cLRE_Embedding || cChar == cRLE_Embedding)
60         return rText;
61 
62     // since we only call the function getCharacterDirection
63     // it does not matter which locale the CharClass is for.
64     // Thus we can readily make use of SvtSysLocale::GetCharClass()
65     // which should come at no cost...
66     SvtSysLocale aSysLocale;
67     const CharClass &rCharClass = aSysLocale.GetCharClass();
68 
69     // we should look for the first non-neutral LTR or RTL character
70     // and use that to determine the embedding of the whole text...
71     // Thus we can avoid to check every character of the text.
72     bool bFound     = false;
73     bool bIsRtlText = false;
74     for (sal_uInt16 i = 0;  i < nLen && !bFound;  ++i)
75     {
76         sal_Int16 nDirection = rCharClass.getCharacterDirection( rText, i );
77         switch (nDirection)
78         {
79             case i18n::DirectionProperty_LEFT_TO_RIGHT :
80             case i18n::DirectionProperty_LEFT_TO_RIGHT_EMBEDDING :
81             case i18n::DirectionProperty_LEFT_TO_RIGHT_OVERRIDE :
82             case i18n::DirectionProperty_EUROPEAN_NUMBER :
83             case i18n::DirectionProperty_ARABIC_NUMBER :        // yes! arabic numbers are written from left to right
84             {
85                 bIsRtlText  = false;
86                 bFound      = true;
87                 break;
88             }
89 
90             case i18n::DirectionProperty_RIGHT_TO_LEFT :
91             case i18n::DirectionProperty_RIGHT_TO_LEFT_ARABIC :
92             case i18n::DirectionProperty_RIGHT_TO_LEFT_EMBEDDING :
93             case i18n::DirectionProperty_RIGHT_TO_LEFT_OVERRIDE :
94             {
95                 bIsRtlText  = true;
96                 bFound      = true;
97                 break;
98             }
99 
100             default:
101             {
102                 // nothing to be done, character is considered to be neutral we need to look further ...
103             }
104         }
105     }
106 
107     sal_Unicode cStart  = cLRE_Embedding; // default is to use LRE embedding characters
108     if (bIsRtlText)
109         cStart = cRLE_Embedding; // then use RLE embedding
110 
111     // add embedding start and end chars to the text if the direction could be determined
112     String aRes( rText );
113     if (bFound)
114     {
115         aRes.Insert( cStart, 0 );
116         aRes.Insert( cPopDirectionalFormat );
117     }
118 
119     return aRes;
120 }
121 
122 //------------------------------------------------------------------------
123 
SvtLanguageTable()124 SvtLanguageTable::SvtLanguageTable() :
125     ResStringArray( SvtResId( STR_ARR_SVT_LANGUAGE_TABLE ) )
126 {
127 }
128 
129 //------------------------------------------------------------------------
130 
~SvtLanguageTable()131 SvtLanguageTable::~SvtLanguageTable()
132 {
133 }
134 
135 //------------------------------------------------------------------------
136 
GetString(const LanguageType eType) const137 const String& SvtLanguageTable::GetString( const LanguageType eType ) const
138 {
139     LanguageType eLang = MsLangId::getReplacementForObsoleteLanguage( eType);
140     sal_uInt32 nPos = FindIndex( eLang );
141 
142     if ( RESARRAY_INDEX_NOTFOUND != nPos && nPos < Count() )
143         return ResStringArray::GetString( nPos );
144     else
145     {
146         // If we knew what a simple "en" should alias to (en_US?) we could
147         // generally raise an error.
148         OSL_ENSURE(
149             eLang == LANGUAGE_ENGLISH, "language entry not found in resource" );
150 
151         nPos = FindIndex( LANGUAGE_DONTKNOW );
152 
153         if ( RESARRAY_INDEX_NOTFOUND != nPos && nPos < Count() )
154             return ResStringArray::GetString( nPos );
155     }
156     static String aEmptyStr;
157     return aEmptyStr;
158 }
159 
GetLanguageString(const LanguageType eType)160 String SvtLanguageTable::GetLanguageString( const LanguageType eType )
161 {
162     static const SvtLanguageTable aLangTable;
163     return aLangTable.GetString( eType );
164 }
165 
166 //------------------------------------------------------------------------
167 
GetType(const String & rStr) const168 LanguageType SvtLanguageTable::GetType( const String& rStr ) const
169 {
170     LanguageType eType = LANGUAGE_DONTKNOW;
171     sal_uInt32 nCount = Count();
172 
173     for ( sal_uInt32 i = 0; i < nCount; ++i )
174     {
175         if ( rStr == ResStringArray::GetString( i ) )
176         {
177             eType = LanguageType( GetValue( i ) );
178             break;
179         }
180     }
181     return eType;
182 }
183 
184 //------------------------------------------------------------------------
185 
GetEntryCount() const186 sal_uInt32 SvtLanguageTable::GetEntryCount() const
187 {
188     return Count();
189 }
190 
191 //------------------------------------------------------------------------
192 
GetTypeAtIndex(sal_uInt32 nIndex) const193 LanguageType SvtLanguageTable::GetTypeAtIndex( sal_uInt32 nIndex ) const
194 {
195     LanguageType nType = LANGUAGE_DONTKNOW;
196     if (nIndex < Count())
197         nType = LanguageType( GetValue( nIndex ) );
198     return nType;
199 }
200 
201 //------------------------------------------------------------------------
202