calc: on editing invalidation of view with different zoom is wrong
[LibreOffice.git] / linguistic / source / lngprophelp.cxx
bloba14c96c9501ebea3b3d68cc4fc584c7117c9e5c0
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <tools/debug.hxx>
22 #include <sal/log.hxx>
24 #include <com/sun/star/linguistic2/LinguServiceEvent.hpp>
25 #include <com/sun/star/linguistic2/LinguServiceEventFlags.hpp>
26 #include <com/sun/star/linguistic2/XLinguServiceEventListener.hpp>
27 #include <com/sun/star/linguistic2/XLinguProperties.hpp>
28 #include <com/sun/star/beans/XPropertySet.hpp>
29 #include <osl/mutex.hxx>
30 #include <unotools/linguprops.hxx>
32 #include <linguistic/misc.hxx>
33 #include <linguistic/lngprops.hxx>
35 #include <linguistic/lngprophelp.hxx>
37 using namespace osl;
38 using namespace com::sun::star;
39 using namespace com::sun::star::beans;
40 using namespace com::sun::star::lang;
41 using namespace com::sun::star::uno;
42 using namespace com::sun::star::linguistic2;
43 using namespace linguistic;
46 namespace linguistic
50 PropertyChgHelper::PropertyChgHelper(
51 const Reference< XInterface > &rxSource,
52 Reference< XLinguProperties > const &rxPropSet,
53 int nAllowedEvents ) :
54 aPropNames ({UPN_IS_IGNORE_CONTROL_CHARACTERS, UPN_IS_USE_DICTIONARY_LIST}),
55 xMyEvtObj (rxSource),
56 aLngSvcEvtListeners (GetLinguMutex()),
57 xPropSet (rxPropSet),
58 nEvtFlags (nAllowedEvents)
60 SetDefaultValues();
63 PropertyChgHelper::~PropertyChgHelper()
67 void PropertyChgHelper::SetDefaultValues()
69 bResIsIgnoreControlCharacters = bIsIgnoreControlCharacters = true;
70 bResIsUseDictionaryList = bIsUseDictionaryList = true;
74 void PropertyChgHelper::GetCurrentValues()
76 const auto& rPropNames = GetPropNames();
77 if (!GetPropSet().is() || rPropNames.empty())
78 return;
80 for (const OUString& rPropName : rPropNames)
82 bool *pbVal = nullptr,
83 *pbResVal = nullptr;
85 if ( rPropName == UPN_IS_IGNORE_CONTROL_CHARACTERS )
87 pbVal = &bIsIgnoreControlCharacters;
88 pbResVal = &bResIsIgnoreControlCharacters;
90 else if ( rPropName == UPN_IS_USE_DICTIONARY_LIST )
92 pbVal = &bIsUseDictionaryList;
93 pbResVal = &bResIsUseDictionaryList;
96 if (pbVal && pbResVal)
98 GetPropSet()->getPropertyValue( rPropName ) >>= *pbVal;
99 *pbResVal = *pbVal;
105 void PropertyChgHelper::SetTmpPropVals( const PropertyValues &rPropVals )
107 // return value is default value unless there is an explicitly supplied
108 // temporary value
109 bResIsIgnoreControlCharacters = bIsIgnoreControlCharacters;
110 bResIsUseDictionaryList = bIsUseDictionaryList;
112 for (const PropertyValue& rVal : rPropVals)
114 bool *pbResVal = nullptr;
115 switch (rVal.Handle)
117 case UPH_IS_IGNORE_CONTROL_CHARACTERS :
118 pbResVal = &bResIsIgnoreControlCharacters; break;
119 case UPH_IS_USE_DICTIONARY_LIST :
120 pbResVal = &bResIsUseDictionaryList; break;
121 default:
124 if (pbResVal)
125 rVal.Value >>= *pbResVal;
130 bool PropertyChgHelper::propertyChange_Impl( const PropertyChangeEvent& rEvt )
132 bool bRes = false;
134 if (GetPropSet().is() && rEvt.Source == GetPropSet())
136 sal_Int16 nLngSvcFlags = (nEvtFlags & AE_HYPHENATOR) ?
137 LinguServiceEventFlags::HYPHENATE_AGAIN : 0;
138 bool bSCWA = false, // SPELL_CORRECT_WORDS_AGAIN ?
139 bSWWA = false; // SPELL_WRONG_WORDS_AGAIN ?
141 bool *pbVal = nullptr;
142 switch (rEvt.PropertyHandle)
144 case UPH_IS_IGNORE_CONTROL_CHARACTERS :
146 pbVal = &bIsIgnoreControlCharacters;
147 nLngSvcFlags = 0;
148 break;
150 case UPH_IS_USE_DICTIONARY_LIST :
152 pbVal = &bIsUseDictionaryList;
153 bSCWA = bSWWA = true;
154 break;
157 if (pbVal)
158 rEvt.NewValue >>= *pbVal;
160 bRes = nullptr != pbVal; // sth changed?
161 if (bRes)
163 bool bSpellEvts = (nEvtFlags & AE_SPELLCHECKER);
164 if (bSCWA && bSpellEvts)
165 nLngSvcFlags |= LinguServiceEventFlags::SPELL_CORRECT_WORDS_AGAIN;
166 if (bSWWA && bSpellEvts)
167 nLngSvcFlags |= LinguServiceEventFlags::SPELL_WRONG_WORDS_AGAIN;
168 if (nLngSvcFlags)
170 LinguServiceEvent aEvt( GetEvtObj(), nLngSvcFlags );
171 LaunchEvent( aEvt );
176 return bRes;
180 void SAL_CALL
181 PropertyChgHelper::propertyChange( const PropertyChangeEvent& rEvt )
183 MutexGuard aGuard( GetLinguMutex() );
184 propertyChange_Impl( rEvt );
188 void PropertyChgHelper::AddAsPropListener()
190 if (xPropSet.is())
192 for (const OUString& rPropName : std::as_const(aPropNames))
194 if (!rPropName.isEmpty())
195 xPropSet->addPropertyChangeListener( rPropName, this );
200 void PropertyChgHelper::RemoveAsPropListener()
202 if (xPropSet.is())
204 for (const OUString& rPropName : std::as_const(aPropNames))
206 if (!rPropName.isEmpty())
207 xPropSet->removePropertyChangeListener( rPropName, this );
213 void PropertyChgHelper::LaunchEvent( const LinguServiceEvent &rEvt )
215 aLngSvcEvtListeners.notifyEach( &XLinguServiceEventListener::processLinguServiceEvent, rEvt );
219 void SAL_CALL PropertyChgHelper::disposing( const EventObject& rSource )
221 MutexGuard aGuard( GetLinguMutex() );
222 if (rSource.Source == xPropSet)
224 RemoveAsPropListener();
225 xPropSet = nullptr;
226 aPropNames.clear();
231 sal_Bool SAL_CALL
232 PropertyChgHelper::addLinguServiceEventListener(
233 const Reference< XLinguServiceEventListener >& rxListener )
235 MutexGuard aGuard( GetLinguMutex() );
237 bool bRes = false;
238 if (rxListener.is())
240 sal_Int32 nCount = aLngSvcEvtListeners.getLength();
241 bRes = aLngSvcEvtListeners.addInterface( rxListener ) != nCount;
243 return bRes;
247 sal_Bool SAL_CALL
248 PropertyChgHelper::removeLinguServiceEventListener(
249 const Reference< XLinguServiceEventListener >& rxListener )
251 MutexGuard aGuard( GetLinguMutex() );
253 bool bRes = false;
254 if (rxListener.is())
256 sal_Int32 nCount = aLngSvcEvtListeners.getLength();
257 bRes = aLngSvcEvtListeners.removeInterface( rxListener ) != nCount;
259 return bRes;
263 PropertyHelper_Thes::PropertyHelper_Thes(
264 const Reference< XInterface > &rxSource,
265 Reference< XLinguProperties > const &rxPropSet ) :
266 PropertyChgHelper ( rxSource, rxPropSet, 0 )
268 SetDefaultValues();
269 GetCurrentValues();
273 PropertyHelper_Thes::~PropertyHelper_Thes()
278 void SAL_CALL
279 PropertyHelper_Thes::propertyChange( const PropertyChangeEvent& rEvt )
281 MutexGuard aGuard( GetLinguMutex() );
282 PropertyChgHelper::propertyChange_Impl( rEvt );
286 PropertyHelper_Spell::PropertyHelper_Spell(
287 const Reference< XInterface > & rxSource,
288 Reference< XLinguProperties > const &rxPropSet ) :
289 PropertyChgHelper ( rxSource, rxPropSet, AE_SPELLCHECKER )
291 auto& rPropNames = GetPropNames();
292 rPropNames.push_back(UPN_IS_SPELL_UPPER_CASE);
293 rPropNames.push_back(UPN_IS_SPELL_WITH_DIGITS);
294 rPropNames.push_back(UPN_IS_SPELL_CAPITALIZATION);
295 SetDefaultValues();
296 GetCurrentValues();
300 PropertyHelper_Spell::~PropertyHelper_Spell()
305 void PropertyHelper_Spell::SetDefaultValues()
307 PropertyChgHelper::SetDefaultValues();
309 bResIsSpellUpperCase = bIsSpellUpperCase = false;
310 bResIsSpellWithDigits = bIsSpellWithDigits = false;
311 bResIsSpellCapitalization = bIsSpellCapitalization = true;
315 void PropertyHelper_Spell::GetCurrentValues()
317 PropertyChgHelper::GetCurrentValues();
319 const auto& rPropNames = GetPropNames();
320 if (!GetPropSet().is() || rPropNames.empty())
321 return;
323 for (const OUString& rPropName : rPropNames)
325 bool *pbVal = nullptr,
326 *pbResVal = nullptr;
328 if ( rPropName == UPN_IS_SPELL_UPPER_CASE )
330 pbVal = &bIsSpellUpperCase;
331 pbResVal = &bResIsSpellUpperCase;
333 else if ( rPropName == UPN_IS_SPELL_WITH_DIGITS )
335 pbVal = &bIsSpellWithDigits;
336 pbResVal = &bResIsSpellWithDigits;
338 else if ( rPropName == UPN_IS_SPELL_CAPITALIZATION )
340 pbVal = &bIsSpellCapitalization;
341 pbResVal = &bResIsSpellCapitalization;
344 if (pbVal && pbResVal)
346 GetPropSet()->getPropertyValue( rPropName ) >>= *pbVal;
347 *pbResVal = *pbVal;
353 bool PropertyHelper_Spell::propertyChange_Impl( const PropertyChangeEvent& rEvt )
355 bool bRes = PropertyChgHelper::propertyChange_Impl( rEvt );
357 if (!bRes && GetPropSet().is() && rEvt.Source == GetPropSet())
359 bool bSCWA = false, // SPELL_CORRECT_WORDS_AGAIN ?
360 bSWWA = false; // SPELL_WRONG_WORDS_AGAIN ?
362 bool *pbVal = nullptr;
363 switch (rEvt.PropertyHandle)
365 case UPH_IS_SPELL_UPPER_CASE :
367 pbVal = &bIsSpellUpperCase;
368 bSCWA = ! *pbVal; // sal_False->sal_True change?
369 bSWWA = !bSCWA; // sal_True->sal_False change?
370 break;
372 case UPH_IS_SPELL_WITH_DIGITS :
374 pbVal = &bIsSpellWithDigits;
375 bSCWA = ! *pbVal; // sal_False->sal_True change?
376 bSWWA = !bSCWA; // sal_True->sal_False change?
377 break;
379 case UPH_IS_SPELL_CAPITALIZATION :
381 pbVal = &bIsSpellCapitalization;
382 bSCWA = ! *pbVal; // sal_False->sal_True change?
383 bSWWA = !bSCWA; // sal_True->sal_False change?
384 break;
386 default:
387 SAL_WARN( "linguistic", "unknown property" );
389 if (pbVal)
390 rEvt.NewValue >>= *pbVal;
392 bRes = (pbVal != nullptr);
393 if (bRes)
395 sal_Int16 nLngSvcFlags = 0;
396 if (bSCWA)
397 nLngSvcFlags |= LinguServiceEventFlags::SPELL_CORRECT_WORDS_AGAIN;
398 if (bSWWA)
399 nLngSvcFlags |= LinguServiceEventFlags::SPELL_WRONG_WORDS_AGAIN;
400 if (nLngSvcFlags)
402 LinguServiceEvent aEvt( GetEvtObj(), nLngSvcFlags );
403 LaunchEvent( aEvt );
408 return bRes;
412 void SAL_CALL
413 PropertyHelper_Spell::propertyChange( const PropertyChangeEvent& rEvt )
415 MutexGuard aGuard( GetLinguMutex() );
416 propertyChange_Impl( rEvt );
420 void PropertyHelper_Spell::SetTmpPropVals( const PropertyValues &rPropVals )
422 PropertyChgHelper::SetTmpPropVals( rPropVals );
424 // return value is default value unless there is an explicitly supplied
425 // temporary value
426 bResIsSpellWithDigits = bIsSpellWithDigits;
427 bResIsSpellCapitalization = bIsSpellCapitalization;
428 bResIsSpellUpperCase = bIsSpellUpperCase;
430 for (const PropertyValue& rVal : rPropVals)
432 if ( rVal.Name == UPN_MAX_NUMBER_OF_SUGGESTIONS )
434 // special value that is not part of the property set and thus needs to be handled differently
436 else
438 bool *pbResVal = nullptr;
439 switch (rVal.Handle)
441 case UPH_IS_SPELL_UPPER_CASE : pbResVal = &bResIsSpellUpperCase; break;
442 case UPH_IS_SPELL_WITH_DIGITS : pbResVal = &bResIsSpellWithDigits; break;
443 case UPH_IS_SPELL_CAPITALIZATION : pbResVal = &bResIsSpellCapitalization; break;
444 default:
445 SAL_WARN( "linguistic", "unknown property" );
447 if (pbResVal)
448 rVal.Value >>= *pbResVal;
453 PropertyHelper_Hyphen::PropertyHelper_Hyphen(
454 const Reference< XInterface > & rxSource,
455 Reference< XLinguProperties > const &rxPropSet ) :
456 PropertyChgHelper ( rxSource, rxPropSet, AE_HYPHENATOR )
458 auto& rPropNames = GetPropNames();
459 rPropNames.push_back(UPN_HYPH_MIN_LEADING);
460 rPropNames.push_back(UPN_HYPH_MIN_TRAILING);
461 rPropNames.push_back(UPN_HYPH_MIN_WORD_LENGTH);
462 SetDefaultValues();
463 GetCurrentValues();
467 PropertyHelper_Hyphen::~PropertyHelper_Hyphen()
472 void PropertyHelper_Hyphen::SetDefaultValues()
474 PropertyChgHelper::SetDefaultValues();
476 nResHyphMinLeading = nHyphMinLeading = 2;
477 nResHyphMinTrailing = nHyphMinTrailing = 2;
478 nResHyphMinWordLength = nHyphMinWordLength = 0;
479 bResNoHyphenateCaps = bNoHyphenateCaps = false;
483 void PropertyHelper_Hyphen::GetCurrentValues()
485 PropertyChgHelper::GetCurrentValues();
487 const auto& rPropNames = GetPropNames();
488 if (!GetPropSet().is() || rPropNames.empty())
489 return;
491 for (const OUString& rPropName : rPropNames)
493 sal_Int16 *pnVal = nullptr,
494 *pnResVal = nullptr;
495 bool *pbVal = nullptr;
496 bool *pbResVal = nullptr;
498 if ( rPropName == UPN_HYPH_MIN_LEADING )
500 pnVal = &nHyphMinLeading;
501 pnResVal = &nResHyphMinLeading;
503 else if ( rPropName == UPN_HYPH_MIN_TRAILING )
505 pnVal = &nHyphMinTrailing;
506 pnResVal = &nResHyphMinTrailing;
508 else if ( rPropName == UPN_HYPH_MIN_WORD_LENGTH )
510 pnVal = &nHyphMinWordLength;
511 pnResVal = &nResHyphMinWordLength;
513 else if ( rPropName == UPN_HYPH_NO_CAPS )
515 pbVal = &bNoHyphenateCaps;
516 pbResVal = &bResNoHyphenateCaps;
519 if (pnVal && pnResVal)
521 GetPropSet()->getPropertyValue( rPropName ) >>= *pnVal;
522 *pnResVal = *pnVal;
524 else if (pbVal && pbResVal)
526 GetPropSet()->getPropertyValue( rPropName ) >>= *pbVal;
527 *pbResVal = *pbVal;
533 bool PropertyHelper_Hyphen::propertyChange_Impl( const PropertyChangeEvent& rEvt )
535 bool bRes = PropertyChgHelper::propertyChange_Impl( rEvt );
537 if (!bRes && GetPropSet().is() && rEvt.Source == GetPropSet())
539 sal_Int16 *pnVal = nullptr;
540 bool *pbVal = nullptr;
541 switch (rEvt.PropertyHandle)
543 case UPH_HYPH_MIN_LEADING : pnVal = &nHyphMinLeading; break;
544 case UPH_HYPH_MIN_TRAILING : pnVal = &nHyphMinTrailing; break;
545 case UPH_HYPH_MIN_WORD_LENGTH : pnVal = &nHyphMinWordLength; break;
546 case UPH_HYPH_NO_CAPS : pbVal = &bNoHyphenateCaps; break;
547 default:
548 SAL_WARN( "linguistic", "unknown property" );
550 if (pnVal)
551 rEvt.NewValue >>= *pnVal;
552 else if (pbVal)
553 rEvt.NewValue >>= *pbVal;
555 bRes = (pnVal != nullptr || pbVal != nullptr);
556 if (bRes)
558 LinguServiceEvent aEvt(GetEvtObj(), LinguServiceEventFlags::HYPHENATE_AGAIN);
559 LaunchEvent(aEvt);
563 return bRes;
567 void SAL_CALL
568 PropertyHelper_Hyphen::propertyChange( const PropertyChangeEvent& rEvt )
570 MutexGuard aGuard( GetLinguMutex() );
571 propertyChange_Impl( rEvt );
575 void PropertyHelper_Hyphen::SetTmpPropVals( const PropertyValues &rPropVals )
577 PropertyChgHelper::SetTmpPropVals( rPropVals );
579 // return value is default value unless there is an explicitly supplied
580 // temporary value
581 nResHyphMinLeading = nHyphMinLeading;
582 nResHyphMinTrailing = nHyphMinTrailing;
583 nResHyphMinWordLength = nHyphMinWordLength;
584 bResNoHyphenateCaps = bNoHyphenateCaps;
586 for (const PropertyValue& rVal : rPropVals)
588 sal_Int16 *pnResVal = nullptr;
589 bool *pbResVal = nullptr;
591 if ( rVal.Name == UPN_HYPH_MIN_LEADING )
592 pnResVal = &nResHyphMinLeading;
593 else if ( rVal.Name == UPN_HYPH_MIN_TRAILING )
594 pnResVal = &nResHyphMinTrailing;
595 else if ( rVal.Name == UPN_HYPH_MIN_WORD_LENGTH )
596 pnResVal = &nResHyphMinWordLength;
597 else if ( rVal.Name == UPN_HYPH_NO_CAPS )
598 pbResVal = &bResNoHyphenateCaps;
600 DBG_ASSERT( pnResVal || pbResVal, "unknown property" );
602 if (pnResVal)
603 rVal.Value >>= *pnResVal;
604 else if (pbResVal)
605 rVal.Value >>= *pbResVal;
609 PropertyHelper_Thesaurus::PropertyHelper_Thesaurus(
610 const css::uno::Reference< css::uno::XInterface > &rxSource,
611 css::uno::Reference< css::linguistic2::XLinguProperties > const &rxPropSet )
613 mxPropHelper = new PropertyHelper_Thes( rxSource, rxPropSet );
616 PropertyHelper_Thesaurus::~PropertyHelper_Thesaurus()
620 void PropertyHelper_Thesaurus::AddAsPropListener()
622 mxPropHelper->AddAsPropListener();
625 void PropertyHelper_Thesaurus::RemoveAsPropListener()
627 mxPropHelper->RemoveAsPropListener();
630 void PropertyHelper_Thesaurus::SetTmpPropVals( const css::beans::PropertyValues &rPropVals )
632 mxPropHelper->SetTmpPropVals( rPropVals );
635 PropertyHelper_Hyphenation::PropertyHelper_Hyphenation(
636 const css::uno::Reference< css::uno::XInterface > &rxSource,
637 css::uno::Reference< css::linguistic2::XLinguProperties > const &rxPropSet)
639 mxPropHelper = new PropertyHelper_Hyphen( rxSource, rxPropSet );
642 PropertyHelper_Hyphenation::~PropertyHelper_Hyphenation()
646 void PropertyHelper_Hyphenation::AddAsPropListener()
648 mxPropHelper->AddAsPropListener();
651 void PropertyHelper_Hyphenation::RemoveAsPropListener()
653 mxPropHelper->RemoveAsPropListener();
656 void PropertyHelper_Hyphenation::SetTmpPropVals( const css::beans::PropertyValues &rPropVals )
658 mxPropHelper->SetTmpPropVals( rPropVals );
661 sal_Int16 PropertyHelper_Hyphenation::GetMinLeading() const
663 return mxPropHelper->GetMinLeading();
666 sal_Int16 PropertyHelper_Hyphenation::GetMinTrailing() const
668 return mxPropHelper->GetMinTrailing();
671 sal_Int16 PropertyHelper_Hyphenation::GetMinWordLength() const
673 return mxPropHelper->GetMinWordLength();
676 bool PropertyHelper_Hyphenation::IsNoHyphenateCaps() const
678 return mxPropHelper->IsNoHyphenateCaps();
681 bool PropertyHelper_Hyphenation::addLinguServiceEventListener(
682 const css::uno::Reference< css::linguistic2::XLinguServiceEventListener >& rxListener )
684 return mxPropHelper->addLinguServiceEventListener( rxListener );
687 bool PropertyHelper_Hyphenation::removeLinguServiceEventListener(
688 const css::uno::Reference< css::linguistic2::XLinguServiceEventListener >& rxListener )
690 return mxPropHelper->removeLinguServiceEventListener( rxListener );
693 PropertyHelper_Spelling::PropertyHelper_Spelling(
694 const css::uno::Reference< css::uno::XInterface > &rxSource,
695 css::uno::Reference< css::linguistic2::XLinguProperties > const &rxPropSet )
697 mxPropHelper = new PropertyHelper_Spell( rxSource, rxPropSet );
700 PropertyHelper_Spelling::~PropertyHelper_Spelling()
704 void PropertyHelper_Spelling::AddAsPropListener()
706 mxPropHelper->AddAsPropListener();
709 void PropertyHelper_Spelling::RemoveAsPropListener()
711 mxPropHelper->RemoveAsPropListener();
714 void PropertyHelper_Spelling::SetTmpPropVals( const css::beans::PropertyValues &rPropVals )
716 mxPropHelper->SetTmpPropVals( rPropVals );
719 bool PropertyHelper_Spelling::IsSpellUpperCase() const
721 return mxPropHelper->IsSpellUpperCase();
724 bool PropertyHelper_Spelling::IsSpellWithDigits() const
726 return mxPropHelper->IsSpellWithDigits();
729 bool PropertyHelper_Spelling::IsSpellCapitalization() const
731 return mxPropHelper->IsSpellCapitalization();
734 bool PropertyHelper_Spelling::addLinguServiceEventListener(
735 const css::uno::Reference<
736 css::linguistic2::XLinguServiceEventListener >& rxListener )
738 return mxPropHelper->addLinguServiceEventListener( rxListener );
741 bool PropertyHelper_Spelling::removeLinguServiceEventListener(
742 const css::uno::Reference<
743 css::linguistic2::XLinguServiceEventListener >& rxListener )
745 return mxPropHelper->removeLinguServiceEventListener( rxListener );
748 } // namespace linguistic
750 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */