summaryrefslogtreecommitdiff
path: root/linguistic/source/convdic.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'linguistic/source/convdic.cxx')
-rw-r--r--linguistic/source/convdic.cxx744
1 files changed, 744 insertions, 0 deletions
diff --git a/linguistic/source/convdic.cxx b/linguistic/source/convdic.cxx
new file mode 100644
index 000000000000..e7c52b500817
--- /dev/null
+++ b/linguistic/source/convdic.cxx
@@ -0,0 +1,744 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_linguistic.hxx"
+
+#include <cppuhelper/factory.hxx>
+#include <i18npool/lang.h>
+#include <osl/mutex.hxx>
+#include <tools/debug.hxx>
+#include <tools/fsys.hxx>
+#include <tools/stream.hxx>
+#include <tools/stream.hxx>
+#include <tools/string.hxx>
+#include <tools/urlobj.hxx>
+#include <ucbhelper/content.hxx>
+#include <unotools/processfactory.hxx>
+#include <unotools/streamwrap.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+
+#include <com/sun/star/linguistic2/XConversionDictionary.hpp>
+#include <com/sun/star/linguistic2/ConversionDictionaryType.hpp>
+#include <com/sun/star/linguistic2/XConversionPropertyType.hpp>
+#include <com/sun/star/linguistic2/ConversionPropertyType.hpp>
+#include <com/sun/star/util/XFlushable.hpp>
+#include <com/sun/star/lang/Locale.hpp>
+#include <com/sun/star/lang/EventObject.hpp>
+#include <com/sun/star/ucb/XSimpleFileAccess.hpp>
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#include <com/sun/star/util/XFlushListener.hpp>
+#include <com/sun/star/io/XActiveDataSource.hpp>
+#include <com/sun/star/io/XActiveDataSource.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
+#include <com/sun/star/document/XFilter.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/xml/sax/InputSource.hpp>
+#include <com/sun/star/xml/sax/XParser.hpp>
+
+
+#include "convdic.hxx"
+#include "convdicxml.hxx"
+#include "linguistic/misc.hxx"
+#include "defs.hxx"
+
+using namespace std;
+using namespace utl;
+using namespace osl;
+using namespace rtl;
+using namespace com::sun::star;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::linguistic2;
+using namespace linguistic;
+
+#define SN_CONV_DICTIONARY "com.sun.star.linguistic2.ConversionDictionary"
+#define SN_HCD_CONV_DICTIONARY "com.sun.star.linguistic2.HangulHanjaConversionDictionary"
+
+
+///////////////////////////////////////////////////////////////////////////
+void ReadThroughDic( const String &rMainURL, ConvDicXMLImport &rImport )
+{
+ if (rMainURL.Len() == 0)
+ return;
+ DBG_ASSERT(!INetURLObject( rMainURL ).HasError(), "invalid URL");
+
+ uno::Reference< lang::XMultiServiceFactory > xServiceFactory( utl::getProcessServiceFactory() );
+
+ // get xInputStream stream
+ uno::Reference< io::XInputStream > xIn;
+ try
+ {
+ uno::Reference< ucb::XSimpleFileAccess > xAccess( xServiceFactory->createInstance(
+ A2OU( "com.sun.star.ucb.SimpleFileAccess" ) ), uno::UNO_QUERY_THROW );
+ xIn = xAccess->openFileRead( rMainURL );
+ }
+ catch (uno::Exception & e)
+ {
+ DBG_ASSERT( 0, "failed to get input stream" );
+ (void) e;
+ }
+ if (!xIn.is())
+ return;
+
+ SvStreamPtr pStream = SvStreamPtr( utl::UcbStreamHelper::CreateStream( xIn ) );
+
+ ULONG nError = sal::static_int_cast< ULONG >(-1);
+
+ // prepare ParserInputSource
+ xml::sax::InputSource aParserInput;
+ aParserInput.aInputStream = xIn;
+
+ // get parser
+ uno::Reference< xml::sax::XParser > xParser;
+ try
+ {
+ xParser = uno::Reference< xml::sax::XParser >( xServiceFactory->createInstance(
+ A2OU( "com.sun.star.xml.sax.Parser" ) ), UNO_QUERY );
+ }
+ catch (uno::Exception &)
+ {
+ }
+ DBG_ASSERT( xParser.is(), "Can't create parser" );
+ if (!xParser.is())
+ return;
+
+ // get filter
+ //ConvDicXMLImport *pImport = new ConvDicXMLImport( this, rMainURL );
+ //!! keep a reference until everything is done to
+ //!! ensure the proper lifetime of the object
+ uno::Reference < xml::sax::XDocumentHandler > xFilter(
+ (xml::sax::XExtendedDocumentHandler *) &rImport, UNO_QUERY );
+
+ // connect parser and filter
+ xParser->setDocumentHandler( xFilter );
+
+ // finally, parser the stream
+ try
+ {
+ xParser->parseStream( aParserInput ); // implicitly calls ConvDicXMLImport::CreateContext
+ if (rImport.GetSuccess())
+ nError = 0;
+ }
+ catch( xml::sax::SAXParseException& )
+ {
+// if( bEncrypted )
+// nError = ERRCODE_SFX_WRONGPASSWORD;
+ }
+ catch( xml::sax::SAXException& )
+ {
+// if( bEncrypted )
+// nError = ERRCODE_SFX_WRONGPASSWORD;
+ }
+ catch( io::IOException& )
+ {
+ }
+}
+
+BOOL IsConvDic( const String &rFileURL, INT16 &nLang, sal_Int16 &nConvType )
+{
+ BOOL bRes = FALSE;
+
+ if (rFileURL.Len() == 0)
+ return bRes;
+
+ // check if file extension matches CONV_DIC_EXT
+ String aExt;
+ xub_StrLen nPos = rFileURL.SearchBackward( '.' );
+ if (STRING_NOTFOUND != nPos)
+ aExt = rFileURL.Copy( nPos + 1 );
+ aExt.ToLowerAscii();
+ if (!aExt.EqualsAscii( CONV_DIC_EXT ))
+ return bRes;
+
+ // first argument being 0 should stop the file from being parsed
+ // up to the end (reading all entries) when the required
+ // data (language, conversion type) is found.
+ ConvDicXMLImport *pImport = new ConvDicXMLImport( 0, rFileURL );
+
+ //!! keep a first reference to ensure the lifetime of the object !!
+ uno::Reference< XInterface > xRef( (document::XFilter *) pImport, UNO_QUERY );
+
+ ReadThroughDic( rFileURL, *pImport ); // will implicitly add the entries
+ bRes = pImport->GetLanguage() != LANGUAGE_NONE &&
+ pImport->GetConversionType() != -1;
+ DBG_ASSERT( bRes, "conversion dictionary corrupted?" );
+
+ if (bRes)
+ {
+ nLang = pImport->GetLanguage();
+ nConvType = pImport->GetConversionType();
+ }
+
+ return bRes;
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+
+ConvDic::ConvDic(
+ const String &rName,
+ INT16 nLang,
+ sal_Int16 nConvType,
+ BOOL bBiDirectional,
+ const String &rMainURL) :
+ aFlushListeners( GetLinguMutex() )
+{
+ aName = rName;
+ nLanguage = nLang;
+ nConversionType = nConvType;
+ aMainURL = rMainURL;
+
+ if (bBiDirectional)
+ pFromRight = std::auto_ptr< ConvMap >( new ConvMap );
+ if (nLang == LANGUAGE_CHINESE_SIMPLIFIED || nLang == LANGUAGE_CHINESE_TRADITIONAL)
+ pConvPropType = std::auto_ptr< PropTypeMap >( new PropTypeMap );
+
+ nMaxLeftCharCount = nMaxRightCharCount = 0;
+ bMaxCharCountIsValid = TRUE;
+
+ bNeedEntries = TRUE;
+ bIsModified = bIsActive = FALSE;
+ bIsReadonly = FALSE;
+
+ if( rMainURL.Len() > 0 )
+ {
+ BOOL bExists = FALSE;
+ bIsReadonly = IsReadOnly( rMainURL, &bExists );
+
+ if( !bExists ) // new empty dictionary
+ {
+ bNeedEntries = FALSE;
+ //! create physical representation of an **empty** dictionary
+ //! that could be found by the dictionary-list implementation
+ // (Note: empty dictionaries are not just empty files!)
+ Save();
+ bIsReadonly = IsReadOnly( rMainURL ); // will be FALSE if Save was succesfull
+ }
+ }
+ else
+ {
+ bNeedEntries = FALSE;
+ }
+}
+
+
+ConvDic::~ConvDic()
+{
+}
+
+
+void ConvDic::Load()
+{
+ DBG_ASSERT( !bIsModified, "dictionary is modified. Really do 'Load'?" );
+
+ //!! prevent function from being called recursively via HasEntry, AddEntry
+ bNeedEntries = FALSE;
+ ConvDicXMLImport *pImport = new ConvDicXMLImport( this, aMainURL );
+ //!! keep a first reference to ensure the lifetime of the object !!
+ uno::Reference< XInterface > xRef( (document::XFilter *) pImport, UNO_QUERY );
+ ReadThroughDic( aMainURL, *pImport ); // will implicitly add the entries
+ bIsModified = FALSE;
+}
+
+
+void ConvDic::Save()
+{
+ DBG_ASSERT( !bNeedEntries, "saving while entries missing" );
+ if (aMainURL.Len() == 0 || bNeedEntries)
+ return;
+ DBG_ASSERT(!INetURLObject( aMainURL ).HasError(), "invalid URL");
+
+ uno::Reference< lang::XMultiServiceFactory > xServiceFactory( utl::getProcessServiceFactory() );
+
+ // get XOutputStream stream
+ uno::Reference< io::XStream > xStream;
+ try
+ {
+ uno::Reference< ucb::XSimpleFileAccess > xAccess( xServiceFactory->createInstance(
+ A2OU( "com.sun.star.ucb.SimpleFileAccess" ) ), uno::UNO_QUERY_THROW );
+ xStream = xAccess->openFileReadWrite( aMainURL );
+ }
+ catch (uno::Exception & e)
+ {
+ DBG_ASSERT( 0, "failed to get input stream" );
+ (void) e;
+ }
+ if (!xStream.is())
+ return;
+
+ SvStreamPtr pStream = SvStreamPtr( utl::UcbStreamHelper::CreateStream( xStream ) );
+
+ // get XML writer
+ uno::Reference< io::XActiveDataSource > xSaxWriter;
+ if (xServiceFactory.is())
+ {
+ try
+ {
+ xSaxWriter = uno::Reference< io::XActiveDataSource >(
+ xServiceFactory->createInstance(
+ OUString::createFromAscii( "com.sun.star.xml.sax.Writer" ) ), UNO_QUERY );
+ }
+ catch (uno::Exception &)
+ {
+ }
+ }
+ DBG_ASSERT( xSaxWriter.is(), "can't instantiate XML writer" );
+
+ if (xSaxWriter.is() && xStream.is())
+ {
+ // connect XML writer to output stream
+ xSaxWriter->setOutputStream( xStream->getOutputStream() );
+
+ // prepare arguments (prepend doc handler to given arguments)
+ uno::Reference< xml::sax::XDocumentHandler > xDocHandler( xSaxWriter, UNO_QUERY );
+ ConvDicXMLExport *pExport = new ConvDicXMLExport( *this, aMainURL, xDocHandler );
+ //!! keep a first(!) reference until everything is done to
+ //!! ensure the proper lifetime of the object
+ uno::Reference< document::XFilter > aRef( (document::XFilter *) pExport );
+ sal_Bool bRet = pExport->Export(); // write entries to file
+ DBG_ASSERT( !pStream->GetError(), "I/O error while writing to stream" );
+ if (bRet)
+ bIsModified = FALSE;
+ }
+ DBG_ASSERT( !bIsModified, "dictionary still modified after save. Save failed?" );
+}
+
+
+ConvMap::iterator ConvDic::GetEntry( ConvMap &rMap, const rtl::OUString &rFirstText, const rtl::OUString &rSecondText )
+{
+ pair< ConvMap::iterator, ConvMap::iterator > aRange =
+ rMap.equal_range( rFirstText );
+ ConvMap::iterator aPos = rMap.end();
+ for (ConvMap::iterator aIt = aRange.first;
+ aIt != aRange.second && aPos == rMap.end();
+ ++aIt)
+ {
+ if ((*aIt).second == rSecondText)
+ aPos = aIt;
+ }
+ return aPos;
+}
+
+
+BOOL ConvDic::HasEntry( const OUString &rLeftText, const OUString &rRightText )
+{
+ if (bNeedEntries)
+ Load();
+ ConvMap::iterator aIt = GetEntry( aFromLeft, rLeftText, rRightText );
+ return aIt != aFromLeft.end();
+}
+
+
+void ConvDic::AddEntry( const OUString &rLeftText, const OUString &rRightText )
+{
+ if (bNeedEntries)
+ Load();
+
+ DBG_ASSERT(!HasEntry( rLeftText, rRightText), "entry already exists" );
+ aFromLeft .insert( ConvMap::value_type( rLeftText, rRightText ) );
+ if (pFromRight.get())
+ pFromRight->insert( ConvMap::value_type( rRightText, rLeftText ) );
+
+ if (bMaxCharCountIsValid)
+ {
+ if (rLeftText.getLength() > nMaxLeftCharCount)
+ nMaxLeftCharCount = (sal_Int16) rLeftText.getLength();
+ if (pFromRight.get() && rRightText.getLength() > nMaxRightCharCount)
+ nMaxRightCharCount = (sal_Int16) rRightText.getLength();
+ }
+
+ bIsModified = TRUE;
+}
+
+
+void ConvDic::RemoveEntry( const OUString &rLeftText, const OUString &rRightText )
+{
+ if (bNeedEntries)
+ Load();
+
+ ConvMap::iterator aLeftIt = GetEntry( aFromLeft, rLeftText, rRightText );
+ DBG_ASSERT( aLeftIt != aFromLeft.end(), "left map entry missing" );
+ aFromLeft .erase( aLeftIt );
+
+ if (pFromRight.get())
+ {
+ ConvMap::iterator aRightIt = GetEntry( *pFromRight, rRightText, rLeftText );
+ DBG_ASSERT( aRightIt != pFromRight->end(), "right map entry missing" );
+ pFromRight->erase( aRightIt );
+ }
+
+ bIsModified = TRUE;
+ bMaxCharCountIsValid = FALSE;
+}
+
+
+OUString SAL_CALL ConvDic::getName( )
+ throw (RuntimeException)
+{
+ MutexGuard aGuard( GetLinguMutex() );
+ return aName;
+}
+
+
+Locale SAL_CALL ConvDic::getLocale( )
+ throw (RuntimeException)
+{
+ MutexGuard aGuard( GetLinguMutex() );
+ return CreateLocale( nLanguage );
+}
+
+
+sal_Int16 SAL_CALL ConvDic::getConversionType( )
+ throw (RuntimeException)
+{
+ MutexGuard aGuard( GetLinguMutex() );
+ return nConversionType;
+}
+
+
+void SAL_CALL ConvDic::setActive( sal_Bool bActivate )
+ throw (RuntimeException)
+{
+ MutexGuard aGuard( GetLinguMutex() );
+ bIsActive = bActivate;
+}
+
+
+sal_Bool SAL_CALL ConvDic::isActive( )
+ throw (RuntimeException)
+{
+ MutexGuard aGuard( GetLinguMutex() );
+ return bIsActive;
+}
+
+
+void SAL_CALL ConvDic::clear( )
+ throw (RuntimeException)
+{
+ MutexGuard aGuard( GetLinguMutex() );
+ aFromLeft .clear();
+ if (pFromRight.get())
+ pFromRight->clear();
+ bNeedEntries = FALSE;
+ bIsModified = TRUE;
+ nMaxLeftCharCount = 0;
+ nMaxRightCharCount = 0;
+ bMaxCharCountIsValid = TRUE;
+}
+
+
+uno::Sequence< OUString > SAL_CALL ConvDic::getConversions(
+ const OUString& aText,
+ sal_Int32 nStartPos,
+ sal_Int32 nLength,
+ ConversionDirection eDirection,
+ sal_Int32 /*nTextConversionOptions*/ )
+ throw (IllegalArgumentException, RuntimeException)
+{
+ MutexGuard aGuard( GetLinguMutex() );
+
+ if (!pFromRight.get() && eDirection == ConversionDirection_FROM_RIGHT)
+ return uno::Sequence< OUString >();
+
+ if (bNeedEntries)
+ Load();
+
+ OUString aLookUpText( aText.copy(nStartPos, nLength) );
+ ConvMap &rConvMap = eDirection == ConversionDirection_FROM_LEFT ?
+ aFromLeft : *pFromRight;
+ pair< ConvMap::iterator, ConvMap::iterator > aRange =
+ rConvMap.equal_range( aLookUpText );
+
+ INT32 nCount = 0;
+ ConvMap::iterator aIt;
+ for (aIt = aRange.first; aIt != aRange.second; ++aIt)
+ ++nCount;
+
+ uno::Sequence< OUString > aRes( nCount );
+ OUString *pRes = aRes.getArray();
+ INT32 i = 0;
+ for (aIt = aRange.first; aIt != aRange.second; ++aIt)
+ pRes[i++] = (*aIt).second;
+
+ return aRes;
+}
+
+
+static BOOL lcl_SeqHasEntry(
+ const OUString *pSeqStart, // first element to check
+ INT32 nToCheck, // number of elements to check
+ const OUString &rText)
+{
+ BOOL bRes = FALSE;
+ if (pSeqStart && nToCheck > 0)
+ {
+ const OUString *pDone = pSeqStart + nToCheck; // one behind last to check
+ while (!bRes && pSeqStart != pDone)
+ {
+ if (*pSeqStart++ == rText)
+ bRes = TRUE;
+ }
+ }
+ return bRes;
+}
+
+uno::Sequence< OUString > SAL_CALL ConvDic::getConversionEntries(
+ ConversionDirection eDirection )
+ throw (RuntimeException)
+{
+ MutexGuard aGuard( GetLinguMutex() );
+
+ if (!pFromRight.get() && eDirection == ConversionDirection_FROM_RIGHT)
+ return uno::Sequence< OUString >();
+
+ if (bNeedEntries)
+ Load();
+
+ ConvMap &rConvMap = eDirection == ConversionDirection_FROM_LEFT ?
+ aFromLeft : *pFromRight;
+ uno::Sequence< OUString > aRes( rConvMap.size() );
+ OUString *pRes = aRes.getArray();
+ ConvMap::iterator aIt = rConvMap.begin();
+ INT32 nIdx = 0;
+ while (aIt != rConvMap.end())
+ {
+ OUString aCurEntry( (*aIt).first );
+ // skip duplicate entries ( duplicate = duplicate entries
+ // respective to the evaluated side (FROM_LEFT or FROM_RIGHT).
+ // Thus if FROM_LEFT is evaluated for pairs (A,B) and (A,C)
+ // only one entry for A will be returned in the result)
+ if (nIdx == 0 || !lcl_SeqHasEntry( pRes, nIdx, aCurEntry ))
+ pRes[ nIdx++ ] = aCurEntry;
+ ++aIt;
+ }
+ aRes.realloc( nIdx );
+
+ return aRes;
+}
+
+
+void SAL_CALL ConvDic::addEntry(
+ const OUString& aLeftText,
+ const OUString& aRightText )
+ throw (IllegalArgumentException, container::ElementExistException, RuntimeException)
+{
+ MutexGuard aGuard( GetLinguMutex() );
+ if (bNeedEntries)
+ Load();
+ if (HasEntry( aLeftText, aRightText ))
+ throw container::ElementExistException();
+ AddEntry( aLeftText, aRightText );
+}
+
+
+void SAL_CALL ConvDic::removeEntry(
+ const OUString& aLeftText,
+ const OUString& aRightText )
+ throw (container::NoSuchElementException, RuntimeException)
+{
+ MutexGuard aGuard( GetLinguMutex() );
+ if (bNeedEntries)
+ Load();
+ if (!HasEntry( aLeftText, aRightText ))
+ throw container::NoSuchElementException();
+ RemoveEntry( aLeftText, aRightText );
+}
+
+
+sal_Int16 SAL_CALL ConvDic::getMaxCharCount( ConversionDirection eDirection )
+ throw (RuntimeException)
+{
+ MutexGuard aGuard( GetLinguMutex() );
+
+ if (!pFromRight.get() && eDirection == ConversionDirection_FROM_RIGHT)
+ {
+ DBG_ASSERT( nMaxRightCharCount == 0, "max right char count should be 0" );
+ return 0;
+ }
+
+ if (bNeedEntries)
+ Load();
+
+ if (!bMaxCharCountIsValid)
+ {
+ nMaxLeftCharCount = 0;
+ ConvMap::iterator aIt = aFromLeft.begin();
+ while (aIt != aFromLeft.end())
+ {
+ sal_Int16 nTmp = (sal_Int16) (*aIt).first.getLength();
+ if (nTmp > nMaxLeftCharCount)
+ nMaxLeftCharCount = nTmp;
+ ++aIt;
+ }
+
+ nMaxRightCharCount = 0;
+ if (pFromRight.get())
+ {
+ aIt = pFromRight->begin();
+ while (aIt != pFromRight->end())
+ {
+ sal_Int16 nTmp = (sal_Int16) (*aIt).first.getLength();
+ if (nTmp > nMaxRightCharCount)
+ nMaxRightCharCount = nTmp;
+ ++aIt;
+ }
+ }
+
+ bMaxCharCountIsValid = TRUE;
+ }
+ sal_Int16 nRes = eDirection == ConversionDirection_FROM_LEFT ?
+ nMaxLeftCharCount : nMaxRightCharCount;
+ DBG_ASSERT( nRes >= 0, "invalid MaxCharCount" );
+ return nRes;
+}
+
+
+void SAL_CALL ConvDic::setPropertyType(
+ const OUString& rLeftText,
+ const OUString& rRightText,
+ sal_Int16 nPropertyType )
+ throw (container::NoSuchElementException, IllegalArgumentException, RuntimeException)
+{
+ sal_Bool bHasElement = HasEntry( rLeftText, rRightText);
+ if (!bHasElement)
+ throw container::NoSuchElementException();
+
+ // currently we assume that entries with the same left text have the
+ // same PropertyType even if the right text is different...
+ if (pConvPropType.get())
+ pConvPropType->insert( PropTypeMap::value_type( rLeftText, nPropertyType ) );
+ bIsModified = sal_True;
+}
+
+
+sal_Int16 SAL_CALL ConvDic::getPropertyType(
+ const OUString& rLeftText,
+ const OUString& rRightText )
+ throw (container::NoSuchElementException, RuntimeException)
+{
+ sal_Bool bHasElement = HasEntry( rLeftText, rRightText);
+ if (!bHasElement)
+ throw container::NoSuchElementException();
+
+ sal_Int16 nRes = ConversionPropertyType::NOT_DEFINED;
+ if (pConvPropType.get())
+ {
+ // still assuming that entries with same left text have same PropertyType
+ // even if they have different right text...
+ PropTypeMap::iterator aIt = pConvPropType->find( rLeftText );
+ if (aIt != pConvPropType->end())
+ nRes = (*aIt).second;
+ }
+ return nRes;
+}
+
+
+void SAL_CALL ConvDic::flush( )
+ throw (RuntimeException)
+{
+ MutexGuard aGuard( GetLinguMutex() );
+
+ if (!bIsModified)
+ return;
+
+ Save();
+
+ // notify listeners
+ EventObject aEvtObj;
+ aEvtObj.Source = uno::Reference< XFlushable >( this );
+ cppu::OInterfaceIteratorHelper aIt( aFlushListeners );
+ while (aIt.hasMoreElements())
+ {
+ uno::Reference< util::XFlushListener > xRef( aIt.next(), UNO_QUERY );
+ if (xRef.is())
+ xRef->flushed( aEvtObj );
+ }
+}
+
+
+void SAL_CALL ConvDic::addFlushListener(
+ const uno::Reference< util::XFlushListener >& rxListener )
+ throw (RuntimeException)
+{
+ MutexGuard aGuard( GetLinguMutex() );
+ if (rxListener.is())
+ aFlushListeners.addInterface( rxListener );
+}
+
+
+void SAL_CALL ConvDic::removeFlushListener(
+ const uno::Reference< util::XFlushListener >& rxListener )
+ throw (RuntimeException)
+{
+ MutexGuard aGuard( GetLinguMutex() );
+ if (rxListener.is())
+ aFlushListeners.removeInterface( rxListener );
+}
+
+
+OUString SAL_CALL ConvDic::getImplementationName( )
+ throw (RuntimeException)
+{
+ MutexGuard aGuard( GetLinguMutex() );
+ return getImplementationName_Static();
+}
+
+
+sal_Bool SAL_CALL ConvDic::supportsService( const OUString& rServiceName )
+ throw (RuntimeException)
+{
+ MutexGuard aGuard( GetLinguMutex() );
+ sal_Bool bRes = sal_False;
+ if (rServiceName.equalsAscii( SN_CONV_DICTIONARY ))
+ bRes = sal_True;
+ return bRes;
+}
+
+
+uno::Sequence< OUString > SAL_CALL ConvDic::getSupportedServiceNames( )
+ throw (RuntimeException)
+{
+ MutexGuard aGuard( GetLinguMutex() );
+ return getSupportedServiceNames_Static();
+}
+
+
+uno::Sequence< OUString > ConvDic::getSupportedServiceNames_Static()
+ throw()
+{
+ uno::Sequence< OUString > aSNS( 1 );
+ aSNS.getArray()[0] = A2OU( SN_CONV_DICTIONARY );
+ return aSNS;
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+