xref: /aoo41x/main/linguistic/source/dlistimp.cxx (revision 3b8558fd)
1*3b8558fdSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*3b8558fdSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*3b8558fdSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*3b8558fdSAndrew Rist  * distributed with this work for additional information
6*3b8558fdSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*3b8558fdSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*3b8558fdSAndrew Rist  * "License"); you may not use this file except in compliance
9*3b8558fdSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*3b8558fdSAndrew Rist  *
11*3b8558fdSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*3b8558fdSAndrew Rist  *
13*3b8558fdSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*3b8558fdSAndrew Rist  * software distributed under the License is distributed on an
15*3b8558fdSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*3b8558fdSAndrew Rist  * KIND, either express or implied.  See the License for the
17*3b8558fdSAndrew Rist  * specific language governing permissions and limitations
18*3b8558fdSAndrew Rist  * under the License.
19*3b8558fdSAndrew Rist  *
20*3b8558fdSAndrew Rist  *************************************************************/
21*3b8558fdSAndrew Rist 
22*3b8558fdSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_linguistic.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <cppuhelper/factory.hxx>
28cdf0e10cSrcweir #include <i18npool/mslangid.hxx>
29cdf0e10cSrcweir #include <osl/file.hxx>
30cdf0e10cSrcweir #include <tools/fsys.hxx>
31cdf0e10cSrcweir #include <tools/stream.hxx>
32cdf0e10cSrcweir #include <tools/urlobj.hxx>
33cdf0e10cSrcweir #include <i18npool/mslangid.hxx>
34cdf0e10cSrcweir #include <unotools/pathoptions.hxx>
35cdf0e10cSrcweir #include <unotools/useroptions.hxx>
36cdf0e10cSrcweir #include <cppuhelper/factory.hxx>	// helper for factories
37cdf0e10cSrcweir #include <unotools/localfilehelper.hxx>
38cdf0e10cSrcweir #include <comphelper/processfactory.hxx>
39cdf0e10cSrcweir #include <unotools/ucbstreamhelper.hxx>
40cdf0e10cSrcweir #include <com/sun/star/frame/XStorable.hpp>
41cdf0e10cSrcweir #include <com/sun/star/lang/Locale.hpp>
42cdf0e10cSrcweir #include <com/sun/star/uno/Reference.h>
43cdf0e10cSrcweir #include <com/sun/star/linguistic2/DictionaryEventFlags.hpp>
44cdf0e10cSrcweir #include <com/sun/star/linguistic2/DictionaryListEventFlags.hpp>
45cdf0e10cSrcweir #include <com/sun/star/registry/XRegistryKey.hpp>
46cdf0e10cSrcweir #include <com/sun/star/ucb/XSimpleFileAccess.hpp>
47cdf0e10cSrcweir 
48cdf0e10cSrcweir #include "defs.hxx"
49cdf0e10cSrcweir #include "dlistimp.hxx"
50cdf0e10cSrcweir #include "dicimp.hxx"
51cdf0e10cSrcweir #include "lngopt.hxx"
52cdf0e10cSrcweir 
53cdf0e10cSrcweir #include "defs.hxx"
54cdf0e10cSrcweir #include "dlistimp.hxx"
55cdf0e10cSrcweir #include "dicimp.hxx"
56cdf0e10cSrcweir #include "lngopt.hxx"
57cdf0e10cSrcweir 
58cdf0e10cSrcweir //using namespace utl;
59cdf0e10cSrcweir using namespace osl;
60cdf0e10cSrcweir using namespace rtl;
61cdf0e10cSrcweir using namespace com::sun::star;
62cdf0e10cSrcweir using namespace com::sun::star::lang;
63cdf0e10cSrcweir using namespace com::sun::star::uno;
64cdf0e10cSrcweir using namespace com::sun::star::linguistic2;
65cdf0e10cSrcweir using namespace linguistic;
66cdf0e10cSrcweir 
67cdf0e10cSrcweir ///////////////////////////////////////////////////////////////////////////
68cdf0e10cSrcweir 
69cdf0e10cSrcweir static sal_Bool IsVers2OrNewer( const String& rFileURL, sal_uInt16& nLng, sal_Bool& bNeg );
70cdf0e10cSrcweir 
71cdf0e10cSrcweir static void AddInternal( const uno::Reference< XDictionary > &rDic,
72cdf0e10cSrcweir                          const rtl::OUString& rNew );
73cdf0e10cSrcweir static void AddUserData( const uno::Reference< XDictionary > &rDic );
74cdf0e10cSrcweir 
75cdf0e10cSrcweir ///////////////////////////////////////////////////////////////////////////
76cdf0e10cSrcweir 
77cdf0e10cSrcweir class DicEvtListenerHelper :
78cdf0e10cSrcweir 	public cppu::WeakImplHelper1
79cdf0e10cSrcweir 	<
80cdf0e10cSrcweir 		XDictionaryEventListener
81cdf0e10cSrcweir 	>
82cdf0e10cSrcweir {
83cdf0e10cSrcweir     cppu::OInterfaceContainerHelper         aDicListEvtListeners;
84cdf0e10cSrcweir     uno::Sequence< DictionaryEvent >        aCollectDicEvt;
85cdf0e10cSrcweir 	uno::Reference< XDictionaryList >		xMyDicList;
86cdf0e10cSrcweir 
87cdf0e10cSrcweir 	sal_Int16								nCondensedEvt;
88cdf0e10cSrcweir 	sal_Int16								nNumCollectEvtListeners,
89cdf0e10cSrcweir 		 								nNumVerboseListeners;
90cdf0e10cSrcweir 
91cdf0e10cSrcweir public:
92cdf0e10cSrcweir 	DicEvtListenerHelper( const uno::Reference< XDictionaryList > &rxDicList );
93cdf0e10cSrcweir 	virtual ~DicEvtListenerHelper();
94cdf0e10cSrcweir 
95cdf0e10cSrcweir 	// XEventListener
96cdf0e10cSrcweir 	virtual void SAL_CALL
97cdf0e10cSrcweir 		disposing( const EventObject& rSource )
98cdf0e10cSrcweir 			throw(RuntimeException);
99cdf0e10cSrcweir 
100cdf0e10cSrcweir 	// XDictionaryEventListener
101cdf0e10cSrcweir     virtual void SAL_CALL
102cdf0e10cSrcweir 		processDictionaryEvent( const DictionaryEvent& rDicEvent )
103cdf0e10cSrcweir 			throw(RuntimeException);
104cdf0e10cSrcweir 
105cdf0e10cSrcweir 	// non-UNO functions
106cdf0e10cSrcweir 	void 	DisposeAndClear( const EventObject &rEvtObj );
107cdf0e10cSrcweir 
108cdf0e10cSrcweir     sal_Bool	AddDicListEvtListener(
109cdf0e10cSrcweir 				const uno::Reference< XDictionaryListEventListener >& rxListener,
110cdf0e10cSrcweir 				sal_Bool bReceiveVerbose );
111cdf0e10cSrcweir     sal_Bool	RemoveDicListEvtListener(
112cdf0e10cSrcweir 				const uno::Reference< XDictionaryListEventListener >& rxListener );
113cdf0e10cSrcweir     sal_Int16	BeginCollectEvents();
114cdf0e10cSrcweir     sal_Int16	EndCollectEvents();
115cdf0e10cSrcweir     sal_Int16	FlushEvents();
ClearEvents()116cdf0e10cSrcweir     void    ClearEvents()   { nCondensedEvt = 0; }
117cdf0e10cSrcweir };
118cdf0e10cSrcweir 
119cdf0e10cSrcweir 
DicEvtListenerHelper(const uno::Reference<XDictionaryList> & rxDicList)120cdf0e10cSrcweir DicEvtListenerHelper::DicEvtListenerHelper(
121cdf0e10cSrcweir 		const uno::Reference< XDictionaryList > &rxDicList ) :
122cdf0e10cSrcweir 	aDicListEvtListeners	( GetLinguMutex() ),
123cdf0e10cSrcweir 	xMyDicList				( rxDicList )
124cdf0e10cSrcweir {
125cdf0e10cSrcweir 	nCondensedEvt	= 0;
126cdf0e10cSrcweir 	nNumCollectEvtListeners = nNumVerboseListeners	= 0;
127cdf0e10cSrcweir }
128cdf0e10cSrcweir 
129cdf0e10cSrcweir 
~DicEvtListenerHelper()130cdf0e10cSrcweir DicEvtListenerHelper::~DicEvtListenerHelper()
131cdf0e10cSrcweir {
132cdf0e10cSrcweir 	DBG_ASSERT(aDicListEvtListeners.getLength() == 0,
133cdf0e10cSrcweir 		"lng : event listeners are still existing");
134cdf0e10cSrcweir }
135cdf0e10cSrcweir 
136cdf0e10cSrcweir 
DisposeAndClear(const EventObject & rEvtObj)137cdf0e10cSrcweir void DicEvtListenerHelper::DisposeAndClear( const EventObject &rEvtObj )
138cdf0e10cSrcweir {
139cdf0e10cSrcweir 	aDicListEvtListeners.disposeAndClear( rEvtObj );
140cdf0e10cSrcweir }
141cdf0e10cSrcweir 
142cdf0e10cSrcweir 
disposing(const EventObject & rSource)143cdf0e10cSrcweir void SAL_CALL DicEvtListenerHelper::disposing( const EventObject& rSource )
144cdf0e10cSrcweir 		throw(RuntimeException)
145cdf0e10cSrcweir {
146cdf0e10cSrcweir     osl::MutexGuard aGuard( GetLinguMutex() );
147cdf0e10cSrcweir 
148cdf0e10cSrcweir 	uno::Reference< XInterface > xSrc( rSource.Source );
149cdf0e10cSrcweir 
150cdf0e10cSrcweir 	// remove event object from EventListener list
151cdf0e10cSrcweir 	if (xSrc.is())
152cdf0e10cSrcweir 		aDicListEvtListeners.removeInterface( xSrc );
153cdf0e10cSrcweir 
154cdf0e10cSrcweir 	// if object is a dictionary then remove it from the dictionary list
155cdf0e10cSrcweir 	// Note: this will probably happen only if someone makes a XDictionary
156cdf0e10cSrcweir 	// implementation of his own that is also a XComponent.
157cdf0e10cSrcweir 	uno::Reference< XDictionary > xDic( xSrc, UNO_QUERY );
158cdf0e10cSrcweir 	if (xDic.is())
159cdf0e10cSrcweir 	{
160cdf0e10cSrcweir 		xMyDicList->removeDictionary( xDic );
161cdf0e10cSrcweir 	}
162cdf0e10cSrcweir }
163cdf0e10cSrcweir 
164cdf0e10cSrcweir 
processDictionaryEvent(const DictionaryEvent & rDicEvent)165cdf0e10cSrcweir void SAL_CALL DicEvtListenerHelper::processDictionaryEvent(
166cdf0e10cSrcweir 			const DictionaryEvent& rDicEvent )
167cdf0e10cSrcweir 		throw(RuntimeException)
168cdf0e10cSrcweir {
169cdf0e10cSrcweir     osl::MutexGuard aGuard( GetLinguMutex() );
170cdf0e10cSrcweir 
171cdf0e10cSrcweir 	uno::Reference< XDictionary > xDic( rDicEvent.Source, UNO_QUERY );
172cdf0e10cSrcweir 	DBG_ASSERT(xDic.is(), "lng : missing event source");
173cdf0e10cSrcweir 
174cdf0e10cSrcweir 	// assert that there is a corresponding dictionary entry if one was
175cdf0e10cSrcweir 	// added or deleted
176cdf0e10cSrcweir 	uno::Reference< XDictionaryEntry > xDicEntry( rDicEvent.xDictionaryEntry, UNO_QUERY );
177cdf0e10cSrcweir 	DBG_ASSERT( !(rDicEvent.nEvent &
178cdf0e10cSrcweir 					(DictionaryEventFlags::ADD_ENTRY | DictionaryEventFlags::DEL_ENTRY))
179cdf0e10cSrcweir 				|| xDicEntry.is(),
180cdf0e10cSrcweir 				"lng : missing dictionary entry" );
181cdf0e10cSrcweir 
182cdf0e10cSrcweir     /*sal_Bool bActiveDicsModified = sal_False;*/
183cdf0e10cSrcweir 	//
184cdf0e10cSrcweir 	// evaluate DictionaryEvents and update data for next DictionaryListEvent
185cdf0e10cSrcweir 	//
186cdf0e10cSrcweir 	DictionaryType eDicType = xDic->getDictionaryType();
187cdf0e10cSrcweir 	DBG_ASSERT(eDicType != DictionaryType_MIXED,
188cdf0e10cSrcweir 		"lng : unexpected dictionary type");
189cdf0e10cSrcweir 	if ((rDicEvent.nEvent & DictionaryEventFlags::ADD_ENTRY) && xDic->isActive())
190cdf0e10cSrcweir 		nCondensedEvt |= xDicEntry->isNegative() ?
191cdf0e10cSrcweir 			DictionaryListEventFlags::ADD_NEG_ENTRY :
192cdf0e10cSrcweir 			DictionaryListEventFlags::ADD_POS_ENTRY;
193cdf0e10cSrcweir 	if ((rDicEvent.nEvent & DictionaryEventFlags::DEL_ENTRY) && xDic->isActive())
194cdf0e10cSrcweir 		nCondensedEvt |= xDicEntry->isNegative() ?
195cdf0e10cSrcweir 			DictionaryListEventFlags::DEL_NEG_ENTRY :
196cdf0e10cSrcweir 			DictionaryListEventFlags::DEL_POS_ENTRY;
197cdf0e10cSrcweir 	if ((rDicEvent.nEvent & DictionaryEventFlags::ENTRIES_CLEARED) && xDic->isActive())
198cdf0e10cSrcweir 		nCondensedEvt |= eDicType == DictionaryType_NEGATIVE ?
199cdf0e10cSrcweir 			DictionaryListEventFlags::DEL_NEG_ENTRY :
200cdf0e10cSrcweir 			DictionaryListEventFlags::DEL_POS_ENTRY;
201cdf0e10cSrcweir 	if ((rDicEvent.nEvent & DictionaryEventFlags::CHG_LANGUAGE) && xDic->isActive())
202cdf0e10cSrcweir 		nCondensedEvt |= eDicType == DictionaryType_NEGATIVE ?
203cdf0e10cSrcweir 			DictionaryListEventFlags::DEACTIVATE_NEG_DIC
204cdf0e10cSrcweir 				| DictionaryListEventFlags::ACTIVATE_NEG_DIC :
205cdf0e10cSrcweir 			DictionaryListEventFlags::DEACTIVATE_POS_DIC
206cdf0e10cSrcweir 				| DictionaryListEventFlags::ACTIVATE_POS_DIC;
207cdf0e10cSrcweir 	if ((rDicEvent.nEvent & DictionaryEventFlags::ACTIVATE_DIC))
208cdf0e10cSrcweir 		nCondensedEvt |= eDicType == DictionaryType_NEGATIVE ?
209cdf0e10cSrcweir 			DictionaryListEventFlags::ACTIVATE_NEG_DIC :
210cdf0e10cSrcweir 			DictionaryListEventFlags::ACTIVATE_POS_DIC;
211cdf0e10cSrcweir 	if ((rDicEvent.nEvent & DictionaryEventFlags::DEACTIVATE_DIC))
212cdf0e10cSrcweir 		nCondensedEvt |= eDicType == DictionaryType_NEGATIVE ?
213cdf0e10cSrcweir 			DictionaryListEventFlags::DEACTIVATE_NEG_DIC :
214cdf0e10cSrcweir 			DictionaryListEventFlags::DEACTIVATE_POS_DIC;
215cdf0e10cSrcweir 
216cdf0e10cSrcweir 	// update list of collected events if needs to be
217cdf0e10cSrcweir 	if (nNumVerboseListeners > 0)
218cdf0e10cSrcweir 	{
219cdf0e10cSrcweir 		sal_Int32 nColEvts = aCollectDicEvt.getLength();
220cdf0e10cSrcweir 		aCollectDicEvt.realloc( nColEvts + 1 );
221cdf0e10cSrcweir 		aCollectDicEvt.getArray()[ nColEvts ] = rDicEvent;
222cdf0e10cSrcweir 	}
223cdf0e10cSrcweir 
224cdf0e10cSrcweir 	if (nNumCollectEvtListeners == 0 && nCondensedEvt != 0)
225cdf0e10cSrcweir 		FlushEvents();
226cdf0e10cSrcweir }
227cdf0e10cSrcweir 
228cdf0e10cSrcweir 
AddDicListEvtListener(const uno::Reference<XDictionaryListEventListener> & xListener,sal_Bool)229cdf0e10cSrcweir sal_Bool DicEvtListenerHelper::AddDicListEvtListener(
230cdf0e10cSrcweir 			const uno::Reference< XDictionaryListEventListener >& xListener,
231cdf0e10cSrcweir             sal_Bool /*bReceiveVerbose*/ )
232cdf0e10cSrcweir {
233cdf0e10cSrcweir 	DBG_ASSERT( xListener.is(), "empty reference" );
234cdf0e10cSrcweir 	sal_Int32	nCount = aDicListEvtListeners.getLength();
235cdf0e10cSrcweir 	return aDicListEvtListeners.addInterface( xListener ) != nCount;
236cdf0e10cSrcweir }
237cdf0e10cSrcweir 
238cdf0e10cSrcweir 
RemoveDicListEvtListener(const uno::Reference<XDictionaryListEventListener> & xListener)239cdf0e10cSrcweir sal_Bool DicEvtListenerHelper::RemoveDicListEvtListener(
240cdf0e10cSrcweir 			const uno::Reference< XDictionaryListEventListener >& xListener )
241cdf0e10cSrcweir {
242cdf0e10cSrcweir 	DBG_ASSERT( xListener.is(), "empty reference" );
243cdf0e10cSrcweir 	sal_Int32	nCount = aDicListEvtListeners.getLength();
244cdf0e10cSrcweir 	return aDicListEvtListeners.removeInterface( xListener ) != nCount;
245cdf0e10cSrcweir }
246cdf0e10cSrcweir 
247cdf0e10cSrcweir 
BeginCollectEvents()248cdf0e10cSrcweir sal_Int16 DicEvtListenerHelper::BeginCollectEvents()
249cdf0e10cSrcweir {
250cdf0e10cSrcweir 	return ++nNumCollectEvtListeners;
251cdf0e10cSrcweir }
252cdf0e10cSrcweir 
253cdf0e10cSrcweir 
EndCollectEvents()254cdf0e10cSrcweir sal_Int16 DicEvtListenerHelper::EndCollectEvents()
255cdf0e10cSrcweir {
256cdf0e10cSrcweir 	DBG_ASSERT(nNumCollectEvtListeners > 0, "lng: mismatched function call");
257cdf0e10cSrcweir 	if (nNumCollectEvtListeners > 0)
258cdf0e10cSrcweir 	{
259cdf0e10cSrcweir 		FlushEvents();
260cdf0e10cSrcweir 		nNumCollectEvtListeners--;
261cdf0e10cSrcweir 	}
262cdf0e10cSrcweir 
263cdf0e10cSrcweir 	return nNumCollectEvtListeners;
264cdf0e10cSrcweir }
265cdf0e10cSrcweir 
266cdf0e10cSrcweir 
FlushEvents()267cdf0e10cSrcweir sal_Int16 DicEvtListenerHelper::FlushEvents()
268cdf0e10cSrcweir {
269cdf0e10cSrcweir 	if (0 != nCondensedEvt)
270cdf0e10cSrcweir 	{
271cdf0e10cSrcweir 		// build DictionaryListEvent to pass on to listeners
272cdf0e10cSrcweir 		uno::Sequence< DictionaryEvent > aDicEvents;
273cdf0e10cSrcweir 		if (nNumVerboseListeners > 0)
274cdf0e10cSrcweir 			aDicEvents = aCollectDicEvt;
275cdf0e10cSrcweir 		DictionaryListEvent aEvent( xMyDicList, nCondensedEvt, aDicEvents );
276cdf0e10cSrcweir 
277cdf0e10cSrcweir 		// pass on event
278cdf0e10cSrcweir 		cppu::OInterfaceIteratorHelper aIt( aDicListEvtListeners );
279cdf0e10cSrcweir 		while (aIt.hasMoreElements())
280cdf0e10cSrcweir 		{
281cdf0e10cSrcweir 			uno::Reference< XDictionaryListEventListener > xRef( aIt.next(), UNO_QUERY );
282cdf0e10cSrcweir 			if (xRef.is())
283cdf0e10cSrcweir 				xRef->processDictionaryListEvent( aEvent );
284cdf0e10cSrcweir 		}
285cdf0e10cSrcweir 
286cdf0e10cSrcweir 		// clear "list" of events
287cdf0e10cSrcweir 		nCondensedEvt = 0;
288cdf0e10cSrcweir 		aCollectDicEvt.realloc( 0 );
289cdf0e10cSrcweir 	}
290cdf0e10cSrcweir 
291cdf0e10cSrcweir 	return nNumCollectEvtListeners;
292cdf0e10cSrcweir }
293cdf0e10cSrcweir 
294cdf0e10cSrcweir 
295cdf0e10cSrcweir ///////////////////////////////////////////////////////////////////////////
296cdf0e10cSrcweir 
297cdf0e10cSrcweir 
AtExit()298cdf0e10cSrcweir void DicList::MyAppExitListener::AtExit()
299cdf0e10cSrcweir {
300cdf0e10cSrcweir     rMyDicList.SaveDics();
301cdf0e10cSrcweir }
302cdf0e10cSrcweir 
303cdf0e10cSrcweir 
DicList()304cdf0e10cSrcweir DicList::DicList() :
305cdf0e10cSrcweir     aEvtListeners   ( GetLinguMutex() )
306cdf0e10cSrcweir {
307cdf0e10cSrcweir 	pDicEvtLstnrHelper	= new DicEvtListenerHelper( this );
308cdf0e10cSrcweir 	xDicEvtLstnrHelper	= pDicEvtLstnrHelper;
309cdf0e10cSrcweir 	bDisposing = sal_False;
310cdf0e10cSrcweir     bInCreation = sal_False;
311cdf0e10cSrcweir 
312cdf0e10cSrcweir 	pExitListener = new MyAppExitListener( *this );
313cdf0e10cSrcweir 	xExitListener = pExitListener;
314cdf0e10cSrcweir 	pExitListener->Activate();
315cdf0e10cSrcweir }
316cdf0e10cSrcweir 
~DicList()317cdf0e10cSrcweir DicList::~DicList()
318cdf0e10cSrcweir {
319cdf0e10cSrcweir 	pExitListener->Deactivate();
320cdf0e10cSrcweir }
321cdf0e10cSrcweir 
322cdf0e10cSrcweir 
SearchForDictionaries(DictionaryVec_t & rDicList,const String & rDicDirURL,sal_Bool bIsWriteablePath)323cdf0e10cSrcweir void DicList::SearchForDictionaries(
324cdf0e10cSrcweir     DictionaryVec_t&rDicList,
325cdf0e10cSrcweir     const String &rDicDirURL,
326cdf0e10cSrcweir     sal_Bool bIsWriteablePath )
327cdf0e10cSrcweir {
328cdf0e10cSrcweir     osl::MutexGuard aGuard( GetLinguMutex() );
329cdf0e10cSrcweir 
330cdf0e10cSrcweir     const uno::Sequence< rtl::OUString > aDirCnt( utl::LocalFileHelper::
331cdf0e10cSrcweir                                         GetFolderContents( rDicDirURL, sal_False ) );
332cdf0e10cSrcweir     const rtl::OUString *pDirCnt = aDirCnt.getConstArray();
333cdf0e10cSrcweir 	sal_Int32 nEntries = aDirCnt.getLength();
334cdf0e10cSrcweir 
335cdf0e10cSrcweir 	String aDCN( String::CreateFromAscii( "dcn" ) );
336cdf0e10cSrcweir 	String aDCP( String::CreateFromAscii( "dcp" ) );
337cdf0e10cSrcweir 	for (sal_Int32 i = 0;  i < nEntries;  ++i)
338cdf0e10cSrcweir 	{
339cdf0e10cSrcweir         String  aURL( pDirCnt[i] );
340cdf0e10cSrcweir 		sal_uInt16	nLang = LANGUAGE_NONE;
341cdf0e10cSrcweir 		sal_Bool	bNeg  = sal_False;
342cdf0e10cSrcweir 
343cdf0e10cSrcweir         if(!::IsVers2OrNewer( aURL, nLang, bNeg ))
344cdf0e10cSrcweir 		{
345cdf0e10cSrcweir 			// Wenn kein
346cdf0e10cSrcweir             xub_StrLen nPos  = aURL.Search('.');
347cdf0e10cSrcweir             String aExt(aURL.Copy(nPos + 1));
348cdf0e10cSrcweir 			aExt.ToLowerAscii();
349cdf0e10cSrcweir 
350cdf0e10cSrcweir 			if(aExt == aDCN)       // negativ
351cdf0e10cSrcweir 				bNeg = sal_True;
352cdf0e10cSrcweir 			else if(aExt == aDCP)  // positiv
353cdf0e10cSrcweir 				bNeg = sal_False;
354cdf0e10cSrcweir 			else
355cdf0e10cSrcweir 				continue;          // andere Files
356cdf0e10cSrcweir 		}
357cdf0e10cSrcweir 
358cdf0e10cSrcweir 		// Aufnehmen in die Liste der Dictionaries
359cdf0e10cSrcweir 		// Wenn existent nicht aufnehmen
360cdf0e10cSrcweir 		//
361cdf0e10cSrcweir 		sal_Int16 nSystemLanguage = MsLangId::getSystemLanguage();
362cdf0e10cSrcweir         String aTmp1 = ToLower( aURL, nSystemLanguage );
363cdf0e10cSrcweir 		xub_StrLen nPos = aTmp1.SearchBackward( '/' );
364cdf0e10cSrcweir 		if (STRING_NOTFOUND != nPos)
365cdf0e10cSrcweir 			aTmp1 = aTmp1.Copy( nPos + 1 );
366cdf0e10cSrcweir 		String aTmp2;
367cdf0e10cSrcweir         size_t j;
368cdf0e10cSrcweir         size_t nCount = rDicList.size();
369cdf0e10cSrcweir 		for(j = 0;  j < nCount;  j++)
370cdf0e10cSrcweir 		{
371cdf0e10cSrcweir             aTmp2 = rDicList[j]->getName().getStr();
372cdf0e10cSrcweir 			aTmp2 = ToLower( aTmp2, nSystemLanguage );
373cdf0e10cSrcweir 			if(aTmp1 == aTmp2)
374cdf0e10cSrcweir 				break;
375cdf0e10cSrcweir 		}
376cdf0e10cSrcweir 		if(j >= nCount)		// dictionary not yet in DicList
377cdf0e10cSrcweir 		{
378cdf0e10cSrcweir             // get decoded dictionary file name
379cdf0e10cSrcweir             INetURLObject aURLObj( aURL );
380cdf0e10cSrcweir             String aDicName = aURLObj.getName( INetURLObject::LAST_SEGMENT,
381cdf0e10cSrcweir                         true, INetURLObject::DECODE_WITH_CHARSET,
382cdf0e10cSrcweir                         RTL_TEXTENCODING_UTF8 );
383cdf0e10cSrcweir 
384cdf0e10cSrcweir             DictionaryType eType = bNeg ? DictionaryType_NEGATIVE : DictionaryType_POSITIVE;
385cdf0e10cSrcweir 			uno::Reference< XDictionary > xDic =
386cdf0e10cSrcweir                         new DictionaryNeo( aDicName, nLang, eType, aURL, bIsWriteablePath );
387cdf0e10cSrcweir 
388cdf0e10cSrcweir 			addDictionary( xDic );
389cdf0e10cSrcweir 			nCount++;
390cdf0e10cSrcweir 		}
391cdf0e10cSrcweir 	}
392cdf0e10cSrcweir }
393cdf0e10cSrcweir 
394cdf0e10cSrcweir 
GetDicPos(const uno::Reference<XDictionary> & xDic)395cdf0e10cSrcweir sal_Int32 DicList::GetDicPos(const uno::Reference< XDictionary > &xDic)
396cdf0e10cSrcweir {
397cdf0e10cSrcweir     osl::MutexGuard aGuard( GetLinguMutex() );
398cdf0e10cSrcweir 
399cdf0e10cSrcweir 	sal_Int32 nPos = -1;
400cdf0e10cSrcweir     DictionaryVec_t& rDicList = GetOrCreateDicList();
401cdf0e10cSrcweir     size_t n = rDicList.size();
402cdf0e10cSrcweir     for (size_t i = 0;  i < n;  i++)
403cdf0e10cSrcweir 	{
404cdf0e10cSrcweir         if ( rDicList[i] == xDic )
405cdf0e10cSrcweir 			return i;
406cdf0e10cSrcweir 	}
407cdf0e10cSrcweir 	return nPos;
408cdf0e10cSrcweir }
409cdf0e10cSrcweir 
410cdf0e10cSrcweir 
411cdf0e10cSrcweir uno::Reference< XInterface > SAL_CALL
DicList_CreateInstance(const uno::Reference<XMultiServiceFactory> &)412cdf0e10cSrcweir     DicList_CreateInstance( const uno::Reference< XMultiServiceFactory > & /*rSMgr*/ )
413cdf0e10cSrcweir 			throw(Exception)
414cdf0e10cSrcweir {
415cdf0e10cSrcweir 	uno::Reference< XInterface > xService = (cppu::OWeakObject *) new DicList;
416cdf0e10cSrcweir 	return xService;
417cdf0e10cSrcweir }
418cdf0e10cSrcweir 
getCount()419cdf0e10cSrcweir sal_Int16 SAL_CALL DicList::getCount() throw(RuntimeException)
420cdf0e10cSrcweir {
421cdf0e10cSrcweir     osl::MutexGuard aGuard( GetLinguMutex() );
422cdf0e10cSrcweir     return static_cast< sal_Int16 >(GetOrCreateDicList().size());
423cdf0e10cSrcweir }
424cdf0e10cSrcweir 
425cdf0e10cSrcweir uno::Sequence< uno::Reference< XDictionary > > SAL_CALL
getDictionaries()426cdf0e10cSrcweir 		DicList::getDictionaries()
427cdf0e10cSrcweir 			throw(RuntimeException)
428cdf0e10cSrcweir {
429cdf0e10cSrcweir     osl::MutexGuard aGuard( GetLinguMutex() );
430cdf0e10cSrcweir 
431cdf0e10cSrcweir     DictionaryVec_t& rDicList = GetOrCreateDicList();
432cdf0e10cSrcweir 
433cdf0e10cSrcweir     uno::Sequence< uno::Reference< XDictionary > > aDics( rDicList.size() );
434cdf0e10cSrcweir 	uno::Reference< XDictionary > *pDic = aDics.getArray();
435cdf0e10cSrcweir 
436cdf0e10cSrcweir     sal_Int32 n = (sal_uInt16) aDics.getLength();
437cdf0e10cSrcweir     for (sal_Int32 i = 0;  i < n;  i++)
438cdf0e10cSrcweir         pDic[i] = rDicList[i];
439cdf0e10cSrcweir 
440cdf0e10cSrcweir 	return aDics;
441cdf0e10cSrcweir }
442cdf0e10cSrcweir 
443cdf0e10cSrcweir uno::Reference< XDictionary > SAL_CALL
getDictionaryByName(const rtl::OUString & aDictionaryName)444cdf0e10cSrcweir         DicList::getDictionaryByName( const rtl::OUString& aDictionaryName )
445cdf0e10cSrcweir 			throw(RuntimeException)
446cdf0e10cSrcweir {
447cdf0e10cSrcweir     osl::MutexGuard aGuard( GetLinguMutex() );
448cdf0e10cSrcweir 
449cdf0e10cSrcweir 	uno::Reference< XDictionary > xDic;
450cdf0e10cSrcweir     DictionaryVec_t& rDicList = GetOrCreateDicList();
451cdf0e10cSrcweir     size_t nCount = rDicList.size();
452cdf0e10cSrcweir     for (size_t i = 0;  i < nCount;  i++)
453cdf0e10cSrcweir 	{
454cdf0e10cSrcweir         const uno::Reference< XDictionary > &rDic = rDicList[i];
455cdf0e10cSrcweir 		if (rDic.is()  &&  rDic->getName() == aDictionaryName)
456cdf0e10cSrcweir 		{
457cdf0e10cSrcweir 			xDic = rDic;
458cdf0e10cSrcweir 			break;
459cdf0e10cSrcweir 		}
460cdf0e10cSrcweir 	}
461cdf0e10cSrcweir 
462cdf0e10cSrcweir 	return xDic;
463cdf0e10cSrcweir }
464cdf0e10cSrcweir 
addDictionary(const uno::Reference<XDictionary> & xDictionary)465cdf0e10cSrcweir sal_Bool SAL_CALL DicList::addDictionary(
466cdf0e10cSrcweir 			const uno::Reference< XDictionary >& xDictionary )
467cdf0e10cSrcweir 		throw(RuntimeException)
468cdf0e10cSrcweir {
469cdf0e10cSrcweir     osl::MutexGuard aGuard( GetLinguMutex() );
470cdf0e10cSrcweir 
471cdf0e10cSrcweir 	if (bDisposing)
472cdf0e10cSrcweir 		return sal_False;
473cdf0e10cSrcweir 
474cdf0e10cSrcweir 	sal_Bool bRes = sal_False;
475cdf0e10cSrcweir 	if (xDictionary.is())
476cdf0e10cSrcweir 	{
477cdf0e10cSrcweir         DictionaryVec_t& rDicList = GetOrCreateDicList();
478cdf0e10cSrcweir         rDicList.push_back( xDictionary );
479cdf0e10cSrcweir 		bRes = sal_True;
480cdf0e10cSrcweir 
481cdf0e10cSrcweir 		// add listener helper to the dictionaries listener lists
482cdf0e10cSrcweir 		xDictionary->addDictionaryEventListener( xDicEvtLstnrHelper );
483cdf0e10cSrcweir 	}
484cdf0e10cSrcweir 	return bRes;
485cdf0e10cSrcweir }
486cdf0e10cSrcweir 
487cdf0e10cSrcweir sal_Bool SAL_CALL
removeDictionary(const uno::Reference<XDictionary> & xDictionary)488cdf0e10cSrcweir 	DicList::removeDictionary( const uno::Reference< XDictionary >& xDictionary )
489cdf0e10cSrcweir 		throw(RuntimeException)
490cdf0e10cSrcweir {
491cdf0e10cSrcweir     osl::MutexGuard aGuard( GetLinguMutex() );
492cdf0e10cSrcweir 
493cdf0e10cSrcweir 	if (bDisposing)
494cdf0e10cSrcweir 		return sal_False;
495cdf0e10cSrcweir 
496cdf0e10cSrcweir 	sal_Bool  bRes = sal_False;
497cdf0e10cSrcweir     sal_Int32 nPos = GetDicPos( xDictionary );
498cdf0e10cSrcweir 	if (nPos >= 0)
499cdf0e10cSrcweir 	{
500cdf0e10cSrcweir 		// remove dictionary list from the dictionaries listener lists
501cdf0e10cSrcweir         DictionaryVec_t& rDicList = GetOrCreateDicList();
502cdf0e10cSrcweir         uno::Reference< XDictionary > xDic( rDicList[ nPos ] );
503cdf0e10cSrcweir 		DBG_ASSERT(xDic.is(), "lng : empty reference");
504cdf0e10cSrcweir 		if (xDic.is())
505cdf0e10cSrcweir 		{
506cdf0e10cSrcweir 			// deactivate dictionary if not already done
507cdf0e10cSrcweir 			xDic->setActive( sal_False );
508cdf0e10cSrcweir 
509cdf0e10cSrcweir 			xDic->removeDictionaryEventListener( xDicEvtLstnrHelper );
510cdf0e10cSrcweir 		}
511cdf0e10cSrcweir 
512cdf0e10cSrcweir         // remove element at nPos
513cdf0e10cSrcweir         rDicList.erase( rDicList.begin() + nPos );
514cdf0e10cSrcweir 		bRes = sal_True;
515cdf0e10cSrcweir 	}
516cdf0e10cSrcweir 	return bRes;
517cdf0e10cSrcweir }
518cdf0e10cSrcweir 
addDictionaryListEventListener(const uno::Reference<XDictionaryListEventListener> & xListener,sal_Bool bReceiveVerbose)519cdf0e10cSrcweir sal_Bool SAL_CALL DicList::addDictionaryListEventListener(
520cdf0e10cSrcweir 			const uno::Reference< XDictionaryListEventListener >& xListener,
521cdf0e10cSrcweir 			sal_Bool bReceiveVerbose )
522cdf0e10cSrcweir 		throw(RuntimeException)
523cdf0e10cSrcweir {
524cdf0e10cSrcweir     osl::MutexGuard aGuard( GetLinguMutex() );
525cdf0e10cSrcweir 
526cdf0e10cSrcweir 	if (bDisposing)
527cdf0e10cSrcweir 		return sal_False;
528cdf0e10cSrcweir 
529cdf0e10cSrcweir 	DBG_ASSERT(!bReceiveVerbose, "lng : not yet supported");
530cdf0e10cSrcweir 
531cdf0e10cSrcweir 	sal_Bool bRes = sal_False;
532cdf0e10cSrcweir 	if (xListener.is())	//! don't add empty references
533cdf0e10cSrcweir 	{
534cdf0e10cSrcweir 		bRes = pDicEvtLstnrHelper->
535cdf0e10cSrcweir 						AddDicListEvtListener( xListener, bReceiveVerbose );
536cdf0e10cSrcweir 	}
537cdf0e10cSrcweir 	return bRes;
538cdf0e10cSrcweir }
539cdf0e10cSrcweir 
removeDictionaryListEventListener(const uno::Reference<XDictionaryListEventListener> & xListener)540cdf0e10cSrcweir sal_Bool SAL_CALL DicList::removeDictionaryListEventListener(
541cdf0e10cSrcweir 			const uno::Reference< XDictionaryListEventListener >& xListener )
542cdf0e10cSrcweir 		throw(RuntimeException)
543cdf0e10cSrcweir {
544cdf0e10cSrcweir     osl::MutexGuard aGuard( GetLinguMutex() );
545cdf0e10cSrcweir 
546cdf0e10cSrcweir 	if (bDisposing)
547cdf0e10cSrcweir 		return sal_False;
548cdf0e10cSrcweir 
549cdf0e10cSrcweir 	sal_Bool bRes = sal_False;
550cdf0e10cSrcweir 	if(xListener.is())
551cdf0e10cSrcweir 	{
552cdf0e10cSrcweir 		bRes = pDicEvtLstnrHelper->RemoveDicListEvtListener( xListener );
553cdf0e10cSrcweir 	}
554cdf0e10cSrcweir 	return bRes;
555cdf0e10cSrcweir }
556cdf0e10cSrcweir 
beginCollectEvents()557cdf0e10cSrcweir sal_Int16 SAL_CALL DicList::beginCollectEvents() throw(RuntimeException)
558cdf0e10cSrcweir {
559cdf0e10cSrcweir     osl::MutexGuard aGuard( GetLinguMutex() );
560cdf0e10cSrcweir 	return pDicEvtLstnrHelper->BeginCollectEvents();
561cdf0e10cSrcweir }
562cdf0e10cSrcweir 
endCollectEvents()563cdf0e10cSrcweir sal_Int16 SAL_CALL DicList::endCollectEvents() throw(RuntimeException)
564cdf0e10cSrcweir {
565cdf0e10cSrcweir     osl::MutexGuard aGuard( GetLinguMutex() );
566cdf0e10cSrcweir 	return pDicEvtLstnrHelper->EndCollectEvents();
567cdf0e10cSrcweir }
568cdf0e10cSrcweir 
flushEvents()569cdf0e10cSrcweir sal_Int16 SAL_CALL DicList::flushEvents() throw(RuntimeException)
570cdf0e10cSrcweir {
571cdf0e10cSrcweir     osl::MutexGuard aGuard( GetLinguMutex() );
572cdf0e10cSrcweir 	return pDicEvtLstnrHelper->FlushEvents();
573cdf0e10cSrcweir }
574cdf0e10cSrcweir 
575cdf0e10cSrcweir uno::Reference< XDictionary > SAL_CALL
createDictionary(const rtl::OUString & rName,const Locale & rLocale,DictionaryType eDicType,const rtl::OUString & rURL)576cdf0e10cSrcweir     DicList::createDictionary( const rtl::OUString& rName, const Locale& rLocale,
577cdf0e10cSrcweir             DictionaryType eDicType, const rtl::OUString& rURL )
578cdf0e10cSrcweir 		throw(RuntimeException)
579cdf0e10cSrcweir {
580cdf0e10cSrcweir     osl::MutexGuard aGuard( GetLinguMutex() );
581cdf0e10cSrcweir 
582cdf0e10cSrcweir 	sal_Int16 nLanguage = LocaleToLanguage( rLocale );
583cdf0e10cSrcweir     bool bIsWriteablePath = rURL.match( GetDictionaryWriteablePath(), 0 );
584cdf0e10cSrcweir     return new DictionaryNeo( rName, nLanguage, eDicType, rURL, bIsWriteablePath );
585cdf0e10cSrcweir }
586cdf0e10cSrcweir 
587cdf0e10cSrcweir 
588cdf0e10cSrcweir uno::Reference< XDictionaryEntry > SAL_CALL
queryDictionaryEntry(const rtl::OUString & rWord,const Locale & rLocale,sal_Bool bSearchPosDics,sal_Bool bSearchSpellEntry)589cdf0e10cSrcweir     DicList::queryDictionaryEntry( const rtl::OUString& rWord, const Locale& rLocale,
590cdf0e10cSrcweir 			sal_Bool bSearchPosDics, sal_Bool bSearchSpellEntry )
591cdf0e10cSrcweir 		throw(RuntimeException)
592cdf0e10cSrcweir {
593cdf0e10cSrcweir     osl::MutexGuard aGuard( GetLinguMutex() );
594cdf0e10cSrcweir 	return SearchDicList( this, rWord, LocaleToLanguage( rLocale ),
595cdf0e10cSrcweir 							bSearchPosDics, bSearchSpellEntry );
596cdf0e10cSrcweir }
597cdf0e10cSrcweir 
598cdf0e10cSrcweir 
599cdf0e10cSrcweir void SAL_CALL
dispose()600cdf0e10cSrcweir 	DicList::dispose()
601cdf0e10cSrcweir 		throw(RuntimeException)
602cdf0e10cSrcweir {
603cdf0e10cSrcweir     osl::MutexGuard aGuard( GetLinguMutex() );
604cdf0e10cSrcweir 
605cdf0e10cSrcweir 	if (!bDisposing)
606cdf0e10cSrcweir 	{
607cdf0e10cSrcweir 		bDisposing = sal_True;
608cdf0e10cSrcweir 		EventObject	aEvtObj( (XDictionaryList *) this );
609cdf0e10cSrcweir 
610cdf0e10cSrcweir 		aEvtListeners.disposeAndClear( aEvtObj );
611cdf0e10cSrcweir 		if (pDicEvtLstnrHelper)
612cdf0e10cSrcweir 			pDicEvtLstnrHelper->DisposeAndClear( aEvtObj );
613cdf0e10cSrcweir 
614cdf0e10cSrcweir         //! avoid creation of dictionaries if not already done
615cdf0e10cSrcweir         if (aDicList.size() > 0)
616cdf0e10cSrcweir         {
617cdf0e10cSrcweir             DictionaryVec_t& rDicList = GetOrCreateDicList();
618cdf0e10cSrcweir             size_t nCount = rDicList.size();
619cdf0e10cSrcweir             for (size_t i = 0;  i < nCount;  i++)
620cdf0e10cSrcweir             {
621cdf0e10cSrcweir                 uno::Reference< XDictionary > xDic( rDicList[i], UNO_QUERY );
622cdf0e10cSrcweir 
623cdf0e10cSrcweir                 // save (modified) dictionaries
624cdf0e10cSrcweir                 uno::Reference< frame::XStorable >  xStor( xDic , UNO_QUERY );
625cdf0e10cSrcweir                 if (xStor.is())
626cdf0e10cSrcweir                 {
627cdf0e10cSrcweir                     try
628cdf0e10cSrcweir                     {
629cdf0e10cSrcweir                         if (!xStor->isReadonly() && xStor->hasLocation())
630cdf0e10cSrcweir                             xStor->store();
631cdf0e10cSrcweir                     }
632cdf0e10cSrcweir                     catch(Exception &)
633cdf0e10cSrcweir                     {
634cdf0e10cSrcweir                     }
635cdf0e10cSrcweir                 }
636cdf0e10cSrcweir 
637cdf0e10cSrcweir                 // release references to (members of) this object hold by
638cdf0e10cSrcweir                 // dictionaries
639cdf0e10cSrcweir                 if (xDic.is())
640cdf0e10cSrcweir                     xDic->removeDictionaryEventListener( xDicEvtLstnrHelper );
641cdf0e10cSrcweir             }
642cdf0e10cSrcweir         }
643cdf0e10cSrcweir 	}
644cdf0e10cSrcweir }
645cdf0e10cSrcweir 
646cdf0e10cSrcweir void SAL_CALL
addEventListener(const uno::Reference<XEventListener> & rxListener)647cdf0e10cSrcweir 	DicList::addEventListener( const uno::Reference< XEventListener >& rxListener )
648cdf0e10cSrcweir 		throw(RuntimeException)
649cdf0e10cSrcweir {
650cdf0e10cSrcweir     osl::MutexGuard aGuard( GetLinguMutex() );
651cdf0e10cSrcweir 
652cdf0e10cSrcweir 	if (!bDisposing && rxListener.is())
653cdf0e10cSrcweir 		aEvtListeners.addInterface( rxListener );
654cdf0e10cSrcweir }
655cdf0e10cSrcweir 
656cdf0e10cSrcweir void SAL_CALL
removeEventListener(const uno::Reference<XEventListener> & rxListener)657cdf0e10cSrcweir 	DicList::removeEventListener( const uno::Reference< XEventListener >& rxListener )
658cdf0e10cSrcweir 		throw(RuntimeException)
659cdf0e10cSrcweir {
660cdf0e10cSrcweir     osl::MutexGuard aGuard( GetLinguMutex() );
661cdf0e10cSrcweir 
662cdf0e10cSrcweir 	if (!bDisposing && rxListener.is())
663cdf0e10cSrcweir 		aEvtListeners.removeInterface( rxListener );
664cdf0e10cSrcweir }
665cdf0e10cSrcweir 
_CreateDicList()666cdf0e10cSrcweir void DicList::_CreateDicList()
667cdf0e10cSrcweir {
668cdf0e10cSrcweir 	bInCreation = sal_True;
669cdf0e10cSrcweir 
670cdf0e10cSrcweir 	// look for dictionaries
671cdf0e10cSrcweir     const rtl::OUString aWriteablePath( GetDictionaryWriteablePath() );
672cdf0e10cSrcweir     uno::Sequence< rtl::OUString > aPaths( GetDictionaryPaths() );
673cdf0e10cSrcweir     const rtl::OUString *pPaths = aPaths.getConstArray();
674cdf0e10cSrcweir     for (sal_Int32 i = 0;  i < aPaths.getLength();  ++i)
675cdf0e10cSrcweir     {
676cdf0e10cSrcweir         const sal_Bool bIsWriteablePath = (pPaths[i] == aWriteablePath);
677cdf0e10cSrcweir         SearchForDictionaries( aDicList, pPaths[i], bIsWriteablePath );
678cdf0e10cSrcweir     }
679cdf0e10cSrcweir 
680cdf0e10cSrcweir 	// create IgnoreAllList dictionary with empty URL (non persistent)
681cdf0e10cSrcweir 	// and add it to list
682cdf0e10cSrcweir     rtl::OUString aDicName( A2OU( "IgnoreAllList" ) );
683cdf0e10cSrcweir 	uno::Reference< XDictionary > xIgnAll(
684cdf0e10cSrcweir 			createDictionary( aDicName, CreateLocale( LANGUAGE_NONE ),
685cdf0e10cSrcweir                               DictionaryType_POSITIVE, rtl::OUString() ) );
686cdf0e10cSrcweir 	if (xIgnAll.is())
687cdf0e10cSrcweir 	{
688cdf0e10cSrcweir 		AddUserData( xIgnAll );
689cdf0e10cSrcweir 		xIgnAll->setActive( sal_True );
690cdf0e10cSrcweir 		addDictionary( xIgnAll );
691cdf0e10cSrcweir 	}
692cdf0e10cSrcweir 
693cdf0e10cSrcweir 
694cdf0e10cSrcweir     // evaluate list of dictionaries to be activated from configuration
695cdf0e10cSrcweir 	//
696cdf0e10cSrcweir 	//! to suppress overwriting the list of active dictionaries in the
697cdf0e10cSrcweir 	//! configuration with incorrect arguments during the following
698cdf0e10cSrcweir 	//! activation of the dictionaries
699cdf0e10cSrcweir 	pDicEvtLstnrHelper->BeginCollectEvents();
700cdf0e10cSrcweir 	//
701cdf0e10cSrcweir     const uno::Sequence< rtl::OUString > aActiveDics( aOpt.GetActiveDics() );
702cdf0e10cSrcweir     const rtl::OUString *pActiveDic = aActiveDics.getConstArray();
703cdf0e10cSrcweir 	sal_Int32 nLen = aActiveDics.getLength();
704cdf0e10cSrcweir 	for (sal_Int32 i = 0;  i < nLen;  ++i)
705cdf0e10cSrcweir 	{
706cdf0e10cSrcweir 		if (pActiveDic[i].getLength())
707cdf0e10cSrcweir 		{
708cdf0e10cSrcweir 			uno::Reference< XDictionary > xDic( getDictionaryByName( pActiveDic[i] ) );
709cdf0e10cSrcweir 			if (xDic.is())
710cdf0e10cSrcweir 				xDic->setActive( sal_True );
711cdf0e10cSrcweir 		}
712cdf0e10cSrcweir 	}
713cdf0e10cSrcweir 
714cdf0e10cSrcweir     // suppress collected events during creation of the dictionary list.
715cdf0e10cSrcweir     // there should be no events during creation.
716cdf0e10cSrcweir     pDicEvtLstnrHelper->ClearEvents();
717cdf0e10cSrcweir 
718cdf0e10cSrcweir     pDicEvtLstnrHelper->EndCollectEvents();
719cdf0e10cSrcweir 
720cdf0e10cSrcweir 	bInCreation = sal_False;
721cdf0e10cSrcweir }
722cdf0e10cSrcweir 
723cdf0e10cSrcweir 
SaveDics()724cdf0e10cSrcweir void DicList::SaveDics()
725cdf0e10cSrcweir {
726cdf0e10cSrcweir     // save dics only if they have already been used/created.
727cdf0e10cSrcweir     //! don't create them just for the purpose of saving them !
728cdf0e10cSrcweir     if (aDicList.size() > 0)
729cdf0e10cSrcweir     {
730cdf0e10cSrcweir         // save (modified) dictionaries
731cdf0e10cSrcweir         DictionaryVec_t& rDicList = GetOrCreateDicList();
732cdf0e10cSrcweir         size_t nCount = rDicList.size();;
733cdf0e10cSrcweir         for (size_t i = 0;  i < nCount;  i++)
734cdf0e10cSrcweir         {
735cdf0e10cSrcweir             // save (modified) dictionaries
736cdf0e10cSrcweir             uno::Reference< frame::XStorable >  xStor( rDicList[i], UNO_QUERY );
737cdf0e10cSrcweir             if (xStor.is())
738cdf0e10cSrcweir             {
739cdf0e10cSrcweir                 try
740cdf0e10cSrcweir                 {
741cdf0e10cSrcweir                     if (!xStor->isReadonly() && xStor->hasLocation())
742cdf0e10cSrcweir                         xStor->store();
743cdf0e10cSrcweir                 }
744cdf0e10cSrcweir                 catch(Exception &)
745cdf0e10cSrcweir                 {
746cdf0e10cSrcweir                 }
747cdf0e10cSrcweir             }
748cdf0e10cSrcweir         }
749cdf0e10cSrcweir     }
750cdf0e10cSrcweir }
751cdf0e10cSrcweir 
752cdf0e10cSrcweir 
753cdf0e10cSrcweir ///////////////////////////////////////////////////////////////////////////
754cdf0e10cSrcweir // Service specific part
755cdf0e10cSrcweir //
756cdf0e10cSrcweir 
getImplementationName()757cdf0e10cSrcweir rtl::OUString SAL_CALL DicList::getImplementationName(  ) throw(RuntimeException)
758cdf0e10cSrcweir {
759cdf0e10cSrcweir     osl::MutexGuard aGuard( GetLinguMutex() );
760cdf0e10cSrcweir 	return getImplementationName_Static();
761cdf0e10cSrcweir }
762cdf0e10cSrcweir 
763cdf0e10cSrcweir 
supportsService(const rtl::OUString & ServiceName)764cdf0e10cSrcweir sal_Bool SAL_CALL DicList::supportsService( const rtl::OUString& ServiceName )
765cdf0e10cSrcweir 		throw(RuntimeException)
766cdf0e10cSrcweir {
767cdf0e10cSrcweir     osl::MutexGuard aGuard( GetLinguMutex() );
768cdf0e10cSrcweir 
769cdf0e10cSrcweir     uno::Sequence< rtl::OUString > aSNL = getSupportedServiceNames();
770cdf0e10cSrcweir     const rtl::OUString * pArray = aSNL.getConstArray();
771cdf0e10cSrcweir 	for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
772cdf0e10cSrcweir 		if( pArray[i] == ServiceName )
773cdf0e10cSrcweir 			return sal_True;
774cdf0e10cSrcweir 	return sal_False;
775cdf0e10cSrcweir }
776cdf0e10cSrcweir 
777cdf0e10cSrcweir 
getSupportedServiceNames()778cdf0e10cSrcweir uno::Sequence< rtl::OUString > SAL_CALL DicList::getSupportedServiceNames(  )
779cdf0e10cSrcweir 		throw(RuntimeException)
780cdf0e10cSrcweir {
781cdf0e10cSrcweir     osl::MutexGuard aGuard( GetLinguMutex() );
782cdf0e10cSrcweir 	return getSupportedServiceNames_Static();
783cdf0e10cSrcweir }
784cdf0e10cSrcweir 
785cdf0e10cSrcweir 
getSupportedServiceNames_Static()786cdf0e10cSrcweir uno::Sequence< rtl::OUString > DicList::getSupportedServiceNames_Static() throw()
787cdf0e10cSrcweir {
788cdf0e10cSrcweir     osl::MutexGuard aGuard( GetLinguMutex() );
789cdf0e10cSrcweir 
790cdf0e10cSrcweir     uno::Sequence< rtl::OUString > aSNS( 1 );   // auch mehr als 1 Service moeglich
791cdf0e10cSrcweir 	aSNS.getArray()[0] = A2OU( SN_DICTIONARY_LIST );
792cdf0e10cSrcweir 	return aSNS;
793cdf0e10cSrcweir }
794cdf0e10cSrcweir 
DicList_getFactory(const sal_Char * pImplName,XMultiServiceFactory * pServiceManager,void *)795cdf0e10cSrcweir void * SAL_CALL DicList_getFactory(	const sal_Char * pImplName,
796cdf0e10cSrcweir 		XMultiServiceFactory * pServiceManager, void *  )
797cdf0e10cSrcweir {
798cdf0e10cSrcweir 	void * pRet = 0;
799cdf0e10cSrcweir 	if ( !DicList::getImplementationName_Static().compareToAscii( pImplName ) )
800cdf0e10cSrcweir 	{
801cdf0e10cSrcweir 		uno::Reference< XSingleServiceFactory > xFactory =
802cdf0e10cSrcweir 			cppu::createOneInstanceFactory(
803cdf0e10cSrcweir 				pServiceManager,
804cdf0e10cSrcweir 				DicList::getImplementationName_Static(),
805cdf0e10cSrcweir 				DicList_CreateInstance,
806cdf0e10cSrcweir 				DicList::getSupportedServiceNames_Static());
807cdf0e10cSrcweir 		// acquire, because we return an interface pointer instead of a reference
808cdf0e10cSrcweir 		xFactory->acquire();
809cdf0e10cSrcweir 		pRet = xFactory.get();
810cdf0e10cSrcweir 	}
811cdf0e10cSrcweir 	return pRet;
812cdf0e10cSrcweir }
813cdf0e10cSrcweir 
814cdf0e10cSrcweir ///////////////////////////////////////////////////////////////////////////
815cdf0e10cSrcweir 
lcl_GetToken(String & rToken,const String & rText,xub_StrLen nPos,const String & rDelim)816cdf0e10cSrcweir xub_StrLen lcl_GetToken( String &rToken,
817cdf0e10cSrcweir 			const String &rText, xub_StrLen nPos, const String &rDelim )
818cdf0e10cSrcweir {
819cdf0e10cSrcweir 	xub_StrLen nRes = STRING_LEN;
820cdf0e10cSrcweir 
821cdf0e10cSrcweir 	if (rText.Len() == 0  ||  nPos >= rText.Len())
822cdf0e10cSrcweir 		rToken = String();
823cdf0e10cSrcweir 	else if (rDelim.Len() == 0)
824cdf0e10cSrcweir 	{
825cdf0e10cSrcweir 		rToken = rText;
826cdf0e10cSrcweir 		if (rToken.Len())
827cdf0e10cSrcweir 			nRes = rText.Len();
828cdf0e10cSrcweir 	}
829cdf0e10cSrcweir 	else
830cdf0e10cSrcweir 	{
831cdf0e10cSrcweir 		xub_StrLen	i;
832cdf0e10cSrcweir 		for (i = nPos;  i < rText.Len();  ++i)
833cdf0e10cSrcweir 		{
834cdf0e10cSrcweir 			if (STRING_NOTFOUND != rDelim.Search( rText.GetChar(i) ))
835cdf0e10cSrcweir 				break;
836cdf0e10cSrcweir 		}
837cdf0e10cSrcweir 
838cdf0e10cSrcweir 		if (i >= rText.Len())	// delimeter not found
839cdf0e10cSrcweir 			rToken	= rText.Copy( nPos );
840cdf0e10cSrcweir 		else
841cdf0e10cSrcweir             rToken  = rText.Copy( nPos, sal::static_int_cast< xub_StrLen >((sal_Int32) i - nPos) );
842cdf0e10cSrcweir 		nRes	= i + 1;	// continue after found delimeter
843cdf0e10cSrcweir 	}
844cdf0e10cSrcweir 
845cdf0e10cSrcweir 	return nRes;
846cdf0e10cSrcweir }
847cdf0e10cSrcweir 
848cdf0e10cSrcweir 
AddInternal(const uno::Reference<XDictionary> & rDic,const rtl::OUString & rNew)849cdf0e10cSrcweir static void AddInternal(
850cdf0e10cSrcweir 		const uno::Reference<XDictionary> &rDic,
851cdf0e10cSrcweir         const rtl::OUString& rNew )
852cdf0e10cSrcweir {
853cdf0e10cSrcweir 	if (rDic.is())
854cdf0e10cSrcweir 	{
855cdf0e10cSrcweir 		//! TL TODO: word iterator should be used to break up the text
856cdf0e10cSrcweir 		static const char *pDefWordDelim =
857cdf0e10cSrcweir 				"!\"#$%&'()*+,-./:;<=>?[]\\_^`{|}~\t \n";
858cdf0e10cSrcweir 		ByteString aDummy( pDefWordDelim );
859cdf0e10cSrcweir         String aDelim( aDummy, osl_getThreadTextEncoding() );
860cdf0e10cSrcweir 		aDelim.EraseAllChars( '.' );
861cdf0e10cSrcweir 
862cdf0e10cSrcweir 		String 		aToken;
863cdf0e10cSrcweir 		xub_StrLen  nPos = 0;
864cdf0e10cSrcweir 		while (STRING_LEN !=
865cdf0e10cSrcweir 					(nPos = lcl_GetToken( aToken, rNew, nPos, aDelim )))
866cdf0e10cSrcweir 		{
867cdf0e10cSrcweir         	if( aToken.Len()  &&  !IsNumeric( aToken ) )
868cdf0e10cSrcweir 			{
869cdf0e10cSrcweir                 rDic->add( aToken, sal_False, rtl::OUString() );
870cdf0e10cSrcweir 			}
871cdf0e10cSrcweir 		}
872cdf0e10cSrcweir 	}
873cdf0e10cSrcweir }
874cdf0e10cSrcweir 
AddUserData(const uno::Reference<XDictionary> & rDic)875cdf0e10cSrcweir static void AddUserData( const uno::Reference< XDictionary > &rDic )
876cdf0e10cSrcweir {
877cdf0e10cSrcweir 	if (rDic.is())
878cdf0e10cSrcweir 	{
879cdf0e10cSrcweir 		SvtUserOptions aUserOpt;
880cdf0e10cSrcweir 		AddInternal( rDic, aUserOpt.GetFullName() );
881cdf0e10cSrcweir 		AddInternal( rDic, aUserOpt.GetCompany() );
882cdf0e10cSrcweir 		AddInternal( rDic, aUserOpt.GetStreet() );
883cdf0e10cSrcweir 		AddInternal( rDic, aUserOpt.GetCity() );
884cdf0e10cSrcweir 		AddInternal( rDic, aUserOpt.GetTitle() );
885cdf0e10cSrcweir 		AddInternal( rDic, aUserOpt.GetPosition() );
886cdf0e10cSrcweir 		AddInternal( rDic, aUserOpt.GetEmail() );
887cdf0e10cSrcweir 	}
888cdf0e10cSrcweir }
889cdf0e10cSrcweir 
890cdf0e10cSrcweir ///////////////////////////////////////////////////////////////////////////
891cdf0e10cSrcweir 
892cdf0e10cSrcweir #if defined _MSC_VER
893cdf0e10cSrcweir #pragma optimize("g",off)
894cdf0e10cSrcweir #endif
895cdf0e10cSrcweir 
IsVers2OrNewer(const String & rFileURL,sal_uInt16 & nLng,sal_Bool & bNeg)896cdf0e10cSrcweir static sal_Bool IsVers2OrNewer( const String& rFileURL, sal_uInt16& nLng, sal_Bool& bNeg )
897cdf0e10cSrcweir {
898cdf0e10cSrcweir 	if (rFileURL.Len() == 0)
899cdf0e10cSrcweir 		return sal_False;
900cdf0e10cSrcweir 	String aDIC( GetDicExtension() );
901cdf0e10cSrcweir 	String aExt;
902cdf0e10cSrcweir 	xub_StrLen nPos = rFileURL.SearchBackward( '.' );
903cdf0e10cSrcweir 	if (STRING_NOTFOUND != nPos)
904cdf0e10cSrcweir 		aExt = rFileURL.Copy( nPos + 1 );
905cdf0e10cSrcweir 	aExt.ToLowerAscii();
906cdf0e10cSrcweir 
907cdf0e10cSrcweir 	if(aExt != aDIC)
908cdf0e10cSrcweir 		return sal_False;
909cdf0e10cSrcweir 
910cdf0e10cSrcweir 	// get stream to be used
911cdf0e10cSrcweir     uno::Reference< lang::XMultiServiceFactory > xServiceFactory( comphelper::getProcessServiceFactory() );
912cdf0e10cSrcweir 
913cdf0e10cSrcweir     // get XInputStream stream
914cdf0e10cSrcweir     uno::Reference< io::XInputStream > xStream;
915cdf0e10cSrcweir     try
916cdf0e10cSrcweir     {
917cdf0e10cSrcweir         uno::Reference< ucb::XSimpleFileAccess > xAccess( xServiceFactory->createInstance(
918cdf0e10cSrcweir                 A2OU( "com.sun.star.ucb.SimpleFileAccess" ) ), uno::UNO_QUERY_THROW );
919cdf0e10cSrcweir         xStream = xAccess->openFileRead( rFileURL );
920cdf0e10cSrcweir     }
921cdf0e10cSrcweir     catch (uno::Exception & e)
922cdf0e10cSrcweir     {
923cdf0e10cSrcweir         DBG_ASSERT( 0, "failed to get input stream" );
924cdf0e10cSrcweir         (void) e;
925cdf0e10cSrcweir     }
926cdf0e10cSrcweir     DBG_ASSERT( xStream.is(), "failed to get stream for read" );
927cdf0e10cSrcweir     if (!xStream.is())
928cdf0e10cSrcweir         return sal_False;
929cdf0e10cSrcweir 
930cdf0e10cSrcweir     SvStreamPtr pStream = SvStreamPtr( utl::UcbStreamHelper::CreateStream( xStream ) );
931cdf0e10cSrcweir 
932cdf0e10cSrcweir     int nDicVersion = ReadDicVersion(pStream, nLng, bNeg);
933cdf0e10cSrcweir     if (2 == nDicVersion || nDicVersion >= 5)
934cdf0e10cSrcweir         return sal_True;
935cdf0e10cSrcweir 
936cdf0e10cSrcweir     return sal_False;
937cdf0e10cSrcweir }
938cdf0e10cSrcweir 
939cdf0e10cSrcweir ///////////////////////////////////////////////////////////////////////////
940cdf0e10cSrcweir 
941