1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <cppuhelper/factory.hxx>
22 #include <i18nlangtag/mslangid.hxx>
23 #include <osl/file.hxx>
24 #include <tools/stream.hxx>
25 #include <tools/urlobj.hxx>
26 #include <unotools/pathoptions.hxx>
27 #include <unotools/useroptions.hxx>
28 #include <cppuhelper/supportsservice.hxx>
29 #include <unotools/localfilehelper.hxx>
30 #include <comphelper/processfactory.hxx>
31 #include <unotools/ucbstreamhelper.hxx>
32 #include <com/sun/star/frame/XStorable.hpp>
33 #include <com/sun/star/lang/Locale.hpp>
34 #include <com/sun/star/uno/Reference.h>
35 #include <com/sun/star/linguistic2/DictionaryEventFlags.hpp>
36 #include <com/sun/star/linguistic2/DictionaryListEventFlags.hpp>
37 #include <com/sun/star/registry/XRegistryKey.hpp>
38 #include <com/sun/star/ucb/SimpleFileAccess.hpp>
41 #include "dlistimp.hxx"
47 using namespace com::sun::star
;
48 using namespace com::sun::star::lang
;
49 using namespace com::sun::star::uno
;
50 using namespace com::sun::star::linguistic2
;
51 using namespace linguistic
;
55 static bool IsVers2OrNewer( const OUString
& rFileURL
, sal_uInt16
& nLng
, bool& bNeg
);
57 static void AddInternal( const uno::Reference
< XDictionary
> &rDic
,
58 const OUString
& rNew
);
59 static void AddUserData( const uno::Reference
< XDictionary
> &rDic
);
62 class DicEvtListenerHelper
:
63 public cppu::WeakImplHelper1
65 XDictionaryEventListener
68 cppu::OInterfaceContainerHelper aDicListEvtListeners
;
69 uno::Sequence
< DictionaryEvent
> aCollectDicEvt
;
70 uno::Reference
< XDictionaryList
> xMyDicList
;
72 sal_Int16 nCondensedEvt
;
73 sal_Int16 nNumCollectEvtListeners
,
77 DicEvtListenerHelper( const uno::Reference
< XDictionaryList
> &rxDicList
);
78 virtual ~DicEvtListenerHelper();
82 disposing( const EventObject
& rSource
)
83 throw(RuntimeException
, std::exception
) SAL_OVERRIDE
;
85 // XDictionaryEventListener
87 processDictionaryEvent( const DictionaryEvent
& rDicEvent
)
88 throw(RuntimeException
, std::exception
) SAL_OVERRIDE
;
91 void DisposeAndClear( const EventObject
&rEvtObj
);
93 bool AddDicListEvtListener(
94 const uno::Reference
< XDictionaryListEventListener
>& rxListener
,
95 bool bReceiveVerbose
);
96 bool RemoveDicListEvtListener(
97 const uno::Reference
< XDictionaryListEventListener
>& rxListener
);
98 sal_Int16
BeginCollectEvents() { return ++nNumCollectEvtListeners
;}
99 sal_Int16
EndCollectEvents();
100 sal_Int16
FlushEvents();
101 void ClearEvents() { nCondensedEvt
= 0; }
105 DicEvtListenerHelper::DicEvtListenerHelper(
106 const uno::Reference
< XDictionaryList
> &rxDicList
) :
107 aDicListEvtListeners ( GetLinguMutex() ),
108 xMyDicList ( rxDicList
)
111 nNumCollectEvtListeners
= nNumVerboseListeners
= 0;
115 DicEvtListenerHelper::~DicEvtListenerHelper()
117 DBG_ASSERT(aDicListEvtListeners
.getLength() == 0,
118 "lng : event listeners are still existing");
122 void DicEvtListenerHelper::DisposeAndClear( const EventObject
&rEvtObj
)
124 aDicListEvtListeners
.disposeAndClear( rEvtObj
);
128 void SAL_CALL
DicEvtListenerHelper::disposing( const EventObject
& rSource
)
129 throw(RuntimeException
, std::exception
)
131 osl::MutexGuard
aGuard( GetLinguMutex() );
133 uno::Reference
< XInterface
> xSrc( rSource
.Source
);
135 // remove event object from EventListener list
137 aDicListEvtListeners
.removeInterface( xSrc
);
139 // if object is a dictionary then remove it from the dictionary list
140 // Note: this will probably happen only if someone makes a XDictionary
141 // implementation of his own that is also a XComponent.
142 uno::Reference
< XDictionary
> xDic( xSrc
, UNO_QUERY
);
145 xMyDicList
->removeDictionary( xDic
);
150 void SAL_CALL
DicEvtListenerHelper::processDictionaryEvent(
151 const DictionaryEvent
& rDicEvent
)
152 throw(RuntimeException
, std::exception
)
154 osl::MutexGuard
aGuard( GetLinguMutex() );
156 uno::Reference
< XDictionary
> xDic( rDicEvent
.Source
, UNO_QUERY
);
157 DBG_ASSERT(xDic
.is(), "lng : missing event source");
159 // assert that there is a corresponding dictionary entry if one was
161 uno::Reference
< XDictionaryEntry
> xDicEntry( rDicEvent
.xDictionaryEntry
, UNO_QUERY
);
162 DBG_ASSERT( !(rDicEvent
.nEvent
&
163 (DictionaryEventFlags::ADD_ENTRY
| DictionaryEventFlags::DEL_ENTRY
))
165 "lng : missing dictionary entry" );
167 // evaluate DictionaryEvents and update data for next DictionaryListEvent
168 DictionaryType eDicType
= xDic
->getDictionaryType();
169 DBG_ASSERT(eDicType
!= DictionaryType_MIXED
,
170 "lng : unexpected dictionary type");
171 if ((rDicEvent
.nEvent
& DictionaryEventFlags::ADD_ENTRY
) && xDic
->isActive())
172 nCondensedEvt
|= xDicEntry
->isNegative() ?
173 DictionaryListEventFlags::ADD_NEG_ENTRY
:
174 DictionaryListEventFlags::ADD_POS_ENTRY
;
175 if ((rDicEvent
.nEvent
& DictionaryEventFlags::DEL_ENTRY
) && xDic
->isActive())
176 nCondensedEvt
|= xDicEntry
->isNegative() ?
177 DictionaryListEventFlags::DEL_NEG_ENTRY
:
178 DictionaryListEventFlags::DEL_POS_ENTRY
;
179 if ((rDicEvent
.nEvent
& DictionaryEventFlags::ENTRIES_CLEARED
) && xDic
->isActive())
180 nCondensedEvt
|= eDicType
== DictionaryType_NEGATIVE
?
181 DictionaryListEventFlags::DEL_NEG_ENTRY
:
182 DictionaryListEventFlags::DEL_POS_ENTRY
;
183 if ((rDicEvent
.nEvent
& DictionaryEventFlags::CHG_LANGUAGE
) && xDic
->isActive())
184 nCondensedEvt
|= eDicType
== DictionaryType_NEGATIVE
?
185 DictionaryListEventFlags::DEACTIVATE_NEG_DIC
186 | DictionaryListEventFlags::ACTIVATE_NEG_DIC
:
187 DictionaryListEventFlags::DEACTIVATE_POS_DIC
188 | DictionaryListEventFlags::ACTIVATE_POS_DIC
;
189 if ((rDicEvent
.nEvent
& DictionaryEventFlags::ACTIVATE_DIC
))
190 nCondensedEvt
|= eDicType
== DictionaryType_NEGATIVE
?
191 DictionaryListEventFlags::ACTIVATE_NEG_DIC
:
192 DictionaryListEventFlags::ACTIVATE_POS_DIC
;
193 if ((rDicEvent
.nEvent
& DictionaryEventFlags::DEACTIVATE_DIC
))
194 nCondensedEvt
|= eDicType
== DictionaryType_NEGATIVE
?
195 DictionaryListEventFlags::DEACTIVATE_NEG_DIC
:
196 DictionaryListEventFlags::DEACTIVATE_POS_DIC
;
198 // update list of collected events if needs to be
199 if (nNumVerboseListeners
> 0)
201 sal_Int32 nColEvts
= aCollectDicEvt
.getLength();
202 aCollectDicEvt
.realloc( nColEvts
+ 1 );
203 aCollectDicEvt
.getArray()[ nColEvts
] = rDicEvent
;
206 if (nNumCollectEvtListeners
== 0 && nCondensedEvt
!= 0)
211 bool DicEvtListenerHelper::AddDicListEvtListener(
212 const uno::Reference
< XDictionaryListEventListener
>& xListener
,
213 bool /*bReceiveVerbose*/ )
215 DBG_ASSERT( xListener
.is(), "empty reference" );
216 sal_Int32 nCount
= aDicListEvtListeners
.getLength();
217 return aDicListEvtListeners
.addInterface( xListener
) != nCount
;
221 bool DicEvtListenerHelper::RemoveDicListEvtListener(
222 const uno::Reference
< XDictionaryListEventListener
>& xListener
)
224 DBG_ASSERT( xListener
.is(), "empty reference" );
225 sal_Int32 nCount
= aDicListEvtListeners
.getLength();
226 return aDicListEvtListeners
.removeInterface( xListener
) != nCount
;
232 sal_Int16
DicEvtListenerHelper::EndCollectEvents()
234 DBG_ASSERT(nNumCollectEvtListeners
> 0, "lng: mismatched function call");
235 if (nNumCollectEvtListeners
> 0)
238 nNumCollectEvtListeners
--;
241 return nNumCollectEvtListeners
;
245 sal_Int16
DicEvtListenerHelper::FlushEvents()
247 if (0 != nCondensedEvt
)
249 // build DictionaryListEvent to pass on to listeners
250 uno::Sequence
< DictionaryEvent
> aDicEvents
;
251 if (nNumVerboseListeners
> 0)
252 aDicEvents
= aCollectDicEvt
;
253 DictionaryListEvent
aEvent( xMyDicList
, nCondensedEvt
, aDicEvents
);
256 cppu::OInterfaceIteratorHelper
aIt( aDicListEvtListeners
);
257 while (aIt
.hasMoreElements())
259 uno::Reference
< XDictionaryListEventListener
> xRef( aIt
.next(), UNO_QUERY
);
261 xRef
->processDictionaryListEvent( aEvent
);
264 // clear "list" of events
266 aCollectDicEvt
.realloc( 0 );
269 return nNumCollectEvtListeners
;
275 void DicList::MyAppExitListener::AtExit()
277 rMyDicList
.SaveDics();
282 aEvtListeners ( GetLinguMutex() )
284 pDicEvtLstnrHelper
= new DicEvtListenerHelper( this );
285 xDicEvtLstnrHelper
= pDicEvtLstnrHelper
;
289 pExitListener
= new MyAppExitListener( *this );
290 xExitListener
= pExitListener
;
291 pExitListener
->Activate();
296 pExitListener
->Deactivate();
300 void DicList::SearchForDictionaries(
301 DictionaryVec_t
&rDicList
,
302 const OUString
&rDicDirURL
,
303 bool bIsWriteablePath
)
305 osl::MutexGuard
aGuard( GetLinguMutex() );
307 const uno::Sequence
< OUString
> aDirCnt( utl::LocalFileHelper::
308 GetFolderContents( rDicDirURL
, false ) );
309 const OUString
*pDirCnt
= aDirCnt
.getConstArray();
310 sal_Int32 nEntries
= aDirCnt
.getLength();
312 OUString
aDCN("dcn");
313 OUString
aDCP("dcp");
314 for (sal_Int32 i
= 0; i
< nEntries
; ++i
)
316 OUString
aURL( pDirCnt
[i
] );
317 sal_uInt16 nLang
= LANGUAGE_NONE
;
320 if(!::IsVers2OrNewer( aURL
, nLang
, bNeg
))
323 sal_Int32 nPos
= aURL
.indexOf('.');
324 OUString
aExt( aURL
.copy(nPos
+ 1).toAsciiLowerCase() );
326 if (aDCN
.equals(aExt
)) // negativ
328 else if (aDCP
.equals(aExt
)) // positiv
331 continue; // andere Files
334 // Record in the list of Dictoinaries
335 // When it already exists don't record
336 sal_Int16 nSystemLanguage
= MsLangId::getSystemLanguage();
337 OUString aTmp1
= ToLower( aURL
, nSystemLanguage
);
338 sal_Int32 nPos
= aTmp1
.lastIndexOf( '/' );
340 aTmp1
= aTmp1
.copy( nPos
+ 1 );
343 size_t nCount
= rDicList
.size();
344 for(j
= 0; j
< nCount
; j
++)
346 aTmp2
= rDicList
[j
]->getName().getStr();
347 aTmp2
= ToLower( aTmp2
, nSystemLanguage
);
351 if(j
>= nCount
) // dictionary not yet in DicList
353 // get decoded dictionary file name
354 INetURLObject
aURLObj( aURL
);
355 OUString aDicName
= aURLObj
.getName( INetURLObject::LAST_SEGMENT
,
356 true, INetURLObject::DECODE_WITH_CHARSET
,
357 RTL_TEXTENCODING_UTF8
);
359 DictionaryType eType
= bNeg
? DictionaryType_NEGATIVE
: DictionaryType_POSITIVE
;
360 uno::Reference
< XDictionary
> xDic
=
361 new DictionaryNeo( aDicName
, nLang
, eType
, aURL
, bIsWriteablePath
);
363 addDictionary( xDic
);
370 sal_Int32
DicList::GetDicPos(const uno::Reference
< XDictionary
> &xDic
)
372 osl::MutexGuard
aGuard( GetLinguMutex() );
375 DictionaryVec_t
& rDicList
= GetOrCreateDicList();
376 size_t n
= rDicList
.size();
377 for (size_t i
= 0; i
< n
; i
++)
379 if ( rDicList
[i
] == xDic
)
386 uno::Reference
< XInterface
> SAL_CALL
387 DicList_CreateInstance( const uno::Reference
< XMultiServiceFactory
> & /*rSMgr*/ )
390 uno::Reference
< XInterface
> xService
= (cppu::OWeakObject
*) new DicList
;
394 sal_Int16 SAL_CALL
DicList::getCount() throw(RuntimeException
, std::exception
)
396 osl::MutexGuard
aGuard( GetLinguMutex() );
397 return static_cast< sal_Int16
>(GetOrCreateDicList().size());
400 uno::Sequence
< uno::Reference
< XDictionary
> > SAL_CALL
401 DicList::getDictionaries()
402 throw(RuntimeException
, std::exception
)
404 osl::MutexGuard
aGuard( GetLinguMutex() );
406 DictionaryVec_t
& rDicList
= GetOrCreateDicList();
408 uno::Sequence
< uno::Reference
< XDictionary
> > aDics( rDicList
.size() );
409 uno::Reference
< XDictionary
> *pDic
= aDics
.getArray();
411 sal_Int32 n
= (sal_uInt16
) aDics
.getLength();
412 for (sal_Int32 i
= 0; i
< n
; i
++)
413 pDic
[i
] = rDicList
[i
];
418 uno::Reference
< XDictionary
> SAL_CALL
419 DicList::getDictionaryByName( const OUString
& aDictionaryName
)
420 throw(RuntimeException
, std::exception
)
422 osl::MutexGuard
aGuard( GetLinguMutex() );
424 uno::Reference
< XDictionary
> xDic
;
425 DictionaryVec_t
& rDicList
= GetOrCreateDicList();
426 size_t nCount
= rDicList
.size();
427 for (size_t i
= 0; i
< nCount
; i
++)
429 const uno::Reference
< XDictionary
> &rDic
= rDicList
[i
];
430 if (rDic
.is() && rDic
->getName() == aDictionaryName
)
440 sal_Bool SAL_CALL
DicList::addDictionary(
441 const uno::Reference
< XDictionary
>& xDictionary
)
442 throw(RuntimeException
, std::exception
)
444 osl::MutexGuard
aGuard( GetLinguMutex() );
450 if (xDictionary
.is())
452 DictionaryVec_t
& rDicList
= GetOrCreateDicList();
453 rDicList
.push_back( xDictionary
);
456 // add listener helper to the dictionaries listener lists
457 xDictionary
->addDictionaryEventListener( xDicEvtLstnrHelper
);
463 DicList::removeDictionary( const uno::Reference
< XDictionary
>& xDictionary
)
464 throw(RuntimeException
, std::exception
)
466 osl::MutexGuard
aGuard( GetLinguMutex() );
472 sal_Int32 nPos
= GetDicPos( xDictionary
);
475 // remove dictionary list from the dictionaries listener lists
476 DictionaryVec_t
& rDicList
= GetOrCreateDicList();
477 uno::Reference
< XDictionary
> xDic( rDicList
[ nPos
] );
478 DBG_ASSERT(xDic
.is(), "lng : empty reference");
481 // deactivate dictionary if not already done
482 xDic
->setActive( sal_False
);
484 xDic
->removeDictionaryEventListener( xDicEvtLstnrHelper
);
487 // remove element at nPos
488 rDicList
.erase( rDicList
.begin() + nPos
);
494 sal_Bool SAL_CALL
DicList::addDictionaryListEventListener(
495 const uno::Reference
< XDictionaryListEventListener
>& xListener
,
496 sal_Bool bReceiveVerbose
)
497 throw(RuntimeException
, std::exception
)
499 osl::MutexGuard
aGuard( GetLinguMutex() );
504 DBG_ASSERT(!bReceiveVerbose
, "lng : not yet supported");
507 if (xListener
.is()) //! don't add empty references
509 bRes
= pDicEvtLstnrHelper
->
510 AddDicListEvtListener( xListener
, bReceiveVerbose
);
515 sal_Bool SAL_CALL
DicList::removeDictionaryListEventListener(
516 const uno::Reference
< XDictionaryListEventListener
>& xListener
)
517 throw(RuntimeException
, std::exception
)
519 osl::MutexGuard
aGuard( GetLinguMutex() );
527 bRes
= pDicEvtLstnrHelper
->RemoveDicListEvtListener( xListener
);
532 sal_Int16 SAL_CALL
DicList::beginCollectEvents() throw(RuntimeException
, std::exception
)
534 osl::MutexGuard
aGuard( GetLinguMutex() );
535 return pDicEvtLstnrHelper
->BeginCollectEvents();
538 sal_Int16 SAL_CALL
DicList::endCollectEvents() throw(RuntimeException
, std::exception
)
540 osl::MutexGuard
aGuard( GetLinguMutex() );
541 return pDicEvtLstnrHelper
->EndCollectEvents();
544 sal_Int16 SAL_CALL
DicList::flushEvents() throw(RuntimeException
, std::exception
)
546 osl::MutexGuard
aGuard( GetLinguMutex() );
547 return pDicEvtLstnrHelper
->FlushEvents();
550 uno::Reference
< XDictionary
> SAL_CALL
551 DicList::createDictionary( const OUString
& rName
, const Locale
& rLocale
,
552 DictionaryType eDicType
, const OUString
& rURL
)
553 throw(RuntimeException
, std::exception
)
555 osl::MutexGuard
aGuard( GetLinguMutex() );
557 sal_Int16 nLanguage
= LinguLocaleToLanguage( rLocale
);
558 bool bIsWriteablePath
= rURL
.match( GetDictionaryWriteablePath(), 0 );
559 return new DictionaryNeo( rName
, nLanguage
, eDicType
, rURL
, bIsWriteablePath
);
563 uno::Reference
< XDictionaryEntry
> SAL_CALL
564 DicList::queryDictionaryEntry( const OUString
& rWord
, const Locale
& rLocale
,
565 sal_Bool bSearchPosDics
, sal_Bool bSearchSpellEntry
)
566 throw(RuntimeException
, std::exception
)
568 osl::MutexGuard
aGuard( GetLinguMutex() );
569 return SearchDicList( this, rWord
, LinguLocaleToLanguage( rLocale
),
570 bSearchPosDics
, bSearchSpellEntry
);
576 throw(RuntimeException
, std::exception
)
578 osl::MutexGuard
aGuard( GetLinguMutex() );
583 EventObject
aEvtObj( (XDictionaryList
*) this );
585 aEvtListeners
.disposeAndClear( aEvtObj
);
586 if (pDicEvtLstnrHelper
)
587 pDicEvtLstnrHelper
->DisposeAndClear( aEvtObj
);
589 //! avoid creation of dictionaries if not already done
590 if ( !aDicList
.empty() )
592 DictionaryVec_t
& rDicList
= GetOrCreateDicList();
593 size_t nCount
= rDicList
.size();
594 for (size_t i
= 0; i
< nCount
; i
++)
596 uno::Reference
< XDictionary
> xDic( rDicList
[i
], UNO_QUERY
);
598 // save (modified) dictionaries
599 uno::Reference
< frame::XStorable
> xStor( xDic
, UNO_QUERY
);
604 if (!xStor
->isReadonly() && xStor
->hasLocation())
612 // release references to (members of) this object hold by
615 xDic
->removeDictionaryEventListener( xDicEvtLstnrHelper
);
618 xDicEvtLstnrHelper
.clear();
623 DicList::addEventListener( const uno::Reference
< XEventListener
>& rxListener
)
624 throw(RuntimeException
, std::exception
)
626 osl::MutexGuard
aGuard( GetLinguMutex() );
628 if (!bDisposing
&& rxListener
.is())
629 aEvtListeners
.addInterface( rxListener
);
633 DicList::removeEventListener( const uno::Reference
< XEventListener
>& rxListener
)
634 throw(RuntimeException
, std::exception
)
636 osl::MutexGuard
aGuard( GetLinguMutex() );
638 if (!bDisposing
&& rxListener
.is())
639 aEvtListeners
.removeInterface( rxListener
);
642 void DicList::_CreateDicList()
646 // look for dictionaries
647 const OUString
aWriteablePath( GetDictionaryWriteablePath() );
648 uno::Sequence
< OUString
> aPaths( GetDictionaryPaths() );
649 const OUString
*pPaths
= aPaths
.getConstArray();
650 for (sal_Int32 i
= 0; i
< aPaths
.getLength(); ++i
)
652 const bool bIsWriteablePath
= (pPaths
[i
] == aWriteablePath
);
653 SearchForDictionaries( aDicList
, pPaths
[i
], bIsWriteablePath
);
656 // create IgnoreAllList dictionary with empty URL (non persistent)
657 // and add it to list
658 OUString
aDicName( "IgnoreAllList" );
659 uno::Reference
< XDictionary
> xIgnAll(
660 createDictionary( aDicName
, LinguLanguageToLocale( LANGUAGE_NONE
),
661 DictionaryType_POSITIVE
, OUString() ) );
664 AddUserData( xIgnAll
);
665 xIgnAll
->setActive( sal_True
);
666 addDictionary( xIgnAll
);
670 // evaluate list of dictionaries to be activated from configuration
671 //! to suppress overwriting the list of active dictionaries in the
672 //! configuration with incorrect arguments during the following
673 //! activation of the dictionaries
674 pDicEvtLstnrHelper
->BeginCollectEvents();
675 const uno::Sequence
< OUString
> aActiveDics( aOpt
.GetActiveDics() );
676 const OUString
*pActiveDic
= aActiveDics
.getConstArray();
677 sal_Int32 nLen
= aActiveDics
.getLength();
678 for (sal_Int32 i
= 0; i
< nLen
; ++i
)
680 if (!pActiveDic
[i
].isEmpty())
682 uno::Reference
< XDictionary
> xDic( getDictionaryByName( pActiveDic
[i
] ) );
684 xDic
->setActive( sal_True
);
688 // suppress collected events during creation of the dictionary list.
689 // there should be no events during creation.
690 pDicEvtLstnrHelper
->ClearEvents();
692 pDicEvtLstnrHelper
->EndCollectEvents();
698 void DicList::SaveDics()
700 // save dics only if they have already been used/created.
701 //! don't create them just for the purpose of saving them !
702 if ( !aDicList
.empty() )
704 // save (modified) dictionaries
705 DictionaryVec_t
& rDicList
= GetOrCreateDicList();
706 size_t nCount
= rDicList
.size();;
707 for (size_t i
= 0; i
< nCount
; i
++)
709 // save (modified) dictionaries
710 uno::Reference
< frame::XStorable
> xStor( rDicList
[i
], UNO_QUERY
);
715 if (!xStor
->isReadonly() && xStor
->hasLocation())
727 // Service specific part
729 OUString SAL_CALL
DicList::getImplementationName( ) throw(RuntimeException
, std::exception
)
731 osl::MutexGuard
aGuard( GetLinguMutex() );
732 return getImplementationName_Static();
736 sal_Bool SAL_CALL
DicList::supportsService( const OUString
& ServiceName
)
737 throw(RuntimeException
, std::exception
)
739 return cppu::supportsService(this, ServiceName
);
742 uno::Sequence
< OUString
> SAL_CALL
DicList::getSupportedServiceNames( )
743 throw(RuntimeException
, std::exception
)
745 osl::MutexGuard
aGuard( GetLinguMutex() );
746 return getSupportedServiceNames_Static();
750 uno::Sequence
< OUString
> DicList::getSupportedServiceNames_Static() throw()
752 osl::MutexGuard
aGuard( GetLinguMutex() );
754 uno::Sequence
< OUString
> aSNS( 1 ); // more than 1 service possible
755 aSNS
.getArray()[0] = "com.sun.star.linguistic2.DictionaryList";
759 void * SAL_CALL
DicList_getFactory( const sal_Char
* pImplName
,
760 XMultiServiceFactory
* pServiceManager
, void * )
763 if ( DicList::getImplementationName_Static().equalsAscii( pImplName
) )
765 uno::Reference
< XSingleServiceFactory
> xFactory
=
766 cppu::createOneInstanceFactory(
768 DicList::getImplementationName_Static(),
769 DicList_CreateInstance
,
770 DicList::getSupportedServiceNames_Static());
771 // acquire, because we return an interface pointer instead of a reference
773 pRet
= xFactory
.get();
779 static sal_Int32
lcl_GetToken( OUString
&rToken
,
780 const OUString
&rText
, sal_Int32 nPos
, const OUString
&rDelim
)
784 if (rText
.isEmpty() || nPos
>= rText
.getLength())
786 else if (rDelim
.isEmpty())
789 if (!rToken
.isEmpty())
790 nRes
= rText
.getLength();
795 for (i
= nPos
; i
< rText
.getLength(); ++i
)
797 if (-1 != rDelim
.indexOf( rText
[i
] ))
801 if (i
>= rText
.getLength()) // delimiter not found
802 rToken
= rText
.copy( nPos
);
804 rToken
= rText
.copy( nPos
, i
- nPos
);
805 nRes
= i
+ 1; // continue after found delimiter
812 static void AddInternal(
813 const uno::Reference
<XDictionary
> &rDic
,
814 const OUString
& rNew
)
818 //! TL TODO: word iterator should be used to break up the text
819 static const char aDefWordDelim
[] =
820 "!\"#$%&'()*+,-/:;<=>?[]\\_^`{|}~\t \n";
821 OUString
aDelim(aDefWordDelim
);
822 OSL_ENSURE(aDelim
.indexOf(static_cast<sal_Unicode
>('.')) == -1,
828 (nPos
= lcl_GetToken( aToken
, rNew
, nPos
, aDelim
)))
830 if( !aToken
.isEmpty() && !IsNumeric( aToken
) )
832 rDic
->add( aToken
, sal_False
, OUString() );
838 static void AddUserData( const uno::Reference
< XDictionary
> &rDic
)
842 SvtUserOptions aUserOpt
;
843 AddInternal( rDic
, aUserOpt
.GetFullName() );
844 AddInternal( rDic
, aUserOpt
.GetCompany() );
845 AddInternal( rDic
, aUserOpt
.GetStreet() );
846 AddInternal( rDic
, aUserOpt
.GetCity() );
847 AddInternal( rDic
, aUserOpt
.GetTitle() );
848 AddInternal( rDic
, aUserOpt
.GetPosition() );
849 AddInternal( rDic
, aUserOpt
.GetEmail() );
853 static bool IsVers2OrNewer( const OUString
& rFileURL
, sal_uInt16
& nLng
, bool& bNeg
)
855 if (rFileURL
.isEmpty())
857 OUString
aDIC("dic");
859 sal_Int32 nPos
= rFileURL
.lastIndexOf( '.' );
861 aExt
= rFileURL
.copy( nPos
+ 1 ).toAsciiLowerCase();
866 // get stream to be used
867 uno::Reference
< uno::XComponentContext
> xContext( comphelper::getProcessComponentContext() );
869 // get XInputStream stream
870 uno::Reference
< io::XInputStream
> xStream
;
873 uno::Reference
< ucb::XSimpleFileAccess3
> xAccess( ucb::SimpleFileAccess::create(xContext
) );
874 xStream
= xAccess
->openFileRead( rFileURL
);
876 catch (const uno::Exception
&)
878 DBG_ASSERT( false, "failed to get input stream" );
880 DBG_ASSERT( xStream
.is(), "failed to get stream for read" );
884 SvStreamPtr pStream
= SvStreamPtr( utl::UcbStreamHelper::CreateStream( xStream
) );
886 int nDicVersion
= ReadDicVersion(pStream
, nLng
, bNeg
);
887 if (2 == nDicVersion
|| nDicVersion
>= 5)
894 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */