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_linguistic.hxx"
26 #include <tools/string.hxx>
27 #include <tools/fsys.hxx>
28 #include <tools/urlobj.hxx>
29 #include <ucbhelper/content.hxx>
30 #include <tools/debug.hxx>
31 #include <unotools/pathoptions.hxx>
32 #include <unotools/processfactory.hxx>
33 #include <unotools/localfilehelper.hxx>
34 #include <unotools/localedatawrapper.hxx>
35 #include <unotools/ucbhelper.hxx>
36 #include <com/sun/star/beans/XPropertySet.hpp>
37 #include <com/sun/star/beans/XFastPropertySet.hpp>
38
39 #include <com/sun/star/beans/PropertyValues.hpp>
40 #include <com/sun/star/uno/Sequence.hxx>
41 #include <com/sun/star/uno/Reference.h>
42
43 #include "linguistic/misc.hxx"
44
45 using namespace com::sun::star;
46
47 namespace linguistic
48 {
49
50 ///////////////////////////////////////////////////////////////////////////
51
FileExists(const String & rMainURL)52 sal_Bool FileExists( const String &rMainURL )
53 {
54 sal_Bool bExists = sal_False;
55 if (rMainURL.Len())
56 {
57 try
58 {
59 ::ucbhelper::Content aContent( rMainURL,
60 uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >());
61 bExists = aContent.isDocument();
62 }
63 catch (uno::Exception &)
64 {
65 }
66 }
67 return bExists;
68 }
69
70
71 #ifdef TL_OUTDATED
72
GetFileURL(SvtPathOptions::Pathes ePath,const String & rFileName)73 String GetFileURL( SvtPathOptions::Pathes ePath, const String &rFileName )
74 {
75 String aURL;
76 if (rFileName.Len())
77 {
78 INetURLObject aURLObj;
79 aURLObj.SetSmartProtocol( INET_PROT_FILE );
80 aURLObj.SetSmartURL( GetModulePath(ePath) );
81 aURLObj.Append( rFileName );
82 if (aURLObj.HasError())
83 {
84 DBG_ASSERT(!aURLObj.HasError(), "lng : invalid URL");
85 }
86 aURL = aURLObj.GetMainURL( INetURLObject::DECODE_TO_IURI );
87 }
88 return aURL;
89 }
90
91
GetModulePath(SvtPathOptions::Pathes ePath,sal_Bool bAddAccessDelim)92 String GetModulePath( SvtPathOptions::Pathes ePath, sal_Bool bAddAccessDelim )
93 {
94 String aRes;
95
96 SvtPathOptions aPathOpt;
97 switch (ePath)
98 {
99 case SvtPathOptions::PATH_MODULE :
100 aRes = aPathOpt.GetModulePath();
101 break;
102 case SvtPathOptions::PATH_LINGUISTIC :
103 {
104 String aTmp( aPathOpt.GetLinguisticPath() );
105 utl::LocalFileHelper::ConvertURLToPhysicalName( aTmp, aRes );
106 break;
107 }
108 /*
109 case SvtPathOptions::PATH_USERDICTIONARY :
110 {
111 String aTmp( aPathOpt.GetUserDictionaryPath() );
112 utl::LocalFileHelper::ConvertURLToPhysicalName( aTmp, aRes );
113 break;
114 }
115 */
116 default:
117 DBG_ASSERT( 0, "unexpected argument (path)" );
118 }
119 if (bAddAccessDelim && aRes.Len())
120 {
121 #ifdef WNT
122 aRes += '\\';
123 #else
124 aRes += '/';
125 #endif
126 }
127
128 return aRes;
129 }
130
131 #endif
132
133 ///////////////////////////////////////////////////////////////////////////
134
StripTrailingChars(rtl::OUString & rTxt,sal_Unicode cChar)135 rtl::OUString StripTrailingChars( rtl::OUString &rTxt, sal_Unicode cChar )
136 {
137 sal_Int32 nTrailing = 0;
138 sal_Int32 nTxtLen = rTxt.getLength();
139 sal_Int32 nIdx = nTxtLen - 1;
140 while (nIdx >= 0 && rTxt[ nIdx-- ] == cChar)
141 ++nTrailing;
142
143 rtl::OUString aRes( rTxt.copy( nTxtLen - nTrailing ) );
144 rTxt = rTxt.copy( 0, nTxtLen - nTrailing );
145 return aRes;
146 }
147
148 ///////////////////////////////////////////////////////////////////////////
149
GetMultiPaths_Impl(const rtl::OUString & rPathPrefix,sal_Int16 nPathFlags)150 static uno::Sequence< rtl::OUString > GetMultiPaths_Impl(
151 const rtl::OUString &rPathPrefix,
152 sal_Int16 nPathFlags )
153 {
154 uno::Sequence< rtl::OUString > aRes;
155 uno::Sequence< rtl::OUString > aInternalPaths;
156 uno::Sequence< rtl::OUString > aUserPaths;
157 rtl::OUString aWritablePath;
158
159 bool bSuccess = true;
160 uno::Reference< lang::XMultiServiceFactory > xMgr( utl::getProcessServiceFactory() );
161 if (xMgr.is())
162 {
163 try
164 {
165 String aInternal( rPathPrefix );
166 String aUser( rPathPrefix );
167 String aWriteable( rPathPrefix );
168 aInternal .AppendAscii( "_internal" );
169 aUser .AppendAscii( "_user" );
170 aWriteable.AppendAscii( "_writable" );
171
172 uno::Reference< beans::XPropertySet > xPathSettings( xMgr->createInstance(
173 A2OU( "com.sun.star.util.PathSettings" ) ), uno::UNO_QUERY_THROW );
174 xPathSettings->getPropertyValue( aInternal ) >>= aInternalPaths;
175 xPathSettings->getPropertyValue( aUser ) >>= aUserPaths;
176 xPathSettings->getPropertyValue( aWriteable ) >>= aWritablePath;
177 }
178 catch (uno::Exception &)
179 {
180 bSuccess = false;
181 }
182 }
183 if (bSuccess)
184 {
185 // build resulting sequence by adding the pathes in the following order:
186 // 1. writable path
187 // 2. all user pathes
188 // 3. all internal pathes
189 sal_Int32 nMaxEntries = aInternalPaths.getLength() + aUserPaths.getLength();
190 if (aWritablePath.getLength() > 0)
191 ++nMaxEntries;
192 aRes.realloc( nMaxEntries );
193 rtl::OUString *pRes = aRes.getArray();
194 sal_Int32 nCount = 0; // number of actually added entries
195 if ((nPathFlags & PATH_FLAG_WRITABLE) && aWritablePath.getLength() != 0)
196 pRes[ nCount++ ] = aWritablePath;
197 for (int i = 0; i < 2; ++i)
198 {
199 const uno::Sequence< rtl::OUString > &rPathSeq = i == 0 ? aUserPaths : aInternalPaths;
200 const rtl::OUString *pPathSeq = rPathSeq.getConstArray();
201 for (sal_Int32 k = 0; k < rPathSeq.getLength(); ++k)
202 {
203 const bool bAddUser = &rPathSeq == &aUserPaths && (nPathFlags & PATH_FLAG_USER);
204 const bool bAddInternal = &rPathSeq == &aInternalPaths && (nPathFlags & PATH_FLAG_INTERNAL);
205 if ((bAddUser || bAddInternal) && pPathSeq[k].getLength() > 0)
206 pRes[ nCount++ ] = pPathSeq[k];
207 }
208 }
209 aRes.realloc( nCount );
210 }
211
212 return aRes;
213 }
214
GetDictionaryWriteablePath()215 rtl::OUString GetDictionaryWriteablePath()
216 {
217 uno::Sequence< rtl::OUString > aPaths( GetMultiPaths_Impl( A2OU("Dictionary"), PATH_FLAG_WRITABLE ) );
218 DBG_ASSERT( aPaths.getLength() == 1, "Dictionary_writable path corrupted?" );
219 String aRes;
220 if (aPaths.getLength() > 0)
221 aRes = aPaths[0];
222 return aRes;
223 }
224
GetDictionaryPaths(sal_Int16 nPathFlags)225 uno::Sequence< rtl::OUString > GetDictionaryPaths( sal_Int16 nPathFlags )
226 {
227 return GetMultiPaths_Impl( A2OU("Dictionary"), nPathFlags );
228 }
229
GetLinguisticPaths(sal_Int16 nPathFlags)230 uno::Sequence< rtl::OUString > GetLinguisticPaths( sal_Int16 nPathFlags )
231 {
232 return GetMultiPaths_Impl( A2OU("Linguistic"), nPathFlags );
233 }
234
GetWritableDictionaryURL(const String & rDicName)235 String GetWritableDictionaryURL( const String &rDicName )
236 {
237 // new user writable dictionaries should be created in the 'writable' path
238 String aDirName( GetDictionaryWriteablePath() );
239
240 // build URL to use for a new (persistent) dictionary
241 INetURLObject aURLObj;
242 aURLObj.SetSmartProtocol( INET_PROT_FILE );
243 aURLObj.SetSmartURL( aDirName );
244 DBG_ASSERT(!aURLObj.HasError(), "lng : invalid URL");
245 aURLObj.Append( rDicName, INetURLObject::ENCODE_ALL );
246 DBG_ASSERT(!aURLObj.HasError(), "lng : invalid URL");
247
248 // NO_DECODE preserves the escape sequences that might be included in aDirName
249 // depending on the characters used in the path string. (Needed when comparing
250 // the dictionary URL with GetDictionaryWriteablePath in DicList::createDictionary.)
251 return aURLObj.GetMainURL( INetURLObject::NO_DECODE );
252 }
253
254
SearchFileInPaths(const String & rFile,const uno::Sequence<rtl::OUString> & rPaths)255 String SearchFileInPaths(
256 const String &rFile,
257 const uno::Sequence< rtl::OUString > &rPaths )
258 {
259 //!! see also SvtPathOptions::SearchFile for the riginal code
260
261 String aRes;
262
263 // check in all paths...
264 const sal_Int32 nPaths = rPaths.getLength();
265 for (sal_Int32 k = 0; k < nPaths; ++k)
266 {
267 sal_Bool bIsURL = sal_True;
268 INetURLObject aObj( rPaths[k] );
269 if ( aObj.HasError() )
270 {
271 bIsURL = sal_False;
272 String aURL;
273 if ( utl::LocalFileHelper::ConvertPhysicalNameToURL( rPaths[k], aURL ) )
274 aObj.SetURL( aURL );
275 }
276
277 xub_StrLen i, nCount = rFile.GetTokenCount( '/' );
278 for ( i = 0; i < nCount; ++i )
279 aObj.insertName( rFile.GetToken( i, '/' ) );
280 bool bRet = ::utl::UCBContentHelper::Exists( aObj.GetMainURL( INetURLObject::NO_DECODE ) );
281
282 if ( bRet )
283 {
284 if ( !bIsURL )
285 ::utl::LocalFileHelper::ConvertURLToPhysicalName(
286 aObj.GetMainURL( INetURLObject::NO_DECODE ), aRes );
287 else
288 aRes = aObj.GetMainURL( INetURLObject::NO_DECODE );
289 break;
290 }
291 }
292
293 return aRes;
294 }
295
296
297 } // namespace linguistic
298
299
300