Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 :
21 : #include <cppuhelper/factory.hxx>
22 : #include <i18nlangtag/lang.h>
23 : #include <osl/mutex.hxx>
24 : #include <tools/debug.hxx>
25 : #include <tools/stream.hxx>
26 : #include <tools/urlobj.hxx>
27 : #include <ucbhelper/content.hxx>
28 : #include <comphelper/processfactory.hxx>
29 : #include <cppuhelper/supportsservice.hxx>
30 : #include <unotools/streamwrap.hxx>
31 : #include <unotools/ucbstreamhelper.hxx>
32 :
33 : #include <com/sun/star/linguistic2/XConversionDictionary.hpp>
34 : #include <com/sun/star/linguistic2/ConversionDictionaryType.hpp>
35 : #include <com/sun/star/linguistic2/XConversionPropertyType.hpp>
36 : #include <com/sun/star/linguistic2/ConversionPropertyType.hpp>
37 : #include <com/sun/star/util/XFlushable.hpp>
38 : #include <com/sun/star/lang/Locale.hpp>
39 : #include <com/sun/star/lang/EventObject.hpp>
40 : #include <com/sun/star/ucb/SimpleFileAccess.hpp>
41 : #include <com/sun/star/uno/Reference.h>
42 : #include <com/sun/star/registry/XRegistryKey.hpp>
43 : #include <com/sun/star/util/XFlushListener.hpp>
44 : #include <com/sun/star/io/XActiveDataSource.hpp>
45 : #include <com/sun/star/io/XInputStream.hpp>
46 : #include <com/sun/star/io/XOutputStream.hpp>
47 : #include <com/sun/star/xml/sax/Writer.hpp>
48 : #include <com/sun/star/document/XFilter.hpp>
49 : #include <com/sun/star/beans/PropertyValue.hpp>
50 : #include <com/sun/star/xml/sax/InputSource.hpp>
51 : #include <com/sun/star/xml/sax/Parser.hpp>
52 :
53 :
54 : #include "convdic.hxx"
55 : #include "convdicxml.hxx"
56 : #include "linguistic/misc.hxx"
57 : #include "defs.hxx"
58 :
59 : using namespace std;
60 : using namespace utl;
61 : using namespace osl;
62 : using namespace com::sun::star;
63 : using namespace com::sun::star::lang;
64 : using namespace com::sun::star::uno;
65 : using namespace com::sun::star::linguistic2;
66 : using namespace linguistic;
67 :
68 :
69 : #define SN_CONV_DICTIONARY "com.sun.star.linguistic2.ConversionDictionary"
70 :
71 0 : void ReadThroughDic( const OUString &rMainURL, ConvDicXMLImport &rImport )
72 : {
73 0 : if (rMainURL.isEmpty())
74 0 : return;
75 : DBG_ASSERT(!INetURLObject( rMainURL ).HasError(), "invalid URL");
76 :
77 0 : uno::Reference< uno::XComponentContext > xContext( comphelper::getProcessComponentContext() );
78 :
79 : // get xInputStream stream
80 0 : uno::Reference< io::XInputStream > xIn;
81 : try
82 : {
83 0 : uno::Reference< ucb::XSimpleFileAccess3 > xAccess( ucb::SimpleFileAccess::create(xContext) );
84 0 : xIn = xAccess->openFileRead( rMainURL );
85 : }
86 0 : catch (const uno::Exception &)
87 : {
88 : DBG_ASSERT( false, "failed to get input stream" );
89 : }
90 0 : if (!xIn.is())
91 0 : return;
92 :
93 0 : SvStreamPtr pStream = SvStreamPtr( utl::UcbStreamHelper::CreateStream( xIn ) );
94 :
95 : // prepare ParserInputSource
96 0 : xml::sax::InputSource aParserInput;
97 0 : aParserInput.aInputStream = xIn;
98 :
99 : // get parser
100 0 : uno::Reference< xml::sax::XParser > xParser = xml::sax::Parser::create( xContext );
101 :
102 : //!! keep a reference until everything is done to
103 : //!! ensure the proper lifetime of the object
104 : uno::Reference < xml::sax::XDocumentHandler > xFilter(
105 0 : static_cast<xml::sax::XExtendedDocumentHandler *>(&rImport), UNO_QUERY );
106 :
107 : // connect parser and filter
108 0 : xParser->setDocumentHandler( xFilter );
109 :
110 : // finally, parser the stream
111 : try
112 : {
113 0 : xParser->parseStream( aParserInput ); // implicitly calls ConvDicXMLImport::CreateContext
114 : }
115 0 : catch( xml::sax::SAXParseException& )
116 : {
117 : }
118 0 : catch( xml::sax::SAXException& )
119 : {
120 : }
121 0 : catch( io::IOException& )
122 : {
123 0 : }
124 : }
125 :
126 0 : bool IsConvDic( const OUString &rFileURL, sal_Int16 &nLang, sal_Int16 &nConvType )
127 : {
128 0 : bool bRes = false;
129 :
130 0 : if (rFileURL.isEmpty())
131 0 : return bRes;
132 :
133 : // check if file extension matches CONV_DIC_EXT
134 0 : OUString aExt;
135 0 : sal_Int32 nPos = rFileURL.lastIndexOf( '.' );
136 0 : if (-1 != nPos)
137 0 : aExt = rFileURL.copy( nPos + 1 ).toAsciiLowerCase();
138 0 : if (aExt != CONV_DIC_EXT)
139 0 : return bRes;
140 :
141 : // first argument being 0 should stop the file from being parsed
142 : // up to the end (reading all entries) when the required
143 : // data (language, conversion type) is found.
144 0 : ConvDicXMLImport *pImport = new ConvDicXMLImport( 0 );
145 :
146 : //!! keep a first reference to ensure the lifetime of the object !!
147 0 : uno::Reference< XInterface > xRef( static_cast<document::XFilter *>(pImport), UNO_QUERY );
148 :
149 0 : ReadThroughDic( rFileURL, *pImport ); // will implicitly add the entries
150 0 : bRes = !LinguIsUnspecified( pImport->GetLanguage()) &&
151 0 : pImport->GetConversionType() != -1;
152 : DBG_ASSERT( bRes, "conversion dictionary corrupted?" );
153 :
154 0 : if (bRes)
155 : {
156 0 : nLang = pImport->GetLanguage();
157 0 : nConvType = pImport->GetConversionType();
158 : }
159 :
160 0 : return bRes;
161 : }
162 :
163 :
164 :
165 0 : ConvDic::ConvDic(
166 : const OUString &rName,
167 : sal_Int16 nLang,
168 : sal_Int16 nConvType,
169 : bool bBiDirectional,
170 : const OUString &rMainURL) :
171 0 : aFlushListeners( GetLinguMutex() )
172 : {
173 0 : aName = rName;
174 0 : nLanguage = nLang;
175 0 : nConversionType = nConvType;
176 0 : aMainURL = rMainURL;
177 :
178 0 : if (bBiDirectional)
179 0 : pFromRight.reset( new ConvMap );
180 0 : if (nLang == LANGUAGE_CHINESE_SIMPLIFIED || nLang == LANGUAGE_CHINESE_TRADITIONAL)
181 0 : pConvPropType.reset( new PropTypeMap );
182 :
183 0 : nMaxLeftCharCount = nMaxRightCharCount = 0;
184 0 : bMaxCharCountIsValid = true;
185 :
186 0 : bNeedEntries = true;
187 0 : bIsModified = bIsActive = false;
188 0 : bIsReadonly = false;
189 :
190 0 : if( !rMainURL.isEmpty() )
191 : {
192 0 : bool bExists = false;
193 0 : bIsReadonly = IsReadOnly( rMainURL, &bExists );
194 :
195 0 : if( !bExists ) // new empty dictionary
196 : {
197 0 : bNeedEntries = false;
198 : //! create physical representation of an **empty** dictionary
199 : //! that could be found by the dictionary-list implementation
200 : // (Note: empty dictionaries are not just empty files!)
201 0 : Save();
202 0 : bIsReadonly = IsReadOnly( rMainURL ); // will be sal_False if Save was successful
203 : }
204 : }
205 : else
206 : {
207 0 : bNeedEntries = false;
208 : }
209 0 : }
210 :
211 :
212 0 : ConvDic::~ConvDic()
213 : {
214 0 : }
215 :
216 :
217 0 : void ConvDic::Load()
218 : {
219 : DBG_ASSERT( !bIsModified, "dictionary is modified. Really do 'Load'?" );
220 :
221 : //!! prevent function from being called recursively via HasEntry, AddEntry
222 0 : bNeedEntries = false;
223 0 : ConvDicXMLImport *pImport = new ConvDicXMLImport( this );
224 : //!! keep a first reference to ensure the lifetime of the object !!
225 0 : uno::Reference< XInterface > xRef( static_cast<document::XFilter *>(pImport), UNO_QUERY );
226 0 : ReadThroughDic( aMainURL, *pImport ); // will implicitly add the entries
227 0 : bIsModified = false;
228 0 : }
229 :
230 :
231 0 : void ConvDic::Save()
232 : {
233 : DBG_ASSERT( !bNeedEntries, "saving while entries missing" );
234 0 : if (aMainURL.isEmpty() || bNeedEntries)
235 0 : return;
236 : DBG_ASSERT(!INetURLObject( aMainURL ).HasError(), "invalid URL");
237 :
238 0 : uno::Reference< uno::XComponentContext > xContext( comphelper::getProcessComponentContext() );
239 :
240 : // get XOutputStream stream
241 0 : uno::Reference< io::XStream > xStream;
242 : try
243 : {
244 0 : uno::Reference< ucb::XSimpleFileAccess3 > xAccess( ucb::SimpleFileAccess::create(xContext) );
245 0 : xStream = xAccess->openFileReadWrite( aMainURL );
246 : }
247 0 : catch (const uno::Exception &)
248 : {
249 : DBG_ASSERT( false, "failed to get input stream" );
250 : }
251 0 : if (!xStream.is())
252 0 : return;
253 :
254 0 : SvStreamPtr pStream = SvStreamPtr( utl::UcbStreamHelper::CreateStream( xStream ) );
255 :
256 : // get XML writer
257 0 : uno::Reference< xml::sax::XWriter > xSaxWriter = xml::sax::Writer::create(xContext);
258 :
259 0 : if (xStream.is())
260 : {
261 : // connect XML writer to output stream
262 0 : xSaxWriter->setOutputStream( xStream->getOutputStream() );
263 :
264 : // prepare arguments (prepend doc handler to given arguments)
265 0 : uno::Reference< xml::sax::XDocumentHandler > xDocHandler( xSaxWriter, UNO_QUERY );
266 0 : ConvDicXMLExport *pExport = new ConvDicXMLExport( *this, aMainURL, xDocHandler );
267 : //!! keep a first(!) reference until everything is done to
268 : //!! ensure the proper lifetime of the object
269 0 : uno::Reference< document::XFilter > aRef( static_cast<document::XFilter *>(pExport) );
270 0 : bool bRet = pExport->Export(); // write entries to file
271 : DBG_ASSERT( !pStream->GetError(), "I/O error while writing to stream" );
272 0 : if (bRet)
273 0 : bIsModified = false;
274 : }
275 0 : DBG_ASSERT( !bIsModified, "dictionary still modified after save. Save failed?" );
276 : }
277 :
278 :
279 0 : ConvMap::iterator ConvDic::GetEntry( ConvMap &rMap, const OUString &rFirstText, const OUString &rSecondText )
280 : {
281 : pair< ConvMap::iterator, ConvMap::iterator > aRange =
282 0 : rMap.equal_range( rFirstText );
283 0 : ConvMap::iterator aPos = rMap.end();
284 0 : for (ConvMap::iterator aIt = aRange.first;
285 0 : aIt != aRange.second && aPos == rMap.end();
286 : ++aIt)
287 : {
288 0 : if ((*aIt).second == rSecondText)
289 0 : aPos = aIt;
290 : }
291 0 : return aPos;
292 : }
293 :
294 :
295 0 : bool ConvDic::HasEntry( const OUString &rLeftText, const OUString &rRightText )
296 : {
297 0 : if (bNeedEntries)
298 0 : Load();
299 0 : ConvMap::iterator aIt = GetEntry( aFromLeft, rLeftText, rRightText );
300 0 : return aIt != aFromLeft.end();
301 : }
302 :
303 :
304 0 : void ConvDic::AddEntry( const OUString &rLeftText, const OUString &rRightText )
305 : {
306 0 : if (bNeedEntries)
307 0 : Load();
308 :
309 : DBG_ASSERT(!HasEntry( rLeftText, rRightText), "entry already exists" );
310 0 : aFromLeft .insert( ConvMap::value_type( rLeftText, rRightText ) );
311 0 : if (pFromRight.get())
312 0 : pFromRight->insert( ConvMap::value_type( rRightText, rLeftText ) );
313 :
314 0 : if (bMaxCharCountIsValid)
315 : {
316 0 : if (rLeftText.getLength() > nMaxLeftCharCount)
317 0 : nMaxLeftCharCount = (sal_Int16) rLeftText.getLength();
318 0 : if (pFromRight.get() && rRightText.getLength() > nMaxRightCharCount)
319 0 : nMaxRightCharCount = (sal_Int16) rRightText.getLength();
320 : }
321 :
322 0 : bIsModified = true;
323 0 : }
324 :
325 :
326 0 : void ConvDic::RemoveEntry( const OUString &rLeftText, const OUString &rRightText )
327 : {
328 0 : if (bNeedEntries)
329 0 : Load();
330 :
331 0 : ConvMap::iterator aLeftIt = GetEntry( aFromLeft, rLeftText, rRightText );
332 : DBG_ASSERT( aLeftIt != aFromLeft.end(), "left map entry missing" );
333 0 : aFromLeft .erase( aLeftIt );
334 :
335 0 : if (pFromRight.get())
336 : {
337 0 : ConvMap::iterator aRightIt = GetEntry( *pFromRight, rRightText, rLeftText );
338 : DBG_ASSERT( aRightIt != pFromRight->end(), "right map entry missing" );
339 0 : pFromRight->erase( aRightIt );
340 : }
341 :
342 0 : bIsModified = true;
343 0 : bMaxCharCountIsValid = false;
344 0 : }
345 :
346 :
347 0 : OUString SAL_CALL ConvDic::getName( )
348 : throw (RuntimeException, std::exception)
349 : {
350 0 : MutexGuard aGuard( GetLinguMutex() );
351 0 : return aName;
352 : }
353 :
354 :
355 0 : Locale SAL_CALL ConvDic::getLocale( )
356 : throw (RuntimeException, std::exception)
357 : {
358 0 : MutexGuard aGuard( GetLinguMutex() );
359 0 : return LanguageTag::convertToLocale( nLanguage );
360 : }
361 :
362 :
363 0 : sal_Int16 SAL_CALL ConvDic::getConversionType( )
364 : throw (RuntimeException, std::exception)
365 : {
366 0 : MutexGuard aGuard( GetLinguMutex() );
367 0 : return nConversionType;
368 : }
369 :
370 :
371 0 : void SAL_CALL ConvDic::setActive( sal_Bool bActivate )
372 : throw (RuntimeException, std::exception)
373 : {
374 0 : MutexGuard aGuard( GetLinguMutex() );
375 0 : bIsActive = bActivate;
376 0 : }
377 :
378 :
379 0 : sal_Bool SAL_CALL ConvDic::isActive( )
380 : throw (RuntimeException, std::exception)
381 : {
382 0 : MutexGuard aGuard( GetLinguMutex() );
383 0 : return bIsActive;
384 : }
385 :
386 :
387 0 : void SAL_CALL ConvDic::clear( )
388 : throw (RuntimeException, std::exception)
389 : {
390 0 : MutexGuard aGuard( GetLinguMutex() );
391 0 : aFromLeft .clear();
392 0 : if (pFromRight.get())
393 0 : pFromRight->clear();
394 0 : bNeedEntries = false;
395 0 : bIsModified = true;
396 0 : nMaxLeftCharCount = 0;
397 0 : nMaxRightCharCount = 0;
398 0 : bMaxCharCountIsValid = true;
399 0 : }
400 :
401 :
402 0 : uno::Sequence< OUString > SAL_CALL ConvDic::getConversions(
403 : const OUString& aText,
404 : sal_Int32 nStartPos,
405 : sal_Int32 nLength,
406 : ConversionDirection eDirection,
407 : sal_Int32 /*nTextConversionOptions*/ )
408 : throw (IllegalArgumentException, RuntimeException, std::exception)
409 : {
410 0 : MutexGuard aGuard( GetLinguMutex() );
411 :
412 0 : if (!pFromRight.get() && eDirection == ConversionDirection_FROM_RIGHT)
413 0 : return uno::Sequence< OUString >();
414 :
415 0 : if (bNeedEntries)
416 0 : Load();
417 :
418 0 : OUString aLookUpText( aText.copy(nStartPos, nLength) );
419 : ConvMap &rConvMap = eDirection == ConversionDirection_FROM_LEFT ?
420 0 : aFromLeft : *pFromRight;
421 : pair< ConvMap::iterator, ConvMap::iterator > aRange =
422 0 : rConvMap.equal_range( aLookUpText );
423 :
424 0 : sal_Int32 nCount = 0;
425 0 : ConvMap::iterator aIt;
426 0 : for (aIt = aRange.first; aIt != aRange.second; ++aIt)
427 0 : ++nCount;
428 :
429 0 : uno::Sequence< OUString > aRes( nCount );
430 0 : OUString *pRes = aRes.getArray();
431 0 : sal_Int32 i = 0;
432 0 : for (aIt = aRange.first; aIt != aRange.second; ++aIt)
433 0 : pRes[i++] = (*aIt).second;
434 :
435 0 : return aRes;
436 : }
437 :
438 :
439 0 : static bool lcl_SeqHasEntry(
440 : const OUString *pSeqStart, // first element to check
441 : sal_Int32 nToCheck, // number of elements to check
442 : const OUString &rText)
443 : {
444 0 : bool bRes = false;
445 0 : if (pSeqStart && nToCheck > 0)
446 : {
447 0 : const OUString *pDone = pSeqStart + nToCheck; // one behind last to check
448 0 : while (!bRes && pSeqStart != pDone)
449 : {
450 0 : if (*pSeqStart++ == rText)
451 0 : bRes = true;
452 : }
453 : }
454 0 : return bRes;
455 : }
456 :
457 0 : uno::Sequence< OUString > SAL_CALL ConvDic::getConversionEntries(
458 : ConversionDirection eDirection )
459 : throw (RuntimeException, std::exception)
460 : {
461 0 : MutexGuard aGuard( GetLinguMutex() );
462 :
463 0 : if (!pFromRight.get() && eDirection == ConversionDirection_FROM_RIGHT)
464 0 : return uno::Sequence< OUString >();
465 :
466 0 : if (bNeedEntries)
467 0 : Load();
468 :
469 : ConvMap &rConvMap = eDirection == ConversionDirection_FROM_LEFT ?
470 0 : aFromLeft : *pFromRight;
471 0 : uno::Sequence< OUString > aRes( rConvMap.size() );
472 0 : OUString *pRes = aRes.getArray();
473 0 : ConvMap::iterator aIt = rConvMap.begin();
474 0 : sal_Int32 nIdx = 0;
475 0 : while (aIt != rConvMap.end())
476 : {
477 0 : OUString aCurEntry( (*aIt).first );
478 : // skip duplicate entries ( duplicate = duplicate entries
479 : // respective to the evaluated side (FROM_LEFT or FROM_RIGHT).
480 : // Thus if FROM_LEFT is evaluated for pairs (A,B) and (A,C)
481 : // only one entry for A will be returned in the result)
482 0 : if (nIdx == 0 || !lcl_SeqHasEntry( pRes, nIdx, aCurEntry ))
483 0 : pRes[ nIdx++ ] = aCurEntry;
484 0 : ++aIt;
485 0 : }
486 0 : aRes.realloc( nIdx );
487 :
488 0 : return aRes;
489 : }
490 :
491 :
492 0 : void SAL_CALL ConvDic::addEntry(
493 : const OUString& aLeftText,
494 : const OUString& aRightText )
495 : throw (IllegalArgumentException, container::ElementExistException, RuntimeException, std::exception)
496 : {
497 0 : MutexGuard aGuard( GetLinguMutex() );
498 0 : if (bNeedEntries)
499 0 : Load();
500 0 : if (HasEntry( aLeftText, aRightText ))
501 0 : throw container::ElementExistException();
502 0 : AddEntry( aLeftText, aRightText );
503 0 : }
504 :
505 :
506 0 : void SAL_CALL ConvDic::removeEntry(
507 : const OUString& aLeftText,
508 : const OUString& aRightText )
509 : throw (container::NoSuchElementException, RuntimeException, std::exception)
510 : {
511 0 : MutexGuard aGuard( GetLinguMutex() );
512 0 : if (bNeedEntries)
513 0 : Load();
514 0 : if (!HasEntry( aLeftText, aRightText ))
515 0 : throw container::NoSuchElementException();
516 0 : RemoveEntry( aLeftText, aRightText );
517 0 : }
518 :
519 :
520 0 : sal_Int16 SAL_CALL ConvDic::getMaxCharCount( ConversionDirection eDirection )
521 : throw (RuntimeException, std::exception)
522 : {
523 0 : MutexGuard aGuard( GetLinguMutex() );
524 :
525 0 : if (!pFromRight.get() && eDirection == ConversionDirection_FROM_RIGHT)
526 : {
527 : DBG_ASSERT( nMaxRightCharCount == 0, "max right char count should be 0" );
528 0 : return 0;
529 : }
530 :
531 0 : if (bNeedEntries)
532 0 : Load();
533 :
534 0 : if (!bMaxCharCountIsValid)
535 : {
536 0 : nMaxLeftCharCount = 0;
537 0 : ConvMap::iterator aIt = aFromLeft.begin();
538 0 : while (aIt != aFromLeft.end())
539 : {
540 0 : sal_Int16 nTmp = (sal_Int16) (*aIt).first.getLength();
541 0 : if (nTmp > nMaxLeftCharCount)
542 0 : nMaxLeftCharCount = nTmp;
543 0 : ++aIt;
544 : }
545 :
546 0 : nMaxRightCharCount = 0;
547 0 : if (pFromRight.get())
548 : {
549 0 : aIt = pFromRight->begin();
550 0 : while (aIt != pFromRight->end())
551 : {
552 0 : sal_Int16 nTmp = (sal_Int16) (*aIt).first.getLength();
553 0 : if (nTmp > nMaxRightCharCount)
554 0 : nMaxRightCharCount = nTmp;
555 0 : ++aIt;
556 : }
557 : }
558 :
559 0 : bMaxCharCountIsValid = true;
560 : }
561 : sal_Int16 nRes = eDirection == ConversionDirection_FROM_LEFT ?
562 0 : nMaxLeftCharCount : nMaxRightCharCount;
563 : DBG_ASSERT( nRes >= 0, "invalid MaxCharCount" );
564 0 : return nRes;
565 : }
566 :
567 :
568 0 : void SAL_CALL ConvDic::setPropertyType(
569 : const OUString& rLeftText,
570 : const OUString& rRightText,
571 : sal_Int16 nPropertyType )
572 : throw (container::NoSuchElementException, IllegalArgumentException, RuntimeException, std::exception)
573 : {
574 0 : bool bHasElement = HasEntry( rLeftText, rRightText);
575 0 : if (!bHasElement)
576 0 : throw container::NoSuchElementException();
577 :
578 : // currently we assume that entries with the same left text have the
579 : // same PropertyType even if the right text is different...
580 0 : if (pConvPropType.get())
581 0 : pConvPropType->insert( PropTypeMap::value_type( rLeftText, nPropertyType ) );
582 0 : bIsModified = true;
583 0 : }
584 :
585 :
586 0 : sal_Int16 SAL_CALL ConvDic::getPropertyType(
587 : const OUString& rLeftText,
588 : const OUString& rRightText )
589 : throw (container::NoSuchElementException, RuntimeException, std::exception)
590 : {
591 0 : bool bHasElement = HasEntry( rLeftText, rRightText);
592 0 : if (!bHasElement)
593 0 : throw container::NoSuchElementException();
594 :
595 0 : sal_Int16 nRes = ConversionPropertyType::NOT_DEFINED;
596 0 : if (pConvPropType.get())
597 : {
598 : // still assuming that entries with same left text have same PropertyType
599 : // even if they have different right text...
600 0 : PropTypeMap::iterator aIt = pConvPropType->find( rLeftText );
601 0 : if (aIt != pConvPropType->end())
602 0 : nRes = (*aIt).second;
603 : }
604 0 : return nRes;
605 : }
606 :
607 :
608 0 : void SAL_CALL ConvDic::flush( )
609 : throw (RuntimeException, std::exception)
610 : {
611 0 : MutexGuard aGuard( GetLinguMutex() );
612 :
613 0 : if (!bIsModified)
614 0 : return;
615 :
616 0 : Save();
617 :
618 : // notify listeners
619 0 : EventObject aEvtObj;
620 0 : aEvtObj.Source = uno::Reference< XFlushable >( this );
621 0 : cppu::OInterfaceIteratorHelper aIt( aFlushListeners );
622 0 : while (aIt.hasMoreElements())
623 : {
624 0 : uno::Reference< util::XFlushListener > xRef( aIt.next(), UNO_QUERY );
625 0 : if (xRef.is())
626 0 : xRef->flushed( aEvtObj );
627 0 : }
628 : }
629 :
630 :
631 0 : void SAL_CALL ConvDic::addFlushListener(
632 : const uno::Reference< util::XFlushListener >& rxListener )
633 : throw (RuntimeException, std::exception)
634 : {
635 0 : MutexGuard aGuard( GetLinguMutex() );
636 0 : if (rxListener.is())
637 0 : aFlushListeners.addInterface( rxListener );
638 0 : }
639 :
640 :
641 0 : void SAL_CALL ConvDic::removeFlushListener(
642 : const uno::Reference< util::XFlushListener >& rxListener )
643 : throw (RuntimeException, std::exception)
644 : {
645 0 : MutexGuard aGuard( GetLinguMutex() );
646 0 : if (rxListener.is())
647 0 : aFlushListeners.removeInterface( rxListener );
648 0 : }
649 :
650 :
651 0 : OUString SAL_CALL ConvDic::getImplementationName( )
652 : throw (RuntimeException, std::exception)
653 : {
654 0 : MutexGuard aGuard( GetLinguMutex() );
655 0 : return getImplementationName_Static();
656 : }
657 :
658 0 : sal_Bool SAL_CALL ConvDic::supportsService( const OUString& rServiceName )
659 : throw (RuntimeException, std::exception)
660 : {
661 0 : return cppu::supportsService(this, rServiceName);
662 : }
663 :
664 0 : uno::Sequence< OUString > SAL_CALL ConvDic::getSupportedServiceNames( )
665 : throw (RuntimeException, std::exception)
666 : {
667 0 : MutexGuard aGuard( GetLinguMutex() );
668 0 : return getSupportedServiceNames_Static();
669 : }
670 :
671 :
672 0 : uno::Sequence< OUString > ConvDic::getSupportedServiceNames_Static()
673 : throw()
674 : {
675 0 : uno::Sequence< OUString > aSNS( 1 );
676 0 : aSNS.getArray()[0] = SN_CONV_DICTIONARY ;
677 0 : return aSNS;
678 : }
679 :
680 :
681 :
682 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|