Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <svl/cjkoptions.hxx>
21 :
22 : #include <svl/languageoptions.hxx>
23 : #include <i18nlangtag/lang.h>
24 : #include <unotools/configitem.hxx>
25 : #include <tools/debug.hxx>
26 : #include <tools/solar.h>
27 : #include <com/sun/star/uno/Any.h>
28 : #include <com/sun/star/uno/Sequence.hxx>
29 : #include <osl/mutex.hxx>
30 : #include <rtl/instance.hxx>
31 :
32 : #include "itemholder2.hxx"
33 :
34 : using namespace ::com::sun::star::uno;
35 :
36 : #define CFG_READONLY_DEFAULT false
37 :
38 : class SvtCJKOptions_Impl : public utl::ConfigItem
39 : {
40 : bool bIsLoaded;
41 : bool bCJKFont;
42 : bool bVerticalText;
43 : bool bAsianTypography;
44 : bool bJapaneseFind;
45 : bool bRuby;
46 : bool bChangeCaseMap;
47 : bool bDoubleLines;
48 : bool bEmphasisMarks;
49 : bool bVerticalCallOut;
50 :
51 : bool bROCJKFont;
52 : bool bROVerticalText;
53 : bool bROAsianTypography;
54 : bool bROJapaneseFind;
55 : bool bRORuby;
56 : bool bROChangeCaseMap;
57 : bool bRODoubleLines;
58 : bool bROEmphasisMarks;
59 : bool bROVerticalCallOut;
60 :
61 : public:
62 : SvtCJKOptions_Impl();
63 : virtual ~SvtCJKOptions_Impl();
64 :
65 : virtual void Notify( const com::sun::star::uno::Sequence< OUString >& rPropertyNames ) SAL_OVERRIDE;
66 : virtual void Commit() SAL_OVERRIDE;
67 : void Load();
68 :
69 24544 : bool IsLoaded() { return bIsLoaded; }
70 :
71 0 : bool IsCJKFontEnabled() const { return bCJKFont; }
72 9281 : bool IsVerticalTextEnabled() const { return bVerticalText; }
73 0 : bool IsAsianTypographyEnabled() const { return bAsianTypography; }
74 0 : bool IsJapaneseFindEnabled() const { return bJapaneseFind; }
75 0 : bool IsRubyEnabled() const { return bRuby; }
76 155 : bool IsChangeCaseMapEnabled() const { return bChangeCaseMap; }
77 0 : bool IsDoubleLinesEnabled() const { return bDoubleLines; }
78 :
79 0 : bool IsAnyEnabled() const {
80 0 : return bCJKFont||bVerticalText||bAsianTypography||bJapaneseFind||
81 0 : bRuby||bChangeCaseMap||bDoubleLines||bEmphasisMarks||bVerticalCallOut; }
82 : void SetAll(bool bSet);
83 : bool IsReadOnly(SvtCJKOptions::EOption eOption) const;
84 : };
85 :
86 : namespace
87 : {
88 : struct PropertyNames
89 : : public rtl::Static< Sequence<OUString>, PropertyNames > {};
90 : }
91 :
92 186 : SvtCJKOptions_Impl::SvtCJKOptions_Impl() :
93 : utl::ConfigItem("Office.Common/I18N/CJK"),
94 : bIsLoaded(false),
95 : bCJKFont(true),
96 : bVerticalText(true),
97 : bAsianTypography(true),
98 : bJapaneseFind(true),
99 : bRuby(true),
100 : bChangeCaseMap(true),
101 : bDoubleLines(true),
102 : bEmphasisMarks(true),
103 : bVerticalCallOut(true),
104 : bROCJKFont(CFG_READONLY_DEFAULT),
105 : bROVerticalText(CFG_READONLY_DEFAULT),
106 : bROAsianTypography(CFG_READONLY_DEFAULT),
107 : bROJapaneseFind(CFG_READONLY_DEFAULT),
108 : bRORuby(CFG_READONLY_DEFAULT),
109 : bROChangeCaseMap(CFG_READONLY_DEFAULT),
110 : bRODoubleLines(CFG_READONLY_DEFAULT),
111 : bROEmphasisMarks(CFG_READONLY_DEFAULT),
112 186 : bROVerticalCallOut(CFG_READONLY_DEFAULT)
113 : {
114 186 : }
115 :
116 372 : SvtCJKOptions_Impl::~SvtCJKOptions_Impl()
117 : {
118 372 : }
119 :
120 0 : void SvtCJKOptions_Impl::SetAll(bool bSet)
121 : {
122 0 : if (
123 0 : !bROCJKFont &&
124 0 : !bROVerticalText &&
125 0 : !bROAsianTypography &&
126 0 : !bROJapaneseFind &&
127 0 : !bRORuby &&
128 0 : !bROChangeCaseMap &&
129 0 : !bRODoubleLines &&
130 0 : !bROEmphasisMarks &&
131 0 : !bROVerticalCallOut
132 : )
133 : {
134 0 : bCJKFont=bSet;
135 0 : bVerticalText=bSet;
136 0 : bAsianTypography=bSet;
137 0 : bJapaneseFind=bSet;
138 0 : bRuby=bSet;
139 0 : bChangeCaseMap=bSet;
140 0 : bDoubleLines=bSet;
141 0 : bEmphasisMarks=bSet;
142 0 : bVerticalCallOut=bSet;
143 :
144 0 : SetModified();
145 0 : Commit();
146 0 : NotifyListeners(0);
147 : }
148 0 : }
149 :
150 186 : void SvtCJKOptions_Impl::Load()
151 : {
152 186 : Sequence<OUString> &rPropertyNames = PropertyNames::get();
153 186 : if(!rPropertyNames.getLength())
154 : {
155 186 : rPropertyNames.realloc(9);
156 186 : OUString* pNames = rPropertyNames.getArray();
157 :
158 186 : pNames[0] = "CJKFont";
159 186 : pNames[1] = "VerticalText";
160 186 : pNames[2] = "AsianTypography";
161 186 : pNames[3] = "JapaneseFind";
162 186 : pNames[4] = "Ruby";
163 186 : pNames[5] = "ChangeCaseMap";
164 186 : pNames[6] = "DoubleLines";
165 186 : pNames[7] = "EmphasisMarks";
166 186 : pNames[8] = "VerticalCallOut";
167 :
168 186 : EnableNotification( rPropertyNames );
169 : }
170 186 : Sequence< Any > aValues = GetProperties(rPropertyNames);
171 372 : Sequence< sal_Bool > aROStates = GetReadOnlyStates(rPropertyNames);
172 186 : const Any* pValues = aValues.getConstArray();
173 186 : const sal_Bool* pROStates = aROStates.getConstArray();
174 : DBG_ASSERT( aValues.getLength() == rPropertyNames.getLength(), "GetProperties failed" );
175 : DBG_ASSERT( aROStates.getLength() == rPropertyNames.getLength(), "GetReadOnlyStates failed" );
176 186 : if ( aValues.getLength() == rPropertyNames.getLength() && aROStates.getLength() == rPropertyNames.getLength() )
177 : {
178 1860 : for ( int nProp = 0; nProp < rPropertyNames.getLength(); nProp++ )
179 : {
180 1674 : if( pValues[nProp].hasValue() )
181 : {
182 1674 : bool bValue = *(sal_Bool*)pValues[nProp].getValue();
183 1674 : switch ( nProp )
184 : {
185 186 : case 0: { bCJKFont = bValue; bROCJKFont = pROStates[nProp]; } break;
186 186 : case 1: { bVerticalText = bValue; bROVerticalText = pROStates[nProp]; } break;
187 186 : case 2: { bAsianTypography = bValue; bROAsianTypography = pROStates[nProp]; } break;
188 186 : case 3: { bJapaneseFind = bValue; bROJapaneseFind = pROStates[nProp]; } break;
189 186 : case 4: { bRuby = bValue; bRORuby = pROStates[nProp]; } break;
190 186 : case 5: { bChangeCaseMap = bValue; bROChangeCaseMap = pROStates[nProp]; } break;
191 186 : case 6: { bDoubleLines = bValue; bRODoubleLines = pROStates[nProp]; } break;
192 186 : case 7: { bEmphasisMarks = bValue; bROEmphasisMarks = pROStates[nProp]; } break;
193 186 : case 8: { bVerticalCallOut = bValue; bROVerticalCallOut = pROStates[nProp]; } break;
194 : }
195 : }
196 : }
197 : }
198 :
199 186 : if (!bCJKFont)
200 : {
201 0 : sal_uInt16 nScriptType = SvtLanguageOptions::GetScriptTypeOfLanguage(LANGUAGE_SYSTEM);
202 : //system locale is CJK
203 0 : bool bAutoEnableCJK = (nScriptType & SCRIPTTYPE_ASIAN);
204 :
205 0 : if (!bAutoEnableCJK)
206 : {
207 0 : SvtSystemLanguageOptions aSystemLocaleSettings;
208 :
209 : //windows secondary system locale is CJK
210 0 : LanguageType eSystemLanguage = aSystemLocaleSettings.GetWin16SystemLanguage();
211 0 : if (eSystemLanguage != LANGUAGE_SYSTEM)
212 : {
213 0 : sal_uInt16 nWinScript = SvtLanguageOptions::GetScriptTypeOfLanguage( eSystemLanguage );
214 0 : bAutoEnableCJK = (nWinScript & SCRIPTTYPE_ASIAN);
215 : }
216 :
217 : //CJK keyboard is installed
218 0 : if (!bAutoEnableCJK)
219 0 : bAutoEnableCJK = aSystemLocaleSettings.isCJKKeyboardLayoutInstalled();
220 : }
221 :
222 0 : if (bAutoEnableCJK)
223 : {
224 0 : SetAll(true);
225 : }
226 : }
227 372 : bIsLoaded = true;
228 186 : }
229 :
230 0 : void SvtCJKOptions_Impl::Notify( const Sequence< OUString >& )
231 : {
232 0 : Load();
233 0 : NotifyListeners(0);
234 0 : }
235 :
236 0 : void SvtCJKOptions_Impl::Commit()
237 : {
238 0 : Sequence<OUString> &rPropertyNames = PropertyNames::get();
239 0 : OUString* pOrgNames = rPropertyNames.getArray();
240 0 : sal_Int32 nOrgCount = rPropertyNames.getLength();
241 :
242 0 : Sequence< OUString > aNames(nOrgCount);
243 0 : Sequence< Any > aValues(nOrgCount);
244 :
245 0 : OUString* pNames = aNames.getArray();
246 0 : Any* pValues = aValues.getArray();
247 0 : sal_Int32 nRealCount = 0;
248 :
249 0 : const Type& rType = ::getBooleanCppuType();
250 0 : for(int nProp = 0; nProp < nOrgCount; nProp++)
251 : {
252 0 : switch(nProp)
253 : {
254 : case 0:
255 : {
256 0 : if (!bROCJKFont)
257 : {
258 0 : pNames[nRealCount] = pOrgNames[nProp];
259 0 : pValues[nRealCount].setValue(&bCJKFont, rType);
260 0 : ++nRealCount;
261 : }
262 : }
263 0 : break;
264 :
265 : case 1:
266 : {
267 0 : if (!bROVerticalText)
268 : {
269 0 : pNames[nRealCount] = pOrgNames[nProp];
270 0 : pValues[nRealCount].setValue(&bVerticalText, rType);
271 0 : ++nRealCount;
272 : }
273 : }
274 0 : break;
275 :
276 : case 2:
277 : {
278 0 : if (!bROAsianTypography)
279 : {
280 0 : pNames[nRealCount] = pOrgNames[nProp];
281 0 : pValues[nRealCount].setValue(&bAsianTypography, rType);
282 0 : ++nRealCount;
283 : }
284 : }
285 0 : break;
286 :
287 : case 3:
288 : {
289 0 : if (!bROJapaneseFind)
290 : {
291 0 : pNames[nRealCount] = pOrgNames[nProp];
292 0 : pValues[nRealCount].setValue(&bJapaneseFind, rType);
293 0 : ++nRealCount;
294 : }
295 : }
296 0 : break;
297 :
298 : case 4:
299 : {
300 0 : if (!bRORuby)
301 : {
302 0 : pNames[nRealCount] = pOrgNames[nProp];
303 0 : pValues[nRealCount].setValue(&bRuby, rType);
304 0 : ++nRealCount;
305 : }
306 : }
307 0 : break;
308 :
309 : case 5:
310 : {
311 0 : if (!bROChangeCaseMap)
312 : {
313 0 : pNames[nRealCount] = pOrgNames[nProp];
314 0 : pValues[nRealCount].setValue(&bChangeCaseMap, rType);
315 0 : ++nRealCount;
316 : }
317 : }
318 0 : break;
319 :
320 : case 6:
321 : {
322 0 : if (!bRODoubleLines)
323 : {
324 0 : pNames[nRealCount] = pOrgNames[nProp];
325 0 : pValues[nRealCount].setValue(&bDoubleLines, rType);
326 0 : ++nRealCount;
327 : }
328 : }
329 0 : break;
330 :
331 : case 7:
332 : {
333 0 : if (!bROEmphasisMarks)
334 : {
335 0 : pNames[nRealCount] = pOrgNames[nProp];
336 0 : pValues[nRealCount].setValue(&bEmphasisMarks, rType);
337 0 : ++nRealCount;
338 : }
339 : }
340 0 : break;
341 :
342 : case 8:
343 : {
344 0 : if (!bROVerticalCallOut)
345 : {
346 0 : pNames[nRealCount] = pOrgNames[nProp];
347 0 : pValues[nRealCount].setValue(&bVerticalCallOut, rType);
348 0 : ++nRealCount;
349 : }
350 : }
351 0 : break;
352 : }
353 : }
354 0 : aNames.realloc(nRealCount);
355 0 : aValues.realloc(nRealCount);
356 0 : PutProperties(aNames, aValues);
357 0 : }
358 :
359 0 : bool SvtCJKOptions_Impl::IsReadOnly(SvtCJKOptions::EOption eOption) const
360 : {
361 0 : bool bReadOnly = CFG_READONLY_DEFAULT;
362 0 : switch(eOption)
363 : {
364 0 : case SvtCJKOptions::E_CJKFONT : bReadOnly = bROCJKFont; break;
365 0 : case SvtCJKOptions::E_VERTICALTEXT : bReadOnly = bROVerticalText; break;
366 0 : case SvtCJKOptions::E_ASIANTYPOGRAPHY : bReadOnly = bROAsianTypography; break;
367 0 : case SvtCJKOptions::E_JAPANESEFIND : bReadOnly = bROJapaneseFind; break;
368 0 : case SvtCJKOptions::E_RUBY : bReadOnly = bRORuby; break;
369 0 : case SvtCJKOptions::E_CHANGECASEMAP : bReadOnly = bROChangeCaseMap; break;
370 0 : case SvtCJKOptions::E_DOUBLELINES : bReadOnly = bRODoubleLines; break;
371 0 : case SvtCJKOptions::E_EMPHASISMARKS : bReadOnly = bROEmphasisMarks; break;
372 0 : case SvtCJKOptions::E_VERTICALCALLOUT : bReadOnly = bROVerticalCallOut; break;
373 0 : case SvtCJKOptions::E_ALL : if (bROCJKFont || bROVerticalText || bROAsianTypography || bROJapaneseFind || bRORuby || bROChangeCaseMap || bRODoubleLines || bROEmphasisMarks || bROVerticalCallOut)
374 0 : bReadOnly = true;
375 0 : break;
376 : }
377 0 : return bReadOnly;
378 : }
379 :
380 : // global
381 :
382 : static SvtCJKOptions_Impl* pCJKOptions = NULL;
383 : static sal_Int32 nCJKRefCount = 0;
384 : namespace { struct theCJKOptionsMutex : public rtl::Static< ::osl::Mutex , theCJKOptionsMutex >{}; }
385 :
386 24704 : SvtCJKOptions::SvtCJKOptions(bool bDontLoad)
387 : {
388 : // Global access, must be guarded (multithreading)
389 24704 : ::osl::MutexGuard aGuard( theCJKOptionsMutex::get() );
390 24704 : if ( !pCJKOptions )
391 : {
392 186 : pCJKOptions = new SvtCJKOptions_Impl;
393 186 : ItemHolder2::holdConfigItem(E_CJKOPTIONS);
394 : }
395 24704 : if( !bDontLoad && !pCJKOptions->IsLoaded())
396 186 : pCJKOptions->Load();
397 :
398 24704 : ++nCJKRefCount;
399 24704 : pImp = pCJKOptions;
400 24704 : }
401 :
402 :
403 :
404 73957 : SvtCJKOptions::~SvtCJKOptions()
405 : {
406 : // Global access, must be guarded (multithreading)
407 24704 : ::osl::MutexGuard aGuard( theCJKOptionsMutex::get() );
408 24704 : if ( !--nCJKRefCount )
409 186 : DELETEZ( pCJKOptions );
410 49253 : }
411 :
412 0 : bool SvtCJKOptions::IsCJKFontEnabled() const
413 : {
414 : DBG_ASSERT(pCJKOptions->IsLoaded(), "CJK options not loaded");
415 0 : return pCJKOptions->IsCJKFontEnabled();
416 : }
417 :
418 9281 : bool SvtCJKOptions::IsVerticalTextEnabled() const
419 : {
420 : DBG_ASSERT(pCJKOptions->IsLoaded(), "CJK options not loaded");
421 9281 : return pCJKOptions->IsVerticalTextEnabled();
422 : }
423 :
424 0 : bool SvtCJKOptions::IsAsianTypographyEnabled() const
425 : {
426 : DBG_ASSERT(pCJKOptions->IsLoaded(), "CJK options not loaded");
427 0 : return pCJKOptions->IsAsianTypographyEnabled();
428 : }
429 :
430 0 : bool SvtCJKOptions::IsJapaneseFindEnabled() const
431 : {
432 : DBG_ASSERT(pCJKOptions->IsLoaded(), "CJK options not loaded");
433 0 : return pCJKOptions->IsJapaneseFindEnabled();
434 : }
435 :
436 0 : bool SvtCJKOptions::IsRubyEnabled() const
437 : {
438 : DBG_ASSERT(pCJKOptions->IsLoaded(), "CJK options not loaded");
439 0 : return pCJKOptions->IsRubyEnabled();
440 : }
441 :
442 155 : bool SvtCJKOptions::IsChangeCaseMapEnabled() const
443 : {
444 : DBG_ASSERT(pCJKOptions->IsLoaded(), "CJK options not loaded");
445 155 : return pCJKOptions->IsChangeCaseMapEnabled();
446 : }
447 :
448 0 : bool SvtCJKOptions::IsDoubleLinesEnabled() const
449 : {
450 : DBG_ASSERT(pCJKOptions->IsLoaded(), "CJK options not loaded");
451 0 : return pCJKOptions->IsDoubleLinesEnabled();
452 : }
453 :
454 0 : void SvtCJKOptions::SetAll(bool bSet)
455 : {
456 : DBG_ASSERT(pCJKOptions->IsLoaded(), "CJK options not loaded");
457 0 : pCJKOptions->SetAll(bSet);
458 0 : }
459 :
460 0 : bool SvtCJKOptions::IsAnyEnabled() const
461 : {
462 : DBG_ASSERT(pCJKOptions->IsLoaded(), "CJK options not loaded");
463 0 : return pCJKOptions->IsAnyEnabled();
464 : }
465 :
466 0 : bool SvtCJKOptions::IsReadOnly(EOption eOption) const
467 : {
468 : DBG_ASSERT(pCJKOptions->IsLoaded(), "CJK options not loaded");
469 0 : return pCJKOptions->IsReadOnly(eOption);
470 : }
471 :
472 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|