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_svl.hxx" 26 27 #include <svl/asiancfg.hxx> 28 #include <svl/svarray.hxx> 29 #include <com/sun/star/uno/Any.hxx> 30 #include <com/sun/star/uno/Sequence.hxx> 31 #include <com/sun/star/lang/Locale.hpp> 32 #include <com/sun/star/beans/PropertyValue.hpp> 33 #include <tools/debug.hxx> 34 35 //----------------------------------------------------------------------------- 36 using namespace utl; 37 using namespace rtl; 38 using namespace com::sun::star; 39 using namespace com::sun::star::uno; 40 using namespace com::sun::star::beans; 41 using namespace com::sun::star::lang; 42 43 #define C2U(cChar) OUString::createFromAscii(cChar) 44 const sal_Char sStartEndCharacters[] = "StartEndCharacters"; 45 const sal_Char sStartCharacters[] = "StartCharacters"; 46 const sal_Char sEndCharacters[] = "EndCharacters"; 47 48 //----------------------------------------------------------------------------- 49 struct SvxForbiddenStruct_Impl 50 { 51 Locale aLocale; 52 OUString sStartChars; 53 OUString sEndChars; 54 }; 55 //----------------------------------------------------------------------------- 56 typedef SvxForbiddenStruct_Impl* SvxForbiddenStruct_ImplPtr; 57 SV_DECL_PTRARR_DEL(SvxForbiddenStructArr, SvxForbiddenStruct_ImplPtr, 2, 2) 58 SV_IMPL_PTRARR(SvxForbiddenStructArr, SvxForbiddenStruct_ImplPtr); 59 //----------------------------------------------------------------------------- 60 struct SvxAsianConfig_Impl 61 { 62 sal_Bool bKerningWesternTextOnly; 63 sal_Int16 nCharDistanceCompression; 64 65 SvxForbiddenStructArr aForbiddenArr; 66 67 SvxAsianConfig_Impl() : 68 bKerningWesternTextOnly(sal_True), 69 nCharDistanceCompression(0) {} 70 }; 71 /* -----------------------------16.01.01 15:36-------------------------------- 72 73 ---------------------------------------------------------------------------*/ 74 Sequence<OUString> lcl_GetPropertyNames() 75 { 76 Sequence<OUString> aNames(2); 77 OUString* pNames = aNames.getArray(); 78 pNames[0] = C2U("IsKerningWesternTextOnly"); 79 pNames[1] = C2U("CompressCharacterDistance"); 80 return aNames;; 81 } 82 // --------------------------------------------------------------------------- 83 SvxAsianConfig::SvxAsianConfig(sal_Bool bEnableNotify) : 84 utl::ConfigItem(C2U("Office.Common/AsianLayout")), 85 pImpl(new SvxAsianConfig_Impl) 86 { 87 if(bEnableNotify) 88 EnableNotification(lcl_GetPropertyNames()); 89 Load(); 90 } 91 /* -----------------------------16.01.01 15:36-------------------------------- 92 93 ---------------------------------------------------------------------------*/ 94 SvxAsianConfig::~SvxAsianConfig() 95 { 96 delete pImpl; 97 } 98 /* -----------------------------17.01.01 09:57-------------------------------- 99 100 ---------------------------------------------------------------------------*/ 101 void SvxAsianConfig::Load() 102 { 103 Sequence<Any> aValues = GetProperties(lcl_GetPropertyNames()); 104 const Any* pValues = aValues.getConstArray(); 105 if(pValues[0].hasValue()) 106 pImpl->bKerningWesternTextOnly = *(sal_Bool*) pValues[0].getValue(); 107 pValues[1] >>= pImpl->nCharDistanceCompression; 108 109 pImpl->aForbiddenArr.DeleteAndDestroy(0, pImpl->aForbiddenArr.Count()); 110 OUString sPropPrefix(C2U(sStartEndCharacters)); 111 Sequence<OUString> aNodes = GetNodeNames(sPropPrefix); 112 113 Sequence<OUString> aPropNames(aNodes.getLength() * 2); 114 OUString* pNames = aPropNames.getArray(); 115 sal_Int32 nName = 0; 116 sPropPrefix += C2U("/"); 117 sal_Int32 nNode; 118 const OUString* pNodes = aNodes.getConstArray(); 119 for(nNode = 0; nNode < aNodes.getLength(); nNode++) 120 { 121 OUString sStart(sPropPrefix); 122 sStart += pNodes[nNode]; 123 sStart += C2U("/"); 124 pNames[nName] = sStart; pNames[nName++] += C2U("StartCharacters"); 125 pNames[nName] = sStart; pNames[nName++] += C2U("EndCharacters"); 126 } 127 Sequence<Any> aNodeValues = GetProperties(aPropNames); 128 const Any* pNodeValues = aNodeValues.getConstArray(); 129 nName = 0; 130 for(nNode = 0; nNode < aNodes.getLength(); nNode++) 131 { 132 SvxForbiddenStruct_ImplPtr pInsert = new SvxForbiddenStruct_Impl; 133 pInsert->aLocale.Language = pNodes[nNode].copy(0, 2); 134 DBG_ASSERT(pInsert->aLocale.Language.getLength(), "illegal language"); 135 pInsert->aLocale.Country = pNodes[nNode].copy(3, 2); 136 137 pNodeValues[nName++] >>= pInsert->sStartChars; 138 pNodeValues[nName++] >>= pInsert->sEndChars; 139 pImpl->aForbiddenArr.Insert(pInsert, pImpl->aForbiddenArr.Count()); 140 } 141 } 142 /* -----------------------------17.01.01 09:57-------------------------------- 143 144 ---------------------------------------------------------------------------*/ 145 void SvxAsianConfig::Notify( const Sequence<OUString>& ) 146 { 147 Load(); 148 } 149 /* -----------------------------16.01.01 15:36-------------------------------- 150 151 ---------------------------------------------------------------------------*/ 152 void SvxAsianConfig::Commit() 153 { 154 Sequence<Any> aValues(2); 155 Any* pValues = aValues.getArray(); 156 pValues[0].setValue(&pImpl->bKerningWesternTextOnly, ::getBooleanCppuType()); 157 pValues[1] <<= pImpl->nCharDistanceCompression; 158 PutProperties(lcl_GetPropertyNames(), aValues); 159 160 161 OUString sNode(C2U(sStartEndCharacters)); 162 if(!pImpl->aForbiddenArr.Count()) 163 ClearNodeSet(sNode); 164 else 165 { 166 Sequence<PropertyValue> aSetValues(2 * pImpl->aForbiddenArr.Count()); 167 PropertyValue* pSetValues = aSetValues.getArray(); 168 sal_Int32 nSetValue = 0; 169 const OUString sStartChars(C2U(sStartCharacters)); 170 const OUString sEndChars(C2U(sEndCharacters)); 171 for(sal_uInt16 i = 0; i < pImpl->aForbiddenArr.Count(); i++) 172 { 173 OUString sPrefix(sNode); 174 sPrefix += C2U("/"); 175 sPrefix += pImpl->aForbiddenArr[i]->aLocale.Language; 176 DBG_ASSERT(pImpl->aForbiddenArr[i]->aLocale.Language.getLength(), "illegal language"); 177 sPrefix += C2U("-"); 178 sPrefix += pImpl->aForbiddenArr[i]->aLocale.Country; 179 sPrefix += C2U("/"); 180 pSetValues[nSetValue].Name = sPrefix; pSetValues[nSetValue].Name += sStartChars; 181 pSetValues[nSetValue++].Value <<= pImpl->aForbiddenArr[i]->sStartChars; 182 pSetValues[nSetValue].Name = sPrefix; pSetValues[nSetValue].Name += sEndChars; 183 pSetValues[nSetValue++].Value <<= pImpl->aForbiddenArr[i]->sEndChars; 184 } 185 ReplaceSetProperties(sNode, aSetValues); 186 } 187 } 188 /* -----------------------------16.01.01 15:36-------------------------------- 189 190 ---------------------------------------------------------------------------*/ 191 sal_Bool SvxAsianConfig::IsKerningWesternTextOnly() const 192 { 193 return pImpl->bKerningWesternTextOnly; 194 } 195 /* -----------------------------16.01.01 15:36-------------------------------- 196 197 ---------------------------------------------------------------------------*/ 198 void SvxAsianConfig::SetKerningWesternTextOnly(sal_Bool bSet) 199 { 200 pImpl->bKerningWesternTextOnly = bSet; 201 SetModified(); 202 } 203 /* -----------------------------16.01.01 15:36-------------------------------- 204 205 ---------------------------------------------------------------------------*/ 206 sal_Int16 SvxAsianConfig::GetCharDistanceCompression() const 207 { 208 return pImpl->nCharDistanceCompression; 209 } 210 /* -----------------------------16.01.01 15:36-------------------------------- 211 212 ---------------------------------------------------------------------------*/ 213 void SvxAsianConfig::SetCharDistanceCompression(sal_Int16 nSet) 214 { 215 DBG_ASSERT(nSet >= 0 && nSet < 3, "compression value illegal"); 216 SetModified(); 217 pImpl->nCharDistanceCompression = nSet; 218 } 219 /* -----------------------------16.01.01 15:36-------------------------------- 220 221 ---------------------------------------------------------------------------*/ 222 uno::Sequence<lang::Locale> SvxAsianConfig::GetStartEndCharLocales() 223 { 224 Sequence<Locale> aRet(pImpl->aForbiddenArr.Count()); 225 Locale* pRet = aRet.getArray(); 226 for(sal_uInt16 i = 0; i < pImpl->aForbiddenArr.Count(); i++) 227 { 228 pRet[i] = pImpl->aForbiddenArr[i]->aLocale; 229 } 230 return aRet; 231 } 232 /* -----------------------------16.01.01 15:36-------------------------------- 233 234 ---------------------------------------------------------------------------*/ 235 sal_Bool SvxAsianConfig::GetStartEndChars( const Locale& rLocale, 236 OUString& rStartChars, 237 OUString& rEndChars ) 238 { 239 for(sal_uInt16 i = 0; i < pImpl->aForbiddenArr.Count(); i++) 240 { 241 if(rLocale.Language == pImpl->aForbiddenArr[i]->aLocale.Language && 242 rLocale.Country == pImpl->aForbiddenArr[i]->aLocale.Country) 243 { 244 rStartChars = pImpl->aForbiddenArr[i]->sStartChars; 245 rEndChars = pImpl->aForbiddenArr[i]->sEndChars; 246 return sal_True; 247 } 248 } 249 return sal_False; 250 } 251 /* -----------------------------16.01.01 15:36-------------------------------- 252 253 ---------------------------------------------------------------------------*/ 254 void SvxAsianConfig::SetStartEndChars( const Locale& rLocale, 255 const OUString* pStartChars, 256 const OUString* pEndChars ) 257 { 258 sal_Bool bFound = sal_False; 259 for(sal_uInt16 i = 0; i < pImpl->aForbiddenArr.Count(); i++) 260 { 261 if(rLocale.Language == pImpl->aForbiddenArr[i]->aLocale.Language && 262 rLocale.Country == pImpl->aForbiddenArr[i]->aLocale.Country) 263 { 264 if(pStartChars && pEndChars) 265 { 266 pImpl->aForbiddenArr[i]->sStartChars = *pStartChars; 267 pImpl->aForbiddenArr[i]->sEndChars = *pEndChars; 268 } 269 else 270 pImpl->aForbiddenArr.DeleteAndDestroy(i, 1); 271 bFound = sal_True; 272 } 273 } 274 if(!bFound && pStartChars && pEndChars) 275 { 276 SvxForbiddenStruct_ImplPtr pInsert = new SvxForbiddenStruct_Impl; 277 pInsert->aLocale = rLocale; 278 pInsert->sStartChars = *pStartChars; 279 pInsert->sEndChars = *pEndChars; 280 pImpl->aForbiddenArr.Insert(pInsert, pImpl->aForbiddenArr.Count()); 281 } 282 #ifdef DBG_UTIL 283 else if(!bFound) 284 DBG_ERROR("attempt to clear unavailable data"); 285 #endif 286 SetModified(); 287 } 288