1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_svl.hxx" 30 31 #include <svl/asiancfg.hxx> 32 #include <svl/svarray.hxx> 33 #include <com/sun/star/uno/Any.hxx> 34 #include <com/sun/star/uno/Sequence.hxx> 35 #include <com/sun/star/lang/Locale.hpp> 36 #include <com/sun/star/beans/PropertyValue.hpp> 37 #include <tools/debug.hxx> 38 39 //----------------------------------------------------------------------------- 40 using namespace utl; 41 using namespace rtl; 42 using namespace com::sun::star; 43 using namespace com::sun::star::uno; 44 using namespace com::sun::star::beans; 45 using namespace com::sun::star::lang; 46 47 #define C2U(cChar) OUString::createFromAscii(cChar) 48 const sal_Char sStartEndCharacters[] = "StartEndCharacters"; 49 const sal_Char sStartCharacters[] = "StartCharacters"; 50 const sal_Char sEndCharacters[] = "EndCharacters"; 51 52 //----------------------------------------------------------------------------- 53 struct SvxForbiddenStruct_Impl 54 { 55 Locale aLocale; 56 OUString sStartChars; 57 OUString sEndChars; 58 }; 59 //----------------------------------------------------------------------------- 60 typedef SvxForbiddenStruct_Impl* SvxForbiddenStruct_ImplPtr; 61 SV_DECL_PTRARR_DEL(SvxForbiddenStructArr, SvxForbiddenStruct_ImplPtr, 2, 2) 62 SV_IMPL_PTRARR(SvxForbiddenStructArr, SvxForbiddenStruct_ImplPtr); 63 //----------------------------------------------------------------------------- 64 struct SvxAsianConfig_Impl 65 { 66 sal_Bool bKerningWesternTextOnly; 67 sal_Int16 nCharDistanceCompression; 68 69 SvxForbiddenStructArr aForbiddenArr; 70 71 SvxAsianConfig_Impl() : 72 bKerningWesternTextOnly(sal_True), 73 nCharDistanceCompression(0) {} 74 }; 75 /* -----------------------------16.01.01 15:36-------------------------------- 76 77 ---------------------------------------------------------------------------*/ 78 Sequence<OUString> lcl_GetPropertyNames() 79 { 80 Sequence<OUString> aNames(2); 81 OUString* pNames = aNames.getArray(); 82 pNames[0] = C2U("IsKerningWesternTextOnly"); 83 pNames[1] = C2U("CompressCharacterDistance"); 84 return aNames;; 85 } 86 // --------------------------------------------------------------------------- 87 SvxAsianConfig::SvxAsianConfig(sal_Bool bEnableNotify) : 88 utl::ConfigItem(C2U("Office.Common/AsianLayout")), 89 pImpl(new SvxAsianConfig_Impl) 90 { 91 if(bEnableNotify) 92 EnableNotification(lcl_GetPropertyNames()); 93 Load(); 94 } 95 /* -----------------------------16.01.01 15:36-------------------------------- 96 97 ---------------------------------------------------------------------------*/ 98 SvxAsianConfig::~SvxAsianConfig() 99 { 100 delete pImpl; 101 } 102 /* -----------------------------17.01.01 09:57-------------------------------- 103 104 ---------------------------------------------------------------------------*/ 105 void SvxAsianConfig::Load() 106 { 107 Sequence<Any> aValues = GetProperties(lcl_GetPropertyNames()); 108 const Any* pValues = aValues.getConstArray(); 109 if(pValues[0].hasValue()) 110 pImpl->bKerningWesternTextOnly = *(sal_Bool*) pValues[0].getValue(); 111 pValues[1] >>= pImpl->nCharDistanceCompression; 112 113 pImpl->aForbiddenArr.DeleteAndDestroy(0, pImpl->aForbiddenArr.Count()); 114 OUString sPropPrefix(C2U(sStartEndCharacters)); 115 Sequence<OUString> aNodes = GetNodeNames(sPropPrefix); 116 117 Sequence<OUString> aPropNames(aNodes.getLength() * 2); 118 OUString* pNames = aPropNames.getArray(); 119 sal_Int32 nName = 0; 120 sPropPrefix += C2U("/"); 121 sal_Int32 nNode; 122 const OUString* pNodes = aNodes.getConstArray(); 123 for(nNode = 0; nNode < aNodes.getLength(); nNode++) 124 { 125 OUString sStart(sPropPrefix); 126 sStart += pNodes[nNode]; 127 sStart += C2U("/"); 128 pNames[nName] = sStart; pNames[nName++] += C2U("StartCharacters"); 129 pNames[nName] = sStart; pNames[nName++] += C2U("EndCharacters"); 130 } 131 Sequence<Any> aNodeValues = GetProperties(aPropNames); 132 const Any* pNodeValues = aNodeValues.getConstArray(); 133 nName = 0; 134 for(nNode = 0; nNode < aNodes.getLength(); nNode++) 135 { 136 SvxForbiddenStruct_ImplPtr pInsert = new SvxForbiddenStruct_Impl; 137 pInsert->aLocale.Language = pNodes[nNode].copy(0, 2); 138 DBG_ASSERT(pInsert->aLocale.Language.getLength(), "illegal language"); 139 pInsert->aLocale.Country = pNodes[nNode].copy(3, 2); 140 141 pNodeValues[nName++] >>= pInsert->sStartChars; 142 pNodeValues[nName++] >>= pInsert->sEndChars; 143 pImpl->aForbiddenArr.Insert(pInsert, pImpl->aForbiddenArr.Count()); 144 } 145 } 146 /* -----------------------------17.01.01 09:57-------------------------------- 147 148 ---------------------------------------------------------------------------*/ 149 void SvxAsianConfig::Notify( const Sequence<OUString>& ) 150 { 151 Load(); 152 } 153 /* -----------------------------16.01.01 15:36-------------------------------- 154 155 ---------------------------------------------------------------------------*/ 156 void SvxAsianConfig::Commit() 157 { 158 Sequence<Any> aValues(2); 159 Any* pValues = aValues.getArray(); 160 pValues[0].setValue(&pImpl->bKerningWesternTextOnly, ::getBooleanCppuType()); 161 pValues[1] <<= pImpl->nCharDistanceCompression; 162 PutProperties(lcl_GetPropertyNames(), aValues); 163 164 165 OUString sNode(C2U(sStartEndCharacters)); 166 if(!pImpl->aForbiddenArr.Count()) 167 ClearNodeSet(sNode); 168 else 169 { 170 Sequence<PropertyValue> aSetValues(2 * pImpl->aForbiddenArr.Count()); 171 PropertyValue* pSetValues = aSetValues.getArray(); 172 sal_Int32 nSetValue = 0; 173 const OUString sStartChars(C2U(sStartCharacters)); 174 const OUString sEndChars(C2U(sEndCharacters)); 175 for(sal_uInt16 i = 0; i < pImpl->aForbiddenArr.Count(); i++) 176 { 177 OUString sPrefix(sNode); 178 sPrefix += C2U("/"); 179 sPrefix += pImpl->aForbiddenArr[i]->aLocale.Language; 180 DBG_ASSERT(pImpl->aForbiddenArr[i]->aLocale.Language.getLength(), "illegal language"); 181 sPrefix += C2U("-"); 182 sPrefix += pImpl->aForbiddenArr[i]->aLocale.Country; 183 sPrefix += C2U("/"); 184 pSetValues[nSetValue].Name = sPrefix; pSetValues[nSetValue].Name += sStartChars; 185 pSetValues[nSetValue++].Value <<= pImpl->aForbiddenArr[i]->sStartChars; 186 pSetValues[nSetValue].Name = sPrefix; pSetValues[nSetValue].Name += sEndChars; 187 pSetValues[nSetValue++].Value <<= pImpl->aForbiddenArr[i]->sEndChars; 188 } 189 ReplaceSetProperties(sNode, aSetValues); 190 } 191 } 192 /* -----------------------------16.01.01 15:36-------------------------------- 193 194 ---------------------------------------------------------------------------*/ 195 sal_Bool SvxAsianConfig::IsKerningWesternTextOnly() const 196 { 197 return pImpl->bKerningWesternTextOnly; 198 } 199 /* -----------------------------16.01.01 15:36-------------------------------- 200 201 ---------------------------------------------------------------------------*/ 202 void SvxAsianConfig::SetKerningWesternTextOnly(sal_Bool bSet) 203 { 204 pImpl->bKerningWesternTextOnly = bSet; 205 SetModified(); 206 } 207 /* -----------------------------16.01.01 15:36-------------------------------- 208 209 ---------------------------------------------------------------------------*/ 210 sal_Int16 SvxAsianConfig::GetCharDistanceCompression() const 211 { 212 return pImpl->nCharDistanceCompression; 213 } 214 /* -----------------------------16.01.01 15:36-------------------------------- 215 216 ---------------------------------------------------------------------------*/ 217 void SvxAsianConfig::SetCharDistanceCompression(sal_Int16 nSet) 218 { 219 DBG_ASSERT(nSet >= 0 && nSet < 3, "compression value illegal"); 220 SetModified(); 221 pImpl->nCharDistanceCompression = nSet; 222 } 223 /* -----------------------------16.01.01 15:36-------------------------------- 224 225 ---------------------------------------------------------------------------*/ 226 uno::Sequence<lang::Locale> SvxAsianConfig::GetStartEndCharLocales() 227 { 228 Sequence<Locale> aRet(pImpl->aForbiddenArr.Count()); 229 Locale* pRet = aRet.getArray(); 230 for(sal_uInt16 i = 0; i < pImpl->aForbiddenArr.Count(); i++) 231 { 232 pRet[i] = pImpl->aForbiddenArr[i]->aLocale; 233 } 234 return aRet; 235 } 236 /* -----------------------------16.01.01 15:36-------------------------------- 237 238 ---------------------------------------------------------------------------*/ 239 sal_Bool SvxAsianConfig::GetStartEndChars( const Locale& rLocale, 240 OUString& rStartChars, 241 OUString& rEndChars ) 242 { 243 for(sal_uInt16 i = 0; i < pImpl->aForbiddenArr.Count(); i++) 244 { 245 if(rLocale.Language == pImpl->aForbiddenArr[i]->aLocale.Language && 246 rLocale.Country == pImpl->aForbiddenArr[i]->aLocale.Country) 247 { 248 rStartChars = pImpl->aForbiddenArr[i]->sStartChars; 249 rEndChars = pImpl->aForbiddenArr[i]->sEndChars; 250 return sal_True; 251 } 252 } 253 return sal_False; 254 } 255 /* -----------------------------16.01.01 15:36-------------------------------- 256 257 ---------------------------------------------------------------------------*/ 258 void SvxAsianConfig::SetStartEndChars( const Locale& rLocale, 259 const OUString* pStartChars, 260 const OUString* pEndChars ) 261 { 262 sal_Bool bFound = sal_False; 263 for(sal_uInt16 i = 0; i < pImpl->aForbiddenArr.Count(); i++) 264 { 265 if(rLocale.Language == pImpl->aForbiddenArr[i]->aLocale.Language && 266 rLocale.Country == pImpl->aForbiddenArr[i]->aLocale.Country) 267 { 268 if(pStartChars && pEndChars) 269 { 270 pImpl->aForbiddenArr[i]->sStartChars = *pStartChars; 271 pImpl->aForbiddenArr[i]->sEndChars = *pEndChars; 272 } 273 else 274 pImpl->aForbiddenArr.DeleteAndDestroy(i, 1); 275 bFound = sal_True; 276 } 277 } 278 if(!bFound && pStartChars && pEndChars) 279 { 280 SvxForbiddenStruct_ImplPtr pInsert = new SvxForbiddenStruct_Impl; 281 pInsert->aLocale = rLocale; 282 pInsert->sStartChars = *pStartChars; 283 pInsert->sEndChars = *pEndChars; 284 pImpl->aForbiddenArr.Insert(pInsert, pImpl->aForbiddenArr.Count()); 285 } 286 #ifdef DBG_UTIL 287 else if(!bFound) 288 DBG_ERROR("attempt to clear unavailable data"); 289 #endif 290 SetModified(); 291 } 292