bump product version to 6.3.0.0.beta1
[LibreOffice.git] / svl / source / config / cjkoptions.cxx
blob32cd9d5ce834bb79c90d17689d69e53c02da88ca
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <svl/cjkoptions.hxx>
22 #include <o3tl/any.hxx>
23 #include <svl/languageoptions.hxx>
24 #include <i18nlangtag/lang.h>
25 #include <unotools/configitem.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>
32 #include "itemholder2.hxx"
34 using namespace ::com::sun::star::uno;
36 #define CFG_READONLY_DEFAULT false
38 class SvtCJKOptions_Impl : public utl::ConfigItem
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;
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;
61 virtual void ImplCommit() override;
63 public:
64 SvtCJKOptions_Impl();
66 virtual void Notify( const css::uno::Sequence< OUString >& rPropertyNames ) override;
67 void Load();
69 bool IsLoaded() const { return bIsLoaded; }
71 bool IsCJKFontEnabled() const { return bCJKFont; }
72 bool IsVerticalTextEnabled() const { return bVerticalText; }
73 bool IsAsianTypographyEnabled() const { return bAsianTypography; }
74 bool IsJapaneseFindEnabled() const { return bJapaneseFind; }
75 bool IsRubyEnabled() const { return bRuby; }
76 bool IsChangeCaseMapEnabled() const { return bChangeCaseMap; }
77 bool IsDoubleLinesEnabled() const { return bDoubleLines; }
79 bool IsAnyEnabled() const {
80 return bCJKFont||bVerticalText||bAsianTypography||bJapaneseFind||
81 bRuby||bChangeCaseMap||bDoubleLines||bEmphasisMarks||bVerticalCallOut; }
82 void SetAll(bool bSet);
83 bool IsReadOnly(SvtCJKOptions::EOption eOption) const;
86 namespace
88 struct PropertyNames
89 : public rtl::Static< Sequence<OUString>, PropertyNames > {};
92 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 bROVerticalCallOut(CFG_READONLY_DEFAULT)
116 void SvtCJKOptions_Impl::SetAll(bool bSet)
118 if (
119 bROCJKFont ||
120 bROVerticalText ||
121 bROAsianTypography ||
122 bROJapaneseFind ||
123 bRORuby ||
124 bROChangeCaseMap ||
125 bRODoubleLines ||
126 bROEmphasisMarks ||
127 bROVerticalCallOut
129 return;
131 bCJKFont=bSet;
132 bVerticalText=bSet;
133 bAsianTypography=bSet;
134 bJapaneseFind=bSet;
135 bRuby=bSet;
136 bChangeCaseMap=bSet;
137 bDoubleLines=bSet;
138 bEmphasisMarks=bSet;
139 bVerticalCallOut=bSet;
141 SetModified();
142 Commit();
143 NotifyListeners(ConfigurationHints::NONE);
146 void SvtCJKOptions_Impl::Load()
148 Sequence<OUString> &rPropertyNames = PropertyNames::get();
149 if(!rPropertyNames.hasElements())
151 rPropertyNames.realloc(9);
152 OUString* pNames = rPropertyNames.getArray();
154 pNames[0] = "CJKFont";
155 pNames[1] = "VerticalText";
156 pNames[2] = "AsianTypography";
157 pNames[3] = "JapaneseFind";
158 pNames[4] = "Ruby";
159 pNames[5] = "ChangeCaseMap";
160 pNames[6] = "DoubleLines";
161 pNames[7] = "EmphasisMarks";
162 pNames[8] = "VerticalCallOut";
164 EnableNotification( rPropertyNames );
166 Sequence< Any > aValues = GetProperties(rPropertyNames);
167 Sequence< sal_Bool > aROStates = GetReadOnlyStates(rPropertyNames);
168 const Any* pValues = aValues.getConstArray();
169 const sal_Bool* pROStates = aROStates.getConstArray();
170 assert(aValues.getLength() == rPropertyNames.getLength() && "GetProperties failed");
171 assert(aROStates.getLength() == rPropertyNames.getLength() && "GetReadOnlyStates failed");
172 if ( aValues.getLength() == rPropertyNames.getLength() && aROStates.getLength() == rPropertyNames.getLength() )
174 for ( int nProp = 0; nProp < rPropertyNames.getLength(); nProp++ )
176 if( pValues[nProp].hasValue() )
178 bool bValue = *o3tl::doAccess<bool>(pValues[nProp]);
179 switch ( nProp )
181 case 0: { bCJKFont = bValue; bROCJKFont = pROStates[nProp]; } break;
182 case 1: { bVerticalText = bValue; bROVerticalText = pROStates[nProp]; } break;
183 case 2: { bAsianTypography = bValue; bROAsianTypography = pROStates[nProp]; } break;
184 case 3: { bJapaneseFind = bValue; bROJapaneseFind = pROStates[nProp]; } break;
185 case 4: { bRuby = bValue; bRORuby = pROStates[nProp]; } break;
186 case 5: { bChangeCaseMap = bValue; bROChangeCaseMap = pROStates[nProp]; } break;
187 case 6: { bDoubleLines = bValue; bRODoubleLines = pROStates[nProp]; } break;
188 case 7: { bEmphasisMarks = bValue; bROEmphasisMarks = pROStates[nProp]; } break;
189 case 8: { bVerticalCallOut = bValue; bROVerticalCallOut = pROStates[nProp]; } break;
195 if (!bCJKFont)
197 SvtScriptType nScriptType = SvtLanguageOptions::GetScriptTypeOfLanguage(LANGUAGE_SYSTEM);
198 //system locale is CJK
199 bool bAutoEnableCJK = bool(nScriptType & SvtScriptType::ASIAN);
201 if (!bAutoEnableCJK)
203 SvtSystemLanguageOptions aSystemLocaleSettings;
205 //windows secondary system locale is CJK
206 LanguageType eSystemLanguage = aSystemLocaleSettings.GetWin16SystemLanguage();
207 if (eSystemLanguage != LANGUAGE_SYSTEM)
209 SvtScriptType nWinScript = SvtLanguageOptions::GetScriptTypeOfLanguage( eSystemLanguage );
210 bAutoEnableCJK = bool(nWinScript & SvtScriptType::ASIAN);
213 //CJK keyboard is installed
214 if (!bAutoEnableCJK)
215 bAutoEnableCJK = aSystemLocaleSettings.isCJKKeyboardLayoutInstalled();
218 if (bAutoEnableCJK)
220 SetAll(true);
223 bIsLoaded = true;
226 void SvtCJKOptions_Impl::Notify( const Sequence< OUString >& )
228 Load();
229 NotifyListeners(ConfigurationHints::NONE);
232 void SvtCJKOptions_Impl::ImplCommit()
234 Sequence<OUString> &rPropertyNames = PropertyNames::get();
235 OUString* pOrgNames = rPropertyNames.getArray();
236 sal_Int32 nOrgCount = rPropertyNames.getLength();
238 Sequence< OUString > aNames(nOrgCount);
239 Sequence< Any > aValues(nOrgCount);
241 OUString* pNames = aNames.getArray();
242 Any* pValues = aValues.getArray();
243 sal_Int32 nRealCount = 0;
245 for(int nProp = 0; nProp < nOrgCount; nProp++)
247 switch(nProp)
249 case 0:
251 if (!bROCJKFont)
253 pNames[nRealCount] = pOrgNames[nProp];
254 pValues[nRealCount] <<= bCJKFont;
255 ++nRealCount;
258 break;
260 case 1:
262 if (!bROVerticalText)
264 pNames[nRealCount] = pOrgNames[nProp];
265 pValues[nRealCount] <<= bVerticalText;
266 ++nRealCount;
269 break;
271 case 2:
273 if (!bROAsianTypography)
275 pNames[nRealCount] = pOrgNames[nProp];
276 pValues[nRealCount] <<= bAsianTypography;
277 ++nRealCount;
280 break;
282 case 3:
284 if (!bROJapaneseFind)
286 pNames[nRealCount] = pOrgNames[nProp];
287 pValues[nRealCount] <<= bJapaneseFind;
288 ++nRealCount;
291 break;
293 case 4:
295 if (!bRORuby)
297 pNames[nRealCount] = pOrgNames[nProp];
298 pValues[nRealCount] <<= bRuby;
299 ++nRealCount;
302 break;
304 case 5:
306 if (!bROChangeCaseMap)
308 pNames[nRealCount] = pOrgNames[nProp];
309 pValues[nRealCount] <<= bChangeCaseMap;
310 ++nRealCount;
313 break;
315 case 6:
317 if (!bRODoubleLines)
319 pNames[nRealCount] = pOrgNames[nProp];
320 pValues[nRealCount] <<= bDoubleLines;
321 ++nRealCount;
324 break;
326 case 7:
328 if (!bROEmphasisMarks)
330 pNames[nRealCount] = pOrgNames[nProp];
331 pValues[nRealCount] <<= bEmphasisMarks;
332 ++nRealCount;
335 break;
337 case 8:
339 if (!bROVerticalCallOut)
341 pNames[nRealCount] = pOrgNames[nProp];
342 pValues[nRealCount] <<= bVerticalCallOut;
343 ++nRealCount;
346 break;
349 aNames.realloc(nRealCount);
350 aValues.realloc(nRealCount);
351 PutProperties(aNames, aValues);
354 bool SvtCJKOptions_Impl::IsReadOnly(SvtCJKOptions::EOption eOption) const
356 bool bReadOnly = CFG_READONLY_DEFAULT;
357 switch(eOption)
359 case SvtCJKOptions::E_CJKFONT : bReadOnly = bROCJKFont; break;
360 case SvtCJKOptions::E_VERTICALTEXT : bReadOnly = bROVerticalText; break;
361 case SvtCJKOptions::E_ASIANTYPOGRAPHY : bReadOnly = bROAsianTypography; break;
362 case SvtCJKOptions::E_JAPANESEFIND : bReadOnly = bROJapaneseFind; break;
363 case SvtCJKOptions::E_RUBY : bReadOnly = bRORuby; break;
364 case SvtCJKOptions::E_CHANGECASEMAP : bReadOnly = bROChangeCaseMap; break;
365 case SvtCJKOptions::E_DOUBLELINES : bReadOnly = bRODoubleLines; break;
366 case SvtCJKOptions::E_EMPHASISMARKS : bReadOnly = bROEmphasisMarks; break;
367 case SvtCJKOptions::E_VERTICALCALLOUT : bReadOnly = bROVerticalCallOut; break;
368 case SvtCJKOptions::E_ALL : if (bROCJKFont || bROVerticalText || bROAsianTypography || bROJapaneseFind || bRORuby || bROChangeCaseMap || bRODoubleLines || bROEmphasisMarks || bROVerticalCallOut)
369 bReadOnly = true;
370 break;
372 return bReadOnly;
375 namespace {
377 // global
378 std::weak_ptr<SvtCJKOptions_Impl> g_pCJKOptions;
380 struct theCJKOptionsMutex : public rtl::Static< ::osl::Mutex , theCJKOptionsMutex >{};
383 SvtCJKOptions::SvtCJKOptions(bool bDontLoad)
385 // Global access, must be guarded (multithreading)
386 ::osl::MutexGuard aGuard( theCJKOptionsMutex::get() );
387 pImpl = g_pCJKOptions.lock();
388 if ( !pImpl )
390 pImpl = std::make_shared<SvtCJKOptions_Impl>();
391 g_pCJKOptions = pImpl;
392 ItemHolder2::holdConfigItem(EItem::CJKOptions);
395 if( !bDontLoad && !pImpl->IsLoaded())
396 pImpl->Load();
400 SvtCJKOptions::~SvtCJKOptions()
402 // Global access, must be guarded (multithreading)
403 ::osl::MutexGuard aGuard( theCJKOptionsMutex::get() );
405 // pImpl needs to be cleared before the mutex is dropped
406 pImpl.reset();
409 bool SvtCJKOptions::IsCJKFontEnabled() const
411 assert(pImpl->IsLoaded());
412 return pImpl->IsCJKFontEnabled();
415 bool SvtCJKOptions::IsVerticalTextEnabled() const
417 assert(pImpl->IsLoaded());
418 return pImpl->IsVerticalTextEnabled();
421 bool SvtCJKOptions::IsAsianTypographyEnabled() const
423 assert(pImpl->IsLoaded());
424 return pImpl->IsAsianTypographyEnabled();
427 bool SvtCJKOptions::IsJapaneseFindEnabled() const
429 assert(pImpl->IsLoaded());
430 return pImpl->IsJapaneseFindEnabled();
433 bool SvtCJKOptions::IsRubyEnabled() const
435 assert(pImpl->IsLoaded());
436 return pImpl->IsRubyEnabled();
439 bool SvtCJKOptions::IsChangeCaseMapEnabled() const
441 assert(pImpl->IsLoaded());
442 return pImpl->IsChangeCaseMapEnabled();
445 bool SvtCJKOptions::IsDoubleLinesEnabled() const
447 assert(pImpl->IsLoaded());
448 return pImpl->IsDoubleLinesEnabled();
451 void SvtCJKOptions::SetAll(bool bSet)
453 assert(pImpl->IsLoaded());
454 pImpl->SetAll(bSet);
457 bool SvtCJKOptions::IsAnyEnabled() const
459 assert(pImpl->IsLoaded());
460 return pImpl->IsAnyEnabled();
463 bool SvtCJKOptions::IsReadOnly(EOption eOption) const
465 assert(pImpl->IsLoaded());
466 return pImpl->IsReadOnly(eOption);
469 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */