1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: cellkeytranslator.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
34 #include "cellkeytranslator.hxx"
35 #include "comphelper/processfactory.hxx"
36 #include "i18npool/mslangid.hxx"
37 #include "i18npool/lang.h"
38 #include "rtl/ustring.hxx"
40 #include <com/sun/star/i18n/TransliterationModules.hpp>
42 using ::com::sun::star::lang::Locale
;
43 using ::com::sun::star::uno::Sequence
;
45 using ::std::hash_map
;
46 using ::rtl::OUString
;
48 using namespace ::com::sun::star
;
52 LOCALE_MATCH_NONE
= 0,
54 LOCALE_MATCH_LANG_COUNTRY
,
58 static LocaleMatch
lclLocaleCompare(const Locale
& rLocale1
, const Locale
& rLocale2
)
60 LocaleMatch eMatchLevel
= LOCALE_MATCH_NONE
;
61 if ( !rLocale1
.Language
.compareTo(rLocale1
.Language
) )
62 eMatchLevel
= LOCALE_MATCH_LANG
;
66 if ( !rLocale1
.Country
.compareTo(rLocale2
.Country
) )
67 eMatchLevel
= LOCALE_MATCH_LANG_COUNTRY
;
71 if ( !rLocale1
.Variant
.compareTo(rLocale2
.Variant
) )
72 eMatchLevel
= LOCALE_MATCH_ALL
;
77 ScCellKeyword::ScCellKeyword(const sal_Char
* pName
, OpCode eOpCode
, const Locale
& rLocale
) :
84 ::std::auto_ptr
<ScCellKeywordTranslator
> ScCellKeywordTranslator::spInstance(NULL
);
86 static void lclMatchKeyword(String
& rName
, const ScCellKeywordHashMap
& aMap
,
87 OpCode eOpCode
= ocNone
, const Locale
* pLocale
= NULL
)
89 ScCellKeywordHashMap::const_iterator itrEnd
= aMap
.end();
90 ScCellKeywordHashMap::const_iterator itr
= aMap
.find(rName
);
92 if ( itr
== itrEnd
|| itr
->second
.empty() )
93 // No candidate strings exist. Bail out.
96 if ( eOpCode
== ocNone
&& !pLocale
)
98 // Since no locale nor opcode matching is needed, simply return
99 // the first item on the list.
100 rName
= String::CreateFromAscii( itr
->second
.front().mpName
);
104 const sal_Char
* aBestMatchName
= itr
->second
.front().mpName
;
105 LocaleMatch eLocaleMatchLevel
= LOCALE_MATCH_NONE
;
106 bool bOpCodeMatched
= false;
108 list
<ScCellKeyword
>::const_iterator itrListEnd
= itr
->second
.end();
109 list
<ScCellKeyword
>::const_iterator itrList
= itr
->second
.begin();
110 for ( ; itrList
!= itrListEnd
; ++itrList
)
112 if ( eOpCode
!= ocNone
&& pLocale
)
114 if ( itrList
->meOpCode
== eOpCode
)
116 LocaleMatch eLevel
= lclLocaleCompare(itrList
->mrLocale
, *pLocale
);
117 if ( eLevel
== LOCALE_MATCH_ALL
)
119 // Name with matching opcode and locale found.
120 rName
= String::CreateFromAscii( itrList
->mpName
);
123 else if ( eLevel
> eLocaleMatchLevel
)
125 // Name with a better matching locale.
126 eLocaleMatchLevel
= eLevel
;
127 aBestMatchName
= itrList
->mpName
;
129 else if ( !bOpCodeMatched
)
130 // At least the opcode matches.
131 aBestMatchName
= itrList
->mpName
;
133 bOpCodeMatched
= true;
136 else if ( eOpCode
!= ocNone
&& !pLocale
)
138 if ( itrList
->meOpCode
== eOpCode
)
140 // Name with a matching opcode preferred.
141 rName
= String::CreateFromAscii( itrList
->mpName
);
145 else if ( !eOpCode
&& pLocale
)
147 LocaleMatch eLevel
= lclLocaleCompare(itrList
->mrLocale
, *pLocale
);
148 if ( eLevel
== LOCALE_MATCH_ALL
)
150 // Name with matching locale preferred.
151 rName
= String::CreateFromAscii( itrList
->mpName
);
154 else if ( eLevel
> eLocaleMatchLevel
)
156 // Name with a better matching locale.
157 eLocaleMatchLevel
= eLevel
;
158 aBestMatchName
= itrList
->mpName
;
163 // No preferred strings found. Return the best matching name.
164 rName
= String::CreateFromAscii(aBestMatchName
);
167 void ScCellKeywordTranslator::transKeyword(String
& rName
, const Locale
* pLocale
, OpCode eOpCode
)
169 if ( !spInstance
.get() )
170 spInstance
.reset( new ScCellKeywordTranslator
);
172 LanguageType eLang
= pLocale
? MsLangId::convertLocaleToLanguageWithFallback(*pLocale
) : LANGUAGE_SYSTEM
;
173 Sequence
<sal_Int32
> aOffsets
;
174 rName
= spInstance
->maTransWrapper
.transliterate(rName
, eLang
, 0, rName
.Len(), &aOffsets
);
175 lclMatchKeyword(rName
, spInstance
->maStringNameMap
, eOpCode
, pLocale
);
178 ScCellKeywordTranslator::ScCellKeywordTranslator() :
179 maTransWrapper( ::comphelper::getProcessServiceFactory(),
180 i18n::TransliterationModules_LOWERCASE_UPPERCASE
)
185 ScCellKeywordTranslator::~ScCellKeywordTranslator()
191 const sal_Unicode
* from
;
196 void ScCellKeywordTranslator::init()
198 ::osl::MutexGuard
aGuard( ::osl::Mutex::getGlobalMutex() );
200 // The file below has been autogenerated by sc/workben/celltrans/parse.py.
201 // To add new locale keywords, edit sc/workben/celltrans/keywords_utf16.txt
202 // and re-run the parse.py script.
204 // All keywords must be uppercase, and the mapping must be from the
205 // localized keyword to the English keyword.
207 // Make sure that the original keyword file (keywords_utf16.txt) is
208 // encoded in UCS-2/UTF-16!
210 #include "cellkeywords.inl"
213 void ScCellKeywordTranslator::addToMap(const String
& rKey
, const sal_Char
* pName
, const Locale
& rLocale
, OpCode eOpCode
)
215 ScCellKeyword
aKeyItem( pName
, eOpCode
, rLocale
);
217 ScCellKeywordHashMap::iterator itrEnd
= maStringNameMap
.end();
218 ScCellKeywordHashMap::iterator itr
= maStringNameMap
.find(rKey
);
223 list
<ScCellKeyword
> aList
;
224 aList
.push_back(aKeyItem
);
225 maStringNameMap
.insert( ScCellKeywordHashMap::value_type(rKey
, aList
) );
228 itr
->second
.push_back(aKeyItem
);
231 void ScCellKeywordTranslator::addToMap(const TransItem
* pItems
, const Locale
& rLocale
)
233 for (sal_uInt16 i
= 0; pItems
[i
].from
!= NULL
; ++i
)
234 addToMap(String(pItems
[i
].from
), pItems
[i
].to
, rLocale
, pItems
[i
].func
);