1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: dlistimp.cxx,v $
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 "dlistimp.hxx"
37 #include <osl/file.hxx>
38 #include <tools/fsys.hxx>
39 #include <tools/stream.hxx>
40 #include <tools/urlobj.hxx>
41 #include <i18npool/mslangid.hxx>
42 #include <svtools/pathoptions.hxx>
43 #include <svtools/useroptions.hxx>
44 #include <sfx2/docfile.hxx>
45 #include <vcl/svapp.hxx>
46 #include <cppuhelper/factory.hxx> // helper for factories
47 #include <unotools/localfilehelper.hxx>
48 #include <com/sun/star/frame/XStorable.hpp>
49 #include <com/sun/star/lang/Locale.hpp>
50 #include <com/sun/star/uno/Reference.h>
51 #include <com/sun/star/linguistic2/DictionaryEventFlags.hpp>
52 #include <com/sun/star/linguistic2/DictionaryListEventFlags.hpp>
53 #include <com/sun/star/registry/XRegistryKey.hpp>
55 //using namespace utl;
58 using namespace com::sun::star
;
59 using namespace com::sun::star::lang
;
60 using namespace com::sun::star::uno
;
61 using namespace com::sun::star::linguistic2
;
62 using namespace linguistic
;
64 ///////////////////////////////////////////////////////////////////////////
66 static BOOL
IsVers2OrNewer( const String
& rFileURL
, USHORT
& nLng
, BOOL
& bNeg
);
68 static void AddInternal( const uno::Reference
< XDictionary
> &rDic
,
69 const rtl::OUString
& rNew
);
70 static void AddUserData( const uno::Reference
< XDictionary
> &rDic
);
72 ///////////////////////////////////////////////////////////////////////////
74 class DicEvtListenerHelper
:
75 public cppu::WeakImplHelper1
77 XDictionaryEventListener
80 cppu::OInterfaceContainerHelper aDicListEvtListeners
;
81 uno::Sequence
< DictionaryEvent
> aCollectDicEvt
;
82 uno::Reference
< XDictionaryList
> xMyDicList
;
85 INT16 nNumCollectEvtListeners
,
89 DicEvtListenerHelper( const uno::Reference
< XDictionaryList
> &rxDicList
);
90 virtual ~DicEvtListenerHelper();
94 disposing( const EventObject
& rSource
)
95 throw(RuntimeException
);
97 // XDictionaryEventListener
99 processDictionaryEvent( const DictionaryEvent
& rDicEvent
)
100 throw(RuntimeException
);
103 void DisposeAndClear( const EventObject
&rEvtObj
);
105 BOOL
AddDicListEvtListener(
106 const uno::Reference
< XDictionaryListEventListener
>& rxListener
,
107 BOOL bReceiveVerbose
);
108 BOOL
RemoveDicListEvtListener(
109 const uno::Reference
< XDictionaryListEventListener
>& rxListener
);
110 INT16
BeginCollectEvents();
111 INT16
EndCollectEvents();
113 void ClearEvents() { nCondensedEvt
= 0; }
117 DicEvtListenerHelper::DicEvtListenerHelper(
118 const uno::Reference
< XDictionaryList
> &rxDicList
) :
119 aDicListEvtListeners ( GetLinguMutex() ),
120 xMyDicList ( rxDicList
)
123 nNumCollectEvtListeners
= nNumVerboseListeners
= 0;
127 DicEvtListenerHelper::~DicEvtListenerHelper()
129 DBG_ASSERT(aDicListEvtListeners
.getLength() == 0,
130 "lng : event listeners are still existing");
134 void DicEvtListenerHelper::DisposeAndClear( const EventObject
&rEvtObj
)
136 aDicListEvtListeners
.disposeAndClear( rEvtObj
);
140 void SAL_CALL
DicEvtListenerHelper::disposing( const EventObject
& rSource
)
141 throw(RuntimeException
)
143 osl::MutexGuard
aGuard( GetLinguMutex() );
145 uno::Reference
< XInterface
> xSrc( rSource
.Source
);
147 // remove event object from EventListener list
149 aDicListEvtListeners
.removeInterface( xSrc
);
151 // if object is a dictionary then remove it from the dictionary list
152 // Note: this will probably happen only if someone makes a XDictionary
153 // implementation of his own that is also a XComponent.
154 uno::Reference
< XDictionary
> xDic( xSrc
, UNO_QUERY
);
157 xMyDicList
->removeDictionary( xDic
);
162 void SAL_CALL
DicEvtListenerHelper::processDictionaryEvent(
163 const DictionaryEvent
& rDicEvent
)
164 throw(RuntimeException
)
166 osl::MutexGuard
aGuard( GetLinguMutex() );
168 uno::Reference
< XDictionary
> xDic( rDicEvent
.Source
, UNO_QUERY
);
169 DBG_ASSERT(xDic
.is(), "lng : missing event source");
171 // assert that there is a corresponding dictionary entry if one was
173 uno::Reference
< XDictionaryEntry
> xDicEntry( rDicEvent
.xDictionaryEntry
, UNO_QUERY
);
174 DBG_ASSERT( !(rDicEvent
.nEvent
&
175 (DictionaryEventFlags::ADD_ENTRY
| DictionaryEventFlags::DEL_ENTRY
))
177 "lng : missing dictionary entry" );
179 /*BOOL bActiveDicsModified = FALSE;*/
181 // evaluate DictionaryEvents and update data for next DictionaryListEvent
183 DictionaryType eDicType
= xDic
->getDictionaryType();
184 DBG_ASSERT(eDicType
!= DictionaryType_MIXED
,
185 "lng : unexpected dictionary type");
186 if ((rDicEvent
.nEvent
& DictionaryEventFlags::ADD_ENTRY
) && xDic
->isActive())
187 nCondensedEvt
|= xDicEntry
->isNegative() ?
188 DictionaryListEventFlags::ADD_NEG_ENTRY
:
189 DictionaryListEventFlags::ADD_POS_ENTRY
;
190 if ((rDicEvent
.nEvent
& DictionaryEventFlags::DEL_ENTRY
) && xDic
->isActive())
191 nCondensedEvt
|= xDicEntry
->isNegative() ?
192 DictionaryListEventFlags::DEL_NEG_ENTRY
:
193 DictionaryListEventFlags::DEL_POS_ENTRY
;
194 if ((rDicEvent
.nEvent
& DictionaryEventFlags::ENTRIES_CLEARED
) && xDic
->isActive())
195 nCondensedEvt
|= eDicType
== DictionaryType_NEGATIVE
?
196 DictionaryListEventFlags::DEL_NEG_ENTRY
:
197 DictionaryListEventFlags::DEL_POS_ENTRY
;
198 if ((rDicEvent
.nEvent
& DictionaryEventFlags::CHG_LANGUAGE
) && xDic
->isActive())
199 nCondensedEvt
|= eDicType
== DictionaryType_NEGATIVE
?
200 DictionaryListEventFlags::DEACTIVATE_NEG_DIC
201 | DictionaryListEventFlags::ACTIVATE_NEG_DIC
:
202 DictionaryListEventFlags::DEACTIVATE_POS_DIC
203 | DictionaryListEventFlags::ACTIVATE_POS_DIC
;
204 if ((rDicEvent
.nEvent
& DictionaryEventFlags::ACTIVATE_DIC
))
205 nCondensedEvt
|= eDicType
== DictionaryType_NEGATIVE
?
206 DictionaryListEventFlags::ACTIVATE_NEG_DIC
:
207 DictionaryListEventFlags::ACTIVATE_POS_DIC
;
208 if ((rDicEvent
.nEvent
& DictionaryEventFlags::DEACTIVATE_DIC
))
209 nCondensedEvt
|= eDicType
== DictionaryType_NEGATIVE
?
210 DictionaryListEventFlags::DEACTIVATE_NEG_DIC
:
211 DictionaryListEventFlags::DEACTIVATE_POS_DIC
;
213 // update list of collected events if needs to be
214 if (nNumVerboseListeners
> 0)
216 INT32 nColEvts
= aCollectDicEvt
.getLength();
217 aCollectDicEvt
.realloc( nColEvts
+ 1 );
218 aCollectDicEvt
.getArray()[ nColEvts
] = rDicEvent
;
221 if (nNumCollectEvtListeners
== 0 && nCondensedEvt
!= 0)
226 BOOL
DicEvtListenerHelper::AddDicListEvtListener(
227 const uno::Reference
< XDictionaryListEventListener
>& xListener
,
228 BOOL
/*bReceiveVerbose*/ )
230 DBG_ASSERT( xListener
.is(), "empty reference" );
231 INT32 nCount
= aDicListEvtListeners
.getLength();
232 return aDicListEvtListeners
.addInterface( xListener
) != nCount
;
236 BOOL
DicEvtListenerHelper::RemoveDicListEvtListener(
237 const uno::Reference
< XDictionaryListEventListener
>& xListener
)
239 DBG_ASSERT( xListener
.is(), "empty reference" );
240 INT32 nCount
= aDicListEvtListeners
.getLength();
241 return aDicListEvtListeners
.removeInterface( xListener
) != nCount
;
245 INT16
DicEvtListenerHelper::BeginCollectEvents()
247 return ++nNumCollectEvtListeners
;
251 INT16
DicEvtListenerHelper::EndCollectEvents()
253 DBG_ASSERT(nNumCollectEvtListeners
> 0, "lng: mismatched function call");
254 if (nNumCollectEvtListeners
> 0)
257 nNumCollectEvtListeners
--;
260 return nNumCollectEvtListeners
;
264 INT16
DicEvtListenerHelper::FlushEvents()
266 if (0 != nCondensedEvt
)
268 // build DictionaryListEvent to pass on to listeners
269 uno::Sequence
< DictionaryEvent
> aDicEvents
;
270 if (nNumVerboseListeners
> 0)
271 aDicEvents
= aCollectDicEvt
;
272 DictionaryListEvent
aEvent( xMyDicList
, nCondensedEvt
, aDicEvents
);
275 cppu::OInterfaceIteratorHelper
aIt( aDicListEvtListeners
);
276 while (aIt
.hasMoreElements())
278 uno::Reference
< XDictionaryListEventListener
> xRef( aIt
.next(), UNO_QUERY
);
280 xRef
->processDictionaryListEvent( aEvent
);
283 // clear "list" of events
285 aCollectDicEvt
.realloc( 0 );
288 return nNumCollectEvtListeners
;
292 ///////////////////////////////////////////////////////////////////////////
295 void DicList::MyAppExitListener::AtExit()
297 rMyDicList
.SaveDics();
302 aEvtListeners ( GetLinguMutex() )
304 pDicEvtLstnrHelper
= new DicEvtListenerHelper( this );
305 xDicEvtLstnrHelper
= pDicEvtLstnrHelper
;
309 pExitListener
= new MyAppExitListener( *this );
310 xExitListener
= pExitListener
;
311 pExitListener
->Activate();
316 pExitListener
->Deactivate();
320 void DicList::SearchForDictionaries(
321 DictionaryVec_t
&rDicList
,
322 const String
&rDicDirURL
,
323 BOOL bIsWriteablePath
)
325 osl::MutexGuard
aGuard( GetLinguMutex() );
327 const uno::Sequence
< rtl::OUString
> aDirCnt( utl::LocalFileHelper::
328 GetFolderContents( rDicDirURL
, FALSE
) );
329 const rtl::OUString
*pDirCnt
= aDirCnt
.getConstArray();
330 INT32 nEntries
= aDirCnt
.getLength();
332 String
aDCN( String::CreateFromAscii( "dcn" ) );
333 String
aDCP( String::CreateFromAscii( "dcp" ) );
334 for (INT32 i
= 0; i
< nEntries
; ++i
)
336 String
aURL( pDirCnt
[i
] );
337 USHORT nLang
= LANGUAGE_NONE
;
340 if(!::IsVers2OrNewer( aURL
, nLang
, bNeg
))
343 xub_StrLen nPos
= aURL
.Search('.');
344 String
aExt(aURL
.Copy(nPos
+ 1));
347 if(aExt
== aDCN
) // negativ
349 else if(aExt
== aDCP
) // positiv
352 continue; // andere Files
355 // Aufnehmen in die Liste der Dictionaries
356 // Wenn existent nicht aufnehmen
358 INT16 nSystemLanguage
= MsLangId::getSystemLanguage();
359 String aTmp1
= ToLower( aURL
, nSystemLanguage
);
360 xub_StrLen nPos
= aTmp1
.SearchBackward( '/' );
361 if (STRING_NOTFOUND
!= nPos
)
362 aTmp1
= aTmp1
.Copy( nPos
+ 1 );
365 size_t nCount
= rDicList
.size();
366 for(j
= 0; j
< nCount
; j
++)
368 aTmp2
= rDicList
[j
]->getName().getStr();
369 aTmp2
= ToLower( aTmp2
, nSystemLanguage
);
373 if(j
>= nCount
) // dictionary not yet in DicList
375 // get decoded dictionary file name
376 INetURLObject
aURLObj( aURL
);
377 String aDicName
= aURLObj
.getName( INetURLObject::LAST_SEGMENT
,
378 true, INetURLObject::DECODE_WITH_CHARSET
,
379 RTL_TEXTENCODING_UTF8
);
381 DictionaryType eType
= bNeg
? DictionaryType_NEGATIVE
: DictionaryType_POSITIVE
;
382 uno::Reference
< XDictionary
> xDic
=
383 new DictionaryNeo( aDicName
, nLang
, eType
, aURL
, bIsWriteablePath
);
385 addDictionary( xDic
);
392 INT32
DicList::GetDicPos(const uno::Reference
< XDictionary
> &xDic
)
394 osl::MutexGuard
aGuard( GetLinguMutex() );
397 DictionaryVec_t
& rDicList
= GetOrCreateDicList();
398 size_t n
= rDicList
.size();
399 for (size_t i
= 0; i
< n
; i
++)
401 if ( rDicList
[i
] == xDic
)
408 uno::Reference
< XInterface
> SAL_CALL
409 DicList_CreateInstance( const uno::Reference
< XMultiServiceFactory
> & /*rSMgr*/ )
412 uno::Reference
< XInterface
> xService
= (cppu::OWeakObject
*) new DicList
;
416 sal_Int16 SAL_CALL
DicList::getCount() throw(RuntimeException
)
418 osl::MutexGuard
aGuard( GetLinguMutex() );
419 return static_cast< sal_Int16
>(GetOrCreateDicList().size());
422 uno::Sequence
< uno::Reference
< XDictionary
> > SAL_CALL
423 DicList::getDictionaries()
424 throw(RuntimeException
)
426 osl::MutexGuard
aGuard( GetLinguMutex() );
428 DictionaryVec_t
& rDicList
= GetOrCreateDicList();
430 uno::Sequence
< uno::Reference
< XDictionary
> > aDics( rDicList
.size() );
431 uno::Reference
< XDictionary
> *pDic
= aDics
.getArray();
433 INT32 n
= (USHORT
) aDics
.getLength();
434 for (INT32 i
= 0; i
< n
; i
++)
435 pDic
[i
] = rDicList
[i
];
440 uno::Reference
< XDictionary
> SAL_CALL
441 DicList::getDictionaryByName( const rtl::OUString
& aDictionaryName
)
442 throw(RuntimeException
)
444 osl::MutexGuard
aGuard( GetLinguMutex() );
446 uno::Reference
< XDictionary
> xDic
;
447 DictionaryVec_t
& rDicList
= GetOrCreateDicList();
448 size_t nCount
= rDicList
.size();
449 for (size_t i
= 0; i
< nCount
; i
++)
451 const uno::Reference
< XDictionary
> &rDic
= rDicList
[i
];
452 if (rDic
.is() && rDic
->getName() == aDictionaryName
)
462 sal_Bool SAL_CALL
DicList::addDictionary(
463 const uno::Reference
< XDictionary
>& xDictionary
)
464 throw(RuntimeException
)
466 osl::MutexGuard
aGuard( GetLinguMutex() );
472 if (xDictionary
.is())
474 DictionaryVec_t
& rDicList
= GetOrCreateDicList();
475 rDicList
.push_back( xDictionary
);
478 // add listener helper to the dictionaries listener lists
479 xDictionary
->addDictionaryEventListener( xDicEvtLstnrHelper
);
485 DicList::removeDictionary( const uno::Reference
< XDictionary
>& xDictionary
)
486 throw(RuntimeException
)
488 osl::MutexGuard
aGuard( GetLinguMutex() );
494 INT32 nPos
= GetDicPos( xDictionary
);
497 // remove dictionary list from the dictionaries listener lists
498 DictionaryVec_t
& rDicList
= GetOrCreateDicList();
499 uno::Reference
< XDictionary
> xDic( rDicList
[ nPos
] );
500 DBG_ASSERT(xDic
.is(), "lng : empty reference");
503 // deactivate dictionary if not already done
504 xDic
->setActive( FALSE
);
506 xDic
->removeDictionaryEventListener( xDicEvtLstnrHelper
);
509 // remove element at nPos
510 rDicList
.erase( rDicList
.begin() + nPos
);
516 sal_Bool SAL_CALL
DicList::addDictionaryListEventListener(
517 const uno::Reference
< XDictionaryListEventListener
>& xListener
,
518 sal_Bool bReceiveVerbose
)
519 throw(RuntimeException
)
521 osl::MutexGuard
aGuard( GetLinguMutex() );
526 DBG_ASSERT(!bReceiveVerbose
, "lng : not yet supported");
529 if (xListener
.is()) //! don't add empty references
531 bRes
= pDicEvtLstnrHelper
->
532 AddDicListEvtListener( xListener
, bReceiveVerbose
);
537 sal_Bool SAL_CALL
DicList::removeDictionaryListEventListener(
538 const uno::Reference
< XDictionaryListEventListener
>& xListener
)
539 throw(RuntimeException
)
541 osl::MutexGuard
aGuard( GetLinguMutex() );
549 bRes
= pDicEvtLstnrHelper
->RemoveDicListEvtListener( xListener
);
554 sal_Int16 SAL_CALL
DicList::beginCollectEvents() throw(RuntimeException
)
556 osl::MutexGuard
aGuard( GetLinguMutex() );
557 return pDicEvtLstnrHelper
->BeginCollectEvents();
560 sal_Int16 SAL_CALL
DicList::endCollectEvents() throw(RuntimeException
)
562 osl::MutexGuard
aGuard( GetLinguMutex() );
563 return pDicEvtLstnrHelper
->EndCollectEvents();
566 sal_Int16 SAL_CALL
DicList::flushEvents() throw(RuntimeException
)
568 osl::MutexGuard
aGuard( GetLinguMutex() );
569 return pDicEvtLstnrHelper
->FlushEvents();
572 uno::Reference
< XDictionary
> SAL_CALL
573 DicList::createDictionary( const rtl::OUString
& rName
, const Locale
& rLocale
,
574 DictionaryType eDicType
, const rtl::OUString
& rURL
)
575 throw(RuntimeException
)
577 osl::MutexGuard
aGuard( GetLinguMutex() );
579 INT16 nLanguage
= LocaleToLanguage( rLocale
);
580 bool bIsWriteablePath
= rURL
.match( GetDictionaryWriteablePath(), 0 );
581 return new DictionaryNeo( rName
, nLanguage
, eDicType
, rURL
, bIsWriteablePath
);
585 uno::Reference
< XDictionaryEntry
> SAL_CALL
586 DicList::queryDictionaryEntry( const rtl::OUString
& rWord
, const Locale
& rLocale
,
587 sal_Bool bSearchPosDics
, sal_Bool bSearchSpellEntry
)
588 throw(RuntimeException
)
590 osl::MutexGuard
aGuard( GetLinguMutex() );
591 return SearchDicList( this, rWord
, LocaleToLanguage( rLocale
),
592 bSearchPosDics
, bSearchSpellEntry
);
598 throw(RuntimeException
)
600 osl::MutexGuard
aGuard( GetLinguMutex() );
605 EventObject
aEvtObj( (XDictionaryList
*) this );
607 aEvtListeners
.disposeAndClear( aEvtObj
);
608 if (pDicEvtLstnrHelper
)
609 pDicEvtLstnrHelper
->DisposeAndClear( aEvtObj
);
611 //! avoid creation of dictionaries if not already done
612 if (aDicList
.size() > 0)
614 DictionaryVec_t
& rDicList
= GetOrCreateDicList();
615 size_t nCount
= rDicList
.size();
616 for (size_t i
= 0; i
< nCount
; i
++)
618 uno::Reference
< XDictionary
> xDic( rDicList
[i
], UNO_QUERY
);
620 // save (modified) dictionaries
621 uno::Reference
< frame::XStorable
> xStor( xDic
, UNO_QUERY
);
626 if (!xStor
->isReadonly() && xStor
->hasLocation())
634 // release references to (members of) this object hold by
637 xDic
->removeDictionaryEventListener( xDicEvtLstnrHelper
);
644 DicList::addEventListener( const uno::Reference
< XEventListener
>& rxListener
)
645 throw(RuntimeException
)
647 osl::MutexGuard
aGuard( GetLinguMutex() );
649 if (!bDisposing
&& rxListener
.is())
650 aEvtListeners
.addInterface( rxListener
);
654 DicList::removeEventListener( const uno::Reference
< XEventListener
>& rxListener
)
655 throw(RuntimeException
)
657 osl::MutexGuard
aGuard( GetLinguMutex() );
659 if (!bDisposing
&& rxListener
.is())
660 aEvtListeners
.removeInterface( rxListener
);
663 void DicList::_CreateDicList()
667 // look for dictionaries
668 const rtl::OUString
aWriteablePath( GetDictionaryWriteablePath() );
669 uno::Sequence
< rtl::OUString
> aPaths( GetDictionaryPaths() );
670 const rtl::OUString
*pPaths
= aPaths
.getConstArray();
671 for (sal_Int32 i
= 0; i
< aPaths
.getLength(); ++i
)
673 const BOOL bIsWriteablePath
= (pPaths
[i
] == aWriteablePath
);
674 SearchForDictionaries( aDicList
, pPaths
[i
], bIsWriteablePath
);
677 // create IgnoreAllList dictionary with empty URL (non persistent)
678 // and add it to list
679 rtl::OUString
aDicName( A2OU( "IgnoreAllList" ) );
680 uno::Reference
< XDictionary
> xIgnAll(
681 createDictionary( aDicName
, CreateLocale( LANGUAGE_NONE
),
682 DictionaryType_POSITIVE
, rtl::OUString() ) );
685 AddUserData( xIgnAll
);
686 xIgnAll
->setActive( TRUE
);
687 addDictionary( xIgnAll
);
691 // evaluate list of dictionaries to be activated from configuration
693 //! to suppress overwriting the list of active dictionaries in the
694 //! configuration with incorrect arguments during the following
695 //! activation of the dictionaries
696 pDicEvtLstnrHelper
->BeginCollectEvents();
698 const uno::Sequence
< rtl::OUString
> aActiveDics( aOpt
.GetActiveDics() );
699 const rtl::OUString
*pActiveDic
= aActiveDics
.getConstArray();
700 INT32 nLen
= aActiveDics
.getLength();
701 for (INT32 i
= 0; i
< nLen
; ++i
)
703 if (pActiveDic
[i
].getLength())
705 uno::Reference
< XDictionary
> xDic( getDictionaryByName( pActiveDic
[i
] ) );
707 xDic
->setActive( TRUE
);
711 // suppress collected events during creation of the dictionary list.
712 // there should be no events during creation.
713 pDicEvtLstnrHelper
->ClearEvents();
715 pDicEvtLstnrHelper
->EndCollectEvents();
721 void DicList::SaveDics()
723 // save dics only if they have already been used/created.
724 //! don't create them just for the purpose of saving them !
725 if (aDicList
.size() > 0)
727 // save (modified) dictionaries
728 DictionaryVec_t
& rDicList
= GetOrCreateDicList();
729 size_t nCount
= rDicList
.size();;
730 for (size_t i
= 0; i
< nCount
; i
++)
732 // save (modified) dictionaries
733 uno::Reference
< frame::XStorable
> xStor( rDicList
[i
], UNO_QUERY
);
738 if (!xStor
->isReadonly() && xStor
->hasLocation())
750 ///////////////////////////////////////////////////////////////////////////
751 // Service specific part
754 rtl::OUString SAL_CALL
DicList::getImplementationName( ) throw(RuntimeException
)
756 osl::MutexGuard
aGuard( GetLinguMutex() );
757 return getImplementationName_Static();
761 sal_Bool SAL_CALL
DicList::supportsService( const rtl::OUString
& ServiceName
)
762 throw(RuntimeException
)
764 osl::MutexGuard
aGuard( GetLinguMutex() );
766 uno::Sequence
< rtl::OUString
> aSNL
= getSupportedServiceNames();
767 const rtl::OUString
* pArray
= aSNL
.getConstArray();
768 for( INT32 i
= 0; i
< aSNL
.getLength(); i
++ )
769 if( pArray
[i
] == ServiceName
)
775 uno::Sequence
< rtl::OUString
> SAL_CALL
DicList::getSupportedServiceNames( )
776 throw(RuntimeException
)
778 osl::MutexGuard
aGuard( GetLinguMutex() );
779 return getSupportedServiceNames_Static();
783 uno::Sequence
< rtl::OUString
> DicList::getSupportedServiceNames_Static() throw()
785 osl::MutexGuard
aGuard( GetLinguMutex() );
787 uno::Sequence
< rtl::OUString
> aSNS( 1 ); // auch mehr als 1 Service moeglich
788 aSNS
.getArray()[0] = A2OU( SN_DICTIONARY_LIST
);
793 sal_Bool SAL_CALL
DicList_writeInfo(
794 void * /*pServiceManager*/, registry::XRegistryKey
* pRegistryKey
)
799 aImpl
+= DicList::getImplementationName_Static().getStr();
800 aImpl
.AppendAscii( "/UNO/SERVICES" );
801 uno::Reference
< registry::XRegistryKey
> xNewKey
=
802 pRegistryKey
->createKey(aImpl
);
803 uno::Sequence
< rtl::OUString
> aServices
=
804 DicList::getSupportedServiceNames_Static();
805 for( INT32 i
= 0; i
< aServices
.getLength(); i
++ )
806 xNewKey
->createKey( aServices
.getConstArray()[i
]);
817 void * SAL_CALL
DicList_getFactory( const sal_Char
* pImplName
,
818 XMultiServiceFactory
* pServiceManager
, void * )
821 if ( !DicList::getImplementationName_Static().compareToAscii( pImplName
) )
823 uno::Reference
< XSingleServiceFactory
> xFactory
=
824 cppu::createOneInstanceFactory(
826 DicList::getImplementationName_Static(),
827 DicList_CreateInstance
,
828 DicList::getSupportedServiceNames_Static());
829 // acquire, because we return an interface pointer instead of a reference
831 pRet
= xFactory
.get();
836 ///////////////////////////////////////////////////////////////////////////
838 xub_StrLen
lcl_GetToken( String
&rToken
,
839 const String
&rText
, xub_StrLen nPos
, const String
&rDelim
)
841 xub_StrLen nRes
= STRING_LEN
;
843 if (rText
.Len() == 0 || nPos
>= rText
.Len())
845 else if (rDelim
.Len() == 0)
854 for (i
= nPos
; i
< rText
.Len(); ++i
)
856 if (STRING_NOTFOUND
!= rDelim
.Search( rText
.GetChar(i
) ))
860 if (i
>= rText
.Len()) // delimeter not found
861 rToken
= rText
.Copy( nPos
);
863 rToken
= rText
.Copy( nPos
, sal::static_int_cast
< xub_StrLen
>((INT32
) i
- nPos
) );
864 nRes
= i
+ 1; // continue after found delimeter
871 static void AddInternal(
872 const uno::Reference
<XDictionary
> &rDic
,
873 const rtl::OUString
& rNew
)
877 //! TL TODO: word iterator should be used to break up the text
878 static const char *pDefWordDelim
=
879 "!\"#$%&'()*+,-./:;<=>?[]\\_^`{|}~\t \n";
880 ByteString
aDummy( pDefWordDelim
);
881 String
aDelim( aDummy
, osl_getThreadTextEncoding() );
882 aDelim
.EraseAllChars( '.' );
887 (nPos
= lcl_GetToken( aToken
, rNew
, nPos
, aDelim
)))
889 if( aToken
.Len() && !IsNumeric( aToken
) )
891 rDic
->add( aToken
, FALSE
, rtl::OUString() );
897 static void AddUserData( const uno::Reference
< XDictionary
> &rDic
)
901 SvtUserOptions aUserOpt
;
902 AddInternal( rDic
, aUserOpt
.GetFullName() );
903 AddInternal( rDic
, aUserOpt
.GetCompany() );
904 AddInternal( rDic
, aUserOpt
.GetStreet() );
905 AddInternal( rDic
, aUserOpt
.GetCity() );
906 AddInternal( rDic
, aUserOpt
.GetTitle() );
907 AddInternal( rDic
, aUserOpt
.GetPosition() );
908 AddInternal( rDic
, aUserOpt
.GetEmail() );
912 ///////////////////////////////////////////////////////////////////////////
915 #pragma optimize("g",off)
918 static BOOL
IsVers2OrNewer( const String
& rFileURL
, USHORT
& nLng
, BOOL
& bNeg
)
920 if (rFileURL
.Len() == 0)
922 String
aDIC( GetDicExtension() );
924 xub_StrLen nPos
= rFileURL
.SearchBackward( '.' );
925 if (STRING_NOTFOUND
!= nPos
)
926 aExt
= rFileURL
.Copy( nPos
+ 1 );
932 // get stream to be used
933 SfxMedium
aMedium( rFileURL
, STREAM_READ
| STREAM_SHARE_DENYWRITE
, FALSE
);
934 SvStream
*pStream
= aMedium
.GetInStream();
936 int nDicVersion
= ReadDicVersion (pStream
, nLng
, bNeg
);
937 if (2 == nDicVersion
|| nDicVersion
>= 5)
943 ///////////////////////////////////////////////////////////////////////////