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