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