blob: 775787a61302198cfab7b7c956fe5fecbdc5e26f [file] [log] [blame]
/**************************************************************
*
* 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
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_unotools.hxx"
#include <com/sun/star/lang/Locale.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/lang/XSingleServiceFactory.hpp>
#include <com/sun/star/container/XNameAccess.hpp>
#include <com/sun/star/container/XNameContainer.hpp>
#include <com/sun/star/container/XNameReplace.hpp>
#include "com/sun/star/util/XMacroExpander.hpp"
#include "com/sun/star/beans/XPropertySet.hpp"
#include <rtl/uri.hxx>
#include <vos/mutex.hxx>
#include <i18npool/mslangid.hxx>
#include <tools/debug.hxx>
#include <tools/string.hxx>
#include <unotools/lingucfg.hxx>
#include <unotools/linguprops.hxx>
#include <comphelper/processfactory.hxx>
#include <itemholder1.hxx>
using namespace rtl;
using namespace com::sun::star;
#define A2OU(x) ::rtl::OUString::createFromAscii( x )
#define EXPAND_PROTOCOL "vnd.sun.star.expand:"
#define FILE_PROTOCOL "file:///"
///////////////////////////////////////////////////////////////////////////
static osl::Mutex & GetOwnMutex()
{
static osl::Mutex aMutex;
return aMutex;
}
///////////////////////////////////////////////////////////////////////////
static sal_Bool lcl_SetLocale( sal_Int16 &rLanguage, const uno::Any &rVal )
{
sal_Bool bSucc = sal_False;
lang::Locale aNew;
if (rVal >>= aNew) // conversion successful?
{
sal_Int16 nNew = MsLangId::convertLocaleToLanguage( aNew );
if (nNew != rLanguage)
{
rLanguage = nNew;
bSucc = sal_True;
}
}
return bSucc;
}
static inline const OUString lcl_LanguageToCfgLocaleStr( sal_Int16 nLanguage )
{
OUString aRes;
if (LANGUAGE_SYSTEM != nLanguage)
aRes = MsLangId::convertLanguageToIsoString( nLanguage );
return aRes;
}
static sal_Int16 lcl_CfgAnyToLanguage( const uno::Any &rVal )
{
OUString aTmp;
rVal >>= aTmp;
return (aTmp.getLength() == 0) ? LANGUAGE_SYSTEM : MsLangId::convertIsoStringToLanguage( aTmp );
}
//////////////////////////////////////////////////////////////////////
SvtLinguOptions::SvtLinguOptions()
{
nDefaultLanguage = LANGUAGE_NONE;
nDefaultLanguage_CJK = LANGUAGE_NONE;
nDefaultLanguage_CTL = LANGUAGE_NONE;
// general options
bIsUseDictionaryList =
bIsIgnoreControlCharacters = sal_True;
// spelling options
bIsSpellCapitalization =
bIsSpellSpecial = sal_True;
bIsSpellAuto =
bIsSpellReverse =
bIsSpellWithDigits =
bIsSpellUpperCase = sal_False;
// text conversion options
bIsIgnorePostPositionalWord = sal_True;
bIsAutoCloseDialog =
bIsShowEntriesRecentlyUsedFirst =
bIsAutoReplaceUniqueEntries = sal_False;
bIsDirectionToSimplified = sal_True;
bIsUseCharacterVariants =
bIsTranslateCommonTerms =
bIsReverseMapping = sal_False;
bROIsDirectionToSimplified =
bROIsUseCharacterVariants =
bROIsTranslateCommonTerms =
bROIsReverseMapping = sal_False;
// hyphenation options
bIsHyphSpecial = sal_True;
bIsHyphAuto = sal_False;
nHyphMinLeading =
nHyphMinTrailing = 2;
nHyphMinWordLength = 0;
nDataFilesChangedCheckValue = 0;
//grammar options
bIsGrammarAuto = sal_False,
bIsGrammarInteractive = sal_False;
}
//////////////////////////////////////////////////////////////////////
class SvtLinguConfigItem : public utl::ConfigItem
{
SvtLinguOptions aOpt;
// disallow copy-constructor and assignment-operator for now
SvtLinguConfigItem( const SvtLinguConfigItem & );
SvtLinguConfigItem & operator = ( const SvtLinguConfigItem & );
static sal_Bool GetHdlByName( sal_Int32 &rnHdl, const OUString &rPropertyName, sal_Bool bFullPropName = sal_False );
static const uno::Sequence< OUString > & GetPropertyNames();
sal_Bool LoadOptions( const uno::Sequence< OUString > &rProperyNames );
sal_Bool SaveOptions( const uno::Sequence< OUString > &rProperyNames );
public:
SvtLinguConfigItem();
virtual ~SvtLinguConfigItem();
// utl::ConfigItem
virtual void Notify( const com::sun::star::uno::Sequence< rtl::OUString > &rPropertyNames );
virtual void Commit();
// make some protected functions of utl::ConfigItem public
using utl::ConfigItem::GetNodeNames;
using utl::ConfigItem::GetProperties;
//using utl::ConfigItem::PutProperties;
//using utl::ConfigItem::SetSetProperties;
using utl::ConfigItem::ReplaceSetProperties;
//using utl::ConfigItem::GetReadOnlyStates;
com::sun::star::uno::Any
GetProperty( const rtl::OUString &rPropertyName ) const;
com::sun::star::uno::Any
GetProperty( sal_Int32 nPropertyHandle ) const;
sal_Bool SetProperty( const rtl::OUString &rPropertyName,
const com::sun::star::uno::Any &rValue );
sal_Bool SetProperty( sal_Int32 nPropertyHandle,
const com::sun::star::uno::Any &rValue );
sal_Bool GetOptions( SvtLinguOptions &rOptions ) const;
sal_Bool SetOptions( const SvtLinguOptions &rOptions );
sal_Bool IsReadOnly( const rtl::OUString &rPropertyName ) const;
sal_Bool IsReadOnly( sal_Int32 nPropertyHandle ) const;
};
SvtLinguConfigItem::SvtLinguConfigItem() :
utl::ConfigItem( String::CreateFromAscii( "Office.Linguistic" ) )
{
LoadOptions( GetPropertyNames() );
ClearModified();
// request notify events when properties change
EnableNotification( GetPropertyNames() );
}
SvtLinguConfigItem::~SvtLinguConfigItem()
{
//! Commit (SaveOptions) will be called by the d-tor of the base called !
}
void SvtLinguConfigItem::Notify( const uno::Sequence< OUString > &rPropertyNames )
{
LoadOptions( rPropertyNames );
NotifyListeners(0);
}
void SvtLinguConfigItem::Commit()
{
SaveOptions( GetPropertyNames() );
}
static struct NamesToHdl
{
const char *pFullPropName; // full qualified name as used in configuration
const char *pPropName; // property name only (atom) of above
sal_Int32 nHdl; // numeric handle representing the property
}aNamesToHdl[] =
{
{/* 0 */ "General/DefaultLocale", UPN_DEFAULT_LOCALE, UPH_DEFAULT_LOCALE},
{/* 1 */ "General/DictionaryList/ActiveDictionaries", UPN_ACTIVE_DICTIONARIES, UPH_ACTIVE_DICTIONARIES},
{/* 2 */ "General/DictionaryList/IsUseDictionaryList", UPN_IS_USE_DICTIONARY_LIST, UPH_IS_USE_DICTIONARY_LIST},
{/* 3 */ "General/IsIgnoreControlCharacters", UPN_IS_IGNORE_CONTROL_CHARACTERS, UPH_IS_IGNORE_CONTROL_CHARACTERS},
{/* 5 */ "General/DefaultLocale_CJK", UPN_DEFAULT_LOCALE_CJK, UPH_DEFAULT_LOCALE_CJK},
{/* 6 */ "General/DefaultLocale_CTL", UPN_DEFAULT_LOCALE_CTL, UPH_DEFAULT_LOCALE_CTL},
{/* 7 */ "SpellChecking/IsSpellUpperCase", UPN_IS_SPELL_UPPER_CASE, UPH_IS_SPELL_UPPER_CASE},
{/* 8 */ "SpellChecking/IsSpellWithDigits", UPN_IS_SPELL_WITH_DIGITS, UPH_IS_SPELL_WITH_DIGITS},
{/* 9 */ "SpellChecking/IsSpellCapitalization", UPN_IS_SPELL_CAPITALIZATION, UPH_IS_SPELL_CAPITALIZATION},
{/* 10 */ "SpellChecking/IsSpellAuto", UPN_IS_SPELL_AUTO, UPH_IS_SPELL_AUTO},
{/* 11 */ "SpellChecking/IsSpellSpecial", UPN_IS_SPELL_SPECIAL, UPH_IS_SPELL_SPECIAL},
{/* 14 */ "SpellChecking/IsReverseDirection", UPN_IS_WRAP_REVERSE, UPH_IS_WRAP_REVERSE},
{/* 15 */ "Hyphenation/MinLeading", UPN_HYPH_MIN_LEADING, UPH_HYPH_MIN_LEADING},
{/* 16 */ "Hyphenation/MinTrailing", UPN_HYPH_MIN_TRAILING, UPH_HYPH_MIN_TRAILING},
{/* 17 */ "Hyphenation/MinWordLength", UPN_HYPH_MIN_WORD_LENGTH, UPH_HYPH_MIN_WORD_LENGTH},
{/* 18 */ "Hyphenation/IsHyphSpecial", UPN_IS_HYPH_SPECIAL, UPH_IS_HYPH_SPECIAL},
{/* 19 */ "Hyphenation/IsHyphAuto", UPN_IS_HYPH_AUTO, UPH_IS_HYPH_AUTO},
{/* 20 */ "TextConversion/ActiveConversionDictionaries", UPN_ACTIVE_CONVERSION_DICTIONARIES, UPH_ACTIVE_CONVERSION_DICTIONARIES},
{/* 21 */ "TextConversion/IsIgnorePostPositionalWord", UPN_IS_IGNORE_POST_POSITIONAL_WORD, UPH_IS_IGNORE_POST_POSITIONAL_WORD},
{/* 22 */ "TextConversion/IsAutoCloseDialog", UPN_IS_AUTO_CLOSE_DIALOG, UPH_IS_AUTO_CLOSE_DIALOG},
{/* 23 */ "TextConversion/IsShowEntriesRecentlyUsedFirst", UPN_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST, UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST},
{/* 24 */ "TextConversion/IsAutoReplaceUniqueEntries", UPN_IS_AUTO_REPLACE_UNIQUE_ENTRIES, UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES},
{/* 25 */ "TextConversion/IsDirectionToSimplified", UPN_IS_DIRECTION_TO_SIMPLIFIED, UPH_IS_DIRECTION_TO_SIMPLIFIED},
{/* 26 */ "TextConversion/IsUseCharacterVariants", UPN_IS_USE_CHARACTER_VARIANTS, UPH_IS_USE_CHARACTER_VARIANTS},
{/* 27 */ "TextConversion/IsTranslateCommonTerms", UPN_IS_TRANSLATE_COMMON_TERMS, UPH_IS_TRANSLATE_COMMON_TERMS},
{/* 28 */ "TextConversion/IsReverseMapping", UPN_IS_REVERSE_MAPPING, UPH_IS_REVERSE_MAPPING},
{/* 29 */ "ServiceManager/DataFilesChangedCheckValue", UPN_DATA_FILES_CHANGED_CHECK_VALUE, UPH_DATA_FILES_CHANGED_CHECK_VALUE},
{/* 30 */ "GrammarChecking/IsAutoCheck", UPN_IS_GRAMMAR_AUTO, UPH_IS_GRAMMAR_AUTO},
{/* 31 */ "GrammarChecking/IsInteractiveCheck", UPN_IS_GRAMMAR_INTERACTIVE, UPH_IS_GRAMMAR_INTERACTIVE},
/* similar to entry 0 (thus no own configuration entry) but with different property name and type */
{ NULL, UPN_DEFAULT_LANGUAGE, UPH_DEFAULT_LANGUAGE},
{ NULL, NULL, -1}
};
const uno::Sequence< OUString > & SvtLinguConfigItem::GetPropertyNames()
{
static uno::Sequence< OUString > aNames;
static sal_Bool bInitialized = sal_False;
if (!bInitialized)
{
sal_Int32 nMax = sizeof(aNamesToHdl) / sizeof(aNamesToHdl[0]);
aNames.realloc( nMax );
OUString *pNames = aNames.getArray();
sal_Int32 nIdx = 0;
for (sal_Int32 i = 0; i < nMax; ++i)
{
const sal_Char *pFullPropName = aNamesToHdl[i].pFullPropName;
if (pFullPropName)
pNames[ nIdx++ ] = A2OU( pFullPropName );
}
aNames.realloc( nIdx );
bInitialized = sal_True;
}
return aNames;
}
sal_Bool SvtLinguConfigItem::GetHdlByName(
sal_Int32 &rnHdl,
const OUString &rPropertyName,
sal_Bool bFullPropName )
{
NamesToHdl *pEntry = &aNamesToHdl[0];
if (bFullPropName)
{
while (pEntry && pEntry->pFullPropName != NULL)
{
if (0 == rPropertyName.compareToAscii( pEntry->pFullPropName ))
{
rnHdl = pEntry->nHdl;
break;
}
++pEntry;
}
return pEntry && pEntry->pFullPropName != NULL;
}
else
{
while (pEntry && pEntry->pPropName != NULL)
{
if (0 == rPropertyName.compareToAscii( pEntry->pPropName ))
{
rnHdl = pEntry->nHdl;
break;
}
++pEntry;
}
return pEntry && pEntry->pPropName != NULL;
}
}
uno::Any SvtLinguConfigItem::GetProperty( const OUString &rPropertyName ) const
{
osl::MutexGuard aGuard( GetOwnMutex() );
sal_Int32 nHdl;
return GetHdlByName( nHdl, rPropertyName ) ? GetProperty( nHdl ) : uno::Any();
}
uno::Any SvtLinguConfigItem::GetProperty( sal_Int32 nPropertyHandle ) const
{
osl::MutexGuard aGuard( GetOwnMutex() );
uno::Any aRes;
const sal_Int16 *pnVal = 0;
const sal_Bool *pbVal = 0;
const sal_Int32 *pnInt32Val = 0;
const SvtLinguOptions &rOpt = const_cast< SvtLinguConfigItem * >(this)->aOpt;
switch (nPropertyHandle)
{
case UPH_IS_USE_DICTIONARY_LIST : pbVal = &rOpt.bIsUseDictionaryList; break;
case UPH_IS_IGNORE_CONTROL_CHARACTERS : pbVal = &rOpt.bIsIgnoreControlCharacters; break;
case UPH_IS_HYPH_AUTO : pbVal = &rOpt.bIsHyphAuto; break;
case UPH_IS_HYPH_SPECIAL : pbVal = &rOpt.bIsHyphSpecial; break;
case UPH_IS_SPELL_AUTO : pbVal = &rOpt.bIsSpellAuto; break;
case UPH_IS_SPELL_SPECIAL : pbVal = &rOpt.bIsSpellSpecial; break;
case UPH_IS_WRAP_REVERSE : pbVal = &rOpt.bIsSpellReverse; break;
case UPH_DEFAULT_LANGUAGE : pnVal = &rOpt.nDefaultLanguage; break;
case UPH_IS_SPELL_CAPITALIZATION : pbVal = &rOpt.bIsSpellCapitalization; break;
case UPH_IS_SPELL_WITH_DIGITS : pbVal = &rOpt.bIsSpellWithDigits; break;
case UPH_IS_SPELL_UPPER_CASE : pbVal = &rOpt.bIsSpellUpperCase; break;
case UPH_HYPH_MIN_LEADING : pnVal = &rOpt.nHyphMinLeading; break;
case UPH_HYPH_MIN_TRAILING : pnVal = &rOpt.nHyphMinTrailing; break;
case UPH_HYPH_MIN_WORD_LENGTH : pnVal = &rOpt.nHyphMinWordLength; break;
case UPH_ACTIVE_DICTIONARIES :
{
aRes <<= rOpt.aActiveDics;
break;
}
case UPH_ACTIVE_CONVERSION_DICTIONARIES :
{
aRes <<= rOpt.aActiveConvDics;
break;
}
case UPH_DEFAULT_LOCALE :
{
lang::Locale aLocale( MsLangId::convertLanguageToLocale( rOpt.nDefaultLanguage, false ) );
aRes.setValue( &aLocale, ::getCppuType((lang::Locale*)0 ));
break;
}
case UPH_DEFAULT_LOCALE_CJK :
{
lang::Locale aLocale( MsLangId::convertLanguageToLocale( rOpt.nDefaultLanguage_CJK, false ) );
aRes.setValue( &aLocale, ::getCppuType((lang::Locale*)0 ));
break;
}
case UPH_DEFAULT_LOCALE_CTL :
{
lang::Locale aLocale( MsLangId::convertLanguageToLocale( rOpt.nDefaultLanguage_CTL, false ) );
aRes.setValue( &aLocale, ::getCppuType((lang::Locale*)0 ));
break;
}
case UPH_IS_IGNORE_POST_POSITIONAL_WORD : pbVal = &rOpt.bIsIgnorePostPositionalWord; break;
case UPH_IS_AUTO_CLOSE_DIALOG : pbVal = &rOpt.bIsAutoCloseDialog; break;
case UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST : pbVal = &rOpt.bIsShowEntriesRecentlyUsedFirst; break;
case UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES : pbVal = &rOpt.bIsAutoReplaceUniqueEntries; break;
case UPH_IS_DIRECTION_TO_SIMPLIFIED: pbVal = &rOpt.bIsDirectionToSimplified; break;
case UPH_IS_USE_CHARACTER_VARIANTS : pbVal = &rOpt.bIsUseCharacterVariants; break;
case UPH_IS_TRANSLATE_COMMON_TERMS : pbVal = &rOpt.bIsTranslateCommonTerms; break;
case UPH_IS_REVERSE_MAPPING : pbVal = &rOpt.bIsReverseMapping; break;
case UPH_DATA_FILES_CHANGED_CHECK_VALUE : pnInt32Val = &rOpt.nDataFilesChangedCheckValue; break;
case UPH_IS_GRAMMAR_AUTO: pbVal = &rOpt.bIsGrammarAuto; break;
case UPH_IS_GRAMMAR_INTERACTIVE: pbVal = &rOpt.bIsGrammarInteractive; break;
default :
DBG_ASSERT( 0, "unexpected property handle" );
}
if (pbVal)
aRes <<= *pbVal;
else if (pnVal)
aRes <<= *pnVal;
else if (pnInt32Val)
aRes <<= *pnInt32Val;
return aRes;
}
sal_Bool SvtLinguConfigItem::SetProperty( const OUString &rPropertyName, const uno::Any &rValue )
{
osl::MutexGuard aGuard( GetOwnMutex() );
sal_Bool bSucc = sal_False;
sal_Int32 nHdl;
if (GetHdlByName( nHdl, rPropertyName ))
bSucc = SetProperty( nHdl, rValue );
return bSucc;
}
sal_Bool SvtLinguConfigItem::SetProperty( sal_Int32 nPropertyHandle, const uno::Any &rValue )
{
osl::MutexGuard aGuard( GetOwnMutex() );
sal_Bool bSucc = sal_False;
if (!rValue.hasValue())
return bSucc;
sal_Bool bMod = sal_False;
sal_Int16 *pnVal = 0;
sal_Bool *pbVal = 0;
sal_Int32 *pnInt32Val = 0;
SvtLinguOptions &rOpt = aOpt;
switch (nPropertyHandle)
{
case UPH_IS_USE_DICTIONARY_LIST : pbVal = &rOpt.bIsUseDictionaryList; break;
case UPH_IS_IGNORE_CONTROL_CHARACTERS : pbVal = &rOpt.bIsIgnoreControlCharacters; break;
case UPH_IS_HYPH_AUTO : pbVal = &rOpt.bIsHyphAuto; break;
case UPH_IS_HYPH_SPECIAL : pbVal = &rOpt.bIsHyphSpecial; break;
case UPH_IS_SPELL_AUTO : pbVal = &rOpt.bIsSpellAuto; break;
case UPH_IS_SPELL_SPECIAL : pbVal = &rOpt.bIsSpellSpecial; break;
case UPH_IS_WRAP_REVERSE : pbVal = &rOpt.bIsSpellReverse; break;
case UPH_DEFAULT_LANGUAGE : pnVal = &rOpt.nDefaultLanguage; break;
case UPH_IS_SPELL_CAPITALIZATION : pbVal = &rOpt.bIsSpellCapitalization; break;
case UPH_IS_SPELL_WITH_DIGITS : pbVal = &rOpt.bIsSpellWithDigits; break;
case UPH_IS_SPELL_UPPER_CASE : pbVal = &rOpt.bIsSpellUpperCase; break;
case UPH_HYPH_MIN_LEADING : pnVal = &rOpt.nHyphMinLeading; break;
case UPH_HYPH_MIN_TRAILING : pnVal = &rOpt.nHyphMinTrailing; break;
case UPH_HYPH_MIN_WORD_LENGTH : pnVal = &rOpt.nHyphMinWordLength; break;
case UPH_ACTIVE_DICTIONARIES :
{
rValue >>= rOpt.aActiveDics;
bMod = sal_True;
break;
}
case UPH_ACTIVE_CONVERSION_DICTIONARIES :
{
rValue >>= rOpt.aActiveConvDics;
bMod = sal_True;
break;
}
case UPH_DEFAULT_LOCALE :
{
bSucc = lcl_SetLocale( rOpt.nDefaultLanguage, rValue );
bMod = bSucc;
break;
}
case UPH_DEFAULT_LOCALE_CJK :
{
bSucc = lcl_SetLocale( rOpt.nDefaultLanguage_CJK, rValue );
bMod = bSucc;
break;
}
case UPH_DEFAULT_LOCALE_CTL :
{
bSucc = lcl_SetLocale( rOpt.nDefaultLanguage_CTL, rValue );
bMod = bSucc;
break;
}
case UPH_IS_IGNORE_POST_POSITIONAL_WORD : pbVal = &rOpt.bIsIgnorePostPositionalWord; break;
case UPH_IS_AUTO_CLOSE_DIALOG : pbVal = &rOpt.bIsAutoCloseDialog; break;
case UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST : pbVal = &rOpt.bIsShowEntriesRecentlyUsedFirst; break;
case UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES : pbVal = &rOpt.bIsAutoReplaceUniqueEntries; break;
case UPH_IS_DIRECTION_TO_SIMPLIFIED : pbVal = &rOpt.bIsDirectionToSimplified; break;
case UPH_IS_USE_CHARACTER_VARIANTS : pbVal = &rOpt.bIsUseCharacterVariants; break;
case UPH_IS_TRANSLATE_COMMON_TERMS : pbVal = &rOpt.bIsTranslateCommonTerms; break;
case UPH_IS_REVERSE_MAPPING : pbVal = &rOpt.bIsReverseMapping; break;
case UPH_DATA_FILES_CHANGED_CHECK_VALUE : pnInt32Val = &rOpt.nDataFilesChangedCheckValue; break;
case UPH_IS_GRAMMAR_AUTO: pbVal = &rOpt.bIsGrammarAuto; break;
case UPH_IS_GRAMMAR_INTERACTIVE: pbVal = &rOpt.bIsGrammarInteractive; break;
default :
DBG_ASSERT( 0, "unexpected property handle" );
}
if (pbVal)
{
sal_Bool bNew = sal_Bool();
if (rValue >>= bNew)
{
if (bNew != *pbVal)
{
*pbVal = bNew;
bMod = sal_True;
}
bSucc = sal_True;
}
}
else if (pnVal)
{
sal_Int16 nNew = sal_Int16();
if (rValue >>= nNew)
{
if (nNew != *pnVal)
{
*pnVal = nNew;
bMod = sal_True;
}
bSucc = sal_True;
}
}
else if (pnInt32Val)
{
sal_Int32 nNew = sal_Int32();
if (rValue >>= nNew)
{
if (nNew != *pnInt32Val)
{
*pnInt32Val = nNew;
bMod = sal_True;
}
bSucc = sal_True;
}
}
if (bMod)
SetModified();
NotifyListeners(0);
return bSucc;
}
sal_Bool SvtLinguConfigItem::GetOptions( SvtLinguOptions &rOptions ) const
{
osl::MutexGuard aGuard( GetOwnMutex() );
rOptions = aOpt;
return sal_True;
}
sal_Bool SvtLinguConfigItem::SetOptions( const SvtLinguOptions &rOptions )
{
osl::MutexGuard aGuard( GetOwnMutex() );
aOpt = rOptions;
SetModified();
NotifyListeners(0);
return sal_True;
}
sal_Bool SvtLinguConfigItem::LoadOptions( const uno::Sequence< OUString > &rProperyNames )
{
osl::MutexGuard aGuard( GetOwnMutex() );
sal_Bool bRes = sal_False;
const OUString *pProperyNames = rProperyNames.getConstArray();
sal_Int32 nProps = rProperyNames.getLength();
const uno::Sequence< uno::Any > aValues = GetProperties( rProperyNames );
const uno::Sequence< sal_Bool > aROStates = GetReadOnlyStates( rProperyNames );
if (nProps && aValues.getLength() == nProps && aROStates.getLength() == nProps)
{
SvtLinguOptions &rOpt = aOpt;
const uno::Any *pValue = aValues.getConstArray();
const sal_Bool *pROStates = aROStates.getConstArray();
for (sal_Int32 i = 0; i < nProps; ++i)
{
const uno::Any &rVal = pValue[i];
sal_Int32 nPropertyHandle;
GetHdlByName( nPropertyHandle, pProperyNames[i], sal_True );
switch ( nPropertyHandle )
{
case UPH_DEFAULT_LOCALE :
{ rOpt.bRODefaultLanguage = pROStates[i]; rOpt.nDefaultLanguage = lcl_CfgAnyToLanguage( rVal ); } break;
case UPH_ACTIVE_DICTIONARIES :
{ rOpt.bROActiveDics = pROStates[i]; rVal >>= rOpt.aActiveDics; } break;
case UPH_IS_USE_DICTIONARY_LIST :
{ rOpt.bROIsUseDictionaryList = pROStates[i]; rVal >>= rOpt.bIsUseDictionaryList; } break;
case UPH_IS_IGNORE_CONTROL_CHARACTERS :
{ rOpt.bROIsIgnoreControlCharacters = pROStates[i]; rVal >>= rOpt.bIsIgnoreControlCharacters; } break;
case UPH_DEFAULT_LOCALE_CJK :
{ rOpt.bRODefaultLanguage_CJK = pROStates[i]; rOpt.nDefaultLanguage_CJK = lcl_CfgAnyToLanguage( rVal ); } break;
case UPH_DEFAULT_LOCALE_CTL :
{ rOpt.bRODefaultLanguage_CTL = pROStates[i]; rOpt.nDefaultLanguage_CTL = lcl_CfgAnyToLanguage( rVal ); } break;
case UPH_IS_SPELL_UPPER_CASE :
{ rOpt.bROIsSpellUpperCase = pROStates[i]; rVal >>= rOpt.bIsSpellUpperCase; } break;
case UPH_IS_SPELL_WITH_DIGITS :
{ rOpt.bROIsSpellWithDigits = pROStates[i]; rVal >>= rOpt.bIsSpellWithDigits; } break;
case UPH_IS_SPELL_CAPITALIZATION :
{ rOpt.bROIsSpellCapitalization = pROStates[i]; rVal >>= rOpt.bIsSpellCapitalization; } break;
case UPH_IS_SPELL_AUTO :
{ rOpt.bROIsSpellAuto = pROStates[i]; rVal >>= rOpt.bIsSpellAuto; } break;
case UPH_IS_SPELL_SPECIAL :
{ rOpt.bROIsSpellSpecial = pROStates[i]; rVal >>= rOpt.bIsSpellSpecial; } break;
case UPH_IS_WRAP_REVERSE :
{ rOpt.bROIsSpellReverse = pROStates[i]; rVal >>= rOpt.bIsSpellReverse; } break;
case UPH_HYPH_MIN_LEADING :
{ rOpt.bROHyphMinLeading = pROStates[i]; rVal >>= rOpt.nHyphMinLeading; } break;
case UPH_HYPH_MIN_TRAILING :
{ rOpt.bROHyphMinTrailing = pROStates[i]; rVal >>= rOpt.nHyphMinTrailing; } break;
case UPH_HYPH_MIN_WORD_LENGTH :
{ rOpt.bROHyphMinWordLength = pROStates[i]; rVal >>= rOpt.nHyphMinWordLength; } break;
case UPH_IS_HYPH_SPECIAL :
{ rOpt.bROIsHyphSpecial = pROStates[i]; rVal >>= rOpt.bIsHyphSpecial; } break;
case UPH_IS_HYPH_AUTO :
{ rOpt.bROIsHyphAuto = pROStates[i]; rVal >>= rOpt.bIsHyphAuto; } break;
case UPH_ACTIVE_CONVERSION_DICTIONARIES : { rOpt.bROActiveConvDics = pROStates[i]; rVal >>= rOpt.aActiveConvDics; } break;
case UPH_IS_IGNORE_POST_POSITIONAL_WORD :
{ rOpt.bROIsIgnorePostPositionalWord = pROStates[i]; rVal >>= rOpt.bIsIgnorePostPositionalWord; } break;
case UPH_IS_AUTO_CLOSE_DIALOG :
{ rOpt.bROIsAutoCloseDialog = pROStates[i]; rVal >>= rOpt.bIsAutoCloseDialog; } break;
case UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST :
{ rOpt.bROIsShowEntriesRecentlyUsedFirst = pROStates[i]; rVal >>= rOpt.bIsShowEntriesRecentlyUsedFirst; } break;
case UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES :
{ rOpt.bROIsAutoReplaceUniqueEntries = pROStates[i]; rVal >>= rOpt.bIsAutoReplaceUniqueEntries; } break;
case UPH_IS_DIRECTION_TO_SIMPLIFIED :
{ rOpt.bROIsDirectionToSimplified = pROStates[i];
if( ! (rVal >>= rOpt.bIsDirectionToSimplified) )
{
//default is locale dependent:
if( rOpt.nDefaultLanguage_CJK == LANGUAGE_CHINESE_HONGKONG
|| rOpt.nDefaultLanguage_CJK == LANGUAGE_CHINESE_MACAU
|| rOpt.nDefaultLanguage_CJK == LANGUAGE_CHINESE_TRADITIONAL )
{
rOpt.bIsDirectionToSimplified = sal_False;
}
else
{
rOpt.bIsDirectionToSimplified = sal_True;
}
}
} break;
case UPH_IS_USE_CHARACTER_VARIANTS :
{ rOpt.bROIsUseCharacterVariants = pROStates[i]; rVal >>= rOpt.bIsUseCharacterVariants; } break;
case UPH_IS_TRANSLATE_COMMON_TERMS :
{ rOpt.bROIsTranslateCommonTerms = pROStates[i]; rVal >>= rOpt.bIsTranslateCommonTerms; } break;
case UPH_IS_REVERSE_MAPPING :
{ rOpt.bROIsReverseMapping = pROStates[i]; rVal >>= rOpt.bIsReverseMapping; } break;
case UPH_DATA_FILES_CHANGED_CHECK_VALUE :
{ rOpt.bRODataFilesChangedCheckValue = pROStates[i]; rVal >>= rOpt.nDataFilesChangedCheckValue; } break;
case UPH_IS_GRAMMAR_AUTO:
{ rOpt.bROIsGrammarAuto = pROStates[i]; rVal >>= rOpt.bIsGrammarAuto; }
break;
case UPH_IS_GRAMMAR_INTERACTIVE:
{ rOpt.bROIsGrammarInteractive = pROStates[i]; rVal >>= rOpt.bIsGrammarInteractive; }
break;
default:
DBG_ASSERT( 0, "unexpected case" );
}
}
bRes = sal_True;
}
DBG_ASSERT( bRes, "LoadOptions failed" );
return bRes;
}
sal_Bool SvtLinguConfigItem::SaveOptions( const uno::Sequence< OUString > &rProperyNames )
{
if (!IsModified())
return sal_True;
osl::MutexGuard aGuard( GetOwnMutex() );
sal_Bool bRet = sal_False;
const uno::Type &rBOOL = ::getBooleanCppuType();
const uno::Type &rINT16 = ::getCppuType( (sal_Int16 *) NULL );
const uno::Type &rINT32 = ::getCppuType( (sal_Int32 *) NULL );
sal_Int32 nProps = rProperyNames.getLength();
uno::Sequence< uno::Any > aValues( nProps );
uno::Any *pValue = aValues.getArray();
if (nProps && aValues.getLength() == nProps)
{
const SvtLinguOptions &rOpt = aOpt;
OUString aTmp( lcl_LanguageToCfgLocaleStr( rOpt.nDefaultLanguage ) );
*pValue++ = uno::makeAny( aTmp ); // 0
*pValue++ = uno::makeAny( rOpt.aActiveDics ); // 1
pValue++->setValue( &rOpt.bIsUseDictionaryList, rBOOL ); // 2
pValue++->setValue( &rOpt.bIsIgnoreControlCharacters, rBOOL ); // 3
aTmp = lcl_LanguageToCfgLocaleStr( rOpt.nDefaultLanguage_CJK );
*pValue++ = uno::makeAny( aTmp ); // 5
aTmp = lcl_LanguageToCfgLocaleStr( rOpt.nDefaultLanguage_CTL );
*pValue++ = uno::makeAny( aTmp ); // 6
pValue++->setValue( &rOpt.bIsSpellUpperCase, rBOOL ); // 7
pValue++->setValue( &rOpt.bIsSpellWithDigits, rBOOL ); // 8
pValue++->setValue( &rOpt.bIsSpellCapitalization, rBOOL ); // 9
pValue++->setValue( &rOpt.bIsSpellAuto, rBOOL ); // 10
pValue++->setValue( &rOpt.bIsSpellSpecial, rBOOL ); // 11
pValue++->setValue( &rOpt.bIsSpellReverse, rBOOL ); // 14
pValue++->setValue( &rOpt.nHyphMinLeading, rINT16 ); // 15
pValue++->setValue( &rOpt.nHyphMinTrailing, rINT16 ); // 16
pValue++->setValue( &rOpt.nHyphMinWordLength, rINT16 ); // 17
pValue++->setValue( &rOpt.bIsHyphSpecial, rBOOL ); // 18
pValue++->setValue( &rOpt.bIsHyphAuto, rBOOL ); // 19
*pValue++ = uno::makeAny( rOpt.aActiveConvDics ); // 20
pValue++->setValue( &rOpt.bIsIgnorePostPositionalWord, rBOOL ); // 21
pValue++->setValue( &rOpt.bIsAutoCloseDialog, rBOOL ); // 22
pValue++->setValue( &rOpt.bIsShowEntriesRecentlyUsedFirst, rBOOL ); // 23
pValue++->setValue( &rOpt.bIsAutoReplaceUniqueEntries, rBOOL ); // 24
pValue++->setValue( &rOpt.bIsDirectionToSimplified, rBOOL ); // 25
pValue++->setValue( &rOpt.bIsUseCharacterVariants, rBOOL ); // 26
pValue++->setValue( &rOpt.bIsTranslateCommonTerms, rBOOL ); // 27
pValue++->setValue( &rOpt.bIsReverseMapping, rBOOL ); // 28
pValue++->setValue( &rOpt.nDataFilesChangedCheckValue, rINT32 ); // 29
pValue++->setValue( &rOpt.bIsGrammarAuto, rBOOL ); // 30
pValue++->setValue( &rOpt.bIsGrammarInteractive, rBOOL ); // 31
bRet |= PutProperties( rProperyNames, aValues );
}
if (bRet)
ClearModified();
return bRet;
}
sal_Bool SvtLinguConfigItem::IsReadOnly( const rtl::OUString &rPropertyName ) const
{
osl::MutexGuard aGuard( GetOwnMutex() );
sal_Bool bReadOnly = sal_False;
sal_Int32 nHdl;
if (GetHdlByName( nHdl, rPropertyName ))
bReadOnly = IsReadOnly( nHdl );
return bReadOnly;
}
sal_Bool SvtLinguConfigItem::IsReadOnly( sal_Int32 nPropertyHandle ) const
{
osl::MutexGuard aGuard( GetOwnMutex() );
sal_Bool bReadOnly = sal_False;
const SvtLinguOptions &rOpt = const_cast< SvtLinguConfigItem * >(this)->aOpt;
switch(nPropertyHandle)
{
case UPH_IS_USE_DICTIONARY_LIST : bReadOnly = rOpt.bROIsUseDictionaryList ; break;
case UPH_IS_IGNORE_CONTROL_CHARACTERS : bReadOnly = rOpt.bROIsIgnoreControlCharacters; break;
case UPH_IS_HYPH_AUTO : bReadOnly = rOpt.bROIsHyphAuto ; break;
case UPH_IS_HYPH_SPECIAL : bReadOnly = rOpt.bROIsHyphSpecial ; break;
case UPH_IS_SPELL_AUTO : bReadOnly = rOpt.bROIsSpellAuto ; break;
case UPH_IS_SPELL_SPECIAL : bReadOnly = rOpt.bROIsSpellSpecial ; break;
case UPH_IS_WRAP_REVERSE : bReadOnly = rOpt.bROIsSpellReverse ; break;
case UPH_DEFAULT_LANGUAGE : bReadOnly = rOpt.bRODefaultLanguage ; break;
case UPH_IS_SPELL_CAPITALIZATION : bReadOnly = rOpt.bROIsSpellCapitalization ; break;
case UPH_IS_SPELL_WITH_DIGITS : bReadOnly = rOpt.bROIsSpellWithDigits ; break;
case UPH_IS_SPELL_UPPER_CASE : bReadOnly = rOpt.bROIsSpellUpperCase ; break;
case UPH_HYPH_MIN_LEADING : bReadOnly = rOpt.bROHyphMinLeading ; break;
case UPH_HYPH_MIN_TRAILING : bReadOnly = rOpt.bROHyphMinTrailing ; break;
case UPH_HYPH_MIN_WORD_LENGTH : bReadOnly = rOpt.bROHyphMinWordLength ; break;
case UPH_ACTIVE_DICTIONARIES : bReadOnly = rOpt.bROActiveDics ; break;
case UPH_ACTIVE_CONVERSION_DICTIONARIES : bReadOnly = rOpt.bROActiveConvDics ; break;
case UPH_DEFAULT_LOCALE : bReadOnly = rOpt.bRODefaultLanguage ; break;
case UPH_DEFAULT_LOCALE_CJK : bReadOnly = rOpt.bRODefaultLanguage_CJK ; break;
case UPH_DEFAULT_LOCALE_CTL : bReadOnly = rOpt.bRODefaultLanguage_CTL ; break;
case UPH_IS_IGNORE_POST_POSITIONAL_WORD : bReadOnly = rOpt.bROIsIgnorePostPositionalWord; break;
case UPH_IS_AUTO_CLOSE_DIALOG : bReadOnly = rOpt.bROIsAutoCloseDialog; break;
case UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST : bReadOnly = rOpt.bROIsShowEntriesRecentlyUsedFirst; break;
case UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES : bReadOnly = rOpt.bROIsAutoReplaceUniqueEntries; break;
case UPH_IS_DIRECTION_TO_SIMPLIFIED : bReadOnly = rOpt.bROIsDirectionToSimplified; break;
case UPH_IS_USE_CHARACTER_VARIANTS : bReadOnly = rOpt.bROIsUseCharacterVariants; break;
case UPH_IS_TRANSLATE_COMMON_TERMS : bReadOnly = rOpt.bROIsTranslateCommonTerms; break;
case UPH_IS_REVERSE_MAPPING : bReadOnly = rOpt.bROIsReverseMapping; break;
case UPH_DATA_FILES_CHANGED_CHECK_VALUE : bReadOnly = rOpt.bRODataFilesChangedCheckValue; break;
case UPH_IS_GRAMMAR_AUTO: bReadOnly = rOpt.bROIsGrammarAuto; break;
case UPH_IS_GRAMMAR_INTERACTIVE: bReadOnly = rOpt.bROIsGrammarInteractive; break;
default :
DBG_ASSERT( 0, "unexpected property handle" );
}
return bReadOnly;
}
//////////////////////////////////////////////////////////////////////
static SvtLinguConfigItem *pCfgItem = 0;
static sal_Int32 nCfgItemRefCount = 0;
static const rtl::OUString aG_SupportedDictionaryFormats( A2OU("SupportedDictionaryFormats") );
static const rtl::OUString aG_Dictionaries( A2OU("Dictionaries") );
static const rtl::OUString aG_Locations( A2OU("Locations") );
static const rtl::OUString aG_Format( A2OU("Format") );
static const rtl::OUString aG_Locales( A2OU("Locales") );
static const rtl::OUString aG_DisabledDictionaries( A2OU("DisabledDictionaries") );
static const rtl::OUString aG_LastActiveDictionaries( A2OU("LastActiveDictionaries") );
SvtLinguConfig::SvtLinguConfig()
{
// Global access, must be guarded (multithreading)
osl::MutexGuard aGuard( GetOwnMutex() );
++nCfgItemRefCount;
}
SvtLinguConfig::~SvtLinguConfig()
{
osl::MutexGuard aGuard( GetOwnMutex() );
if (pCfgItem && pCfgItem->IsModified())
pCfgItem->Commit();
if (--nCfgItemRefCount <= 0)
{
if (pCfgItem)
delete pCfgItem;
pCfgItem = 0;
}
}
SvtLinguConfigItem & SvtLinguConfig::GetConfigItem()
{
// Global access, must be guarded (multithreading)
osl::MutexGuard aGuard( GetOwnMutex() );
if (!pCfgItem)
{
pCfgItem = new SvtLinguConfigItem;
ItemHolder1::holdConfigItem(E_LINGUCFG);
}
return *pCfgItem;
}
uno::Sequence< OUString > SvtLinguConfig::GetNodeNames( const OUString &rNode )
{
return GetConfigItem().GetNodeNames( rNode );
}
uno::Sequence< uno::Any > SvtLinguConfig::GetProperties( const uno::Sequence< OUString > &rNames )
{
return GetConfigItem().GetProperties(rNames);
}
sal_Bool SvtLinguConfig::ReplaceSetProperties(
const OUString &rNode, uno::Sequence< beans::PropertyValue > rValues )
{
return GetConfigItem().ReplaceSetProperties( rNode, rValues );
}
uno::Any SvtLinguConfig::GetProperty( const OUString &rPropertyName ) const
{
return GetConfigItem().GetProperty( rPropertyName );
}
uno::Any SvtLinguConfig::GetProperty( sal_Int32 nPropertyHandle ) const
{
return GetConfigItem().GetProperty( nPropertyHandle );
}
sal_Bool SvtLinguConfig::SetProperty( const OUString &rPropertyName, const uno::Any &rValue )
{
return GetConfigItem().SetProperty( rPropertyName, rValue );
}
sal_Bool SvtLinguConfig::SetProperty( sal_Int32 nPropertyHandle, const uno::Any &rValue )
{
return GetConfigItem().SetProperty( nPropertyHandle, rValue );
}
sal_Bool SvtLinguConfig::GetOptions( SvtLinguOptions &rOptions ) const
{
return GetConfigItem().GetOptions( rOptions );
}
sal_Bool SvtLinguConfig::SetOptions( const SvtLinguOptions &rOptions )
{
return GetConfigItem().SetOptions( rOptions );
}
sal_Bool SvtLinguConfig::IsReadOnly( const rtl::OUString &rPropertyName ) const
{
return GetConfigItem().IsReadOnly( rPropertyName );
}
sal_Bool SvtLinguConfig::IsReadOnly( sal_Int32 nPropertyHandle ) const
{
return GetConfigItem().IsReadOnly( nPropertyHandle );
}
sal_Bool SvtLinguConfig::GetElementNamesFor(
const rtl::OUString &rNodeName,
uno::Sequence< rtl::OUString > &rElementNames ) const
{
bool bSuccess = false;
try
{
uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW );
xNA.set( xNA->getByName( A2OU("ServiceManager") ), uno::UNO_QUERY_THROW );
xNA.set( xNA->getByName( rNodeName ), uno::UNO_QUERY_THROW );
rElementNames = xNA->getElementNames();
bSuccess = true;
}
catch (uno::Exception &)
{
}
return bSuccess;
}
static uno::Reference< container::XNameAccess > GetOrCreateSetEntry_Impl(
const uno::Reference< container::XNameAccess > &rxSetNameAccess,
const rtl::OUString &rEntryName )
{
uno::Reference< container::XNameAccess > xResult;
try
{
if (!rxSetNameAccess->hasByName( rEntryName ))
{
uno::Reference< lang::XSingleServiceFactory > xFactory( rxSetNameAccess, uno::UNO_QUERY_THROW);
uno::Reference< uno::XInterface > xNewEntry( xFactory->createInstance() );
uno::Reference< container::XNameContainer > xNC( rxSetNameAccess, uno::UNO_QUERY_THROW );
xNC->insertByName( rEntryName, makeAny( xNewEntry ) );
}
xResult.set( rxSetNameAccess->getByName( rEntryName ), uno::UNO_QUERY_THROW );
}
catch (uno::Exception &)
{
}
return xResult;
}
sal_Bool SvtLinguConfig::GetSupportedDictionaryFormatsFor(
const rtl::OUString &rSetName,
const rtl::OUString &rSetEntry,
uno::Sequence< rtl::OUString > &rFormatList ) const
{
if (rSetName.getLength() == 0 || rSetEntry.getLength() == 0)
return sal_False;
bool bSuccess = false;
try
{
uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW );
xNA.set( xNA->getByName( A2OU("ServiceManager") ), uno::UNO_QUERY_THROW );
xNA.set( xNA->getByName( rSetName ), uno::UNO_QUERY_THROW );
xNA.set( xNA->getByName( rSetEntry ), uno::UNO_QUERY_THROW );
if (xNA->getByName( aG_SupportedDictionaryFormats ) >>= rFormatList)
bSuccess = true;
DBG_ASSERT( rFormatList.getLength(), "supported dictionary format list is empty" );
}
catch (uno::Exception &)
{
}
return bSuccess;
}
void SvtLinguConfig::SetOrCreateSupportedDictionaryFormatsFor(
const rtl::OUString &rSetName,
const rtl::OUString &rSetEntry,
const uno::Sequence< rtl::OUString > &rFormatList ) const
{
if (rSetName.getLength() == 0 || rSetEntry.getLength() == 0)
return;
try
{
DBG_ASSERT( rFormatList.getLength(), "applying empty format list. Really??" );
uno::Reference< util::XChangesBatch > xUpdateAccess( GetMainUpdateAccess() );
uno::Reference< container::XNameAccess > xNA( xUpdateAccess, uno::UNO_QUERY_THROW );
xNA.set( xNA->getByName( A2OU("ServiceManager") ), uno::UNO_QUERY_THROW );
xNA.set( xNA->getByName( rSetName ), uno::UNO_QUERY_THROW );
xNA = GetOrCreateSetEntry_Impl( xNA, rSetEntry );
uno::Reference< container::XNameReplace > xNR( xNA, uno::UNO_QUERY_THROW );
xNR->replaceByName( aG_SupportedDictionaryFormats, uno::makeAny( rFormatList ) );
xUpdateAccess->commitChanges();
}
catch (uno::Exception &)
{
}
}
static uno::WeakReference< util::XMacroExpander > aG_xMacroExpander;
static uno::Reference< util::XMacroExpander > lcl_GetMacroExpander()
{
uno::Reference< util::XMacroExpander > xMacroExpander( aG_xMacroExpander );
if ( !xMacroExpander.is() )
{
if ( !xMacroExpander.is() )
{
uno::Reference< uno::XComponentContext > xContext;
uno::Reference< beans::XPropertySet > xProps( ::comphelper::getProcessServiceFactory(), uno::UNO_QUERY );
xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>= xContext;
if ( xContext.is() )
{
aG_xMacroExpander = uno::Reference< com::sun::star::util::XMacroExpander >( xContext->getValueByName(
OUString( RTL_CONSTASCII_USTRINGPARAM( "/singletons/com.sun.star.util.theMacroExpander"))),
uno::UNO_QUERY );
xMacroExpander = aG_xMacroExpander;
}
}
}
return xMacroExpander;
}
static bool lcl_GetFileUrlFromOrigin(
OUString /*out*/ &rFileUrl,
const OUString &rOrigin,
uno::Reference< util::XMacroExpander > &rxMacroExpander )
{
bool bSuccess = false;
if (rOrigin.getLength() > 0 && rxMacroExpander.is())
{
rtl::OUString aURL( rOrigin );
if (( aURL.compareToAscii( RTL_CONSTASCII_STRINGPARAM( EXPAND_PROTOCOL )) == 0 ) &&
rxMacroExpander.is() )
{
// cut protocol
OUString aMacro( aURL.copy( sizeof ( EXPAND_PROTOCOL ) -1 ) );
// decode uric class chars
aMacro = Uri::decode( aMacro, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
// expand macro string
aURL = rxMacroExpander->expandMacros( aMacro );
bool bIsFileUrl = aURL.compareToAscii( RTL_CONSTASCII_STRINGPARAM( FILE_PROTOCOL )) == 0;
if (bIsFileUrl)
{
rFileUrl = aURL;
bSuccess = true;
}
else
{
DBG_ASSERT( bIsFileUrl, "not a file URL");
}
}
else
{
DBG_ASSERT( 0, "failed to get file URL" );
}
}
return bSuccess;
}
sal_Bool SvtLinguConfig::GetDictionaryEntry(
const rtl::OUString &rNodeName,
SvtLinguConfigDictionaryEntry &rDicEntry ) const
{
if (rNodeName.getLength() == 0)
return sal_False;
bool bSuccess = false;
try
{
uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW );
xNA.set( xNA->getByName( A2OU("ServiceManager") ), uno::UNO_QUERY_THROW );
xNA.set( xNA->getByName( aG_Dictionaries ), uno::UNO_QUERY_THROW );
xNA.set( xNA->getByName( rNodeName ), uno::UNO_QUERY_THROW );
// read group data...
uno::Sequence< rtl::OUString > aLocations;
rtl::OUString aFormatName;
uno::Sequence< rtl::OUString > aLocaleNames;
bSuccess = (xNA->getByName( aG_Locations ) >>= aLocations) &&
(xNA->getByName( aG_Format ) >>= aFormatName) &&
(xNA->getByName( aG_Locales ) >>= aLocaleNames);
DBG_ASSERT( aLocations.getLength(), "Dictionary locations not set" );
DBG_ASSERT( aFormatName.getLength(), "Dictionary format name not set" );
DBG_ASSERT( aLocaleNames.getLength(), "No locales set for the dictionary" );
// if sucessful continue
if (bSuccess)
{
// get file URL's for the locations
uno::Reference< util::XMacroExpander > xMacroExpander( lcl_GetMacroExpander() );
for (sal_Int32 i = 0; i < aLocations.getLength(); ++i)
{
rtl::OUString &rLocation = aLocations[i];
if (!lcl_GetFileUrlFromOrigin( rLocation, rLocation, xMacroExpander ))
bSuccess = false;
}
// if everything was fine return the result
if (bSuccess)
{
rDicEntry.aLocations = aLocations;
rDicEntry.aFormatName = aFormatName;
rDicEntry.aLocaleNames = aLocaleNames;
}
}
}
catch (uno::Exception &)
{
}
return bSuccess;
}
void SvtLinguConfig::SetOrCreateDictionaryEntry(
const rtl::OUString &rNodeName,
const SvtLinguConfigDictionaryEntry &rDicEntry ) const
{
if (rNodeName.getLength() == 0)
return;
try
{
uno::Reference< util::XChangesBatch > xUpdateAccess( GetMainUpdateAccess() );
uno::Reference< container::XNameAccess > xNA( xUpdateAccess, uno::UNO_QUERY_THROW );
xNA.set( xNA->getByName( A2OU("ServiceManager") ), uno::UNO_QUERY_THROW );
xNA.set( xNA->getByName( aG_Dictionaries ), uno::UNO_QUERY_THROW );
xNA = GetOrCreateSetEntry_Impl( xNA, rNodeName );
DBG_ASSERT( rDicEntry.aLocations.getLength(), "Applying empty dictionary locations. Really correct??" );
DBG_ASSERT( rDicEntry.aFormatName.getLength(), "Applying empty dictionary format name. Really correct??" );
DBG_ASSERT( rDicEntry.aLocaleNames.getLength(), "Applying empty list of locales for the dictionary. Really correct??" );
uno::Reference< container::XNameReplace > xNR( xNA, uno::UNO_QUERY_THROW );
xNR->replaceByName( aG_Locations, uno::makeAny( rDicEntry.aLocations ) );
xNR->replaceByName( aG_Format, uno::makeAny( rDicEntry.aFormatName ) );
xNR->replaceByName( aG_Locales, uno::makeAny( rDicEntry.aLocaleNames ) );
xUpdateAccess->commitChanges();
}
catch (uno::Exception &)
{
}
}
uno::Sequence< rtl::OUString > SvtLinguConfig::GetDisabledDictionaries() const
{
uno::Sequence< rtl::OUString > aResult;
try
{
uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW );
xNA.set( xNA->getByName( A2OU("ServiceManager") ), uno::UNO_QUERY_THROW );
xNA->getByName( aG_DisabledDictionaries ) >>= aResult;
}
catch (uno::Exception &)
{
}
return aResult;
}
void SvtLinguConfig::SetDisabledDictionaries(
const uno::Sequence< rtl::OUString > &rDictionaries ) const
{
try
{
uno::Reference< util::XChangesBatch > xUpdateAccess( GetMainUpdateAccess() );
uno::Reference< container::XNameAccess > xNA( xUpdateAccess, uno::UNO_QUERY_THROW );
xNA.set( xNA->getByName( A2OU("ServiceManager") ), uno::UNO_QUERY_THROW );
if (xNA->hasByName( aG_DisabledDictionaries ))
{
uno::Reference< container::XNameReplace > xNR( xNA, uno::UNO_QUERY_THROW );
xNR->replaceByName( aG_DisabledDictionaries, makeAny( rDictionaries ) );
}
else
{
uno::Reference< container::XNameContainer > xNC( xNA, uno::UNO_QUERY_THROW );
xNC->insertByName( aG_DisabledDictionaries, makeAny( rDictionaries ) );
}
xUpdateAccess->commitChanges();
}
catch (uno::Exception &)
{
}
}
std::vector< SvtLinguConfigDictionaryEntry > SvtLinguConfig::GetActiveDictionariesByFormat(
const rtl::OUString &rFormatName )
{
std::vector< SvtLinguConfigDictionaryEntry > aRes;
if (rFormatName.getLength() == 0)
return aRes;
try
{
uno::Sequence< rtl::OUString > aElementNames;
GetElementNamesFor( aG_Dictionaries, aElementNames );
sal_Int32 nLen = aElementNames.getLength();
const rtl::OUString *pElementNames = aElementNames.getConstArray();
SvtLinguConfigDictionaryEntry aDicEntry;
for (sal_Int32 i = 0; i < nLen; ++i)
{
// does dictionary match the format we are looking for?
if (GetDictionaryEntry( pElementNames[i], aDicEntry ) &&
aDicEntry.aFormatName == rFormatName)
{
// check if it is active or not
bool bDicIsActive = true;
const uno::Sequence< rtl::OUString > aDisabledDics( GetDisabledDictionaries() );
for (sal_Int32 k = 0; bDicIsActive && k < aDisabledDics.getLength(); ++k)
{
if (aDisabledDics[k] == pElementNames[i])
bDicIsActive = false;
}
if (bDicIsActive)
{
DBG_ASSERT( aDicEntry.aFormatName.getLength(),
"FormatName not set" );
DBG_ASSERT( aDicEntry.aLocations.getLength(),
"Locations not set" );
DBG_ASSERT( aDicEntry.aLocaleNames.getLength(),
"Locales not set" );
aRes.push_back( aDicEntry );
}
}
}
}
catch (uno::Exception &)
{
}
return aRes;
}
uno::Reference< util::XChangesBatch > SvtLinguConfig::GetMainUpdateAccess() const
{
if (!m_xMainUpdateAccess.is())
{
try
{
// get configuration provider
uno::Reference< lang::XMultiServiceFactory > xConfigurationProvider;
uno::Reference< lang::XMultiServiceFactory > xMgr = comphelper::getProcessServiceFactory();
if (xMgr.is())
{
xConfigurationProvider = uno::Reference< lang::XMultiServiceFactory > (
xMgr->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM(
"com.sun.star.configuration.ConfigurationProvider" ) ) ),
uno::UNO_QUERY_THROW ) ;
}
// get configuration update access
beans::PropertyValue aValue;
aValue.Name = A2OU( "nodepath" );
aValue.Value = uno::makeAny( A2OU("org.openoffice.Office.Linguistic") );
uno::Sequence< uno::Any > aProps(1);
aProps[0] <<= aValue;
m_xMainUpdateAccess = uno::Reference< util::XChangesBatch >(
xConfigurationProvider->createInstanceWithArguments(
A2OU( "com.sun.star.configuration.ConfigurationUpdateAccess" ), aProps ),
uno::UNO_QUERY_THROW );
}
catch (uno::Exception &)
{
}
}
return m_xMainUpdateAccess;
}
rtl::OUString SvtLinguConfig::GetVendorImageUrl_Impl(
const rtl::OUString &rServiceImplName,
const rtl::OUString &rImageName ) const
{
rtl::OUString aRes;
try
{
uno::Reference< container::XNameAccess > xImagesNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW );
xImagesNA.set( xImagesNA->getByName( A2OU("Images") ), uno::UNO_QUERY_THROW );
uno::Reference< container::XNameAccess > xNA( xImagesNA->getByName( A2OU("ServiceNameEntries") ), uno::UNO_QUERY_THROW );
xNA.set( xNA->getByName( rServiceImplName ), uno::UNO_QUERY_THROW );
uno::Any aAny( xNA->getByName( A2OU("VendorImagesNode") ) );
rtl::OUString aVendorImagesNode;
if (aAny >>= aVendorImagesNode)
{
xNA = xImagesNA;
xNA.set( xNA->getByName( A2OU("VendorImages") ), uno::UNO_QUERY_THROW );
xNA.set( xNA->getByName( aVendorImagesNode ), uno::UNO_QUERY_THROW );
aAny = xNA->getByName( rImageName );
rtl::OUString aTmp;
if (aAny >>= aTmp)
{
uno::Reference< util::XMacroExpander > xMacroExpander( lcl_GetMacroExpander() );
if (lcl_GetFileUrlFromOrigin( aTmp, aTmp, xMacroExpander ))
aRes = aTmp;
}
}
}
catch (uno::Exception &)
{
DBG_ASSERT( 0, "exception caught. GetVendorImageUrl_Impl failed" );
}
return aRes;
}
rtl::OUString SvtLinguConfig::GetSpellAndGrammarDialogImage(
const rtl::OUString &rServiceImplName,
bool bHighContrast ) const
{
rtl::OUString aRes;
if (rServiceImplName.getLength() > 0)
{
rtl::OUString aImageName( A2OU( bHighContrast ? "SpellAndGrammarDialogImage_HC" : "SpellAndGrammarDialogImage" ));
rtl::OUString aPath( GetVendorImageUrl_Impl( rServiceImplName, aImageName ) );
aRes = aPath;
}
return aRes;
}
rtl::OUString SvtLinguConfig::GetSpellAndGrammarContextSuggestionImage(
const rtl::OUString &rServiceImplName,
bool bHighContrast ) const
{
rtl::OUString aRes;
if (rServiceImplName.getLength() > 0)
{
rtl::OUString aImageName( A2OU( bHighContrast ? "SpellAndGrammarContextMenuSuggestionImage_HC" : "SpellAndGrammarContextMenuSuggestionImage" ));
rtl::OUString aPath( GetVendorImageUrl_Impl( rServiceImplName, aImageName ) );
aRes = aPath;
}
return aRes;
}
rtl::OUString SvtLinguConfig::GetSpellAndGrammarContextDictionaryImage(
const rtl::OUString &rServiceImplName,
bool bHighContrast ) const
{
rtl::OUString aRes;
if (rServiceImplName.getLength() > 0)
{
rtl::OUString aImageName( A2OU( bHighContrast ? "SpellAndGrammarContextMenuDictionaryImage_HC" : "SpellAndGrammarContextMenuDictionaryImage" ));
rtl::OUString aPath( GetVendorImageUrl_Impl( rServiceImplName, aImageName ) );
aRes = aPath;
}
return aRes;
}
::rtl::OUString SvtLinguConfig::GetThesaurusDialogImage(
const ::rtl::OUString &rServiceImplName,
bool bHighContrast ) const
{
rtl::OUString aRes;
if (rServiceImplName.getLength() > 0)
{
rtl::OUString aImageName( A2OU( bHighContrast ? "ThesaurusDialogImage_HC" : "ThesaurusDialogImage" ));
rtl::OUString aPath( GetVendorImageUrl_Impl( rServiceImplName, aImageName ) );
aRes = aPath;
}
return aRes;
}
::rtl::OUString SvtLinguConfig::GetSynonymsContextImage(
const ::rtl::OUString &rServiceImplName,
bool bHighContrast ) const
{
rtl::OUString aRes;
if (rServiceImplName.getLength() > 0)
{
rtl::OUString aImageName( A2OU( bHighContrast ? "SynonymsContextMenuImage_HC" : "SynonymsContextMenuImage" ));
rtl::OUString aPath( GetVendorImageUrl_Impl( rServiceImplName, aImageName ) );
aRes = aPath;
}
return aRes;
}
bool SvtLinguConfig::HasVendorImages( const char *pImageName ) const
{
bool bRes = false;
if (pImageName)
{
try
{
uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW );
xNA.set( xNA->getByName( A2OU("Images") ), uno::UNO_QUERY_THROW );
xNA.set( xNA->getByName( A2OU("VendorImages") ), uno::UNO_QUERY_THROW );
uno::Sequence< rtl::OUString > aElementNames( xNA->getElementNames() );
sal_Int32 nVendors = aElementNames.getLength();
const rtl::OUString *pVendor = aElementNames.getConstArray();
for (sal_Int32 i = 0; i < nVendors; ++i)
{
uno::Reference< container::XNameAccess > xNA2( xNA->getByName( pVendor[i] ), uno::UNO_QUERY_THROW );
uno::Sequence< rtl::OUString > aPropNames( xNA2->getElementNames() );
sal_Int32 nProps = aPropNames.getLength();
const rtl::OUString *pPropNames = aPropNames.getConstArray();
for (sal_Int32 k = 0; k < nProps; ++k)
{
// for a quicker check we ignore the HC image names here
const OUString &rName = pPropNames[k];
if (rName.equalsAscii( pImageName ))
{
bRes = true;
break;
}
}
}
}
catch (uno::Exception &)
{
DBG_ASSERT( 0, "exception caught. HasVendorImages failed" );
}
}
return bRes;
}
bool SvtLinguConfig::HasGrammarChecker() const
{
bool bRes = false;
try
{
uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW );
xNA.set( xNA->getByName( A2OU("ServiceManager") ), uno::UNO_QUERY_THROW );
xNA.set( xNA->getByName( A2OU("GrammarCheckerList") ), uno::UNO_QUERY_THROW );
uno::Sequence< rtl::OUString > aElementNames( xNA->getElementNames() );
bRes = aElementNames.getLength() > 0;
}
catch (uno::Exception &)
{
}
return bRes;
}
//////////////////////////////////////////////////////////////////////