summaryrefslogtreecommitdiffstats
path: root/linguistic/source/lngopt.cxx
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--linguistic/source/lngopt.cxx461
1 files changed, 461 insertions, 0 deletions
diff --git a/linguistic/source/lngopt.cxx b/linguistic/source/lngopt.cxx
new file mode 100644
index 000000000..dfe620504
--- /dev/null
+++ b/linguistic/source/lngopt.cxx
@@ -0,0 +1,461 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+
+#include <sal/macros.h>
+#include "lngopt.hxx"
+#include "lngreg.hxx"
+#include <linguistic/misc.hxx>
+#include <tools/debug.hxx>
+#include <unotools/lingucfg.hxx>
+
+#include <comphelper/sequence.hxx>
+#include <cppuhelper/factory.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <com/sun/star/lang/Locale.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+
+using namespace utl;
+using namespace osl;
+using namespace com::sun::star;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::linguistic2;
+using namespace linguistic;
+
+using namespace com::sun::star::registry;
+
+
+// static member initialization
+SvtLinguOptions * LinguOptions::pData = nullptr;
+oslInterlockedCount LinguOptions::nRefCount;
+
+
+LinguOptions::LinguOptions()
+{
+ if (!pData)
+ {
+ pData = new SvtLinguOptions;
+ SvtLinguConfig aLinguCfg;
+ aLinguCfg.GetOptions( *pData );
+ }
+
+ osl_atomic_increment( &nRefCount );
+}
+
+
+LinguOptions::LinguOptions(const LinguOptions & /*rOpt*/)
+{
+ DBG_ASSERT( pData, "lng : data missing" );
+ osl_atomic_increment( &nRefCount );
+}
+
+
+LinguOptions::~LinguOptions()
+{
+ MutexGuard aGuard( GetLinguMutex() );
+
+ if ( osl_atomic_decrement( &nRefCount ) == 0 )
+ {
+ delete pData; pData = nullptr;
+ }
+}
+
+namespace {
+
+struct WID_Name
+{
+ sal_Int32 nWID;
+ const char *pPropertyName;
+};
+
+}
+
+//! order of entries is import (see LinguOptions::GetName)
+//! since the WID is used as index in this table!
+WID_Name const aWID_Name[] =
+{
+ { 0, nullptr },
+ { UPH_IS_USE_DICTIONARY_LIST, UPN_IS_USE_DICTIONARY_LIST },
+ { UPH_IS_IGNORE_CONTROL_CHARACTERS, UPN_IS_IGNORE_CONTROL_CHARACTERS },
+ { UPH_IS_SPELL_UPPER_CASE, UPN_IS_SPELL_UPPER_CASE },
+ { UPH_IS_SPELL_WITH_DIGITS, UPN_IS_SPELL_WITH_DIGITS },
+ { UPH_IS_SPELL_CAPITALIZATION, UPN_IS_SPELL_CAPITALIZATION },
+ { UPH_HYPH_MIN_LEADING, UPN_HYPH_MIN_LEADING },
+ { UPH_HYPH_MIN_TRAILING, UPN_HYPH_MIN_TRAILING },
+ { UPH_HYPH_MIN_WORD_LENGTH, UPN_HYPH_MIN_WORD_LENGTH },
+ { UPH_DEFAULT_LOCALE, UPN_DEFAULT_LOCALE },
+ { UPH_IS_SPELL_AUTO, UPN_IS_SPELL_AUTO },
+ { 0, nullptr },
+ { 0, nullptr },
+ { UPH_IS_SPELL_SPECIAL, UPN_IS_SPELL_SPECIAL },
+ { UPH_IS_HYPH_AUTO, UPN_IS_HYPH_AUTO },
+ { UPH_IS_HYPH_SPECIAL, UPN_IS_HYPH_SPECIAL },
+ { UPH_IS_WRAP_REVERSE, UPN_IS_WRAP_REVERSE },
+ { 0, nullptr },
+ { 0, nullptr },
+ { 0, nullptr },
+ { 0, nullptr },
+ { UPH_DEFAULT_LANGUAGE, UPN_DEFAULT_LANGUAGE },
+ { UPH_DEFAULT_LOCALE_CJK, UPN_DEFAULT_LOCALE_CJK },
+ { UPH_DEFAULT_LOCALE_CTL, UPN_DEFAULT_LOCALE_CTL }
+};
+
+
+OUString LinguOptions::GetName( sal_Int32 nWID )
+{
+ MutexGuard aGuard( GetLinguMutex() );
+
+ OUString aRes;
+
+ if (0 <= nWID && nWID < sal_Int32(SAL_N_ELEMENTS(aWID_Name)) && aWID_Name[ nWID ].nWID == nWID)
+ aRes = OUString::createFromAscii(aWID_Name[nWID].pPropertyName);
+ else
+ OSL_FAIL("lng : unknown WID");
+
+ return aRes;
+}
+
+
+//! map must be sorted by first entry in alphabetical increasing order.
+static const SfxItemPropertyMapEntry* lcl_GetLinguProps()
+{
+ static const SfxItemPropertyMapEntry aLinguProps[] =
+ {
+ { OUString(UPN_DEFAULT_LANGUAGE), UPH_DEFAULT_LANGUAGE,
+ ::cppu::UnoType<sal_Int16>::get(), 0, 0 },
+ { OUString(UPN_DEFAULT_LOCALE), UPH_DEFAULT_LOCALE,
+ ::cppu::UnoType<Locale>::get(), 0, 0 },
+ { OUString(UPN_DEFAULT_LOCALE_CJK), UPH_DEFAULT_LOCALE_CJK,
+ ::cppu::UnoType<Locale>::get(), 0, 0 },
+ { OUString(UPN_DEFAULT_LOCALE_CTL), UPH_DEFAULT_LOCALE_CTL,
+ ::cppu::UnoType<Locale>::get(), 0, 0 },
+ { OUString(UPN_HYPH_MIN_LEADING), UPH_HYPH_MIN_LEADING,
+ ::cppu::UnoType<sal_Int16>::get(), 0, 0 },
+ { OUString(UPN_HYPH_MIN_TRAILING), UPH_HYPH_MIN_TRAILING,
+ ::cppu::UnoType<sal_Int16>::get(), 0, 0 },
+ { OUString(UPN_HYPH_MIN_WORD_LENGTH), UPH_HYPH_MIN_WORD_LENGTH,
+ ::cppu::UnoType<sal_Int16>::get(), 0, 0 },
+ { OUString(UPN_IS_GERMAN_PRE_REFORM), UPH_IS_GERMAN_PRE_REFORM, /*! deprecated !*/
+ cppu::UnoType<bool>::get(), 0, 0 },
+ { OUString(UPN_IS_HYPH_AUTO), UPH_IS_HYPH_AUTO,
+ cppu::UnoType<bool>::get(), 0, 0 },
+ { OUString(UPN_IS_HYPH_SPECIAL), UPH_IS_HYPH_SPECIAL,
+ cppu::UnoType<bool>::get(), 0, 0 },
+ { OUString(UPN_IS_IGNORE_CONTROL_CHARACTERS), UPH_IS_IGNORE_CONTROL_CHARACTERS,
+ cppu::UnoType<bool>::get(), 0, 0 },
+ { OUString(UPN_IS_SPELL_AUTO), UPH_IS_SPELL_AUTO,
+ cppu::UnoType<bool>::get(), 0, 0 },
+ { OUString(UPN_IS_SPELL_CAPITALIZATION), UPH_IS_SPELL_CAPITALIZATION,
+ cppu::UnoType<bool>::get(), 0, 0 },
+ { OUString(UPN_IS_SPELL_HIDE), UPH_IS_SPELL_HIDE, /*! deprecated !*/
+ cppu::UnoType<bool>::get(), 0, 0 },
+ { OUString(UPN_IS_SPELL_IN_ALL_LANGUAGES), UPH_IS_SPELL_IN_ALL_LANGUAGES, /*! deprecated !*/
+ cppu::UnoType<bool>::get(), 0, 0 },
+ { OUString(UPN_IS_SPELL_SPECIAL), UPH_IS_SPELL_SPECIAL,
+ cppu::UnoType<bool>::get(), 0, 0 },
+ { OUString(UPN_IS_SPELL_UPPER_CASE), UPH_IS_SPELL_UPPER_CASE,
+ cppu::UnoType<bool>::get(), 0, 0 },
+ { OUString(UPN_IS_SPELL_WITH_DIGITS), UPH_IS_SPELL_WITH_DIGITS,
+ cppu::UnoType<bool>::get(), 0, 0 },
+ { OUString(UPN_IS_USE_DICTIONARY_LIST), UPH_IS_USE_DICTIONARY_LIST,
+ cppu::UnoType<bool>::get(), 0, 0 },
+ { OUString(UPN_IS_WRAP_REVERSE), UPH_IS_WRAP_REVERSE,
+ cppu::UnoType<bool>::get(), 0, 0 },
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ return aLinguProps;
+}
+LinguProps::LinguProps() :
+ aEvtListeners (GetLinguMutex()),
+ aPropListeners (GetLinguMutex()),
+ aPropertyMap(lcl_GetLinguProps())
+{
+ bDisposing = false;
+}
+
+void LinguProps::launchEvent( const PropertyChangeEvent &rEvt ) const
+{
+ cppu::OInterfaceContainerHelper *pContainer =
+ aPropListeners.getContainer( rEvt.PropertyHandle );
+ if (pContainer)
+ {
+ cppu::OInterfaceIteratorHelper aIt( *pContainer );
+ while (aIt.hasMoreElements())
+ {
+ Reference< XPropertyChangeListener > xRef( aIt.next(), UNO_QUERY );
+ if (xRef.is())
+ xRef->propertyChange( rEvt );
+ }
+ }
+}
+
+/// @throws Exception
+static Reference< XInterface > LinguProps_CreateInstance(
+ const Reference< XMultiServiceFactory > & /*rSMgr*/ )
+{
+ Reference< XInterface > xService = static_cast<cppu::OWeakObject*>(new LinguProps);
+ return xService;
+}
+
+Reference< XPropertySetInfo > SAL_CALL LinguProps::getPropertySetInfo()
+{
+ MutexGuard aGuard( GetLinguMutex() );
+
+ static Reference< XPropertySetInfo > aRef =
+ new SfxItemPropertySetInfo( aPropertyMap );
+ return aRef;
+}
+
+void SAL_CALL LinguProps::setPropertyValue(
+ const OUString& rPropertyName, const Any& rValue )
+{
+ MutexGuard aGuard( GetLinguMutex() );
+
+ const SfxItemPropertySimpleEntry* pCur = aPropertyMap.getByName( rPropertyName );
+ if (pCur)
+ {
+ Any aOld( aConfig.GetProperty( pCur->nWID ) );
+ if (aOld != rValue && aConfig.SetProperty( pCur->nWID, rValue ))
+ {
+ PropertyChangeEvent aChgEvt( static_cast<XPropertySet *>(this), rPropertyName,
+ false, pCur->nWID, aOld, rValue );
+ launchEvent( aChgEvt );
+ }
+ }
+}
+
+Any SAL_CALL LinguProps::getPropertyValue( const OUString& rPropertyName )
+{
+ MutexGuard aGuard( GetLinguMutex() );
+
+ Any aRet;
+
+ const SfxItemPropertySimpleEntry* pCur = aPropertyMap.getByName( rPropertyName );
+ if(pCur)
+ {
+ aRet = aConfig.GetProperty( pCur->nWID );
+ }
+
+ return aRet;
+}
+
+void SAL_CALL LinguProps::addPropertyChangeListener(
+ const OUString& rPropertyName,
+ const Reference< XPropertyChangeListener >& rxListener )
+{
+ MutexGuard aGuard( GetLinguMutex() );
+
+ if (!bDisposing && rxListener.is())
+ {
+ const SfxItemPropertySimpleEntry* pCur = aPropertyMap.getByName( rPropertyName );
+ if(pCur)
+ aPropListeners.addInterface( pCur->nWID, rxListener );
+ }
+}
+
+void SAL_CALL LinguProps::removePropertyChangeListener(
+ const OUString& rPropertyName,
+ const Reference< XPropertyChangeListener >& rxListener )
+{
+ MutexGuard aGuard( GetLinguMutex() );
+
+ if (!bDisposing && rxListener.is())
+ {
+ const SfxItemPropertySimpleEntry* pCur = aPropertyMap.getByName( rPropertyName );
+ if(pCur)
+ aPropListeners.removeInterface( pCur->nWID, rxListener );
+ }
+}
+
+void SAL_CALL LinguProps::addVetoableChangeListener(
+ const OUString& /*rPropertyName*/,
+ const Reference< XVetoableChangeListener >& /*xListener*/ )
+{
+}
+
+void SAL_CALL LinguProps::removeVetoableChangeListener(
+ const OUString& /*rPropertyName*/,
+ const Reference< XVetoableChangeListener >& /*xListener*/ )
+{
+}
+
+
+void SAL_CALL LinguProps::setFastPropertyValue( sal_Int32 nHandle, const Any& rValue )
+{
+ MutexGuard aGuard( GetLinguMutex() );
+
+ Any aOld( aConfig.GetProperty( nHandle ) );
+ if (aOld != rValue && aConfig.SetProperty( nHandle, rValue ))
+ {
+ PropertyChangeEvent aChgEvt( static_cast<XPropertySet *>(this),
+ LinguOptions::GetName( nHandle ), false, nHandle, aOld, rValue );
+ launchEvent( aChgEvt );
+ }
+}
+
+
+Any SAL_CALL LinguProps::getFastPropertyValue( sal_Int32 nHandle )
+{
+ MutexGuard aGuard( GetLinguMutex() );
+
+ Any aRes( aConfig.GetProperty( nHandle ) );
+ return aRes;
+}
+
+
+Sequence< PropertyValue > SAL_CALL
+ LinguProps::getPropertyValues()
+{
+ MutexGuard aGuard( GetLinguMutex() );
+
+ PropertyEntryVector_t aPropEntries = aPropertyMap.getPropertyEntries();
+ std::vector<PropertyValue> aProps;
+ aProps.reserve(aPropertyMap.getSize());
+
+ std::transform(aPropEntries.begin(), aPropEntries.end(), std::back_inserter(aProps),
+ [this](PropertyEntryVector_t::const_reference rPropEntry) {
+ return PropertyValue(rPropEntry.sName, rPropEntry.nWID,
+ aConfig.GetProperty(rPropEntry.nWID),
+ css::beans::PropertyState_DIRECT_VALUE); });
+ return comphelper::containerToSequence(aProps);
+}
+
+void SAL_CALL
+ LinguProps::setPropertyValues( const Sequence< PropertyValue >& rProps )
+{
+ MutexGuard aGuard( GetLinguMutex() );
+
+ for (const PropertyValue &rVal : rProps)
+ {
+ setPropertyValue( rVal.Name, rVal.Value );
+ }
+}
+
+void SAL_CALL
+ LinguProps::dispose()
+{
+ MutexGuard aGuard( GetLinguMutex() );
+
+ if (!bDisposing)
+ {
+ bDisposing = true;
+
+ //! it's too late to save the options here!
+ // (see AppExitListener for saving)
+ //aOpt.Save(); // save (possible) changes before exiting
+
+ EventObject aEvtObj( static_cast<XPropertySet *>(this) );
+ aEvtListeners.disposeAndClear( aEvtObj );
+ aPropListeners.disposeAndClear( aEvtObj );
+ }
+}
+
+void SAL_CALL
+ LinguProps::addEventListener( const Reference< XEventListener >& rxListener )
+{
+ MutexGuard aGuard( GetLinguMutex() );
+
+ if (!bDisposing && rxListener.is())
+ aEvtListeners.addInterface( rxListener );
+}
+
+void SAL_CALL
+ LinguProps::removeEventListener( const Reference< XEventListener >& rxListener )
+{
+ MutexGuard aGuard( GetLinguMutex() );
+
+ if (!bDisposing && rxListener.is())
+ aEvtListeners.removeInterface( rxListener );
+}
+
+
+// Service specific part
+
+// XServiceInfo
+OUString SAL_CALL LinguProps::getImplementationName()
+{
+ return getImplementationName_Static();
+}
+
+// XServiceInfo
+sal_Bool SAL_CALL LinguProps::supportsService( const OUString& ServiceName )
+{
+ return cppu::supportsService(this, ServiceName);
+}
+
+// XServiceInfo
+uno::Sequence< OUString > SAL_CALL LinguProps::getSupportedServiceNames()
+{
+ return getSupportedServiceNames_Static();
+}
+
+// ORegistryServiceManager_Static
+uno::Sequence< OUString > LinguProps::getSupportedServiceNames_Static()
+ throw()
+{
+ return { "com.sun.star.linguistic2.LinguProperties" };
+}
+
+bool LinguProps::getPropertyBool(const OUString& aPropertyName)
+{
+ uno::Any any = getPropertyValue(aPropertyName);
+ bool b = false;
+ any >>= b;
+ return b;
+}
+
+sal_Int16 LinguProps::getPropertyInt16(const OUString& aPropertyName)
+{
+ uno::Any any = getPropertyValue(aPropertyName);
+ sal_Int16 b = 0;
+ any >>= b;
+ return b;
+}
+
+Locale LinguProps::getPropertyLocale(const OUString& aPropertyName)
+{
+ uno::Any any = getPropertyValue(aPropertyName);
+ css::lang::Locale b;
+ any >>= b;
+ return b;
+}
+
+void * LinguProps_getFactory( const char * pImplName,
+ XMultiServiceFactory *pServiceManager )
+{
+ void * pRet = nullptr;
+ if ( LinguProps::getImplementationName_Static().equalsAscii( pImplName ) )
+ {
+ Reference< XSingleServiceFactory > xFactory =
+ cppu::createOneInstanceFactory(
+ pServiceManager,
+ LinguProps::getImplementationName_Static(),
+ LinguProps_CreateInstance,
+ LinguProps::getSupportedServiceNames_Static());
+ // acquire, because we return an interface pointer instead of a reference
+ xFactory->acquire();
+ pRet = xFactory.get();
+ }
+ return pRet;
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */