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 : : #if defined(WNT)
31 : : #include <windows.h>
32 : : #endif
33 : :
34 : : #include <osl/thread.h>
35 : : #include <osl/file.hxx>
36 : : #include <tools/debug.hxx>
37 : : #include <tools/urlobj.hxx>
38 : : #include <i18npool/mslangid.hxx>
39 : : #include <unotools/lingucfg.hxx>
40 : : #include <unotools/pathoptions.hxx>
41 : : #include <rtl/ustring.hxx>
42 : : #include <rtl/string.hxx>
43 : : #include <rtl/tencinfo.h>
44 : : #include <linguistic/misc.hxx>
45 : :
46 : : #include <set>
47 : : #include <vector>
48 : : #include <string.h>
49 : :
50 : : #include <lingutil.hxx>
51 : : #include <dictmgr.hxx>
52 : :
53 : : #include <sal/macros.h>
54 : :
55 : :
56 : : using ::com::sun::star::lang::Locale;
57 : : using namespace ::com::sun::star;
58 : :
59 : : #if 0
60 : : //////////////////////////////////////////////////////////////////////
61 : :
62 : : String GetDirectoryPathFromFileURL( const String &rFileURL )
63 : : {
64 : : // get file URL
65 : : INetURLObject aURLObj;
66 : : aURLObj.SetSmartProtocol( INET_PROT_FILE );
67 : : aURLObj.SetSmartURL( rFileURL );
68 : : aURLObj.removeSegment();
69 : : DBG_ASSERT( !aURLObj.HasError(), "invalid URL" );
70 : : String aRes = aURLObj.GetMainURL( INetURLObject::DECODE_TO_IURI );
71 : : return aRes;
72 : : }
73 : : #endif
74 : :
75 : : #if defined(WNT)
76 : : rtl::OString Win_GetShortPathName( const rtl::OUString &rLongPathName )
77 : : {
78 : : rtl::OString aRes;
79 : :
80 : : sal_Unicode aShortBuffer[1024] = {0};
81 : : sal_Int32 nShortBufSize = SAL_N_ELEMENTS( aShortBuffer );
82 : :
83 : : // use the version of 'GetShortPathName' that can deal with Unicode...
84 : : sal_Int32 nShortLen = GetShortPathNameW(
85 : : reinterpret_cast<LPCWSTR>( rLongPathName.getStr() ),
86 : : reinterpret_cast<LPWSTR>( aShortBuffer ),
87 : : nShortBufSize );
88 : :
89 : : if (nShortLen < nShortBufSize) // conversion successful?
90 : : aRes = rtl::OString( OU2ENC( rtl::OUString( aShortBuffer, nShortLen ), osl_getThreadTextEncoding()) );
91 : : else
92 : : OSL_FAIL( "Win_GetShortPathName: buffer to short" );
93 : :
94 : : return aRes;
95 : : }
96 : : #endif //defined(WNT)
97 : :
98 : : //////////////////////////////////////////////////////////////////////
99 : :
100 : : // build list of old style diuctionaries (not as extensions) to use.
101 : : // User installed dictionaries (the ones residing in the user paths)
102 : : // will get precedence over system installed ones for the same language.
103 : 138 : std::vector< SvtLinguConfigDictionaryEntry > GetOldStyleDics( const char *pDicType )
104 : : {
105 [ + - ]: 138 : std::vector< SvtLinguConfigDictionaryEntry > aRes;
106 : :
107 [ + - ]: 138 : if (!pDicType)
108 : : return aRes;
109 : :
110 : 138 : rtl::OUString aFormatName;
111 [ + - ]: 138 : String aDicExtension;
112 : : #ifdef SYSTEM_DICTS
113 : 138 : rtl::OUString aSystemDir;
114 : 138 : rtl::OUString aSystemPrefix;
115 : 138 : rtl::OUString aSystemSuffix;
116 : : #endif
117 [ + + ]: 138 : if (strcmp( pDicType, "DICT" ) == 0)
118 : : {
119 [ + - ]: 46 : aFormatName = A2OU("DICT_SPELL");
120 [ + - ]: 46 : aDicExtension = rtl::OUString( ".dic" );
121 : : #ifdef SYSTEM_DICTS
122 [ + - ]: 46 : aSystemDir = A2OU( DICT_SYSTEM_DIR );
123 [ + - ]: 46 : aSystemSuffix = aDicExtension;
124 : : #endif
125 : : }
126 [ + + ]: 92 : else if (strcmp( pDicType, "HYPH" ) == 0)
127 : : {
128 [ + - ]: 46 : aFormatName = A2OU("DICT_HYPH");
129 [ + - ]: 46 : aDicExtension = rtl::OUString( ".dic" );
130 : : #ifdef SYSTEM_DICTS
131 [ + - ]: 46 : aSystemDir = A2OU( HYPH_SYSTEM_DIR );
132 [ + - ]: 46 : aSystemPrefix = A2OU( "hyph_" );
133 [ + - ]: 46 : aSystemSuffix = aDicExtension;
134 : : #endif
135 : : }
136 [ + - ]: 46 : else if (strcmp( pDicType, "THES" ) == 0)
137 : : {
138 [ + - ]: 46 : aFormatName = A2OU("DICT_THES");
139 [ + - ]: 46 : aDicExtension = rtl::OUString( ".dat" );
140 : : #ifdef SYSTEM_DICTS
141 [ + - ]: 46 : aSystemDir = A2OU( THES_SYSTEM_DIR );
142 [ + - ]: 46 : aSystemPrefix = A2OU( "th_" );
143 [ + - ]: 46 : aSystemSuffix = A2OU( "_v2.dat" );
144 : : #endif
145 : : }
146 : :
147 : :
148 [ + - ][ - + ]: 138 : if (aFormatName.isEmpty() || aDicExtension.Len() == 0)
[ + - ]
149 : : return aRes;
150 : :
151 : : // set of languages to remember the language where it is already
152 : : // decided to make use of the dictionary.
153 [ + - ]: 138 : std::set< LanguageType > aDicLangInUse;
154 : :
155 : : #ifdef SYSTEM_DICTS
156 : 138 : osl::Directory aSystemDicts(aSystemDir);
157 [ + - ][ + - ]: 138 : if (aSystemDicts.open() == osl::FileBase::E_None)
158 : : {
159 : 138 : osl::DirectoryItem aItem;
160 : 138 : osl::FileStatus aFileStatus(osl_FileStatus_Mask_FileURL);
161 [ + - ][ + + ]: 3036 : while (aSystemDicts.getNextItem(aItem) == osl::FileBase::E_None)
162 : : {
163 [ + - ]: 2898 : aItem.getFileStatus(aFileStatus);
164 [ + - ]: 2898 : rtl::OUString sPath = aFileStatus.getFileURL();
165 [ + + ]: 2898 : if (sPath.lastIndexOf(aSystemSuffix) == sPath.getLength()-aSystemSuffix.getLength())
166 : : {
167 : 1932 : sal_Int32 nStartIndex = sPath.lastIndexOf(sal_Unicode('/')) + 1;
168 [ - + ]: 1932 : if (!sPath.match(aSystemPrefix, nStartIndex))
169 : 0 : continue;
170 : 1932 : rtl::OUString sChunk = sPath.copy(0, sPath.getLength() - aSystemSuffix.getLength());
171 : 1932 : sal_Int32 nIndex = nStartIndex + aSystemPrefix.getLength();
172 : 1932 : rtl::OUString sLang = sChunk.getToken( 0, '_', nIndex );
173 [ - + ]: 1932 : if (!sLang.getLength())
174 : 0 : continue;
175 : 1932 : rtl::OUString sRegion;
176 [ + - ]: 1932 : if (nIndex != -1)
177 : 1932 : sRegion = sChunk.copy( nIndex, sChunk.getLength() - nIndex );
178 : :
179 : : // Thus we first get the language of the dictionary
180 : : LanguageType nLang = MsLangId::convertIsoNamesToLanguage(
181 [ + - ]: 1932 : sLang, sRegion );
182 : :
183 [ + - ][ + + ]: 1932 : if (aDicLangInUse.count( nLang ) == 0)
184 : : {
185 : : // remember the new language in use
186 [ + - ]: 1702 : aDicLangInUse.insert( nLang );
187 : :
188 : : // add the dictionary to the resulting vector
189 [ + - ]: 1702 : SvtLinguConfigDictionaryEntry aDicEntry;
190 [ + - ]: 1702 : aDicEntry.aLocations.realloc(1);
191 [ + - ]: 1702 : aDicEntry.aLocaleNames.realloc(1);
192 [ + - ]: 1702 : rtl::OUString aLocaleName( MsLangId::convertLanguageToIsoString( nLang ) );
193 [ + - ]: 1702 : aDicEntry.aLocations[0] = sPath;
194 : 1702 : aDicEntry.aFormatName = aFormatName;
195 [ + - ]: 1702 : aDicEntry.aLocaleNames[0] = aLocaleName;
196 [ + - ][ + - ]: 1702 : aRes.push_back( aDicEntry );
197 [ - + ][ + - ]: 2898 : }
198 : : }
199 [ + - ][ + - ]: 3036 : }
200 : : }
201 : :
202 : : #endif
203 : :
204 [ + - ][ + - ]: 138 : return aRes;
205 : : }
206 : :
207 : :
208 : 138 : void MergeNewStyleDicsAndOldStyleDics(
209 : : std::list< SvtLinguConfigDictionaryEntry > &rNewStyleDics,
210 : : const std::vector< SvtLinguConfigDictionaryEntry > &rOldStyleDics )
211 : : {
212 : : // get list of languages supported by new style dictionaries
213 [ + - ]: 138 : std::set< LanguageType > aNewStyleLanguages;
214 [ + - ]: 138 : std::list< SvtLinguConfigDictionaryEntry >::const_iterator aIt;
215 [ + - ][ + - ]: 782 : for (aIt = rNewStyleDics.begin() ; aIt != rNewStyleDics.end(); ++aIt)
[ + - ][ + - ]
[ + + ]
216 : : {
217 [ + - ][ + - ]: 644 : const uno::Sequence< rtl::OUString > aLocaleNames( aIt->aLocaleNames );
218 : 644 : sal_Int32 nLocaleNames = aLocaleNames.getLength();
219 [ + + ]: 6578 : for (sal_Int32 k = 0; k < nLocaleNames; ++k)
220 : : {
221 [ + - ]: 5934 : LanguageType nLang = MsLangId::convertIsoStringToLanguage( aLocaleNames[k] );
222 [ + - ]: 5934 : aNewStyleLanguages.insert( nLang );
223 : : }
224 [ + - ]: 644 : }
225 : :
226 : : // now check all old style dictionaries if they will add a not yet
227 : : // added language. If so add them to the resulting vector
228 : 138 : std::vector< SvtLinguConfigDictionaryEntry >::const_iterator aIt2;
229 [ + - ][ + - ]: 1840 : for (aIt2 = rOldStyleDics.begin(); aIt2 != rOldStyleDics.end(); ++aIt2)
[ + + ]
230 : : {
231 [ + - ]: 1702 : sal_Int32 nOldStyleDics = aIt2->aLocaleNames.getLength();
232 : :
233 : : // old style dics should only have one language listed...
234 : : DBG_ASSERT( nOldStyleDics, "old style dictionary with more then one language found!");
235 [ + - ]: 1702 : if (nOldStyleDics > 0)
236 : : {
237 [ + - ][ + - ]: 1702 : LanguageType nLang = MsLangId::convertIsoStringToLanguage( aIt2->aLocaleNames[0] );
238 : :
239 [ + - ][ - + ]: 1702 : if (nLang == LANGUAGE_DONTKNOW || nLang == LANGUAGE_NONE)
240 : : {
241 : : OSL_FAIL( "old style dictionary with invalid language found!" );
242 : 0 : continue;
243 : : }
244 : :
245 : : // language not yet added?
246 [ + - ][ + + ]: 1702 : if (aNewStyleLanguages.count( nLang ) == 0)
247 [ + - ][ + - ]: 1702 : rNewStyleDics.push_back( *aIt2 );
248 : : }
249 : : else
250 : : {
251 : : OSL_FAIL( "old style dictionary with no language found!" );
252 : : }
253 : 138 : }
254 : 138 : }
255 : :
256 : :
257 : 49 : rtl_TextEncoding getTextEncodingFromCharset(const sal_Char* pCharset)
258 : : {
259 : : // default result: used to indicate that we failed to get the proper encoding
260 : 49 : rtl_TextEncoding eRet = RTL_TEXTENCODING_DONTKNOW;
261 : :
262 [ + - ]: 49 : if (pCharset)
263 : : {
264 : 49 : eRet = rtl_getTextEncodingFromMimeCharset(pCharset);
265 [ - + ]: 49 : if (eRet == RTL_TEXTENCODING_DONTKNOW)
266 : 0 : eRet = rtl_getTextEncodingFromUnixCharset(pCharset);
267 [ - + ]: 49 : if (eRet == RTL_TEXTENCODING_DONTKNOW)
268 : : {
269 [ # # ]: 0 : if (strcmp("ISCII-DEVANAGARI", pCharset) == 0)
270 : 0 : eRet = RTL_TEXTENCODING_ISCII_DEVANAGARI;
271 : : }
272 : : }
273 : 49 : return eRet;
274 : : }
275 : :
276 : : //////////////////////////////////////////////////////////////////////
277 : :
278 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|