[Libreoffice-commits] .: 5 commits - cui/source editeng/inc editeng/source linguistic/Library_lng.mk linguistic/prj linguistic/source

Caolán McNamara caolan at kemper.freedesktop.org
Wed Jul 11 02:02:27 PDT 2012


 cui/source/options/optlingu.cxx  |    6 
 editeng/inc/editeng/unolingu.hxx |   23 --
 editeng/source/misc/unolingu.cxx |  372 ---------------------------------------
 linguistic/Library_lng.mk        |    1 
 linguistic/prj/build.lst         |    2 
 linguistic/source/lngsvcmgr.cxx  |  347 +++++++++++++++++++++++++++++++++++-
 linguistic/source/lngsvcmgr.hxx  |   26 ++
 7 files changed, 360 insertions(+), 417 deletions(-)

New commits:
commit 464f69b8bb5f64f9f4660ba2e2095cdc1c65952b
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Wed Jul 11 09:50:49 2012 +0100

    Resolves: rhbz#836937 insanely slow with Zemberek installed
    
    Zemberek is a java spellchecker extension. With it installed the collecting of
    spellchecker information on first activation of spellchecking is insanely slow
    as the cache of spellcheckers is thrown away on each iteration through each
    language known to LibreOffice.
    
    So...
    
    move the config updating stuff from editeng down to the linguistic layer. Let
    the linguistic layer keep its spellchecker cache and listen to the extension
    manager to know if an extension which might be a spellchecker one has been
    modified and only throw away the cache on that event or if (existing
    implementation) the config data for linguistics changes.
    
    The polling of changed linguistic data in SvxLinguConfigUpdate::IsNeedUpdateAll
    can be removed and leave it up to LngSvcMgr to load everything in its ctor and
    keep itself up to date with its config and extension listeners.
    
    Change-Id: I9c93d998928e2e7f5128c36771b3e450a8057cd6

diff --git a/cui/source/options/optlingu.cxx b/cui/source/options/optlingu.cxx
index a321349..8ee3d37 100644
--- a/cui/source/options/optlingu.cxx
+++ b/cui/source/options/optlingu.cxx
@@ -1141,12 +1141,6 @@ SvxLinguTabPage::SvxLinguTabPage( Window* pParent,
     aLinguDicsEditPB.SetAccessibleName(sAccessibleNameDicsEdit);
     aLinguOptionsEditPB.SetAccessibleName(sAccessibleNameOptionEdit);
 
-    // force recalculation of hash value used for checking the need of updating
-    // because new dictionaries might be installed / downloaded.
-    //! Thus it needs to be called now since it may infuence the supported languages
-    //! to be reported AND the found user-dictionaries(!) as well.
-    SvxLinguConfigUpdate::UpdateAll( sal_True );
-
     xProp = uno::Reference< XPropertySet >( SvxGetLinguPropertySet(), UNO_QUERY );
     xDicList = uno::Reference< XDictionaryList >( SvxGetDictionaryList(), UNO_QUERY );
     if (xDicList.is())
diff --git a/editeng/inc/editeng/unolingu.hxx b/editeng/inc/editeng/unolingu.hxx
index d25be04..d35737a 100644
--- a/editeng/inc/editeng/unolingu.hxx
+++ b/editeng/inc/editeng/unolingu.hxx
@@ -46,26 +46,6 @@ class LinguMgrExitLstnr;
 class Window;
 
 ///////////////////////////////////////////////////////////////////////////
-// SvxLinguConfigUpdate
-// class to update configuration items when (before!) the linguistic is used.
-//
-// This class is called by all the dummy implementations to update all of the
-// configuration (list of used/available services) when the linguistic is
-// accessed for the first time.
-
-class SvxLinguConfigUpdate
-{
-    static sal_Int16    nNeedUpdating;  // n == -1 => needs to be checked
-                                    // n ==  0 => already updated, nothing to be done
-                                    // n ==  1 => needs to be updated
-
-public:
-
-    EDITENG_DLLPUBLIC static void UpdateAll( sal_Bool bForceCheck = sal_False );
-    static sal_Bool IsNeedUpdateAll( sal_Bool bForceCheck = sal_False );
-};
-
-///////////////////////////////////////////////////////////////////////////
 
 class EDITENG_DLLPUBLIC LinguMgr
 {
diff --git a/editeng/source/misc/unolingu.cxx b/editeng/source/misc/unolingu.cxx
index bad9e03..16f2eba 100644
--- a/editeng/source/misc/unolingu.cxx
+++ b/editeng/source/misc/unolingu.cxx
@@ -86,309 +86,6 @@ static uno::Reference< XLinguServiceManager > GetLngSvcMgr_Impl()
     return xRes;
 }
 
-sal_Bool lcl_FindEntry( const OUString &rEntry, const Sequence< OUString > &rCfgSvcs )
-{
-    sal_Int32 nRes = -1;
-    sal_Int32 nEntries = rCfgSvcs.getLength();
-    const OUString *pEntry = rCfgSvcs.getConstArray();
-    for (sal_Int32 i = 0;  i < nEntries && nRes == -1;  ++i)
-    {
-        if (rEntry == pEntry[i])
-            nRes = i;
-    }
-    return nRes != -1;
-}
-
-
-Sequence< OUString > lcl_RemoveMissingEntries(
-        const Sequence< OUString > &rCfgSvcs,
-        const Sequence< OUString > &rAvailSvcs )
-{
-    Sequence< OUString > aRes( rCfgSvcs.getLength() );
-    OUString *pRes = aRes.getArray();
-    sal_Int32 nCnt = 0;
-
-    sal_Int32 nEntries = rCfgSvcs.getLength();
-    const OUString *pEntry = rCfgSvcs.getConstArray();
-    for (sal_Int32 i = 0;  i < nEntries;  ++i)
-    {
-        if (!pEntry[i].isEmpty() && lcl_FindEntry( pEntry[i], rAvailSvcs ))
-            pRes[ nCnt++ ] = pEntry[i];
-    }
-
-    aRes.realloc( nCnt );
-    return aRes;
-}
-
-
-Sequence< OUString > lcl_GetLastFoundSvcs(
-        SvtLinguConfig &rCfg,
-        const OUString &rLastFoundList ,
-        const Locale &rAvailLocale )
-{
-    Sequence< OUString > aRes;
-
-    OUString aCfgLocaleStr( MsLangId::convertLanguageToIsoString(
-                                SvxLocaleToLanguage( rAvailLocale ) ) );
-
-    Sequence< OUString > aNodeNames( rCfg.GetNodeNames(rLastFoundList) );
-    sal_Bool bFound = lcl_FindEntry( aCfgLocaleStr, aNodeNames);
-
-    if (bFound)
-    {
-        Sequence< OUString > aNames(1);
-        OUString &rNodeName = aNames.getArray()[0];
-        rNodeName = rLastFoundList;
-        rNodeName += OUString::valueOf( (sal_Unicode)'/' );
-        rNodeName += aCfgLocaleStr;
-        Sequence< Any > aValues( rCfg.GetProperties( aNames ) );
-        if (aValues.getLength())
-        {
-            OSL_ENSURE( aValues.getLength() == 1, "unexpected length of sequence" );
-            Sequence< OUString > aSvcImplNames;
-            if (aValues.getConstArray()[0] >>= aSvcImplNames)
-                aRes = aSvcImplNames;
-            else
-            {
-                OSL_FAIL( "type mismatch" );
-            }
-        }
-    }
-
-    return aRes;
-}
-
-
-Sequence< OUString > lcl_GetNewEntries(
-        const Sequence< OUString > &rLastFoundSvcs,
-        const Sequence< OUString > &rAvailSvcs )
-{
-    sal_Int32 nLen = rAvailSvcs.getLength();
-    Sequence< OUString > aRes( nLen );
-    OUString *pRes = aRes.getArray();
-    sal_Int32 nCnt = 0;
-
-    const OUString *pEntry = rAvailSvcs.getConstArray();
-    for (sal_Int32 i = 0;  i < nLen;  ++i)
-    {
-        if (!pEntry[i].isEmpty() && !lcl_FindEntry( pEntry[i], rLastFoundSvcs ))
-            pRes[ nCnt++ ] = pEntry[i];
-    }
-
-    aRes.realloc( nCnt );
-    return aRes;
-}
-
-
-Sequence< OUString > lcl_MergeSeq(
-        const Sequence< OUString > &rCfgSvcs,
-        const Sequence< OUString > &rNewSvcs )
-{
-    Sequence< OUString > aRes( rCfgSvcs.getLength() + rNewSvcs.getLength() );
-    OUString *pRes = aRes.getArray();
-    sal_Int32 nCnt = 0;
-
-    for (sal_Int32 k = 0;  k < 2;  ++k)
-    {
-        // add previously configuerd service first and append
-        // new found services at the end
-        const Sequence< OUString > &rSeq = k == 0 ? rCfgSvcs : rNewSvcs;
-
-        sal_Int32 nLen = rSeq.getLength();
-        const OUString *pEntry = rSeq.getConstArray();
-        for (sal_Int32 i = 0;  i < nLen;  ++i)
-        {
-            if (!pEntry[i].isEmpty() && !lcl_FindEntry( pEntry[i], aRes ))
-                pRes[ nCnt++ ] = pEntry[i];
-        }
-    }
-
-    aRes.realloc( nCnt );
-    return aRes;
-}
-
-sal_Int16 SvxLinguConfigUpdate::nNeedUpdating = -1;
-
-void SvxLinguConfigUpdate::UpdateAll( sal_Bool bForceCheck )
-{
-    RTL_LOGFILE_CONTEXT( aLog, "svx: SvxLinguConfigUpdate::UpdateAll" );
-
-    if (IsNeedUpdateAll( bForceCheck ))
-    {
-        typedef OUString OUstring_t;
-        typedef Sequence< OUString > Sequence_OUString_t;
-        typedef std::map< OUstring_t, Sequence_OUString_t > list_entry_map_t;
-
-        RTL_LOGFILE_CONTEXT( aLog, "svx: SvxLinguConfigUpdate::UpdateAll - updating..." );
-
-        OSL_ENSURE( nNeedUpdating == 1, "SvxLinguConfigUpdate::UpdateAll already updated!" );
-
-        uno::Reference< XLinguServiceManager > xLngSvcMgr( GetLngSvcMgr_Impl() );
-        OSL_ENSURE( xLngSvcMgr.is(), "service manager missing");
-        if (!xLngSvcMgr.is())
-            return;
-
-        SvtLinguConfig aCfg;
-
-        const int nNumServices = 4;
-        const sal_Char * apServices[nNumServices]       =  { SN_SPELLCHECKER, SN_GRAMMARCHECKER, SN_HYPHENATOR, SN_THESAURUS };
-        const sal_Char * apCurLists[nNumServices]       =  { "ServiceManager/SpellCheckerList",       "ServiceManager/GrammarCheckerList",       "ServiceManager/HyphenatorList",       "ServiceManager/ThesaurusList" };
-        const sal_Char * apLastFoundLists[nNumServices] =  { "ServiceManager/LastFoundSpellCheckers", "ServiceManager/LastFoundGrammarCheckers", "ServiceManager/LastFoundHyphenators", "ServiceManager/LastFoundThesauri" };
-
-        // usage of indices as above: 0 = spell checker, 1 = grammar checker, 2 = hyphenator, 3 = thesaurus
-        std::vector< list_entry_map_t > aLastFoundSvcs(nNumServices);
-        std::vector< list_entry_map_t > aCurSvcs(nNumServices);
-
-        for (int k = 0;  k < nNumServices;  ++k)
-        {
-            OUString aService( ::rtl::OUString::createFromAscii( apServices[k] ) );
-            OUString aActiveList( ::rtl::OUString::createFromAscii( apCurLists[k] ) );
-            OUString aLastFoundList( ::rtl::OUString::createFromAscii( apLastFoundLists[k] ) );
-            sal_Int32 i;
-
-            //
-            // remove configured but not available language/services entries
-            //
-            Sequence< OUString > aNodeNames( aCfg.GetNodeNames( aActiveList ) );   // list of configured locales
-            sal_Int32 nNodeNames = aNodeNames.getLength();
-            const OUString *pNodeName = aNodeNames.getConstArray();
-            for (i = 0;  i < nNodeNames;  ++i)
-            {
-                Locale aLocale( SvxCreateLocale( MsLangId::convertIsoStringToLanguage(pNodeName[i]) ) );
-                Sequence< OUString > aCfgSvcs(
-                        xLngSvcMgr->getConfiguredServices( aService, aLocale ));
-                Sequence< OUString > aAvailSvcs(
-                        xLngSvcMgr->getAvailableServices( aService, aLocale ));
-
-                aCfgSvcs = lcl_RemoveMissingEntries( aCfgSvcs, aAvailSvcs );
-
-                aCurSvcs[k][ pNodeName[i] ] = aCfgSvcs;
-            }
-
-            //
-            // add new available language/service entries
-            // and
-            // set last found services to currently available ones
-            //
-            uno::Reference< XAvailableLocales > xAvail( xLngSvcMgr, UNO_QUERY );
-            Sequence< Locale > aAvailLocales( xAvail->getAvailableLocales(aService) );
-            sal_Int32 nAvailLocales = aAvailLocales.getLength();
-            const Locale *pAvailLocale = aAvailLocales.getConstArray();
-            for (i = 0;  i < nAvailLocales;  ++i)
-            {
-                OUString aCfgLocaleStr( MsLangId::convertLanguageToIsoString(
-                                            SvxLocaleToLanguage( pAvailLocale[i] ) ) );
-
-                Sequence< OUString > aAvailSvcs(
-                        xLngSvcMgr->getAvailableServices( aService, pAvailLocale[i] ));
-
-                aLastFoundSvcs[k][ aCfgLocaleStr ] = aAvailSvcs;
-
-                Sequence< OUString > aLastSvcs(
-                        lcl_GetLastFoundSvcs( aCfg, aLastFoundList , pAvailLocale[i] ));
-                Sequence< OUString > aNewSvcs =
-                        lcl_GetNewEntries( aLastSvcs, aAvailSvcs );
-
-                Sequence< OUString > aCfgSvcs( aCurSvcs[k][ aCfgLocaleStr ] );
-
-                // merge services list (previously configured to be listed first).
-                aCfgSvcs = lcl_MergeSeq( aCfgSvcs, aNewSvcs );
-
-                aCurSvcs[k][ aCfgLocaleStr ] = aCfgSvcs;
-            }
-        }
-
-        //
-        // write new data back to configuration
-        //
-        for (int k = 0;  k < nNumServices;  ++k)
-        {
-            for (int i = 0;  i < 2;  ++i)
-            {
-                const sal_Char *pSubNodeName = (i == 0) ? apCurLists[k] : apLastFoundLists[k];
-                OUString aSubNodeName( ::rtl::OUString::createFromAscii(pSubNodeName) );
-
-                list_entry_map_t &rCurMap = (i == 0) ? aCurSvcs[k] : aLastFoundSvcs[k];
-                list_entry_map_t::const_iterator aIt( rCurMap.begin() );
-                sal_Int32 nVals = static_cast< sal_Int32 >( rCurMap.size() );
-                Sequence< PropertyValue > aNewValues( nVals );
-                PropertyValue *pNewValue = aNewValues.getArray();
-                while (aIt != rCurMap.end())
-                {
-                    OUString aCfgEntryName( aSubNodeName );
-                    aCfgEntryName += OUString::valueOf( (sal_Unicode) '/' );
-                    aCfgEntryName += (*aIt).first;
-
-                    pNewValue->Name  = aCfgEntryName;
-                    pNewValue->Value <<= (*aIt).second;
-                    ++pNewValue;
-                    ++aIt;
-                }
-                OSL_ENSURE( pNewValue - aNewValues.getArray() == nVals,
-                        "possible mismatch of sequence size and property number" );
-
-                {
-                    RTL_LOGFILE_CONTEXT( aLog, "svx: SvxLinguConfigUpdate::UpdateAll - ReplaceSetProperties" );
-                    // add new or replace existing entries.
-                    sal_Bool bRes = aCfg.ReplaceSetProperties( aSubNodeName, aNewValues );
-                    if (!bRes)
-                    {
-#if OSL_DEBUG_LEVEL > 1
-                        OSL_FAIL( "failed to set new configuration values" );
-#endif
-                    }
-                }
-            }
-        }
-        Any aAny;
-
-        // for the time being (developer builds until OOo 3.0)
-        // we should always check for everything available
-        // otherwise we may miss a new installed extension dicitonary
-        // just because e.g. the spellchecker is not asked what
-        // languages it does support currently...
-        // Since the check is on-demand occuring and executed once it should
-        // not be too troublesome.
-        // In OOo 3.0 we will not need the respective code anymore at all.
-        aAny <<= (sal_Int32) -1;    // keep the value set to 'need to check'
-
-        aCfg.SetProperty( A2OU( "DataFilesChangedCheckValue" ), aAny );
-
-        //! Note 1: the new values are commited when the 'aCfg' object
-        //!     gets destroyed.
-        //! Note 2: the new settings in the configuration get applied
-        //!     because the 'LngSvcMgr' (in linguistic/source/lngsvcmgr.hxx)
-        //!     listens to the configuration for changes of the relevant
-        //!     properties and then applies the new settings.
-
-        // nothing needs to be done anymore
-        nNeedUpdating = 0;
-    }
-}
-
-
-sal_Bool SvxLinguConfigUpdate::IsNeedUpdateAll( sal_Bool bForceCheck )
-{
-    RTL_LOGFILE_CONTEXT( aLog, "svx: SvxLinguConfigUpdate::IsNeedUpdateAll" );
-    if (nNeedUpdating == -1 || bForceCheck )    // need to check if updating is necessary
-    {
-        // calculate hash value for current data files
-        sal_Int32 nCurrentDataFilesChangedCheckValue = 0;
-
-        // compare hash value and check value to see if anything has changed
-        // and thus the configuration needs to be updated
-        SvtLinguOptions aLinguOpt;
-        SvtLinguConfig aCfg;
-        aCfg.GetOptions( aLinguOpt );
-        nNeedUpdating = (nCurrentDataFilesChangedCheckValue == aLinguOpt.nDataFilesChangedCheckValue) ? 0 : 1;
-    }
-    OSL_ENSURE( nNeedUpdating != -1,
-            "need for linguistic configuration update should have been already checked." );
-
-    return nNeedUpdating == 1;
-}
-
-
 //! Dummy implementation in order to avoid loading of lingu DLL
 //! when only the XSupportedLocales interface is used.
 //! The dummy accesses the real implementation (and thus loading the DLL)
@@ -456,10 +153,6 @@ void ThesDummy_Impl::GetCfgLocales()
 
 void ThesDummy_Impl::GetThes_Impl()
 {
-    // update configuration before accessing the service
-    if (SvxLinguConfigUpdate::IsNeedUpdateAll())
-        SvxLinguConfigUpdate::UpdateAll();
-
     if (!xThes.is())
     {
         uno::Reference< XLinguServiceManager > xLngSvcMgr( GetLngSvcMgr_Impl() );
@@ -479,8 +172,7 @@ uno::Sequence< lang::Locale > SAL_CALL
         ThesDummy_Impl::getLocales()
             throw(uno::RuntimeException)
 {
-    if (!SvxLinguConfigUpdate::IsNeedUpdateAll())   // configuration already update and thus lingu DLL's already loaded ?
-        GetThes_Impl();
+    GetThes_Impl();
     if (xThes.is())
         return xThes->getLocales();
     else if (!pLocaleSeq)       // if not already loaded save startup time by avoiding loading them now
@@ -493,8 +185,7 @@ sal_Bool SAL_CALL
         ThesDummy_Impl::hasLocale( const lang::Locale& rLocale )
             throw(uno::RuntimeException)
 {
-    if (!SvxLinguConfigUpdate::IsNeedUpdateAll())   // configuration already update and thus lingu DLL's already loaded ?
-        GetThes_Impl();
+    GetThes_Impl();
     if (xThes.is())
         return xThes->hasLocale( rLocale );
     else if (!pLocaleSeq)       // if not already loaded save startup time by avoiding loading them now
@@ -568,10 +259,6 @@ public:
 
 void SpellDummy_Impl::GetSpell_Impl()
 {
-    // update configuration before accessing the service
-    if (SvxLinguConfigUpdate::IsNeedUpdateAll())
-        SvxLinguConfigUpdate::UpdateAll();
-
     if (!xSpell.is())
     {
         uno::Reference< XLinguServiceManager > xLngSvcMgr( GetLngSvcMgr_Impl() );
@@ -684,10 +371,6 @@ public:
 
 void HyphDummy_Impl::GetHyph_Impl()
 {
-    // update configuration before accessing the service
-    if (SvxLinguConfigUpdate::IsNeedUpdateAll())
-        SvxLinguConfigUpdate::UpdateAll();
-
     if (!xHyph.is())
     {
         uno::Reference< XLinguServiceManager > xLngSvcMgr( GetLngSvcMgr_Impl() );
diff --git a/linguistic/Library_lng.mk b/linguistic/Library_lng.mk
index 4459c45..d451348 100644
--- a/linguistic/Library_lng.mk
+++ b/linguistic/Library_lng.mk
@@ -53,6 +53,7 @@ $(eval $(call gb_Library_use_libraries,lng,\
 	tl \
 	ucbhelper \
 	utl \
+	vcl \
 	xo \
     $(gb_STDLIBS) \
 ))
diff --git a/linguistic/prj/build.lst b/linguistic/prj/build.lst
index 3ef507e..fe7d24d 100644
--- a/linguistic/prj/build.lst
+++ b/linguistic/prj/build.lst
@@ -1,2 +1,2 @@
-lg  linguistic  :   svl xmloff ucbhelper comphelper ICU:icu LIBXSLT:libxslt NULL
+lg  linguistic  :   svl vcl xmloff ucbhelper comphelper ICU:icu LIBXSLT:libxslt NULL
 lg	linguistic\prj							nmake		-	all	lg_prj NULL
diff --git a/linguistic/source/lngsvcmgr.cxx b/linguistic/source/lngsvcmgr.cxx
index adf9da3..6dc2d69 100644
--- a/linguistic/source/lngsvcmgr.cxx
+++ b/linguistic/source/lngsvcmgr.cxx
@@ -27,6 +27,7 @@
  ************************************************************************/
 
 
+#include <com/sun/star/deployment/ExtensionManager.hpp>
 #include <com/sun/star/registry/XRegistryKey.hpp>
 #include <com/sun/star/container/XContentEnumerationAccess.hpp>
 #include <com/sun/star/container/XEnumeration.hpp>
@@ -270,8 +271,6 @@ void SAL_CALL LngSvcMgrListenerHelper::disposing( const lang::EventObject& rSour
     }
 }
 
-
-//IMPL_LINK( LngSvcMgrListenerHelper, TimeOut, Timer*, pTimer )
 long LngSvcMgrListenerHelper::Timeout()
 {
     osl::MutexGuard aGuard( GetLinguMutex() );
@@ -483,11 +482,98 @@ LngSvcMgr::LngSvcMgr()
     pNames[2] = "ServiceManager/HyphenatorList";
     pNames[3] = "ServiceManager/ThesaurusList";
     EnableNotification( aNames );
+
+    UpdateAll();
+
+    aUpdateTimer.SetTimeout(500);
+    aUpdateTimer.SetTimeoutHdl(LINK(this, LngSvcMgr, updateAndBroadcast));
+
+    // request to be notified if an extension has been added/removed
+    uno::Reference<uno::XComponentContext> xContext(comphelper::getProcessComponentContext());
+
+    uno::Reference<deployment::XExtensionManager> xExtensionManager(
+        deployment::ExtensionManager::get(xContext));
+    if (xExtensionManager.is())
+    {
+        xMB = uno::Reference<util::XModifyBroadcaster>(xExtensionManager, uno::UNO_QUERY_THROW);
+
+        uno::Reference<util::XModifyListener> xListener(this);
+        xMB->addModifyListener( xListener );
+    }
+}
+
+// ::com::sun::star::util::XModifyListener
+void LngSvcMgr::modified(const lang::EventObject&)
+    throw(uno::RuntimeException)
+{
+    osl::MutexGuard aGuard(GetLinguMutex());
+    //assume that if an extension has been added/removed that
+    //it might be a dictionary extension, so drop our cache
+
+    delete pAvailSpellSvcs;
+    pAvailSpellSvcs = NULL;
+    delete pAvailGrammarSvcs;
+    pAvailGrammarSvcs = NULL;
+    delete pAvailHyphSvcs;
+    pAvailHyphSvcs = NULL;
+    delete pAvailThesSvcs;
+    pAvailThesSvcs = NULL;
+
+    //schedule in an update to execute in the main thread
+    aUpdateTimer.Start();
 }
 
+//run update, and inform everyone that dictionaries (may) have changed, this
+//needs to be run in the main thread because
+//utl::ConfigChangeListener_Impl::changesOccurred grabs the SolarMutex and we
+//get notified that an extension was added from an extension manager thread
+IMPL_LINK_NOARG(LngSvcMgr, updateAndBroadcast)
+{
+    osl::MutexGuard aGuard( GetLinguMutex() );
+
+    UpdateAll();
+
+    if (pListenerHelper)
+    {
+        pListenerHelper->AddLngSvcEvt(
+                linguistic2::LinguServiceEventFlags::SPELL_CORRECT_WORDS_AGAIN |
+                linguistic2::LinguServiceEventFlags::SPELL_WRONG_WORDS_AGAIN |
+                linguistic2::LinguServiceEventFlags::PROOFREAD_AGAIN |
+                linguistic2::LinguServiceEventFlags::HYPHENATE_AGAIN );
+    }
+
+    return 0;
+}
+
+void LngSvcMgr::stopListening()
+{
+    osl::MutexGuard aGuard(GetLinguMutex());
+
+    if (xMB.is())
+    {
+        try
+        {
+                uno::Reference<util::XModifyListener>  xListener(this);
+                xMB->removeModifyListener(xListener);
+        }
+        catch (const uno::Exception&)
+        {
+        }
+
+        xMB.clear();
+    }
+}
+
+void LngSvcMgr::disposing(const lang::EventObject&)
+    throw (uno::RuntimeException)
+{
+    stopListening();
+}
 
 LngSvcMgr::~LngSvcMgr()
 {
+    stopListening();
+
     // memory for pSpellDsp, pHyphDsp, pThesDsp, pListenerHelper
     // will be freed in the destructor of the respective Reference's
     // xSpellDsp, xGrammarDsp, xHyphDsp, xThesDsp
@@ -498,6 +584,252 @@ LngSvcMgr::~LngSvcMgr()
     delete pAvailThesSvcs;
 }
 
+namespace
+{
+    using lang::Locale;
+    using uno::Any;
+    using uno::Sequence;
+
+    sal_Bool lcl_FindEntry( const OUString &rEntry, const Sequence< OUString > &rCfgSvcs )
+    {
+        sal_Int32 nRes = -1;
+        sal_Int32 nEntries = rCfgSvcs.getLength();
+        const OUString *pEntry = rCfgSvcs.getConstArray();
+        for (sal_Int32 i = 0;  i < nEntries && nRes == -1;  ++i)
+        {
+            if (rEntry == pEntry[i])
+                nRes = i;
+        }
+        return nRes != -1;
+    }
+
+    Sequence< OUString > lcl_GetLastFoundSvcs(
+            SvtLinguConfig &rCfg,
+            const OUString &rLastFoundList ,
+            const Locale &rAvailLocale )
+    {
+        Sequence< OUString > aRes;
+
+        OUString aCfgLocaleStr( MsLangId::convertLanguageToIsoString(
+                                    LocaleToLanguage( rAvailLocale ) ) );
+
+        Sequence< OUString > aNodeNames( rCfg.GetNodeNames(rLastFoundList) );
+        sal_Bool bFound = lcl_FindEntry( aCfgLocaleStr, aNodeNames);
+
+        if (bFound)
+        {
+            Sequence< OUString > aNames(1);
+            OUString &rNodeName = aNames.getArray()[0];
+            rNodeName = rLastFoundList;
+            rNodeName += OUString::valueOf( (sal_Unicode)'/' );
+            rNodeName += aCfgLocaleStr;
+            Sequence< Any > aValues( rCfg.GetProperties( aNames ) );
+            if (aValues.getLength())
+            {
+                OSL_ENSURE( aValues.getLength() == 1, "unexpected length of sequence" );
+                Sequence< OUString > aSvcImplNames;
+                if (aValues.getConstArray()[0] >>= aSvcImplNames)
+                    aRes = aSvcImplNames;
+                else
+                {
+                    OSL_FAIL( "type mismatch" );
+                }
+            }
+        }
+
+        return aRes;
+    }
+
+    Sequence< OUString > lcl_RemoveMissingEntries(
+            const Sequence< OUString > &rCfgSvcs,
+            const Sequence< OUString > &rAvailSvcs )
+    {
+        Sequence< OUString > aRes( rCfgSvcs.getLength() );
+        OUString *pRes = aRes.getArray();
+        sal_Int32 nCnt = 0;
+
+        sal_Int32 nEntries = rCfgSvcs.getLength();
+        const OUString *pEntry = rCfgSvcs.getConstArray();
+        for (sal_Int32 i = 0;  i < nEntries;  ++i)
+        {
+            if (!pEntry[i].isEmpty() && lcl_FindEntry( pEntry[i], rAvailSvcs ))
+                pRes[ nCnt++ ] = pEntry[i];
+        }
+
+        aRes.realloc( nCnt );
+        return aRes;
+    }
+
+    Sequence< OUString > lcl_GetNewEntries(
+            const Sequence< OUString > &rLastFoundSvcs,
+            const Sequence< OUString > &rAvailSvcs )
+    {
+        sal_Int32 nLen = rAvailSvcs.getLength();
+        Sequence< OUString > aRes( nLen );
+        OUString *pRes = aRes.getArray();
+        sal_Int32 nCnt = 0;
+
+        const OUString *pEntry = rAvailSvcs.getConstArray();
+        for (sal_Int32 i = 0;  i < nLen;  ++i)
+        {
+            if (!pEntry[i].isEmpty() && !lcl_FindEntry( pEntry[i], rLastFoundSvcs ))
+                pRes[ nCnt++ ] = pEntry[i];
+        }
+
+        aRes.realloc( nCnt );
+        return aRes;
+    }
+
+    Sequence< OUString > lcl_MergeSeq(
+            const Sequence< OUString > &rCfgSvcs,
+            const Sequence< OUString > &rNewSvcs )
+    {
+        Sequence< OUString > aRes( rCfgSvcs.getLength() + rNewSvcs.getLength() );
+        OUString *pRes = aRes.getArray();
+        sal_Int32 nCnt = 0;
+
+        for (sal_Int32 k = 0;  k < 2;  ++k)
+        {
+            // add previously configuerd service first and append
+            // new found services at the end
+            const Sequence< OUString > &rSeq = k == 0 ? rCfgSvcs : rNewSvcs;
+
+            sal_Int32 nLen = rSeq.getLength();
+            const OUString *pEntry = rSeq.getConstArray();
+            for (sal_Int32 i = 0;  i < nLen;  ++i)
+            {
+                if (!pEntry[i].isEmpty() && !lcl_FindEntry( pEntry[i], aRes ))
+                    pRes[ nCnt++ ] = pEntry[i];
+            }
+        }
+
+        aRes.realloc( nCnt );
+        return aRes;
+    }
+}
+
+void LngSvcMgr::UpdateAll()
+{
+    using beans::PropertyValue;
+    using lang::Locale;
+    using uno::Sequence;
+
+    typedef OUString OUstring_t;
+    typedef Sequence< OUString > Sequence_OUString_t;
+    typedef std::map< OUstring_t, Sequence_OUString_t > list_entry_map_t;
+
+    SvtLinguConfig aCfg;
+
+    const int nNumServices = 4;
+    const sal_Char * apServices[nNumServices]       =  { SN_SPELLCHECKER, SN_GRAMMARCHECKER, SN_HYPHENATOR, SN_THESAURUS };
+    const sal_Char * apCurLists[nNumServices]       =  { "ServiceManager/SpellCheckerList",       "ServiceManager/GrammarCheckerList",       "ServiceManager/HyphenatorList",       "ServiceManager/ThesaurusList" };
+    const sal_Char * apLastFoundLists[nNumServices] =  { "ServiceManager/LastFoundSpellCheckers", "ServiceManager/LastFoundGrammarCheckers", "ServiceManager/LastFoundHyphenators", "ServiceManager/LastFoundThesauri" };
+
+    // usage of indices as above: 0 = spell checker, 1 = grammar checker, 2 = hyphenator, 3 = thesaurus
+    std::vector< list_entry_map_t > aLastFoundSvcs(nNumServices);
+    std::vector< list_entry_map_t > aCurSvcs(nNumServices);
+
+    for (int k = 0;  k < nNumServices;  ++k)
+    {
+        OUString aService( ::rtl::OUString::createFromAscii( apServices[k] ) );
+        OUString aActiveList( ::rtl::OUString::createFromAscii( apCurLists[k] ) );
+        OUString aLastFoundList( ::rtl::OUString::createFromAscii( apLastFoundLists[k] ) );
+        sal_Int32 i;
+
+        //
+        // remove configured but not available language/services entries
+        //
+        Sequence< OUString > aNodeNames( aCfg.GetNodeNames( aActiveList ) );   // list of configured locales
+        sal_Int32 nNodeNames = aNodeNames.getLength();
+        const OUString *pNodeName = aNodeNames.getConstArray();
+        for (i = 0;  i < nNodeNames;  ++i)
+        {
+            Locale aLocale( CreateLocale( MsLangId::convertIsoStringToLanguage(pNodeName[i]) ) );
+            Sequence< OUString > aCfgSvcs( getConfiguredServices( aService, aLocale ));
+            Sequence< OUString > aAvailSvcs( getAvailableServices( aService, aLocale ));
+
+            aCfgSvcs = lcl_RemoveMissingEntries( aCfgSvcs, aAvailSvcs );
+
+            aCurSvcs[k][ pNodeName[i] ] = aCfgSvcs;
+        }
+
+        //
+        // add new available language/service entries
+        // and
+        // set last found services to currently available ones
+        //
+        Sequence< Locale > aAvailLocales( getAvailableLocales(aService) );
+        sal_Int32 nAvailLocales = aAvailLocales.getLength();
+        const Locale *pAvailLocale = aAvailLocales.getConstArray();
+        for (i = 0;  i < nAvailLocales;  ++i)
+        {
+            OUString aCfgLocaleStr( MsLangId::convertLanguageToIsoString(
+                                        LocaleToLanguage( pAvailLocale[i] ) ) );
+
+            Sequence< OUString > aAvailSvcs( getAvailableServices( aService, pAvailLocale[i] ));
+
+            aLastFoundSvcs[k][ aCfgLocaleStr ] = aAvailSvcs;
+
+            Sequence< OUString > aLastSvcs(
+                    lcl_GetLastFoundSvcs( aCfg, aLastFoundList , pAvailLocale[i] ));
+            Sequence< OUString > aNewSvcs =
+                    lcl_GetNewEntries( aLastSvcs, aAvailSvcs );
+
+            Sequence< OUString > aCfgSvcs( aCurSvcs[k][ aCfgLocaleStr ] );
+
+            // merge services list (previously configured to be listed first).
+            aCfgSvcs = lcl_MergeSeq( aCfgSvcs, aNewSvcs );
+
+            aCurSvcs[k][ aCfgLocaleStr ] = aCfgSvcs;
+        }
+    }
+
+    //
+    // write new data back to configuration
+    //
+    for (int k = 0;  k < nNumServices;  ++k)
+    {
+        for (int i = 0;  i < 2;  ++i)
+        {
+            const sal_Char *pSubNodeName = (i == 0) ? apCurLists[k] : apLastFoundLists[k];
+            OUString aSubNodeName( ::rtl::OUString::createFromAscii(pSubNodeName) );
+
+            list_entry_map_t &rCurMap = (i == 0) ? aCurSvcs[k] : aLastFoundSvcs[k];
+            list_entry_map_t::const_iterator aIt( rCurMap.begin() );
+            sal_Int32 nVals = static_cast< sal_Int32 >( rCurMap.size() );
+            Sequence< PropertyValue > aNewValues( nVals );
+            PropertyValue *pNewValue = aNewValues.getArray();
+            while (aIt != rCurMap.end())
+            {
+                OUString aCfgEntryName( aSubNodeName );
+                aCfgEntryName += OUString::valueOf( (sal_Unicode) '/' );
+                aCfgEntryName += (*aIt).first;
+
+                pNewValue->Name  = aCfgEntryName;
+                pNewValue->Value <<= (*aIt).second;
+                ++pNewValue;
+                ++aIt;
+            }
+            OSL_ENSURE( pNewValue - aNewValues.getArray() == nVals,
+                    "possible mismatch of sequence size and property number" );
+
+            {
+                // add new or replace existing entries.
+                sal_Bool bRes = aCfg.ReplaceSetProperties( aSubNodeName, aNewValues );
+                if (!bRes)
+                {
+#if OSL_DEBUG_LEVEL > 1
+                    OSL_FAIL( "failed to set new configuration values" );
+#endif
+                }
+            }
+        }
+    }
+
+    //The new settings in the configuration get applied ! because we are
+    //listening to the configuration for changes of the relevant ! properties
+    //and Notify applies the new settings.
+}
 
 void LngSvcMgr::Notify( const uno::Sequence< OUString > &rPropertyNames )
 {
@@ -1256,32 +1588,21 @@ uno::Sequence< OUString > SAL_CALL
 
     if (0 == rServiceName.compareToAscii( SN_SPELLCHECKER ))
     {
-        // don't used cached data here (force re-evaluation in order to have downloaded dictionaries
-        // already found without the need to restart the office
-        delete pAvailSpellSvcs;  pAvailSpellSvcs = 0;
         GetAvailableSpellSvcs_Impl();
         pInfoArray = pAvailSpellSvcs;
     }
     else if (0 == rServiceName.compareToAscii( SN_GRAMMARCHECKER ))
     {
-// disable force re-loading of the cache - re-start needed for new grammer checkers: fdo#35270
-//        delete pAvailGrammarSvcs;  pAvailGrammarSvcs = 0;
         GetAvailableGrammarSvcs_Impl();
         pInfoArray = pAvailGrammarSvcs;
     }
     else if (0 == rServiceName.compareToAscii( SN_HYPHENATOR ))
     {
-        // don't used cached data here (force re-evaluation in order to have downloaded dictionaries
-        // already found without the need to restart the office
-        delete pAvailHyphSvcs;  pAvailHyphSvcs = 0;
         GetAvailableHyphSvcs_Impl();
         pInfoArray = pAvailHyphSvcs;
     }
     else if (0 == rServiceName.compareToAscii( SN_THESAURUS ))
     {
-        // don't used cached data here (force re-evaluation in order to have downloaded dictionaries
-        // already found without the need to restart the office
-        delete pAvailThesSvcs;  pAvailThesSvcs = 0;
         GetAvailableThesSvcs_Impl();
         pInfoArray = pAvailThesSvcs;
     }
diff --git a/linguistic/source/lngsvcmgr.hxx b/linguistic/source/lngsvcmgr.hxx
index 80cbd3d..537750d 100644
--- a/linguistic/source/lngsvcmgr.hxx
+++ b/linguistic/source/lngsvcmgr.hxx
@@ -30,7 +30,7 @@
 #define _LINGUISTIC_LNGSVCMGR_HXX_
 
 #include <uno/lbnames.h>            // CPPU_CURRENT_LANGUAGE_BINDING_NAME macro, which specify the environment type
-#include <cppuhelper/implbase4.hxx> // helper for implementations
+#include <cppuhelper/implbase5.hxx> // helper for implementations
 #include <cppuhelper/interfacecontainer.h>  //OMultiTypeInterfaceContainerHelper
 
 
@@ -39,8 +39,10 @@
 #include <com/sun/star/lang/XComponent.hpp>
 #include <com/sun/star/linguistic2/XLinguServiceManager.hpp>
 #include <com/sun/star/linguistic2/XAvailableLocales.hpp>
+#include <com/sun/star/util/XModifyBroadcaster.hpp>
+#include <com/sun/star/util/XModifyListener.hpp>
 #include <unotools/configitem.hxx>
-
+#include <vcl/timer.hxx>
 #include <boost/ptr_container/ptr_vector.hpp>
 
 #include "linguistic/misc.hxx"
@@ -64,12 +66,13 @@ namespace com { namespace sun { namespace star { namespace linguistic2 {
 
 
 class LngSvcMgr :
-    public cppu::WeakImplHelper4
+    public cppu::WeakImplHelper5
     <
         com::sun::star::linguistic2::XLinguServiceManager,
         com::sun::star::linguistic2::XAvailableLocales,
         com::sun::star::lang::XComponent,
-        com::sun::star::lang::XServiceInfo
+        com::sun::star::lang::XServiceInfo,
+        com::sun::star::util::XModifyListener
     >,
     private utl::ConfigItem
 {
@@ -89,6 +92,12 @@ class LngSvcMgr :
     com::sun::star::uno::Reference<
         ::com::sun::star::lang::XEventListener >        xListenerHelper;
 
+    com::sun::star::uno::Reference<
+        ::com::sun::star::util::XModifyBroadcaster>     xMB;
+
+    Timer                                               aUpdateTimer;
+
+
     com::sun::star::uno::Sequence<
         com::sun::star::lang::Locale >                  aAvailSpellLocales;
     com::sun::star::uno::Sequence<
@@ -139,6 +148,10 @@ class LngSvcMgr :
     virtual void    Notify( const com::sun::star::uno::Sequence< rtl::OUString > &rPropertyNames );
     virtual void    Commit();
 
+    void UpdateAll();
+    void stopListening();
+    DECL_LINK( updateAndBroadcast, void* );
+
 public:
     LngSvcMgr();
     virtual ~LngSvcMgr();
@@ -166,6 +179,11 @@ public:
     virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw (::com::sun::star::uno::RuntimeException);
     virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames(  ) throw (::com::sun::star::uno::RuntimeException);
 
+    // XEventListener
+    virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& rSource ) throw(::com::sun::star::uno::RuntimeException);
+
+    // XModifyListener
+    virtual void SAL_CALL modified( const ::com::sun::star::lang::EventObject& rEvent ) throw(::com::sun::star::uno::RuntimeException);
 
     static inline ::rtl::OUString   getImplementationName_Static();
     static ::com::sun::star::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_Static() throw();
commit 7fe61368cead27eef5d6175abd1cc254e99e8a05
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Tue Jul 10 14:59:28 2012 +0100

    CalcDataFilesChangedCheckValue is always zero
    
    Change-Id: I851c0ac078b57f07e0a58a9fb2119d11cc5048e5

diff --git a/editeng/inc/editeng/unolingu.hxx b/editeng/inc/editeng/unolingu.hxx
index 5b41e48..d25be04 100644
--- a/editeng/inc/editeng/unolingu.hxx
+++ b/editeng/inc/editeng/unolingu.hxx
@@ -59,8 +59,6 @@ class SvxLinguConfigUpdate
                                     // n ==  0 => already updated, nothing to be done
                                     // n ==  1 => needs to be updated
 
-    static sal_Int32 CalcDataFilesChangedCheckValue();
-
 public:
 
     EDITENG_DLLPUBLIC static void UpdateAll( sal_Bool bForceCheck = sal_False );
diff --git a/editeng/source/misc/unolingu.cxx b/editeng/source/misc/unolingu.cxx
index da2fac5..bad9e03 100644
--- a/editeng/source/misc/unolingu.cxx
+++ b/editeng/source/misc/unolingu.cxx
@@ -367,23 +367,13 @@ void SvxLinguConfigUpdate::UpdateAll( sal_Bool bForceCheck )
 }
 
 
-sal_Int32 SvxLinguConfigUpdate::CalcDataFilesChangedCheckValue()
-{
-    RTL_LOGFILE_CONTEXT( aLog, "svx: SvxLinguConfigUpdate::CalcDataFilesChangedCheckValue" );
-
-    sal_Int32 nHashVal = 0;
-    // nothing to be checked anymore since those old directory paths are gone by now
-    return nHashVal;
-}
-
-
 sal_Bool SvxLinguConfigUpdate::IsNeedUpdateAll( sal_Bool bForceCheck )
 {
     RTL_LOGFILE_CONTEXT( aLog, "svx: SvxLinguConfigUpdate::IsNeedUpdateAll" );
     if (nNeedUpdating == -1 || bForceCheck )    // need to check if updating is necessary
     {
         // calculate hash value for current data files
-        sal_Int32 nCurrentDataFilesChangedCheckValue = CalcDataFilesChangedCheckValue();
+        sal_Int32 nCurrentDataFilesChangedCheckValue = 0;
 
         // compare hash value and check value to see if anything has changed
         // and thus the configuration needs to be updated
commit 0473296bd9a71b81c6aa9638d8a231ace503dbb8
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Tue Jul 10 14:57:56 2012 +0100

    nCurrentDataFilesChangedCheckValue is kind of pointless
    
    Change-Id: Ibded6b0a72c9501d35fb884c93c505a2f716f678

diff --git a/editeng/inc/editeng/unolingu.hxx b/editeng/inc/editeng/unolingu.hxx
index 2773015..5b41e48 100644
--- a/editeng/inc/editeng/unolingu.hxx
+++ b/editeng/inc/editeng/unolingu.hxx
@@ -55,7 +55,6 @@ class Window;
 
 class SvxLinguConfigUpdate
 {
-    static sal_Int32    nCurrentDataFilesChangedCheckValue;
     static sal_Int16    nNeedUpdating;  // n == -1 => needs to be checked
                                     // n ==  0 => already updated, nothing to be done
                                     // n ==  1 => needs to be updated
diff --git a/editeng/source/misc/unolingu.cxx b/editeng/source/misc/unolingu.cxx
index d9cc031..da2fac5 100644
--- a/editeng/source/misc/unolingu.cxx
+++ b/editeng/source/misc/unolingu.cxx
@@ -208,7 +208,6 @@ Sequence< OUString > lcl_MergeSeq(
 }
 
 sal_Int16 SvxLinguConfigUpdate::nNeedUpdating = -1;
-sal_Int32 SvxLinguConfigUpdate::nCurrentDataFilesChangedCheckValue = -1;
 
 void SvxLinguConfigUpdate::UpdateAll( sal_Bool bForceCheck )
 {
@@ -341,7 +340,6 @@ void SvxLinguConfigUpdate::UpdateAll( sal_Bool bForceCheck )
                 }
             }
         }
-        OSL_ENSURE( nCurrentDataFilesChangedCheckValue != -1, "SvxLinguConfigUpdate::UpdateAll DataFilesChangedCheckValue not yet calculated!" );
         Any aAny;
 
         // for the time being (developer builds until OOo 3.0)
@@ -352,7 +350,6 @@ void SvxLinguConfigUpdate::UpdateAll( sal_Bool bForceCheck )
         // Since the check is on-demand occuring and executed once it should
         // not be too troublesome.
         // In OOo 3.0 we will not need the respective code anymore at all.
-//      aAny <<= nCurrentDataFilesChangedCheckValue;
         aAny <<= (sal_Int32) -1;    // keep the value set to 'need to check'
 
         aCfg.SetProperty( A2OU( "DataFilesChangedCheckValue" ), aAny );
@@ -386,7 +383,7 @@ sal_Bool SvxLinguConfigUpdate::IsNeedUpdateAll( sal_Bool bForceCheck )
     if (nNeedUpdating == -1 || bForceCheck )    // need to check if updating is necessary
     {
         // calculate hash value for current data files
-        nCurrentDataFilesChangedCheckValue = CalcDataFilesChangedCheckValue();
+        sal_Int32 nCurrentDataFilesChangedCheckValue = CalcDataFilesChangedCheckValue();
 
         // compare hash value and check value to see if anything has changed
         // and thus the configuration needs to be updated
commit b18e1e705148348392632596ec686206ec213019
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Tue Jul 10 13:22:15 2012 +0100

    Related: rhbz#836937 halve calls to expensive getAvailableServices
    
    getAvailableServices is very expensive, so halve the amount of calls to it that
    we need. This should be logically equivalent
    
    Change-Id: I5627ed539695fd837a497362cf9873debd254013

diff --git a/editeng/source/misc/unolingu.cxx b/editeng/source/misc/unolingu.cxx
index 486052e..d9cc031 100644
--- a/editeng/source/misc/unolingu.cxx
+++ b/editeng/source/misc/unolingu.cxx
@@ -267,7 +267,9 @@ void SvxLinguConfigUpdate::UpdateAll( sal_Bool bForceCheck )
             }
 
             //
-            // add new available language/servcice entries
+            // add new available language/service entries
+            // and
+            // set last found services to currently available ones
             //
             uno::Reference< XAvailableLocales > xAvail( xLngSvcMgr, UNO_QUERY );
             Sequence< Locale > aAvailLocales( xAvail->getAvailableLocales(aService) );
@@ -275,15 +277,19 @@ void SvxLinguConfigUpdate::UpdateAll( sal_Bool bForceCheck )
             const Locale *pAvailLocale = aAvailLocales.getConstArray();
             for (i = 0;  i < nAvailLocales;  ++i)
             {
+                OUString aCfgLocaleStr( MsLangId::convertLanguageToIsoString(
+                                            SvxLocaleToLanguage( pAvailLocale[i] ) ) );
+
                 Sequence< OUString > aAvailSvcs(
                         xLngSvcMgr->getAvailableServices( aService, pAvailLocale[i] ));
+
+                aLastFoundSvcs[k][ aCfgLocaleStr ] = aAvailSvcs;
+
                 Sequence< OUString > aLastSvcs(
                         lcl_GetLastFoundSvcs( aCfg, aLastFoundList , pAvailLocale[i] ));
                 Sequence< OUString > aNewSvcs =
                         lcl_GetNewEntries( aLastSvcs, aAvailSvcs );
 
-                OUString aCfgLocaleStr( MsLangId::convertLanguageToIsoString(
-                                            SvxLocaleToLanguage( pAvailLocale[i] ) ) );
                 Sequence< OUString > aCfgSvcs( aCurSvcs[k][ aCfgLocaleStr ] );
 
                 // merge services list (previously configured to be listed first).
@@ -291,19 +297,6 @@ void SvxLinguConfigUpdate::UpdateAll( sal_Bool bForceCheck )
 
                 aCurSvcs[k][ aCfgLocaleStr ] = aCfgSvcs;
             }
-
-            //
-            // set last found services to currently available ones
-            //
-            for (i = 0;  i < nAvailLocales;  ++i)
-            {
-                Sequence< OUString > aSvcImplNames(
-                        xLngSvcMgr->getAvailableServices( aService, pAvailLocale[i] ) );
-
-                OUString aCfgLocaleStr( MsLangId::convertLanguageToIsoString(
-                                            SvxLocaleToLanguage( pAvailLocale[i] ) ) );
-                aLastFoundSvcs[k][ aCfgLocaleStr ] = aSvcImplNames;
-            }
         }
 
         //
commit e18f1d6216b13c38525d37448da882a63a3d0055
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Tue Jul 10 13:20:27 2012 +0100

    remove distracting and unhelpful debugging code
    
    Change-Id: I870df7d4af666c1cb087cec6d4daebcba87ff8ab

diff --git a/editeng/source/misc/unolingu.cxx b/editeng/source/misc/unolingu.cxx
index 431053b..486052e 100644
--- a/editeng/source/misc/unolingu.cxx
+++ b/editeng/source/misc/unolingu.cxx
@@ -260,12 +260,7 @@ void SvxLinguConfigUpdate::UpdateAll( sal_Bool bForceCheck )
                         xLngSvcMgr->getConfiguredServices( aService, aLocale ));
                 Sequence< OUString > aAvailSvcs(
                         xLngSvcMgr->getAvailableServices( aService, aLocale ));
-#if OSL_DEBUG_LEVEL > 1
-                const OUString * pCfgSvcs   = aCfgSvcs.getConstArray();
-                const OUString * pAvailSvcs = aAvailSvcs.getConstArray();
-                (void) pCfgSvcs;
-                (void) pAvailSvcs;
-#endif
+
                 aCfgSvcs = lcl_RemoveMissingEntries( aCfgSvcs, aAvailSvcs );
 
                 aCurSvcs[k][ pNodeName[i] ] = aCfgSvcs;
@@ -286,14 +281,6 @@ void SvxLinguConfigUpdate::UpdateAll( sal_Bool bForceCheck )
                         lcl_GetLastFoundSvcs( aCfg, aLastFoundList , pAvailLocale[i] ));
                 Sequence< OUString > aNewSvcs =
                         lcl_GetNewEntries( aLastSvcs, aAvailSvcs );
-#if OSL_DEBUG_LEVEL > 1
-                const OUString * pAvailSvcs = aAvailSvcs.getConstArray();
-                const OUString * pLastSvcs  = aLastSvcs.getConstArray();
-                const OUString * pNewSvcs   = aNewSvcs.getConstArray();
-                (void) pAvailSvcs;
-                (void) pLastSvcs;
-                (void) pNewSvcs;
-#endif
 
                 OUString aCfgLocaleStr( MsLangId::convertLanguageToIsoString(
                                             SvxLocaleToLanguage( pAvailLocale[i] ) ) );
@@ -313,15 +300,6 @@ void SvxLinguConfigUpdate::UpdateAll( sal_Bool bForceCheck )
                 Sequence< OUString > aSvcImplNames(
                         xLngSvcMgr->getAvailableServices( aService, pAvailLocale[i] ) );
 
-#if OSL_DEBUG_LEVEL > 1
-                sal_Int32 nSvcs = aSvcImplNames.getLength();
-                const OUString *pSvcImplName = aSvcImplNames.getConstArray();
-                for (sal_Int32 j = 0;  j < nSvcs;  ++j)
-                {
-                    OUString aImplName( pSvcImplName[j] );
-                }
-#endif
-
                 OUString aCfgLocaleStr( MsLangId::convertLanguageToIsoString(
                                             SvxLocaleToLanguage( pAvailLocale[i] ) ) );
                 aLastFoundSvcs[k][ aCfgLocaleStr ] = aSvcImplNames;
@@ -349,15 +327,6 @@ void SvxLinguConfigUpdate::UpdateAll( sal_Bool bForceCheck )
                     aCfgEntryName += OUString::valueOf( (sal_Unicode) '/' );
                     aCfgEntryName += (*aIt).first;
 
-#if OSL_DEBUG_LEVEL > 1
-                    Sequence< OUString > aSvcImplNames( (*aIt).second );
-                    sal_Int32 nSvcs = aSvcImplNames.getLength();
-                    const OUString *pSvcImplName = aSvcImplNames.getConstArray();
-                    for (sal_Int32 j = 0;  j < nSvcs;  ++j)
-                    {
-                        OUString aImplName( pSvcImplName[j] );
-                    }
-#endif
                     pNewValue->Name  = aCfgEntryName;
                     pNewValue->Value <<= (*aIt).second;
                     ++pNewValue;


More information about the Libreoffice-commits mailing list