Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include "cellkeytranslator.hxx"
31 : : #include "comphelper/processfactory.hxx"
32 : : #include "i18npool/mslangid.hxx"
33 : : #include "i18npool/lang.h"
34 : : #include "rtl/ustring.hxx"
35 : :
36 : : #include <com/sun/star/i18n/TransliterationModules.hpp>
37 : :
38 : : using ::com::sun::star::lang::Locale;
39 : : using ::com::sun::star::uno::Sequence;
40 : : using ::std::list;
41 : : using ::boost::unordered_map;
42 : : using ::rtl::OUString;
43 : :
44 : : using namespace ::com::sun::star;
45 : :
46 : : enum LocaleMatch
47 : : {
48 : : LOCALE_MATCH_NONE = 0,
49 : : LOCALE_MATCH_LANG,
50 : : LOCALE_MATCH_LANG_COUNTRY,
51 : : LOCALE_MATCH_ALL
52 : : };
53 : :
54 : 0 : static LocaleMatch lclLocaleCompare(const Locale& rLocale1, const Locale& rLocale2)
55 : : {
56 : 0 : LocaleMatch eMatchLevel = LOCALE_MATCH_NONE;
57 [ # # ]: 0 : if ( !rLocale1.Language.compareTo(rLocale1.Language) )
58 : 0 : eMatchLevel = LOCALE_MATCH_LANG;
59 : : else
60 : 0 : return eMatchLevel;
61 : :
62 [ # # ]: 0 : if ( !rLocale1.Country.compareTo(rLocale2.Country) )
63 : 0 : eMatchLevel = LOCALE_MATCH_LANG_COUNTRY;
64 : : else
65 : 0 : return eMatchLevel;
66 : :
67 [ # # ]: 0 : if ( !rLocale1.Variant.compareTo(rLocale2.Variant) )
68 : 0 : eMatchLevel = LOCALE_MATCH_ALL;
69 : :
70 : 0 : return eMatchLevel;
71 : : }
72 : :
73 : 282 : ScCellKeyword::ScCellKeyword(const sal_Char* pName, OpCode eOpCode, const Locale& rLocale) :
74 : : mpName(pName),
75 : : meOpCode(eOpCode),
76 : 282 : mrLocale(rLocale)
77 : : {
78 : 282 : }
79 : :
80 : 51 : ::std::auto_ptr<ScCellKeywordTranslator> ScCellKeywordTranslator::spInstance(NULL);
81 : :
82 : 57 : static void lclMatchKeyword(String& rName, const ScCellKeywordHashMap& aMap,
83 : : OpCode eOpCode = ocNone, const Locale* pLocale = NULL)
84 : : {
85 [ + - ]: 57 : ScCellKeywordHashMap::const_iterator itrEnd = aMap.end();
86 [ + - ]: 57 : ScCellKeywordHashMap::const_iterator itr = aMap.find(rName);
87 : :
88 [ - + ][ # # ]: 57 : if ( itr == itrEnd || itr->second.empty() )
[ # # ][ - + ]
89 : : // No candidate strings exist. Bail out.
90 : : return;
91 : :
92 [ # # ][ # # ]: 0 : if ( eOpCode == ocNone && !pLocale )
93 : : {
94 : : // Since no locale nor opcode matching is needed, simply return
95 : : // the first item on the list.
96 [ # # ][ # # ]: 0 : rName = rtl::OUString::createFromAscii( itr->second.front().mpName );
[ # # ]
97 : : return;
98 : : }
99 : :
100 [ # # ][ # # ]: 0 : const sal_Char* aBestMatchName = itr->second.front().mpName;
101 : 0 : LocaleMatch eLocaleMatchLevel = LOCALE_MATCH_NONE;
102 : 0 : bool bOpCodeMatched = false;
103 : :
104 [ # # ]: 0 : list<ScCellKeyword>::const_iterator itrListEnd = itr->second.end();
105 [ # # ]: 0 : list<ScCellKeyword>::const_iterator itrList = itr->second.begin();
106 [ # # ]: 0 : for ( ; itrList != itrListEnd; ++itrList )
107 : : {
108 [ # # ][ # # ]: 0 : if ( eOpCode != ocNone && pLocale )
109 : : {
110 [ # # ]: 0 : if ( itrList->meOpCode == eOpCode )
111 : : {
112 : 0 : LocaleMatch eLevel = lclLocaleCompare(itrList->mrLocale, *pLocale);
113 [ # # ]: 0 : if ( eLevel == LOCALE_MATCH_ALL )
114 : : {
115 : : // Name with matching opcode and locale found.
116 [ # # ]: 0 : rName = rtl::OUString::createFromAscii( itrList->mpName );
117 : : return;
118 : : }
119 [ # # ]: 0 : else if ( eLevel > eLocaleMatchLevel )
120 : : {
121 : : // Name with a better matching locale.
122 : 0 : eLocaleMatchLevel = eLevel;
123 : 0 : aBestMatchName = itrList->mpName;
124 : : }
125 [ # # ]: 0 : else if ( !bOpCodeMatched )
126 : : // At least the opcode matches.
127 : 0 : aBestMatchName = itrList->mpName;
128 : :
129 : 0 : bOpCodeMatched = true;
130 : 0 : }
131 : : }
132 [ # # ][ # # ]: 0 : else if ( eOpCode != ocNone && !pLocale )
133 : : {
134 [ # # ]: 0 : if ( itrList->meOpCode == eOpCode )
135 : : {
136 : : // Name with a matching opcode preferred.
137 [ # # ]: 0 : rName = rtl::OUString::createFromAscii( itrList->mpName );
138 : : return;
139 : : }
140 : : }
141 [ # # ][ # # ]: 0 : else if ( !eOpCode && pLocale )
142 : : {
143 : 0 : LocaleMatch eLevel = lclLocaleCompare(itrList->mrLocale, *pLocale);
144 [ # # ]: 0 : if ( eLevel == LOCALE_MATCH_ALL )
145 : : {
146 : : // Name with matching locale preferred.
147 [ # # ]: 0 : rName = rtl::OUString::createFromAscii( itrList->mpName );
148 : : return;
149 : : }
150 [ # # ]: 0 : else if ( eLevel > eLocaleMatchLevel )
151 : : {
152 : : // Name with a better matching locale.
153 : 0 : eLocaleMatchLevel = eLevel;
154 : 0 : aBestMatchName = itrList->mpName;
155 : : }
156 : : }
157 : : }
158 : :
159 : : // No preferred strings found. Return the best matching name.
160 [ # # ]: 57 : rName = rtl::OUString::createFromAscii(aBestMatchName);
161 : : }
162 : :
163 : 57 : void ScCellKeywordTranslator::transKeyword(String& rName, const Locale* pLocale, OpCode eOpCode)
164 : : {
165 [ + + ]: 57 : if ( !spInstance.get() )
166 [ + - ][ + - ]: 6 : spInstance.reset( new ScCellKeywordTranslator );
167 : :
168 [ + - ][ + - ]: 57 : LanguageType eLang = pLocale ? MsLangId::convertLocaleToLanguageWithFallback(*pLocale) : LANGUAGE_SYSTEM;
169 [ + - ]: 57 : Sequence<sal_Int32> aOffsets;
170 [ + - ][ + - ]: 57 : rName = spInstance->maTransWrapper.transliterate(rName, eLang, 0, rName.Len(), &aOffsets);
[ + - ]
171 [ + - ][ + - ]: 57 : lclMatchKeyword(rName, spInstance->maStringNameMap, eOpCode, pLocale);
172 : 57 : }
173 : :
174 : 0 : void ScCellKeywordTranslator::transKeyword(rtl::OUString& rName, const Locale* pLocale, OpCode eOpCode)
175 : : {
176 [ # # ]: 0 : String aName = rName;
177 [ # # ]: 0 : transKeyword(aName, pLocale, eOpCode);
178 [ # # ][ # # ]: 0 : rName = aName;
179 : 0 : }
180 : :
181 : 6 : ScCellKeywordTranslator::ScCellKeywordTranslator() :
182 : : maTransWrapper( ::comphelper::getProcessServiceFactory(),
183 [ + - ][ + - ]: 6 : i18n::TransliterationModules_LOWERCASE_UPPERCASE )
[ + - ]
184 : : {
185 [ + - ]: 6 : init();
186 : 6 : }
187 : :
188 [ + - ]: 6 : ScCellKeywordTranslator::~ScCellKeywordTranslator()
189 : : {
190 : 6 : }
191 : :
192 : : struct TransItem
193 : : {
194 : : const sal_Unicode* from;
195 : : const sal_Char* to;
196 : : OpCode func;
197 : : };
198 : :
199 : 6 : void ScCellKeywordTranslator::init()
200 : : {
201 [ + - ][ + - ]: 6 : ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
202 : :
203 : : // The file below has been autogenerated by sc/workben/celltrans/parse.py.
204 : : // To add new locale keywords, edit sc/workben/celltrans/keywords_utf16.txt
205 : : // and re-run the parse.py script.
206 : : //
207 : : // All keywords must be uppercase, and the mapping must be from the
208 : : // localized keyword to the English keyword.
209 : : //
210 : : // Make sure that the original keyword file (keywords_utf16.txt) is
211 : : // encoded in UCS-2/UTF-16!
212 : :
213 : : #include "cellkeywords.inl"
214 : 6 : }
215 : :
216 : 282 : void ScCellKeywordTranslator::addToMap(const String& rKey, const sal_Char* pName, const Locale& rLocale, OpCode eOpCode)
217 : : {
218 : 282 : ScCellKeyword aKeyItem( pName, eOpCode, rLocale );
219 : :
220 [ + - ]: 282 : ScCellKeywordHashMap::iterator itrEnd = maStringNameMap.end();
221 [ + - ]: 282 : ScCellKeywordHashMap::iterator itr = maStringNameMap.find(rKey);
222 : :
223 [ + + ]: 282 : if ( itr == itrEnd )
224 : : {
225 : : // New keyword.
226 [ + - ]: 270 : list<ScCellKeyword> aList;
227 [ + - ]: 270 : aList.push_back(aKeyItem);
228 [ + - ][ + - ]: 270 : maStringNameMap.insert( ScCellKeywordHashMap::value_type(rKey, aList) );
[ + - ]
229 : : }
230 : : else
231 [ + - ][ + - ]: 12 : itr->second.push_back(aKeyItem);
232 : 282 : }
233 : :
234 : 18 : void ScCellKeywordTranslator::addToMap(const TransItem* pItems, const Locale& rLocale)
235 : : {
236 [ + + ]: 300 : for (sal_uInt16 i = 0; pItems[i].from != NULL; ++i)
237 [ + - ][ + - ]: 282 : addToMap(rtl::OUString(pItems[i].from), pItems[i].to, rLocale, pItems[i].func);
[ + - ]
238 [ + - ][ + - ]: 171 : }
239 : :
240 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|