1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
21 #include <sal/macros.h>
23 #include <linguistic/misc.hxx>
24 #include <tools/debug.hxx>
25 #include <unotools/lingucfg.hxx>
27 #include <comphelper/sequence.hxx>
28 #include <cppuhelper/factory.hxx>
29 #include <cppuhelper/supportsservice.hxx>
30 #include <cppuhelper/weak.hxx>
31 #include <com/sun/star/lang/Locale.hpp>
35 using namespace com::sun::star
;
36 using namespace com::sun::star::beans
;
37 using namespace com::sun::star::lang
;
38 using namespace com::sun::star::uno
;
39 using namespace com::sun::star::linguistic2
;
40 using namespace linguistic
;
42 using namespace com::sun::star::registry
;
45 // static member initialization
46 SvtLinguOptions
* LinguOptions::pData
= nullptr;
47 oslInterlockedCount
LinguOptions::nRefCount
;
50 LinguOptions::LinguOptions()
54 pData
= new SvtLinguOptions
;
55 SvtLinguConfig aLinguCfg
;
56 aLinguCfg
.GetOptions( *pData
);
59 osl_atomic_increment( &nRefCount
);
63 LinguOptions::LinguOptions(const LinguOptions
& /*rOpt*/)
65 DBG_ASSERT( pData
, "lng : data missing" );
66 osl_atomic_increment( &nRefCount
);
70 LinguOptions::~LinguOptions()
72 MutexGuard
aGuard( GetLinguMutex() );
74 if ( osl_atomic_decrement( &nRefCount
) == 0 )
76 delete pData
; pData
= nullptr;
85 const char *pPropertyName
;
90 //! order of entries is import (see LinguOptions::GetName)
91 //! since the WID is used as index in this table!
92 WID_Name
const aWID_Name
[] =
95 { UPH_IS_USE_DICTIONARY_LIST
, UPN_IS_USE_DICTIONARY_LIST
},
96 { UPH_IS_IGNORE_CONTROL_CHARACTERS
, UPN_IS_IGNORE_CONTROL_CHARACTERS
},
97 { UPH_IS_SPELL_UPPER_CASE
, UPN_IS_SPELL_UPPER_CASE
},
98 { UPH_IS_SPELL_WITH_DIGITS
, UPN_IS_SPELL_WITH_DIGITS
},
99 { UPH_IS_SPELL_CAPITALIZATION
, UPN_IS_SPELL_CAPITALIZATION
},
100 { UPH_HYPH_MIN_LEADING
, UPN_HYPH_MIN_LEADING
},
101 { UPH_HYPH_MIN_TRAILING
, UPN_HYPH_MIN_TRAILING
},
102 { UPH_HYPH_MIN_WORD_LENGTH
, UPN_HYPH_MIN_WORD_LENGTH
},
103 { UPH_DEFAULT_LOCALE
, UPN_DEFAULT_LOCALE
},
104 { UPH_IS_SPELL_AUTO
, UPN_IS_SPELL_AUTO
},
107 { UPH_IS_SPELL_SPECIAL
, UPN_IS_SPELL_SPECIAL
},
108 { UPH_IS_HYPH_AUTO
, UPN_IS_HYPH_AUTO
},
109 { UPH_IS_HYPH_SPECIAL
, UPN_IS_HYPH_SPECIAL
},
110 { UPH_IS_WRAP_REVERSE
, UPN_IS_WRAP_REVERSE
},
115 { UPH_DEFAULT_LANGUAGE
, UPN_DEFAULT_LANGUAGE
},
116 { UPH_DEFAULT_LOCALE_CJK
, UPN_DEFAULT_LOCALE_CJK
},
117 { UPH_DEFAULT_LOCALE_CTL
, UPN_DEFAULT_LOCALE_CTL
}
121 OUString
LinguOptions::GetName( sal_Int32 nWID
)
123 MutexGuard
aGuard( GetLinguMutex() );
127 if (0 <= nWID
&& nWID
< sal_Int32(SAL_N_ELEMENTS(aWID_Name
)) && aWID_Name
[ nWID
].nWID
== nWID
)
128 aRes
= OUString::createFromAscii(aWID_Name
[nWID
].pPropertyName
);
130 OSL_FAIL("lng : unknown WID");
136 //! map must be sorted by first entry in alphabetical increasing order.
137 static const SfxItemPropertyMapEntry
* lcl_GetLinguProps()
139 static const SfxItemPropertyMapEntry aLinguProps
[] =
141 { u
"" UPN_DEFAULT_LANGUAGE
, UPH_DEFAULT_LANGUAGE
,
142 ::cppu::UnoType
<sal_Int16
>::get(), 0, 0 },
143 { u
"" UPN_DEFAULT_LOCALE
, UPH_DEFAULT_LOCALE
,
144 ::cppu::UnoType
<Locale
>::get(), 0, 0 },
145 { u
"" UPN_DEFAULT_LOCALE_CJK
, UPH_DEFAULT_LOCALE_CJK
,
146 ::cppu::UnoType
<Locale
>::get(), 0, 0 },
147 { u
"" UPN_DEFAULT_LOCALE_CTL
, UPH_DEFAULT_LOCALE_CTL
,
148 ::cppu::UnoType
<Locale
>::get(), 0, 0 },
149 { u
"" UPN_HYPH_MIN_LEADING
, UPH_HYPH_MIN_LEADING
,
150 ::cppu::UnoType
<sal_Int16
>::get(), 0, 0 },
151 { u
"" UPN_HYPH_MIN_TRAILING
, UPH_HYPH_MIN_TRAILING
,
152 ::cppu::UnoType
<sal_Int16
>::get(), 0, 0 },
153 { u
"" UPN_HYPH_MIN_WORD_LENGTH
, UPH_HYPH_MIN_WORD_LENGTH
,
154 ::cppu::UnoType
<sal_Int16
>::get(), 0, 0 },
155 { u
"" UPN_IS_GERMAN_PRE_REFORM
, UPH_IS_GERMAN_PRE_REFORM
, /*! deprecated !*/
156 cppu::UnoType
<bool>::get(), 0, 0 },
157 { u
"" UPN_IS_HYPH_AUTO
, UPH_IS_HYPH_AUTO
,
158 cppu::UnoType
<bool>::get(), 0, 0 },
159 { u
"" UPN_IS_HYPH_SPECIAL
, UPH_IS_HYPH_SPECIAL
,
160 cppu::UnoType
<bool>::get(), 0, 0 },
161 { u
"" UPN_IS_IGNORE_CONTROL_CHARACTERS
, UPH_IS_IGNORE_CONTROL_CHARACTERS
,
162 cppu::UnoType
<bool>::get(), 0, 0 },
163 { u
"" UPN_IS_SPELL_AUTO
, UPH_IS_SPELL_AUTO
,
164 cppu::UnoType
<bool>::get(), 0, 0 },
165 { u
"" UPN_IS_SPELL_CAPITALIZATION
, UPH_IS_SPELL_CAPITALIZATION
,
166 cppu::UnoType
<bool>::get(), 0, 0 },
167 { u
"" UPN_IS_SPELL_HIDE
, UPH_IS_SPELL_HIDE
, /*! deprecated !*/
168 cppu::UnoType
<bool>::get(), 0, 0 },
169 { u
"" UPN_IS_SPELL_IN_ALL_LANGUAGES
, UPH_IS_SPELL_IN_ALL_LANGUAGES
, /*! deprecated !*/
170 cppu::UnoType
<bool>::get(), 0, 0 },
171 { u
"" UPN_IS_SPELL_SPECIAL
, UPH_IS_SPELL_SPECIAL
,
172 cppu::UnoType
<bool>::get(), 0, 0 },
173 { u
"" UPN_IS_SPELL_UPPER_CASE
, UPH_IS_SPELL_UPPER_CASE
,
174 cppu::UnoType
<bool>::get(), 0, 0 },
175 { u
"" UPN_IS_SPELL_WITH_DIGITS
, UPH_IS_SPELL_WITH_DIGITS
,
176 cppu::UnoType
<bool>::get(), 0, 0 },
177 { u
"" UPN_IS_USE_DICTIONARY_LIST
, UPH_IS_USE_DICTIONARY_LIST
,
178 cppu::UnoType
<bool>::get(), 0, 0 },
179 { u
"" UPN_IS_WRAP_REVERSE
, UPH_IS_WRAP_REVERSE
,
180 cppu::UnoType
<bool>::get(), 0, 0 },
181 { u
"", 0, css::uno::Type(), 0, 0 }
185 LinguProps::LinguProps() :
186 aEvtListeners (GetLinguMutex()),
187 aPropListeners (GetLinguMutex()),
188 aPropertyMap(lcl_GetLinguProps())
193 void LinguProps::launchEvent( const PropertyChangeEvent
&rEvt
) const
195 cppu::OInterfaceContainerHelper
*pContainer
=
196 aPropListeners
.getContainer( rEvt
.PropertyHandle
);
199 cppu::OInterfaceIteratorHelper
aIt( *pContainer
);
200 while (aIt
.hasMoreElements())
202 Reference
< XPropertyChangeListener
> xRef( aIt
.next(), UNO_QUERY
);
204 xRef
->propertyChange( rEvt
);
209 Reference
< XPropertySetInfo
> SAL_CALL
LinguProps::getPropertySetInfo()
211 MutexGuard
aGuard( GetLinguMutex() );
213 static Reference
< XPropertySetInfo
> aRef
=
214 new SfxItemPropertySetInfo( aPropertyMap
);
218 void SAL_CALL
LinguProps::setPropertyValue(
219 const OUString
& rPropertyName
, const Any
& rValue
)
221 MutexGuard
aGuard( GetLinguMutex() );
223 const SfxItemPropertyMapEntry
* pCur
= aPropertyMap
.getByName( rPropertyName
);
226 Any
aOld( aConfig
.GetProperty( pCur
->nWID
) );
227 if (aOld
!= rValue
&& aConfig
.SetProperty( pCur
->nWID
, rValue
))
229 PropertyChangeEvent
aChgEvt( static_cast<XPropertySet
*>(this), rPropertyName
,
230 false, pCur
->nWID
, aOld
, rValue
);
231 launchEvent( aChgEvt
);
236 Any SAL_CALL
LinguProps::getPropertyValue( const OUString
& rPropertyName
)
238 MutexGuard
aGuard( GetLinguMutex() );
242 const SfxItemPropertyMapEntry
* pCur
= aPropertyMap
.getByName( rPropertyName
);
245 aRet
= aConfig
.GetProperty( pCur
->nWID
);
251 void SAL_CALL
LinguProps::addPropertyChangeListener(
252 const OUString
& rPropertyName
,
253 const Reference
< XPropertyChangeListener
>& rxListener
)
255 MutexGuard
aGuard( GetLinguMutex() );
257 if (!bDisposing
&& rxListener
.is())
259 const SfxItemPropertyMapEntry
* pCur
= aPropertyMap
.getByName( rPropertyName
);
261 aPropListeners
.addInterface( pCur
->nWID
, rxListener
);
265 void SAL_CALL
LinguProps::removePropertyChangeListener(
266 const OUString
& rPropertyName
,
267 const Reference
< XPropertyChangeListener
>& rxListener
)
269 MutexGuard
aGuard( GetLinguMutex() );
271 if (!bDisposing
&& rxListener
.is())
273 const SfxItemPropertyMapEntry
* pCur
= aPropertyMap
.getByName( rPropertyName
);
275 aPropListeners
.removeInterface( pCur
->nWID
, rxListener
);
279 void SAL_CALL
LinguProps::addVetoableChangeListener(
280 const OUString
& /*rPropertyName*/,
281 const Reference
< XVetoableChangeListener
>& /*xListener*/ )
285 void SAL_CALL
LinguProps::removeVetoableChangeListener(
286 const OUString
& /*rPropertyName*/,
287 const Reference
< XVetoableChangeListener
>& /*xListener*/ )
292 void SAL_CALL
LinguProps::setFastPropertyValue( sal_Int32 nHandle
, const Any
& rValue
)
294 MutexGuard
aGuard( GetLinguMutex() );
296 Any
aOld( aConfig
.GetProperty( nHandle
) );
297 if (aOld
!= rValue
&& aConfig
.SetProperty( nHandle
, rValue
))
299 PropertyChangeEvent
aChgEvt( static_cast<XPropertySet
*>(this),
300 LinguOptions::GetName( nHandle
), false, nHandle
, aOld
, rValue
);
301 launchEvent( aChgEvt
);
306 Any SAL_CALL
LinguProps::getFastPropertyValue( sal_Int32 nHandle
)
308 MutexGuard
aGuard( GetLinguMutex() );
310 Any
aRes( aConfig
.GetProperty( nHandle
) );
315 Sequence
< PropertyValue
> SAL_CALL
316 LinguProps::getPropertyValues()
318 MutexGuard
aGuard( GetLinguMutex() );
320 std::vector
<PropertyValue
> aProps
;
321 aProps
.reserve(aPropertyMap
.getPropertyEntries().size());
322 for(auto pEntry
: aPropertyMap
.getPropertyEntries())
323 aProps
.push_back(PropertyValue(pEntry
->aName
, pEntry
->nWID
,
324 aConfig
.GetProperty(pEntry
->nWID
),
325 css::beans::PropertyState_DIRECT_VALUE
));
326 return comphelper::containerToSequence(aProps
);
330 LinguProps::setPropertyValues( const Sequence
< PropertyValue
>& rProps
)
332 MutexGuard
aGuard( GetLinguMutex() );
334 for (const PropertyValue
&rVal
: rProps
)
336 setPropertyValue( rVal
.Name
, rVal
.Value
);
341 LinguProps::dispose()
343 MutexGuard
aGuard( GetLinguMutex() );
349 //! it's too late to save the options here!
350 // (see AppExitListener for saving)
351 //aOpt.Save(); // save (possible) changes before exiting
353 EventObject
aEvtObj( static_cast<XPropertySet
*>(this) );
354 aEvtListeners
.disposeAndClear( aEvtObj
);
355 aPropListeners
.disposeAndClear( aEvtObj
);
360 LinguProps::addEventListener( const Reference
< XEventListener
>& rxListener
)
362 MutexGuard
aGuard( GetLinguMutex() );
364 if (!bDisposing
&& rxListener
.is())
365 aEvtListeners
.addInterface( rxListener
);
369 LinguProps::removeEventListener( const Reference
< XEventListener
>& rxListener
)
371 MutexGuard
aGuard( GetLinguMutex() );
373 if (!bDisposing
&& rxListener
.is())
374 aEvtListeners
.removeInterface( rxListener
);
378 // Service specific part
381 OUString SAL_CALL
LinguProps::getImplementationName()
383 return "com.sun.star.lingu2.LinguProps";
387 sal_Bool SAL_CALL
LinguProps::supportsService( const OUString
& ServiceName
)
389 return cppu::supportsService(this, ServiceName
);
393 uno::Sequence
< OUString
> SAL_CALL
LinguProps::getSupportedServiceNames()
395 return { "com.sun.star.linguistic2.LinguProperties" };
398 bool LinguProps::getPropertyBool(const OUString
& aPropertyName
)
400 uno::Any any
= getPropertyValue(aPropertyName
);
406 sal_Int16
LinguProps::getPropertyInt16(const OUString
& aPropertyName
)
408 uno::Any any
= getPropertyValue(aPropertyName
);
414 Locale
LinguProps::getPropertyLocale(const OUString
& aPropertyName
)
416 uno::Any any
= getPropertyValue(aPropertyName
);
422 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
423 linguistic_LinguProps_get_implementation(
424 css::uno::XComponentContext
* , css::uno::Sequence
<css::uno::Any
> const&)
426 return cppu::acquire(new LinguProps());
430 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */