merge the formfield patch from ooo-build
[ooovba.git] / linguistic / source / convdic.cxx
blob8a544d045087c5a6d6f4c2426f7465ee749e52ec
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: convdic.cxx,v $
10 * $Revision: 1.13 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_linguistic.hxx"
33 #include <i18npool/lang.h>
34 #include <tools/urlobj.hxx>
35 #include <tools/debug.hxx>
36 #include <tools/fsys.hxx>
37 #include <tools/stream.hxx>
38 #include <tools/string.hxx>
39 #include <tools/stream.hxx>
40 #include <sfx2/docfile.hxx>
41 #include <osl/mutex.hxx>
42 #include <unotools/processfactory.hxx>
43 #include <ucbhelper/content.hxx>
45 #include <cppuhelper/factory.hxx> // helper for factories
46 #include <com/sun/star/linguistic2/XConversionDictionary.hpp>
47 #include <com/sun/star/linguistic2/ConversionDictionaryType.hpp>
48 #include <com/sun/star/linguistic2/XConversionPropertyType.hpp>
49 #include <com/sun/star/linguistic2/ConversionPropertyType.hpp>
50 #include <com/sun/star/util/XFlushable.hpp>
51 #include <com/sun/star/lang/Locale.hpp>
52 #include <com/sun/star/lang/EventObject.hpp>
53 #ifndef _COM_SUN_STAR_UNO_REFERENCE_HPP_
54 #include <com/sun/star/uno/Reference.h>
55 #endif
56 #include <com/sun/star/registry/XRegistryKey.hpp>
57 #include <com/sun/star/util/XFlushListener.hpp>
58 #include <com/sun/star/io/XActiveDataSource.hpp>
59 #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
60 #include <com/sun/star/document/XFilter.hpp>
61 #include <com/sun/star/beans/PropertyValue.hpp>
62 #include <com/sun/star/xml/sax/InputSource.hpp>
63 #include <com/sun/star/xml/sax/XParser.hpp>
64 #include <unotools/streamwrap.hxx>
67 #include "convdic.hxx"
68 #include "convdicxml.hxx"
69 #include "misc.hxx"
70 #include "defs.hxx"
72 using namespace std;
73 using namespace utl;
74 using namespace osl;
75 using namespace rtl;
76 using namespace com::sun::star;
77 using namespace com::sun::star::lang;
78 using namespace com::sun::star::uno;
79 using namespace com::sun::star::linguistic2;
80 using namespace linguistic;
82 #define SN_CONV_DICTIONARY "com.sun.star.linguistic2.ConversionDictionary"
83 #define SN_HCD_CONV_DICTIONARY "com.sun.star.linguistic2.HangulHanjaConversionDictionary"
86 ///////////////////////////////////////////////////////////////////////////
88 void ReadThroughDic( const String &rMainURL, ConvDicXMLImport &rImport )
90 if (rMainURL.Len() == 0)
91 return;
93 // get stream to be used
94 DBG_ASSERT(!INetURLObject( rMainURL ).HasError(), "invalid URL");
95 SfxMedium aMedium( rMainURL, STREAM_READ | STREAM_SHARE_DENYWRITE, FALSE );
96 SvStream *pStream = aMedium.GetInStream();
97 DBG_ASSERT( pStream, "input stream missing" );
98 if (!pStream || pStream->GetError())
99 return;
101 uno::Reference< lang::XMultiServiceFactory > xServiceFactory(
102 utl::getProcessServiceFactory() );
103 DBG_ASSERT( xServiceFactory.is(), "XMLReader::Read: got no service manager" );
104 if (!xServiceFactory.is())
105 return;
107 uno::Reference< io::XInputStream > xIn = new utl::OInputStreamWrapper( *pStream );
108 DBG_ASSERT( xIn.is(), "input stream missing" );
110 ULONG nError = sal::static_int_cast< ULONG >(-1);
112 // prepare ParserInputSource
113 xml::sax::InputSource aParserInput;
114 aParserInput.aInputStream = xIn;
116 // get parser
117 uno::Reference< xml::sax::XParser > xParser;
120 xParser = uno::Reference< xml::sax::XParser >( xServiceFactory->createInstance(
121 A2OU( "com.sun.star.xml.sax.Parser" ) ), UNO_QUERY );
123 catch (uno::Exception &)
126 DBG_ASSERT( xParser.is(), "Can't create parser" );
127 if (!xParser.is())
128 return;
130 // get filter
131 //ConvDicXMLImport *pImport = new ConvDicXMLImport( this, rMainURL );
132 //!! keep a reference until everything is done to
133 //!! ensure the proper lifetime of the object
134 uno::Reference < xml::sax::XDocumentHandler > xFilter(
135 (xml::sax::XExtendedDocumentHandler *) &rImport, UNO_QUERY );
137 // connect parser and filter
138 xParser->setDocumentHandler( xFilter );
140 // finally, parser the stream
143 xParser->parseStream( aParserInput ); // implicitly calls ConvDicXMLImport::CreateContext
144 if (rImport.GetSuccess())
145 nError = 0;
147 catch( xml::sax::SAXParseException& )
149 // if( bEncrypted )
150 // nError = ERRCODE_SFX_WRONGPASSWORD;
152 catch( xml::sax::SAXException& )
154 // if( bEncrypted )
155 // nError = ERRCODE_SFX_WRONGPASSWORD;
157 catch( io::IOException& )
163 BOOL IsConvDic( const String &rFileURL, INT16 &nLang, sal_Int16 &nConvType )
165 BOOL bRes = FALSE;
167 if (rFileURL.Len() == 0)
168 return bRes;
170 // check if file extension matches CONV_DIC_EXT
171 String aExt;
172 xub_StrLen nPos = rFileURL.SearchBackward( '.' );
173 if (STRING_NOTFOUND != nPos)
174 aExt = rFileURL.Copy( nPos + 1 );
175 aExt.ToLowerAscii();
176 if (!aExt.EqualsAscii( CONV_DIC_EXT ))
177 return bRes;
179 // first argument being 0 should stop the file from being parsed
180 // up to the end (reading all entries) when the required
181 // data (language, conversion type) is found.
182 ConvDicXMLImport *pImport = new ConvDicXMLImport( 0, rFileURL );
184 //!! keep a first reference to ensure the lifetime of the object !!
185 uno::Reference< XInterface > xRef( (document::XFilter *) pImport, UNO_QUERY );
187 ReadThroughDic( rFileURL, *pImport ); // will implicitly add the entries
188 bRes = pImport->GetLanguage() != LANGUAGE_NONE &&
189 pImport->GetConversionType() != -1;
190 DBG_ASSERT( bRes, "conversion dictionary corrupted?" );
192 if (bRes)
194 nLang = pImport->GetLanguage();
195 nConvType = pImport->GetConversionType();
198 return bRes;
202 ///////////////////////////////////////////////////////////////////////////
204 ConvDic::ConvDic(
205 const String &rName,
206 INT16 nLang,
207 sal_Int16 nConvType,
208 BOOL bBiDirectional,
209 const String &rMainURL) :
210 aFlushListeners( GetLinguMutex() )
212 aName = rName;
213 nLanguage = nLang;
214 nConversionType = nConvType;
215 aMainURL = rMainURL;
217 if (bBiDirectional)
218 pFromRight = std::auto_ptr< ConvMap >( new ConvMap );
219 if (nLang == LANGUAGE_CHINESE_SIMPLIFIED || nLang == LANGUAGE_CHINESE_TRADITIONAL)
220 pConvPropType = std::auto_ptr< PropTypeMap >( new PropTypeMap );
222 nMaxLeftCharCount = nMaxRightCharCount = 0;
223 bMaxCharCountIsValid = TRUE;
225 bNeedEntries = TRUE;
226 bIsModified = bIsActive = FALSE;
227 bIsReadonly = FALSE;
229 if( rMainURL.Len() > 0 )
231 BOOL bExists = FALSE;
232 bIsReadonly = IsReadOnly( rMainURL, &bExists );
234 if( !bExists ) // new empty dictionary
236 bNeedEntries = FALSE;
237 //! create physical representation of an **empty** dictionary
238 //! that could be found by the dictionary-list implementation
239 // (Note: empty dictionaries are not just empty files!)
240 Save();
241 bIsReadonly = IsReadOnly( rMainURL ); // will be FALSE if Save was succesfull
244 else
246 bNeedEntries = FALSE;
251 ConvDic::~ConvDic()
256 void ConvDic::Load()
258 DBG_ASSERT( !bIsModified, "dictionary is modified. Really do 'Load'?" );
260 //!! prevent function from being called recursively via HasEntry, AddEntry
261 bNeedEntries = FALSE;
263 ConvDicXMLImport *pImport = new ConvDicXMLImport( this, aMainURL );
264 //!! keep a first reference to ensure the lifetime of the object !!
265 uno::Reference< XInterface > xRef( (document::XFilter *) pImport, UNO_QUERY );
266 ReadThroughDic( aMainURL, *pImport ); // will implicitly add the entries
268 bIsModified = FALSE;
272 void ConvDic::Save()
274 DBG_ASSERT( !bNeedEntries, "saving while entries missing" );
275 if (aMainURL.Len() == 0 || bNeedEntries)
276 return;
278 DBG_ASSERT(!INetURLObject( aMainURL ).HasError(), "invalid URL");
279 SfxMedium aMedium( aMainURL, STREAM_WRITE | STREAM_TRUNC | STREAM_SHARE_DENYALL,
280 FALSE );
281 aMedium.CreateTempFile(); // use temp file to write to...
283 SvStream *pStream = aMedium.GetOutStream();
284 DBG_ASSERT( pStream, "output stream missing" );
285 if (!pStream || pStream->GetError())
286 return;
287 uno::Reference< io::XOutputStream > xOut(
288 new utl::OOutputStreamWrapper( *pStream ) );
289 DBG_ASSERT( xOut.is(), "output stream missing" );
291 // get XML writer
292 uno::Reference< lang::XMultiServiceFactory > xServiceFactory(
293 utl::getProcessServiceFactory() );
294 uno::Reference< io::XActiveDataSource > xSaxWriter;
295 if (xServiceFactory.is())
299 xSaxWriter = uno::Reference< io::XActiveDataSource >(
300 xServiceFactory->createInstance(
301 OUString::createFromAscii( "com.sun.star.xml.sax.Writer" ) ), UNO_QUERY );
303 catch (uno::Exception &)
307 DBG_ASSERT( xSaxWriter.is(), "can't instantiate XML writer" );
309 if (xSaxWriter.is() && xOut.is())
311 // connect XML writer to output stream
312 xSaxWriter->setOutputStream( xOut );
314 // prepare arguments (prepend doc handler to given arguments)
315 uno::Reference< xml::sax::XDocumentHandler > xDocHandler( xSaxWriter, UNO_QUERY );
317 ConvDicXMLExport *pExport = new ConvDicXMLExport( *this, aMainURL, xDocHandler );
318 //!! keep a first(!) reference until everything is done to
319 //!! ensure the proper lifetime of the object
320 uno::Reference< document::XFilter > aRef( (document::XFilter *) pExport );
321 sal_Bool bRet = pExport->Export( aMedium ); // write entries to file
322 DBG_ASSERT( !pStream->GetError(), "I/O error while writing to stream" );
323 if (bRet)
325 // flush file, close it and release any lock
326 aMedium.Close();
327 aMedium.Commit();
328 bIsModified = FALSE;
331 DBG_ASSERT( !bIsModified, "dictionary still modified after save. Save failed?" );
335 ConvMap::iterator ConvDic::GetEntry( ConvMap &rMap, const rtl::OUString &rFirstText, const rtl::OUString &rSecondText )
337 pair< ConvMap::iterator, ConvMap::iterator > aRange =
338 rMap.equal_range( rFirstText );
339 ConvMap::iterator aPos = rMap.end();
340 for (ConvMap::iterator aIt = aRange.first;
341 aIt != aRange.second && aPos == rMap.end();
342 ++aIt)
344 if ((*aIt).second == rSecondText)
345 aPos = aIt;
347 return aPos;
351 BOOL ConvDic::HasEntry( const OUString &rLeftText, const OUString &rRightText )
353 if (bNeedEntries)
354 Load();
355 ConvMap::iterator aIt = GetEntry( aFromLeft, rLeftText, rRightText );
356 return aIt != aFromLeft.end();
360 void ConvDic::AddEntry( const OUString &rLeftText, const OUString &rRightText )
362 if (bNeedEntries)
363 Load();
365 DBG_ASSERT(!HasEntry( rLeftText, rRightText), "entry already exists" );
366 aFromLeft .insert( ConvMap::value_type( rLeftText, rRightText ) );
367 if (pFromRight.get())
368 pFromRight->insert( ConvMap::value_type( rRightText, rLeftText ) );
370 if (bMaxCharCountIsValid)
372 if (rLeftText.getLength() > nMaxLeftCharCount)
373 nMaxLeftCharCount = (sal_Int16) rLeftText.getLength();
374 if (pFromRight.get() && rRightText.getLength() > nMaxRightCharCount)
375 nMaxRightCharCount = (sal_Int16) rRightText.getLength();
378 bIsModified = TRUE;
382 void ConvDic::RemoveEntry( const OUString &rLeftText, const OUString &rRightText )
384 if (bNeedEntries)
385 Load();
387 ConvMap::iterator aLeftIt = GetEntry( aFromLeft, rLeftText, rRightText );
388 DBG_ASSERT( aLeftIt != aFromLeft.end(), "left map entry missing" );
389 aFromLeft .erase( aLeftIt );
391 if (pFromRight.get())
393 ConvMap::iterator aRightIt = GetEntry( *pFromRight, rRightText, rLeftText );
394 DBG_ASSERT( aRightIt != pFromRight->end(), "right map entry missing" );
395 pFromRight->erase( aRightIt );
398 bIsModified = TRUE;
399 bMaxCharCountIsValid = FALSE;
403 OUString SAL_CALL ConvDic::getName( )
404 throw (RuntimeException)
406 MutexGuard aGuard( GetLinguMutex() );
407 return aName;
411 Locale SAL_CALL ConvDic::getLocale( )
412 throw (RuntimeException)
414 MutexGuard aGuard( GetLinguMutex() );
415 return CreateLocale( nLanguage );
419 sal_Int16 SAL_CALL ConvDic::getConversionType( )
420 throw (RuntimeException)
422 MutexGuard aGuard( GetLinguMutex() );
423 return nConversionType;
427 void SAL_CALL ConvDic::setActive( sal_Bool bActivate )
428 throw (RuntimeException)
430 MutexGuard aGuard( GetLinguMutex() );
431 bIsActive = bActivate;
435 sal_Bool SAL_CALL ConvDic::isActive( )
436 throw (RuntimeException)
438 MutexGuard aGuard( GetLinguMutex() );
439 return bIsActive;
443 void SAL_CALL ConvDic::clear( )
444 throw (RuntimeException)
446 MutexGuard aGuard( GetLinguMutex() );
447 aFromLeft .clear();
448 if (pFromRight.get())
449 pFromRight->clear();
450 bNeedEntries = FALSE;
451 bIsModified = TRUE;
452 nMaxLeftCharCount = 0;
453 nMaxRightCharCount = 0;
454 bMaxCharCountIsValid = TRUE;
458 uno::Sequence< OUString > SAL_CALL ConvDic::getConversions(
459 const OUString& aText,
460 sal_Int32 nStartPos,
461 sal_Int32 nLength,
462 ConversionDirection eDirection,
463 sal_Int32 /*nTextConversionOptions*/ )
464 throw (IllegalArgumentException, RuntimeException)
466 MutexGuard aGuard( GetLinguMutex() );
468 if (!pFromRight.get() && eDirection == ConversionDirection_FROM_RIGHT)
469 return uno::Sequence< OUString >();
471 if (bNeedEntries)
472 Load();
474 OUString aLookUpText( aText.copy(nStartPos, nLength) );
475 ConvMap &rConvMap = eDirection == ConversionDirection_FROM_LEFT ?
476 aFromLeft : *pFromRight;
477 pair< ConvMap::iterator, ConvMap::iterator > aRange =
478 rConvMap.equal_range( aLookUpText );
480 INT32 nCount = 0;
481 ConvMap::iterator aIt;
482 for (aIt = aRange.first; aIt != aRange.second; ++aIt)
483 ++nCount;
485 uno::Sequence< OUString > aRes( nCount );
486 OUString *pRes = aRes.getArray();
487 INT32 i = 0;
488 for (aIt = aRange.first; aIt != aRange.second; ++aIt)
489 pRes[i++] = (*aIt).second;
491 return aRes;
495 static BOOL lcl_SeqHasEntry(
496 const OUString *pSeqStart, // first element to check
497 INT32 nToCheck, // number of elements to check
498 const OUString &rText)
500 BOOL bRes = FALSE;
501 if (pSeqStart && nToCheck > 0)
503 const OUString *pDone = pSeqStart + nToCheck; // one behind last to check
504 while (!bRes && pSeqStart != pDone)
506 if (*pSeqStart++ == rText)
507 bRes = TRUE;
510 return bRes;
513 uno::Sequence< OUString > SAL_CALL ConvDic::getConversionEntries(
514 ConversionDirection eDirection )
515 throw (RuntimeException)
517 MutexGuard aGuard( GetLinguMutex() );
519 if (!pFromRight.get() && eDirection == ConversionDirection_FROM_RIGHT)
520 return uno::Sequence< OUString >();
522 if (bNeedEntries)
523 Load();
525 ConvMap &rConvMap = eDirection == ConversionDirection_FROM_LEFT ?
526 aFromLeft : *pFromRight;
527 uno::Sequence< OUString > aRes( rConvMap.size() );
528 OUString *pRes = aRes.getArray();
529 ConvMap::iterator aIt = rConvMap.begin();
530 INT32 nIdx = 0;
531 while (aIt != rConvMap.end())
533 OUString aCurEntry( (*aIt).first );
534 // skip duplicate entries ( duplicate = duplicate entries
535 // respective to the evaluated side (FROM_LEFT or FROM_RIGHT).
536 // Thus if FROM_LEFT is evaluated for pairs (A,B) and (A,C)
537 // only one entry for A will be returned in the result)
538 if (nIdx == 0 || !lcl_SeqHasEntry( pRes, nIdx, aCurEntry ))
539 pRes[ nIdx++ ] = aCurEntry;
540 ++aIt;
542 aRes.realloc( nIdx );
544 return aRes;
548 void SAL_CALL ConvDic::addEntry(
549 const OUString& aLeftText,
550 const OUString& aRightText )
551 throw (IllegalArgumentException, container::ElementExistException, RuntimeException)
553 MutexGuard aGuard( GetLinguMutex() );
554 if (bNeedEntries)
555 Load();
556 if (HasEntry( aLeftText, aRightText ))
557 throw container::ElementExistException();
558 AddEntry( aLeftText, aRightText );
562 void SAL_CALL ConvDic::removeEntry(
563 const OUString& aLeftText,
564 const OUString& aRightText )
565 throw (container::NoSuchElementException, RuntimeException)
567 MutexGuard aGuard( GetLinguMutex() );
568 if (bNeedEntries)
569 Load();
570 if (!HasEntry( aLeftText, aRightText ))
571 throw container::NoSuchElementException();
572 RemoveEntry( aLeftText, aRightText );
576 sal_Int16 SAL_CALL ConvDic::getMaxCharCount( ConversionDirection eDirection )
577 throw (RuntimeException)
579 MutexGuard aGuard( GetLinguMutex() );
581 if (!pFromRight.get() && eDirection == ConversionDirection_FROM_RIGHT)
583 DBG_ASSERT( nMaxRightCharCount == 0, "max right char count should be 0" );
584 return 0;
587 if (bNeedEntries)
588 Load();
590 if (!bMaxCharCountIsValid)
592 nMaxLeftCharCount = 0;
593 ConvMap::iterator aIt = aFromLeft.begin();
594 while (aIt != aFromLeft.end())
596 sal_Int16 nTmp = (sal_Int16) (*aIt).first.getLength();
597 if (nTmp > nMaxLeftCharCount)
598 nMaxLeftCharCount = nTmp;
599 ++aIt;
602 nMaxRightCharCount = 0;
603 if (pFromRight.get())
605 aIt = pFromRight->begin();
606 while (aIt != pFromRight->end())
608 sal_Int16 nTmp = (sal_Int16) (*aIt).first.getLength();
609 if (nTmp > nMaxRightCharCount)
610 nMaxRightCharCount = nTmp;
611 ++aIt;
615 bMaxCharCountIsValid = TRUE;
617 sal_Int16 nRes = eDirection == ConversionDirection_FROM_LEFT ?
618 nMaxLeftCharCount : nMaxRightCharCount;
619 DBG_ASSERT( nRes >= 0, "invalid MaxCharCount" );
620 return nRes;
624 void SAL_CALL ConvDic::setPropertyType(
625 const OUString& rLeftText,
626 const OUString& rRightText,
627 sal_Int16 nPropertyType )
628 throw (container::NoSuchElementException, IllegalArgumentException, RuntimeException)
630 sal_Bool bHasElement = HasEntry( rLeftText, rRightText);
631 if (!bHasElement)
632 throw container::NoSuchElementException();
634 // currently we assume that entries with the same left text have the
635 // same PropertyType even if the right text is different...
636 if (pConvPropType.get())
637 pConvPropType->insert( PropTypeMap::value_type( rLeftText, nPropertyType ) );
638 bIsModified = sal_True;
642 sal_Int16 SAL_CALL ConvDic::getPropertyType(
643 const OUString& rLeftText,
644 const OUString& rRightText )
645 throw (container::NoSuchElementException, RuntimeException)
647 sal_Bool bHasElement = HasEntry( rLeftText, rRightText);
648 if (!bHasElement)
649 throw container::NoSuchElementException();
651 sal_Int16 nRes = ConversionPropertyType::NOT_DEFINED;
652 if (pConvPropType.get())
654 // still assuming that entries with same left text have same PropertyType
655 // even if they have different right text...
656 PropTypeMap::iterator aIt = pConvPropType->find( rLeftText );
657 if (aIt != pConvPropType->end())
658 nRes = (*aIt).second;
660 return nRes;
664 void SAL_CALL ConvDic::flush( )
665 throw (RuntimeException)
667 MutexGuard aGuard( GetLinguMutex() );
669 if (!bIsModified)
670 return;
672 Save();
674 // notify listeners
675 EventObject aEvtObj;
676 aEvtObj.Source = uno::Reference< XFlushable >( this );
677 cppu::OInterfaceIteratorHelper aIt( aFlushListeners );
678 while (aIt.hasMoreElements())
680 uno::Reference< util::XFlushListener > xRef( aIt.next(), UNO_QUERY );
681 if (xRef.is())
682 xRef->flushed( aEvtObj );
687 void SAL_CALL ConvDic::addFlushListener(
688 const uno::Reference< util::XFlushListener >& rxListener )
689 throw (RuntimeException)
691 MutexGuard aGuard( GetLinguMutex() );
692 if (rxListener.is())
693 aFlushListeners.addInterface( rxListener );
697 void SAL_CALL ConvDic::removeFlushListener(
698 const uno::Reference< util::XFlushListener >& rxListener )
699 throw (RuntimeException)
701 MutexGuard aGuard( GetLinguMutex() );
702 if (rxListener.is())
703 aFlushListeners.removeInterface( rxListener );
707 OUString SAL_CALL ConvDic::getImplementationName( )
708 throw (RuntimeException)
710 MutexGuard aGuard( GetLinguMutex() );
711 return getImplementationName_Static();
715 sal_Bool SAL_CALL ConvDic::supportsService( const OUString& rServiceName )
716 throw (RuntimeException)
718 MutexGuard aGuard( GetLinguMutex() );
719 sal_Bool bRes = sal_False;
720 if (rServiceName.equalsAscii( SN_CONV_DICTIONARY ))
721 bRes = sal_True;
722 return bRes;
726 uno::Sequence< OUString > SAL_CALL ConvDic::getSupportedServiceNames( )
727 throw (RuntimeException)
729 MutexGuard aGuard( GetLinguMutex() );
730 return getSupportedServiceNames_Static();
734 uno::Sequence< OUString > ConvDic::getSupportedServiceNames_Static()
735 throw()
737 uno::Sequence< OUString > aSNS( 1 );
738 aSNS.getArray()[0] = A2OU( SN_CONV_DICTIONARY );
739 return aSNS;
742 ///////////////////////////////////////////////////////////////////////////