LibreOffice Module linguistic (master) 1
dlistimp.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20
22#include <osl/file.hxx>
23#include <tools/debug.hxx>
24#include <tools/stream.hxx>
25#include <tools/urlobj.hxx>
28#include <cppuhelper/weak.hxx>
33#include <com/sun/star/frame/XStorable.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/ucb/SimpleFileAccess.hpp>
38#include <svtools/strings.hrc>
39#include <unotools/resmgr.hxx>
41#include <sal/log.hxx>
42#include <utility>
43
44#include "dlistimp.hxx"
45#include "dicimp.hxx"
46#include "lngopt.hxx"
47
48using namespace osl;
49using namespace com::sun::star;
50using namespace com::sun::star::lang;
51using namespace com::sun::star::uno;
52using namespace com::sun::star::linguistic2;
53using namespace linguistic;
54
55
56static bool IsVers2OrNewer( const OUString& rFileURL, LanguageType& nLng, bool& bNeg, OUString& aDicName );
57
58static void AddInternal( const uno::Reference< XDictionary > &rDic,
59 const OUString& rNew );
60static void AddUserData( const uno::Reference< XDictionary > &rDic );
61
62
64 public cppu::WeakImplHelper
65 <
66 XDictionaryEventListener
67 >
68{
70 uno::Reference< XDictionaryList > xMyDicList;
71
72 sal_Int16 nCondensedEvt;
74
75public:
76 explicit DicEvtListenerHelper( uno::Reference< XDictionaryList > xDicList );
77 virtual ~DicEvtListenerHelper() override;
78
79 // XEventListener
80 virtual void SAL_CALL
81 disposing( const EventObject& rSource ) override;
82
83 // XDictionaryEventListener
84 virtual void SAL_CALL
85 processDictionaryEvent( const DictionaryEvent& rDicEvent ) override;
86
87 // non-UNO functions
88 void DisposeAndClear( const EventObject &rEvtObj );
89
91 const uno::Reference< XDictionaryListEventListener >& rxListener );
93 const uno::Reference< XDictionaryListEventListener >& rxListener );
95 sal_Int16 EndCollectEvents();
96 sal_Int16 FlushEvents();
97 void ClearEvents() { nCondensedEvt = 0; }
98};
99
100
102 uno::Reference< XDictionaryList > xDicList ) :
103 aDicListEvtListeners ( GetLinguMutex() ),
104 xMyDicList (std::move( xDicList )),
105 nCondensedEvt(0), nNumCollectEvtListeners(0)
106{
107}
108
109
111{
113 "lng : event listeners are still existing");
114}
115
116
117void DicEvtListenerHelper::DisposeAndClear( const EventObject &rEvtObj )
118{
120}
121
122
123void SAL_CALL DicEvtListenerHelper::disposing( const EventObject& rSource )
124{
125 osl::MutexGuard aGuard( GetLinguMutex() );
126
127 uno::Reference< XDictionaryListEventListener > xSrc( rSource.Source, UNO_QUERY );
128
129 // remove event object from EventListener list
130 if (xSrc.is())
132
133 // if object is a dictionary then remove it from the dictionary list
134 // Note: this will probably happen only if someone makes a XDictionary
135 // implementation of his own that is also a XComponent.
136 uno::Reference< XDictionary > xDic( rSource.Source, UNO_QUERY );
137 if (xDic.is())
138 {
139 xMyDicList->removeDictionary( xDic );
140 }
141}
142
143
145 const DictionaryEvent& rDicEvent )
146{
147 osl::MutexGuard aGuard( GetLinguMutex() );
148
149 uno::Reference< XDictionary > xDic( rDicEvent.Source, UNO_QUERY );
150 DBG_ASSERT(xDic.is(), "lng : missing event source");
151
152 // assert that there is a corresponding dictionary entry if one was
153 // added or deleted
154 DBG_ASSERT( !(rDicEvent.nEvent &
155 (DictionaryEventFlags::ADD_ENTRY | DictionaryEventFlags::DEL_ENTRY))
156 || rDicEvent.xDictionaryEntry.is(),
157 "lng : missing dictionary entry" );
158
159 // evaluate DictionaryEvents and update data for next DictionaryListEvent
160 DictionaryType eDicType = xDic->getDictionaryType();
161 DBG_ASSERT(eDicType != DictionaryType_MIXED,
162 "lng : unexpected dictionary type");
163 if ((rDicEvent.nEvent & DictionaryEventFlags::ADD_ENTRY) && xDic->isActive())
164 nCondensedEvt |= rDicEvent.xDictionaryEntry->isNegative() ?
165 DictionaryListEventFlags::ADD_NEG_ENTRY :
166 DictionaryListEventFlags::ADD_POS_ENTRY;
167 if ((rDicEvent.nEvent & DictionaryEventFlags::DEL_ENTRY) && xDic->isActive())
168 nCondensedEvt |= rDicEvent.xDictionaryEntry->isNegative() ?
169 DictionaryListEventFlags::DEL_NEG_ENTRY :
170 DictionaryListEventFlags::DEL_POS_ENTRY;
171 if ((rDicEvent.nEvent & DictionaryEventFlags::ENTRIES_CLEARED) && xDic->isActive())
172 nCondensedEvt |= eDicType == DictionaryType_NEGATIVE ?
173 DictionaryListEventFlags::DEL_NEG_ENTRY :
174 DictionaryListEventFlags::DEL_POS_ENTRY;
175 if ((rDicEvent.nEvent & DictionaryEventFlags::CHG_LANGUAGE) && xDic->isActive())
176 nCondensedEvt |= eDicType == DictionaryType_NEGATIVE ?
177 DictionaryListEventFlags::DEACTIVATE_NEG_DIC
178 | DictionaryListEventFlags::ACTIVATE_NEG_DIC :
179 DictionaryListEventFlags::DEACTIVATE_POS_DIC
180 | DictionaryListEventFlags::ACTIVATE_POS_DIC;
181 if (rDicEvent.nEvent & DictionaryEventFlags::ACTIVATE_DIC)
182 nCondensedEvt |= eDicType == DictionaryType_NEGATIVE ?
183 DictionaryListEventFlags::ACTIVATE_NEG_DIC :
184 DictionaryListEventFlags::ACTIVATE_POS_DIC;
185 if (rDicEvent.nEvent & DictionaryEventFlags::DEACTIVATE_DIC)
186 nCondensedEvt |= eDicType == DictionaryType_NEGATIVE ?
187 DictionaryListEventFlags::DEACTIVATE_NEG_DIC :
188 DictionaryListEventFlags::DEACTIVATE_POS_DIC;
189
190 if (nNumCollectEvtListeners == 0 && nCondensedEvt != 0)
191 FlushEvents();
192}
193
194
196 const uno::Reference< XDictionaryListEventListener >& xListener )
197{
198 DBG_ASSERT( xListener.is(), "empty reference" );
200 return aDicListEvtListeners.addInterface( xListener ) != nCount;
201}
202
203
205 const uno::Reference< XDictionaryListEventListener >& xListener )
206{
207 DBG_ASSERT( xListener.is(), "empty reference" );
209 return aDicListEvtListeners.removeInterface( xListener ) != nCount;
210}
211
212
214{
215 DBG_ASSERT(nNumCollectEvtListeners > 0, "lng: mismatched function call");
217 {
218 FlushEvents();
220 }
221
223}
224
225
227{
228 if (0 != nCondensedEvt)
229 {
230 // build DictionaryListEvent to pass on to listeners
231 uno::Sequence< DictionaryEvent > aDicEvents;
232 DictionaryListEvent aEvent( xMyDicList, nCondensedEvt, aDicEvents );
233
234 // pass on event
235 aDicListEvtListeners.notifyEach( &XDictionaryListEventListener::processDictionaryListEvent, aEvent );
236
237 // clear "list" of events
238 nCondensedEvt = 0;
239 }
240
242}
243
244
246{
248}
249
250
253{
255 bDisposing = false;
256 bInCreation = false;
257
258 mxExitListener = new MyAppExitListener( *this );
259 mxExitListener->Activate();
260}
261
263{
264 mxExitListener->Deactivate();
265}
266
267
269 DictionaryVec_t&rDicList,
270 const OUString &rDicDirURL,
271 bool bIsWriteablePath )
272{
273 osl::MutexGuard aGuard( GetLinguMutex() );
274
275 const uno::Sequence< OUString > aDirCnt( utl::LocalFileHelper::
276 GetFolderContents( rDicDirURL, false ) );
277 SvtSysLocale aSysLocale;
278
279 for (const OUString& aURL : aDirCnt)
280 {
282 bool bNeg = false;
283 OUString aDicTitle = "";
284
285 if(!::IsVers2OrNewer( aURL, nLang, bNeg, aDicTitle ))
286 {
287 // When not
288 sal_Int32 nPos = aURL.indexOf('.');
289 OUString aExt( aURL.copy(nPos + 1).toAsciiLowerCase() );
290
291 if ("dcn" == aExt) // negative
292 bNeg = true;
293 else if ("dcp" == aExt) // positive
294 bNeg = false;
295 else
296 continue; // other files
297 }
298
299 // Record in the list of Dictionaries
300 // When it already exists don't record
301 OUString aTmp1 = aSysLocale.GetCharClass().lowercase( aURL);
302 sal_Int32 nPos = aTmp1.lastIndexOf( '/' );
303 if (-1 != nPos)
304 aTmp1 = aTmp1.copy( nPos + 1 );
305 OUString aTmp2;
306 size_t j;
307 size_t nCount = rDicList.size();
308 for(j = 0; j < nCount; j++)
309 {
310 aTmp2 = rDicList[j]->getName();
311 aTmp2 = aSysLocale.GetCharClass().lowercase( aTmp2);
312 if(aTmp1 == aTmp2)
313 break;
314 }
315 if(j >= nCount) // dictionary not yet in DicList
316 {
317 // get decoded dictionary file name
318 INetURLObject aURLObj( aURL );
319 OUString aDicName = aURLObj.getName( INetURLObject::LAST_SEGMENT,
321
322 DictionaryType eType = bNeg ? DictionaryType_NEGATIVE : DictionaryType_POSITIVE;
323 uno::Reference< XDictionary > xDic =
324 new DictionaryNeo( aDicTitle.isEmpty() ? aDicName : aDicTitle, nLang, eType, aURL, bIsWriteablePath );
325
326 addDictionary( xDic );
327 nCount++;
328 }
329 }
330}
331
332
333sal_Int32 DicList::GetDicPos(const uno::Reference< XDictionary > &xDic)
334{
335 osl::MutexGuard aGuard( GetLinguMutex() );
336
338 size_t n = rDicList.size();
339 for (size_t i = 0; i < n; i++)
340 {
341 if ( rDicList[i] == xDic )
342 return i;
343 }
344 return -1;
345}
346
347sal_Int16 SAL_CALL DicList::getCount()
348{
349 osl::MutexGuard aGuard( GetLinguMutex() );
350 return static_cast< sal_Int16 >(GetOrCreateDicList().size());
351}
352
353uno::Sequence< uno::Reference< XDictionary > > SAL_CALL
355{
356 osl::MutexGuard aGuard( GetLinguMutex() );
357
359
360 return comphelper::containerToSequence(rDicList);
361}
362
363uno::Reference< XDictionary > SAL_CALL
364 DicList::getDictionaryByName( const OUString& aDictionaryName )
365{
366 osl::MutexGuard aGuard( GetLinguMutex() );
367
368 uno::Reference< XDictionary > xDic;
370 size_t nCount = rDicList.size();
371 for (size_t i = 0; i < nCount; i++)
372 {
373 const uno::Reference< XDictionary > &rDic = rDicList[i];
374 if (rDic.is() && rDic->getName() == aDictionaryName)
375 {
376 xDic = rDic;
377 break;
378 }
379 }
380
381 return xDic;
382}
383
385 const uno::Reference< XDictionary >& xDictionary )
386{
387 osl::MutexGuard aGuard( GetLinguMutex() );
388
389 if (bDisposing)
390 return false;
391
392 bool bRes = false;
393 if (xDictionary.is())
394 {
396 rDicList.push_back( xDictionary );
397 bRes = true;
398
399 // add listener helper to the dictionaries listener lists
400 xDictionary->addDictionaryEventListener( mxDicEvtLstnrHelper );
401 }
402 return bRes;
403}
404
405sal_Bool SAL_CALL
406 DicList::removeDictionary( const uno::Reference< XDictionary >& xDictionary )
407{
408 osl::MutexGuard aGuard( GetLinguMutex() );
409
410 if (bDisposing)
411 return false;
412
413 bool bRes = false;
414 sal_Int32 nPos = GetDicPos( xDictionary );
415 if (nPos >= 0)
416 {
417 // remove dictionary list from the dictionaries listener lists
419 uno::Reference< XDictionary > xDic( rDicList[ nPos ] );
420 DBG_ASSERT(xDic.is(), "lng : empty reference");
421 if (xDic.is())
422 {
423 // deactivate dictionary if not already done
424 xDic->setActive( false );
425
426 xDic->removeDictionaryEventListener( mxDicEvtLstnrHelper );
427 }
428
429 // remove element at nPos
430 rDicList.erase( rDicList.begin() + nPos );
431 bRes = true;
432 }
433 return bRes;
434}
435
437 const uno::Reference< XDictionaryListEventListener >& xListener,
438 sal_Bool bReceiveVerbose )
439{
440 osl::MutexGuard aGuard( GetLinguMutex() );
441
442 if (bDisposing)
443 return false;
444
445 DBG_ASSERT(!bReceiveVerbose, "lng : not yet supported");
446
447 bool bRes = false;
448 if (xListener.is())
449 {
450 bRes = mxDicEvtLstnrHelper->AddDicListEvtListener( xListener );
451 }
452 return bRes;
453}
454
456 const uno::Reference< XDictionaryListEventListener >& xListener )
457{
458 osl::MutexGuard aGuard( GetLinguMutex() );
459
460 if (bDisposing)
461 return false;
462
463 bool bRes = false;
464 if(xListener.is())
465 {
466 bRes = mxDicEvtLstnrHelper->RemoveDicListEvtListener( xListener );
467 }
468 return bRes;
469}
470
471sal_Int16 SAL_CALL DicList::beginCollectEvents()
472{
473 osl::MutexGuard aGuard( GetLinguMutex() );
474 return mxDicEvtLstnrHelper->BeginCollectEvents();
475}
476
477sal_Int16 SAL_CALL DicList::endCollectEvents()
478{
479 osl::MutexGuard aGuard( GetLinguMutex() );
480 return mxDicEvtLstnrHelper->EndCollectEvents();
481}
482
483sal_Int16 SAL_CALL DicList::flushEvents()
484{
485 osl::MutexGuard aGuard( GetLinguMutex() );
486 return mxDicEvtLstnrHelper->FlushEvents();
487}
488
489uno::Reference< XDictionary > SAL_CALL
490 DicList::createDictionary( const OUString& rName, const Locale& rLocale,
491 DictionaryType eDicType, const OUString& rURL )
492{
493 osl::MutexGuard aGuard( GetLinguMutex() );
494
495 LanguageType nLanguage = LinguLocaleToLanguage( rLocale );
496 bool bIsWriteablePath = rURL.match( GetDictionaryWriteablePath() );
497 return new DictionaryNeo( rName, nLanguage, eDicType, rURL, bIsWriteablePath );
498}
499
500
501uno::Reference< XDictionaryEntry > SAL_CALL
502 DicList::queryDictionaryEntry( const OUString& rWord, const Locale& rLocale,
503 sal_Bool bSearchPosDics, sal_Bool bSearchSpellEntry )
504{
505 osl::MutexGuard aGuard( GetLinguMutex() );
506 return SearchDicList( this, rWord, LinguLocaleToLanguage( rLocale ),
507 bSearchPosDics, bSearchSpellEntry );
508}
509
510
511void SAL_CALL
513{
514 osl::MutexGuard aGuard( GetLinguMutex() );
515
516 if (bDisposing)
517 return;
518
519 bDisposing = true;
520 EventObject aEvtObj( static_cast<XDictionaryList *>(this) );
521
523 if (mxDicEvtLstnrHelper.is())
524 mxDicEvtLstnrHelper->DisposeAndClear( aEvtObj );
525
527 if ( !aDicList.empty() )
528 {
530 size_t nCount = rDicList.size();
531 for (size_t i = 0; i < nCount; i++)
532 {
533 // save (modified) dictionaries
534 uno::Reference< frame::XStorable > xStor( rDicList[i] , UNO_QUERY );
535 if (xStor.is())
536 {
537 try
538 {
539 if (!xStor->isReadonly() && xStor->hasLocation())
540 xStor->store();
541 }
542 catch(Exception &)
543 {
544 }
545 }
546
547 // release references to (members of) this object hold by
548 // dictionaries
549 if (rDicList[i].is())
550 rDicList[i]->removeDictionaryEventListener( mxDicEvtLstnrHelper );
551 }
552 }
553 mxDicEvtLstnrHelper.clear();
554}
555
556void SAL_CALL
557 DicList::addEventListener( const uno::Reference< XEventListener >& rxListener )
558{
559 osl::MutexGuard aGuard( GetLinguMutex() );
560
561 if (!bDisposing && rxListener.is())
562 aEvtListeners.addInterface( rxListener );
563}
564
565void SAL_CALL
566 DicList::removeEventListener( const uno::Reference< XEventListener >& rxListener )
567{
568 osl::MutexGuard aGuard( GetLinguMutex() );
569
570 if (!bDisposing && rxListener.is())
571 aEvtListeners.removeInterface( rxListener );
572}
573
575{
576 bInCreation = true;
577
578 // look for dictionaries
579 const OUString aWriteablePath( GetDictionaryWriteablePath() );
580 std::vector< OUString > aPaths( GetDictionaryPaths() );
581 for (const OUString & aPath : aPaths)
582 {
583 const bool bIsWriteablePath = (aPath == aWriteablePath);
584 SearchForDictionaries( aDicList, aPath, bIsWriteablePath );
585 }
586
587 // create IgnoreAllList dictionary with empty URL (non persistent)
588 // and add it to list
589 std::locale loc(Translate::Create("svt"));
590 uno::Reference< XDictionary > xIgnAll(
591 createDictionary( Translate::get(STR_DESCRIPTION_IGNOREALLLIST, loc), LinguLanguageToLocale( LANGUAGE_NONE ),
592 DictionaryType_POSITIVE, OUString() ) );
593 if (xIgnAll.is())
594 {
595 AddUserData( xIgnAll );
596 xIgnAll->setActive( true );
597 addDictionary( xIgnAll );
598 }
599
600
601 // evaluate list of dictionaries to be activated from configuration
605 mxDicEvtLstnrHelper->BeginCollectEvents();
606 const uno::Sequence< OUString > aActiveDics( aOpt.GetActiveDics() );
607 for (const OUString& rActiveDic : aActiveDics)
608 {
609 if (!rActiveDic.isEmpty())
610 {
611 uno::Reference< XDictionary > xDic( getDictionaryByName( rActiveDic ) );
612 if (xDic.is())
613 xDic->setActive( true );
614 }
615 }
616
617 // suppress collected events during creation of the dictionary list.
618 // there should be no events during creation.
619 mxDicEvtLstnrHelper->ClearEvents();
620
621 mxDicEvtLstnrHelper->EndCollectEvents();
622
623 bInCreation = false;
624}
625
626
628{
629 // save dics only if they have already been used/created.
631 if ( aDicList.empty() )
632 return;
633
634 // save (modified) dictionaries
636 size_t nCount = rDicList.size();
637 for (size_t i = 0; i < nCount; i++)
638 {
639 // save (modified) dictionaries
640 uno::Reference< frame::XStorable > xStor( rDicList[i], UNO_QUERY );
641 if (xStor.is())
642 {
643 try
644 {
645 if (!xStor->isReadonly() && xStor->hasLocation())
646 xStor->store();
647 }
648 catch(Exception &)
649 {
650 }
651 }
652 }
653}
654
655
656// Service specific part
657
659{
660 return "com.sun.star.lingu2.DicList";
661}
662
663
664sal_Bool SAL_CALL DicList::supportsService( const OUString& ServiceName )
665{
667}
668
669uno::Sequence< OUString > SAL_CALL DicList::getSupportedServiceNames( )
670{
671 return { "com.sun.star.linguistic2.DictionaryList" };
672}
673
674
675
676static sal_Int32 lcl_GetToken( OUString &rToken,
677 const OUString &rText, sal_Int32 nPos, std::u16string_view rDelim )
678{
679 sal_Int32 nRes = -1;
680
681 if (rText.isEmpty() || nPos >= rText.getLength())
682 rToken.clear();
683 else if (rDelim.empty())
684 {
685 rToken = rText;
686 if (!rToken.isEmpty())
687 nRes = rText.getLength();
688 }
689 else
690 {
691 sal_Int32 i;
692 for (i = nPos; i < rText.getLength(); ++i)
693 {
694 if (std::string_view::npos != rDelim.find( rText[i] ))
695 break;
696 }
697
698 if (i >= rText.getLength()) // delimiter not found
699 rToken = rText.copy( nPos );
700 else
701 rToken = rText.copy( nPos, i - nPos );
702 nRes = i + 1; // continue after found delimiter
703 }
704
705 return nRes;
706}
707
708
709static void AddInternal(
710 const uno::Reference<XDictionary> &rDic,
711 const OUString& rNew )
712{
713 if (!rDic.is())
714 return;
715
717 OUString aDelim("!\"#$%&'()*+,-/:;<=>?[]\\_^`{|}~\t \n");
718 OSL_ENSURE(aDelim.indexOf(u'.') == -1,
719 "ensure no '.'");
720
721 OUString aToken;
722 sal_Int32 nPos = 0;
723 while (-1 != (nPos = lcl_GetToken( aToken, rNew, nPos, aDelim )))
724 {
725 if( !aToken.isEmpty() && !IsNumeric( aToken ) )
726 {
727 rDic->add( aToken, false, OUString() );
728 }
729 }
730}
731
732static void AddUserData( const uno::Reference< XDictionary > &rDic )
733{
734 if (rDic.is())
735 {
736 SvtUserOptions aUserOpt;
737 AddInternal( rDic, aUserOpt.GetFullName() );
738 AddInternal( rDic, aUserOpt.GetCompany() );
739 AddInternal( rDic, aUserOpt.GetStreet() );
740 AddInternal( rDic, aUserOpt.GetCity() );
741 AddInternal( rDic, aUserOpt.GetTitle() );
742 AddInternal( rDic, aUserOpt.GetPosition() );
743 AddInternal( rDic, aUserOpt.GetEmail() );
744 }
745}
746
747static bool IsVers2OrNewer( const OUString& rFileURL, LanguageType& nLng, bool& bNeg, OUString& aDicName )
748{
749 if (rFileURL.isEmpty())
750 return false;
751 OUString aExt;
752 sal_Int32 nPos = rFileURL.lastIndexOf( '.' );
753 if (-1 != nPos)
754 aExt = rFileURL.copy( nPos + 1 ).toAsciiLowerCase();
755
756 if (aExt != "dic")
757 return false;
758
759 // get stream to be used
760 uno::Reference< uno::XComponentContext > xContext( comphelper::getProcessComponentContext() );
761
762 // get XInputStream stream
763 uno::Reference< io::XInputStream > xStream;
764 try
765 {
766 uno::Reference< ucb::XSimpleFileAccess3 > xAccess( ucb::SimpleFileAccess::create(xContext) );
767 xStream = xAccess->openFileRead( rFileURL );
768 }
769 catch (const uno::Exception &)
770 {
771 SAL_WARN( "linguistic", "failed to get input stream" );
772 }
773 DBG_ASSERT( xStream.is(), "failed to get stream for read" );
774 if (!xStream.is())
775 return false;
776
777 std::unique_ptr<SvStream> pStream( utl::UcbStreamHelper::CreateStream( xStream ) );
778
779 int nDicVersion = ReadDicVersion(*pStream, nLng, bNeg, aDicName);
780 return 2 == nDicVersion || nDicVersion >= 5;
781}
782
783extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
785 css::uno::XComponentContext* , css::uno::Sequence<css::uno::Any> const&)
786{
787 return cppu::acquire(new DicList());
788}
789
790/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Reference< XInputStream > xStream
AnyEventRef aEvent
OUString lowercase(const OUString &rStr, sal_Int32 nPos, sal_Int32 nCount) const
void DisposeAndClear(const EventObject &rEvtObj)
Definition: dlistimp.cxx:117
sal_Int16 EndCollectEvents()
Definition: dlistimp.cxx:213
comphelper::OInterfaceContainerHelper3< XDictionaryListEventListener > aDicListEvtListeners
Definition: dlistimp.cxx:69
sal_Int16 BeginCollectEvents()
Definition: dlistimp.cxx:94
sal_Int16 FlushEvents()
Definition: dlistimp.cxx:226
virtual void SAL_CALL disposing(const EventObject &rSource) override
Definition: dlistimp.cxx:123
DicEvtListenerHelper(uno::Reference< XDictionaryList > xDicList)
Definition: dlistimp.cxx:101
bool RemoveDicListEvtListener(const uno::Reference< XDictionaryListEventListener > &rxListener)
Definition: dlistimp.cxx:204
uno::Reference< XDictionaryList > xMyDicList
Definition: dlistimp.cxx:70
virtual void SAL_CALL processDictionaryEvent(const DictionaryEvent &rDicEvent) override
Definition: dlistimp.cxx:144
sal_Int16 nCondensedEvt
Definition: dlistimp.cxx:72
virtual ~DicEvtListenerHelper() override
Definition: dlistimp.cxx:110
bool AddDicListEvtListener(const uno::Reference< XDictionaryListEventListener > &rxListener)
Definition: dlistimp.cxx:195
sal_Int16 nNumCollectEvtListeners
Definition: dlistimp.cxx:73
virtual void AtExit() override
Definition: dlistimp.cxx:245
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
Definition: dlistimp.cxx:669
DictionaryVec_t aDicList
Definition: dlistimp.hxx:60
virtual void SAL_CALL dispose() override
Definition: dlistimp.cxx:512
virtual sal_Bool SAL_CALL addDictionary(const css::uno::Reference< css::linguistic2::XDictionary > &xDictionary) override
Definition: dlistimp.cxx:384
void SaveDics()
Definition: dlistimp.cxx:627
rtl::Reference< DicEvtListenerHelper > mxDicEvtLstnrHelper
Definition: dlistimp.hxx:62
bool bInCreation
Definition: dlistimp.hxx:66
virtual css::uno::Reference< css::linguistic2::XDictionaryEntry > SAL_CALL queryDictionaryEntry(const OUString &aWord, const css::lang::Locale &aLocale, sal_Bool bSearchPosDics, sal_Bool bSpellEntry) override
Definition: dlistimp.cxx:502
void SearchForDictionaries(DictionaryVec_t &rDicList, const OUString &rDicDir, bool bIsWritePath)
Definition: dlistimp.cxx:268
virtual css::uno::Reference< css::linguistic2::XDictionary > SAL_CALL getDictionaryByName(const OUString &aDictionaryName) override
Definition: dlistimp.cxx:364
virtual sal_Bool SAL_CALL supportsService(const OUString &ServiceName) override
Definition: dlistimp.cxx:664
virtual ::sal_Int16 SAL_CALL flushEvents() override
Definition: dlistimp.cxx:483
virtual css::uno::Reference< css::linguistic2::XDictionary > SAL_CALL createDictionary(const OUString &aName, const css::lang::Locale &aLocale, css::linguistic2::DictionaryType eDicType, const OUString &aURL) override
Definition: dlistimp.cxx:490
std::vector< css::uno::Reference< css::linguistic2::XDictionary > > DictionaryVec_t
Definition: dlistimp.hxx:59
LinguOptions aOpt
Definition: dlistimp.hxx:55
virtual ~DicList() override
Definition: dlistimp.cxx:262
virtual ::sal_Int16 SAL_CALL beginCollectEvents() override
Definition: dlistimp.cxx:471
void CreateDicList()
Definition: dlistimp.cxx:574
rtl::Reference< MyAppExitListener > mxExitListener
Definition: dlistimp.hxx:63
DictionaryVec_t & GetOrCreateDicList()
Definition: dlistimp.hxx:72
bool bDisposing
Definition: dlistimp.hxx:65
sal_Int32 GetDicPos(const css::uno::Reference< css::linguistic2::XDictionary > &xDic)
Definition: dlistimp.cxx:333
virtual sal_Bool SAL_CALL addDictionaryListEventListener(const css::uno::Reference< css::linguistic2::XDictionaryListEventListener > &xListener, sal_Bool bReceiveVerbose) override
Definition: dlistimp.cxx:436
virtual ::sal_Int16 SAL_CALL endCollectEvents() override
Definition: dlistimp.cxx:477
virtual void SAL_CALL removeEventListener(const css::uno::Reference< css::lang::XEventListener > &aListener) override
Definition: dlistimp.cxx:566
virtual sal_Bool SAL_CALL removeDictionary(const css::uno::Reference< css::linguistic2::XDictionary > &xDictionary) override
Definition: dlistimp.cxx:406
virtual sal_Bool SAL_CALL removeDictionaryListEventListener(const css::uno::Reference< css::linguistic2::XDictionaryListEventListener > &xListener) override
Definition: dlistimp.cxx:455
virtual ::sal_Int16 SAL_CALL getCount() override
Definition: dlistimp.cxx:347
virtual void SAL_CALL addEventListener(const css::uno::Reference< css::lang::XEventListener > &xListener) override
Definition: dlistimp.cxx:557
::comphelper::OInterfaceContainerHelper3< css::lang::XEventListener > aEvtListeners
Definition: dlistimp.hxx:57
virtual OUString SAL_CALL getImplementationName() override
Definition: dlistimp.cxx:658
virtual css::uno::Sequence< css::uno::Reference< css::linguistic2::XDictionary > > SAL_CALL getDictionaries() override
Definition: dlistimp.cxx:354
OUString getName(sal_Int32 nIndex=LAST_SEGMENT, bool bIgnoreFinalSlash=true, DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
const css::uno::Sequence< OUString > & GetActiveDics() const
Definition: lngopt.hxx:58
const CharClass & GetCharClass() const
OUString GetFullName() const
OUString GetEmail() const
OUString GetTitle() const
OUString GetCity() const
OUString GetCompany() const
OUString GetPosition() const
OUString GetStreet() const
sal_Int32 addInterface(const css::uno::Reference< ListenerT > &rxIFace)
void disposeAndClear(const css::lang::EventObject &rEvt)
sal_Int32 removeInterface(const css::uno::Reference< ListenerT > &rxIFace)
void notifyEach(void(SAL_CALL ListenerT::*NotificationMethod)(const EventT &), const EventT &Event)
static std::unique_ptr< SvStream > CreateStream(const OUString &rFileName, StreamMode eOpenMode, css::uno::Reference< css::awt::XWindow > xParentWin=nullptr)
int nCount
#define DBG_ASSERT(sCon, aError)
sal_Int16 ReadDicVersion(SvStream &rStream, LanguageType &nLng, bool &bNeg, OUString &aDicName)
Definition: dicimp.cxx:109
URL aURL
static sal_Int32 lcl_GetToken(OUString &rToken, const OUString &rText, sal_Int32 nPos, std::u16string_view rDelim)
Definition: dlistimp.cxx:676
static void AddInternal(const uno::Reference< XDictionary > &rDic, const OUString &rNew)
Definition: dlistimp.cxx:709
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * linguistic_DicList_get_implementation(css::uno::XComponentContext *, css::uno::Sequence< css::uno::Any > const &)
Definition: dlistimp.cxx:784
static void AddUserData(const uno::Reference< XDictionary > &rDic)
Definition: dlistimp.cxx:732
static bool IsVers2OrNewer(const OUString &rFileURL, LanguageType &nLng, bool &bNeg, OUString &aDicName)
Definition: dlistimp.cxx:747
float u
DocumentType eType
sal_Int64 n
#define LANGUAGE_NONE
sal_uInt16 nPos
#define SAL_WARN(area, stream)
std::locale Create(std::string_view aPrefixName, const LanguageTag &rLocale)
OUString get(TranslateId sContextAndId, const std::locale &loc)
@ Exception
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
Reference< XComponentContext > getProcessComponentContext()
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
int i
uno::Reference< XDictionaryEntry > SearchDicList(const uno::Reference< XSearchableDictionaryList > &xDicList, const OUString &rWord, LanguageType nLanguage, bool bSearchPosDics, bool bSearchSpellEntry)
Definition: misc.cxx:248
OUString GetDictionaryWriteablePath()
Definition: misc2.cxx:131
osl::Mutex & GetLinguMutex()
! multi-thread safe mutex for all platforms !!
Definition: misc.cxx:60
bool IsNumeric(std::u16string_view rText)
Definition: misc.cxx:646
css::lang::Locale LinguLanguageToLocale(LanguageType nLanguage)
Convert LanguageType to Locale for legacy handling.
Definition: misc.cxx:81
std::vector< OUString > GetDictionaryPaths()
Definition: misc2.cxx:142
LanguageType LinguLocaleToLanguage(const css::lang::Locale &rLocale)
Convert Locale to LanguageType for legacy handling.
Definition: misc.cxx:74
unsigned char sal_Bool