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