1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <vcl/msgbox.hxx>
21 #include <vcl/field.hxx>
22 #include <vcl/fixed.hxx>
23 #include <vcl/settings.hxx>
24 #include <tools/shl.hxx>
25 #include <i18nlangtag/mslangid.hxx>
26 #include <unotools/lingucfg.hxx>
27 #include <editeng/unolingu.hxx>
28 #include <svx/dlgutil.hxx>
29 #include <linguistic/lngprops.hxx>
30 #include <linguistic/misc.hxx>
31 #include <sfx2/sfxuno.hxx>
32 #include <sfx2/dispatch.hxx>
33 #include <tools/urlobj.hxx>
34 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
35 #include <comphelper/processfactory.hxx>
36 #include <com/sun/star/linguistic2/LinguServiceManager.hpp>
37 #include <com/sun/star/linguistic2/XSpellChecker.hpp>
38 #include <com/sun/star/linguistic2/XProofreader.hpp>
39 #include <com/sun/star/linguistic2/XHyphenator.hpp>
40 #include <com/sun/star/linguistic2/XThesaurus.hpp>
41 #include <com/sun/star/linguistic2/XAvailableLocales.hpp>
42 #include <com/sun/star/lang/XServiceDisplayName.hpp>
43 #include <com/sun/star/linguistic2/DictionaryListEventFlags.hpp>
44 #include <com/sun/star/linguistic2/DictionaryListEvent.hpp>
45 #include <com/sun/star/linguistic2/XDictionaryListEventListener.hpp>
46 #include <com/sun/star/linguistic2/XDictionaryList.hpp>
47 #include <com/sun/star/frame/XStorable.hpp>
48 #include <com/sun/star/ucb/CommandAbortedException.hpp>
49 #include <com/sun/star/system/SystemShellExecute.hpp>
50 #include <com/sun/star/system/SystemShellExecuteFlags.hpp>
51 #include <unotools/extendedsecurityoptions.hxx>
52 #include <svtools/treelistbox.hxx>
53 #include "svtools/treelistentry.hxx"
54 #include <svtools/langhelp.hxx>
55 #include <svl/eitem.hxx>
56 #include <svl/intitem.hxx>
57 #include <sfx2/viewfrm.hxx>
58 #include <vcl/svapp.hxx>
60 #include <svx/svxdlg.hxx>
61 #include <editeng/optitems.hxx>
62 #include "optlingu.hxx"
63 #include <dialmgr.hxx>
67 #include <ucbhelper/content.hxx>
73 using namespace ::ucbhelper
;
74 using namespace ::rtl
;
75 using namespace ::com::sun::star
;
76 using namespace ::com::sun::star::lang
;
77 using namespace ::com::sun::star::uno
;
78 using namespace ::com::sun::star::linguistic2
;
79 using namespace ::com::sun::star::beans
;
82 #define CBCOL_SECOND 1
84 static const sal_Char cSpell
[] = SN_SPELLCHECKER
;
85 static const sal_Char cGrammar
[] = SN_GRAMMARCHECKER
;
86 static const sal_Char cHyph
[] = SN_HYPHENATOR
;
87 static const sal_Char cThes
[] = SN_THESAURUS
;
89 // static ----------------------------------------------------------------
91 static Sequence
< sal_Int16
> lcl_LocaleSeqToLangSeq( const Sequence
< Locale
> &rSeq
)
93 sal_Int32 nLen
= rSeq
.getLength();
94 Sequence
< sal_Int16
> aRes( nLen
);
95 sal_Int16
*pRes
= aRes
.getArray();
96 const Locale
*pSeq
= rSeq
.getConstArray();
97 for (sal_Int32 i
= 0; i
< nLen
; ++i
)
99 pRes
[i
] = LanguageTag::convertToLanguageType( pSeq
[i
] );
105 static bool lcl_SeqHasLang( const Sequence
< sal_Int16
> &rSeq
, sal_Int16 nLang
)
107 sal_Int32 nLen
= rSeq
.getLength();
108 const sal_Int16
*pLang
= rSeq
.getConstArray();
110 for (sal_Int32 i
= 0; i
< nLen
&& nPos
< 0; ++i
)
112 if (nLang
== pLang
[i
])
119 static sal_Int32
lcl_SeqGetEntryPos(
120 const Sequence
< OUString
> &rSeq
, const OUString
&rEntry
)
123 sal_Int32 nLen
= rSeq
.getLength();
124 const OUString
*pItem
= rSeq
.getConstArray();
125 for (i
= 0; i
< nLen
; ++i
)
127 if (rEntry
== pItem
[i
])
130 return i
< nLen
? i
: -1;
133 static void lcl_OpenURL( const OUString
& _sURL
)
135 if ( !_sURL
.isEmpty() )
137 OUString sURL
= _sURL
;
138 localizeWebserviceURI(sURL
);
141 uno::Reference
< uno::XComponentContext
> xContext
=
142 ::comphelper::getProcessComponentContext();
143 uno::Reference
< css::system::XSystemShellExecute
> xSystemShell(
144 css::system::SystemShellExecute::create(xContext
) );
145 xSystemShell
->execute( sURL
, OUString(), css::system::SystemShellExecuteFlags::URIS_ONLY
);
147 catch( const uno::Exception
& e
)
149 OSL_TRACE( "Caught exception: %s\n thread terminated.\n",
150 OUStringToOString(e
.Message
, RTL_TEXTENCODING_UTF8
).getStr());
155 static const sal_uInt16 pRanges
[] =
162 bool KillFile_Impl( const OUString
& rURL
)
167 Content
aCnt( rURL
, uno::Reference
< ::com::sun::star::ucb::XCommandEnvironment
>(), comphelper::getProcessComponentContext() );
168 aCnt
.executeCommand( OUString("delete"), makeAny( true ) );
170 catch( ::com::sun::star::ucb::CommandAbortedException
& )
172 SAL_WARN( "cui.options", "KillFile: CommandAbortedException" );
177 SAL_WARN( "cui.options", "KillFile: Any other exception" );
186 // t: 1 -> spell, 2 -> hyph, 3 -> thes, 4 -> grammar
187 // c: 1 -> checked 0 -> unchecked
190 #define TYPE_SPELL (sal_uInt8)1
191 #define TYPE_GRAMMAR (sal_uInt8)2
192 #define TYPE_HYPH (sal_uInt8)3
193 #define TYPE_THES (sal_uInt8)4
195 class ModuleUserData_Impl
204 ModuleUserData_Impl( const OUString
& sImpName
, bool bIsParent
, bool bChecked
, sal_uInt8 nSetType
, sal_uInt8 nSetIndex
) :
206 bIsChecked(bChecked
),
212 bool IsParent() const {return bParent
;}
213 sal_uInt8
GetType() const {return nType
;}
214 bool IsChecked() const {return bIsChecked
;}
215 sal_uInt8
GetIndex() const {return nIndex
;}
216 const OUString
& GetImplName() const {return sImplName
;}
221 // User for user-dictionaries (XDictionary interface)
228 DicUserData( sal_uLong nUserData
) : nVal( nUserData
) {}
229 DicUserData( sal_uInt16 nEID
,
230 bool bChecked
, bool bEditable
, bool bDeletable
);
232 sal_uLong
GetUserData() const { return nVal
; }
233 sal_uInt16
GetEntryId() const { return (sal_uInt16
)(nVal
>> 16); }
234 bool IsChecked() const { return (bool)((nVal
>> 8) & 0x01); }
235 bool IsDeletable() const { return (bool)((nVal
>> 10) & 0x01); }
239 DicUserData::DicUserData(
241 bool bChecked
, bool bEditable
, bool bDeletable
)
243 DBG_ASSERT( nEID
< 65000, "Entry Id out of range" );
244 nVal
= ((sal_uLong
)(0xFFFF & nEID
) << 16) |
245 ((sal_uLong
)(bChecked
? 1 : 0) << 8) |
246 ((sal_uLong
)(bEditable
? 1 : 0) << 9) |
247 ((sal_uLong
)(bDeletable
? 1 : 0) << 10);
251 // class BrwString_Impl -------------------------------------------------
253 static void lcl_SetCheckButton( SvTreeListEntry
* pEntry
, bool bCheck
)
255 SvLBoxButton
* pItem
= (SvLBoxButton
*)(pEntry
->GetFirstItem(SV_ITEM_ID_LBOXBUTTON
));
257 DBG_ASSERT(pItem
,"SetCheckButton:Item not found");
258 if (pItem
->GetType() == SV_ITEM_ID_LBOXBUTTON
)
261 pItem
->SetStateChecked();
263 pItem
->SetStateUnchecked();
268 class BrwStringDic_Impl
: public SvLBoxString
272 BrwStringDic_Impl( SvTreeListEntry
* pEntry
, sal_uInt16 nFlags
,
273 const OUString
& rStr
) : SvLBoxString( pEntry
, nFlags
, rStr
) {}
276 const Point
& rPos
, SvTreeListBox
& rOutDev
, const SvViewDataEntry
* pView
, const SvTreeListEntry
* pEntry
) SAL_OVERRIDE
;
279 void BrwStringDic_Impl::Paint(
280 const Point
& rPos
, SvTreeListBox
& rDev
, const SvViewDataEntry
* /*pView*/,
281 const SvTreeListEntry
* pEntry
)
283 ModuleUserData_Impl
* pData
= (ModuleUserData_Impl
*)pEntry
->GetUserData();
285 Font
aOldFont( rDev
.GetFont());
286 if(pData
->IsParent())
288 Font
aFont( aOldFont
);
289 aFont
.SetWeight( WEIGHT_BOLD
);
290 rDev
.SetFont( aFont
);
295 rDev
.DrawText( aPos
, GetText() );
296 rDev
.SetFont( aOldFont
);
299 /*--------------------------------------------------
300 Entry IDs for options listbox of dialog
301 --------------------------------------------------*/
308 EID_WORDS_WITH_DIGITS
,
317 //! this array must have an entry for every value of EID_OPTIONS.
318 // It is used to get the respective property name.
319 static const char * aEidToPropName
[] =
321 UPN_IS_SPELL_AUTO
, // EID_SPELL_AUTO
322 UPN_IS_GRAMMAR_AUTO
, // EID_GRAMMAR_AUTO
323 UPN_IS_SPELL_UPPER_CASE
, // EID_CAPITAL_WORDS
324 UPN_IS_SPELL_WITH_DIGITS
, // EID_WORDS_WITH_DIGITS
325 UPN_IS_SPELL_SPECIAL
, // EID_SPELL_SPECIAL
326 UPN_HYPH_MIN_WORD_LENGTH
, // EID_NUM_MIN_WORDLEN,
327 UPN_HYPH_MIN_LEADING
, // EID_NUM_PRE_BREAK
328 UPN_HYPH_MIN_TRAILING
, // EID_NUM_POST_BREAK
329 UPN_IS_HYPH_AUTO
, // EID_HYPH_AUTO
330 UPN_IS_HYPH_SPECIAL
// EID_HYPH_SPECIAL
333 static inline OUString
lcl_GetPropertyName( EID_OPTIONS eEntryId
)
335 DBG_ASSERT( (unsigned int) eEntryId
< SAL_N_ELEMENTS(aEidToPropName
), "index out of range" );
336 return OUString::createFromAscii( aEidToPropName
[ (int) eEntryId
] );
339 class OptionsBreakSet
: public ModalDialog
341 VclFrame
* m_pBeforeFrame
;
342 VclFrame
* m_pAfterFrame
;
343 VclFrame
* m_pMinimalFrame
;
344 NumericField
* m_pBreakNF
;
347 OptionsBreakSet(Window
* pParent
, sal_uInt16 nRID
)
348 : ModalDialog(pParent
, "BreakNumberOption",
349 "cui/ui/breaknumberoption.ui")
352 get(m_pBeforeFrame
, "beforeframe");
353 get(m_pAfterFrame
, "afterframe");
354 get(m_pMinimalFrame
, "miniframe");
356 assert(EID_NUM_PRE_BREAK
== nRID
||
357 EID_NUM_POST_BREAK
== nRID
||
358 EID_NUM_MIN_WORDLEN
== nRID
); //unexpected ID
360 if (nRID
== EID_NUM_PRE_BREAK
)
362 m_pBeforeFrame
->Show();
363 get(m_pBreakNF
, "beforebreak");
365 else if(nRID
== EID_NUM_POST_BREAK
)
367 m_pAfterFrame
->Show();
368 get(m_pBreakNF
, "afterbreak");
370 else if(nRID
== EID_NUM_MIN_WORDLEN
)
372 m_pMinimalFrame
->Show();
373 get(m_pBreakNF
, "wordlength");
377 NumericField
& GetNumericFld()
383 // class OptionsUserData -------------------------------------------------
385 class OptionsUserData
392 OptionsUserData( sal_uLong nUserData
) : nVal( nUserData
) {}
393 OptionsUserData( sal_uInt16 nEID
,
394 bool bHasNV
, sal_uInt16 nNumVal
,
395 bool bCheckable
, bool bChecked
);
397 sal_uLong
GetUserData() const { return nVal
; }
398 sal_uInt16
GetEntryId() const { return (sal_uInt16
)(nVal
>> 16); }
399 bool HasNumericValue() const { return (bool)((nVal
>> 10) & 0x01); }
400 sal_uInt16
GetNumericValue() const { return (sal_uInt16
)(nVal
& 0xFF); }
401 bool IsCheckable() const { return (bool)((nVal
>> 9) & 0x01); }
402 bool IsModified() const { return (bool)((nVal
>> 11) & 0x01); }
404 void SetNumericValue( sal_uInt8 nNumVal
);
407 OptionsUserData::OptionsUserData( sal_uInt16 nEID
,
408 bool bHasNV
, sal_uInt16 nNumVal
,
409 bool bCheckable
, bool bChecked
)
411 DBG_ASSERT( nEID
< 65000, "Entry Id out of range" );
412 DBG_ASSERT( nNumVal
< 256, "value out of range" );
413 nVal
= ((sal_uLong
)(0xFFFF & nEID
) << 16) |
414 ((sal_uLong
)(bHasNV
? 1 : 0) << 10) |
415 ((sal_uLong
)(bCheckable
? 1 : 0) << 9) |
416 ((sal_uLong
)(bChecked
? 1 : 0) << 8) |
417 ((sal_uLong
)(0xFF & nNumVal
));
420 void OptionsUserData::SetNumericValue( sal_uInt8 nNumVal
)
422 if (HasNumericValue() && (GetNumericValue() != nNumVal
))
430 void OptionsUserData::SetModified()
432 nVal
|= (sal_uLong
)1 << 11;
435 // class BrwString_Impl -------------------------------------------------
437 class BrwString_Impl
: public SvLBoxString
441 BrwString_Impl( SvTreeListEntry
* pEntry
, sal_uInt16 nFlags
,
442 const OUString
& rStr
) : SvLBoxString( pEntry
, nFlags
, rStr
) {}
445 const Point
& rPos
, SvTreeListBox
& rOutDev
, const SvViewDataEntry
* pView
, const SvTreeListEntry
* pEntry
) SAL_OVERRIDE
;
448 void BrwString_Impl::Paint(
449 const Point
& rPos
, SvTreeListBox
& rDev
, const SvViewDataEntry
* /*pView*/,
450 const SvTreeListEntry
* pEntry
)
454 rDev
.DrawText( aPos
, GetText() );
455 if(pEntry
->GetUserData())
458 aNewPos
.X() += rDev
.GetTextWidth(GetText());
459 Font
aOldFont( rDev
.GetFont());
460 Font
aFont( aOldFont
);
461 aFont
.SetWeight( WEIGHT_BOLD
);
463 //??? convert the lower byte from the user date into a string
464 OptionsUserData
aData( (sal_uLong
) pEntry
->GetUserData() );
465 if(aData
.HasNumericValue())
468 sTxt
.append(' ').append(static_cast<sal_Int32
>(aData
.GetNumericValue()));
469 rDev
.SetFont( aFont
);
470 rDev
.DrawText( aNewPos
, sTxt
.makeStringAndClear() );
473 rDev
.SetFont( aOldFont
);
477 // ServiceInfo_Impl ----------------------------------------------------
479 struct ServiceInfo_Impl
481 OUString sDisplayName
;
482 OUString sSpellImplName
;
483 OUString sHyphImplName
;
484 OUString sThesImplName
;
485 OUString sGrammarImplName
;
486 uno::Reference
< XSpellChecker
> xSpell
;
487 uno::Reference
< XHyphenator
> xHyph
;
488 uno::Reference
< XThesaurus
> xThes
;
489 uno::Reference
< XProofreader
> xGrammar
;
492 ServiceInfo_Impl() : bConfigured(false) {}
495 typedef std::vector
< ServiceInfo_Impl
> ServiceInfoArr
;
496 typedef std::map
< sal_Int16
/*LanguageType*/, Sequence
< OUString
> > LangImplNameTable
;
499 // SvxLinguData_Impl ----------------------------------------------------
501 class SvxLinguData_Impl
503 //contains services and implementation names sorted by implementation names
504 ServiceInfoArr aDisplayServiceArr
;
505 sal_uLong nDisplayServices
;
507 Sequence
< Locale
> aAllServiceLocales
;
508 LangImplNameTable aCfgSpellTable
;
509 LangImplNameTable aCfgHyphTable
;
510 LangImplNameTable aCfgThesTable
;
511 LangImplNameTable aCfgGrammarTable
;
512 uno::Reference
< XLinguServiceManager2
> xLinguSrvcMgr
;
515 bool AddRemove( Sequence
< OUString
> &rConfigured
,
516 const OUString
&rImplName
, bool bAdd
);
520 SvxLinguData_Impl( const SvxLinguData_Impl
&rData
);
521 ~SvxLinguData_Impl();
523 SvxLinguData_Impl
& operator = (const SvxLinguData_Impl
&rData
);
525 uno::Reference
<XLinguServiceManager2
> & GetManager() { return xLinguSrvcMgr
; }
527 void SetChecked( const Sequence
< OUString
> &rConfiguredServices
);
528 void Reconfigure( const OUString
&rDisplayName
, bool bEnable
);
530 const Sequence
<Locale
> & GetAllSupportedLocales() const { return aAllServiceLocales
; }
532 LangImplNameTable
& GetSpellTable() { return aCfgSpellTable
; }
533 LangImplNameTable
& GetHyphTable() { return aCfgHyphTable
; }
534 LangImplNameTable
& GetThesTable() { return aCfgThesTable
; }
535 LangImplNameTable
& GetGrammarTable() { return aCfgGrammarTable
; }
537 ServiceInfoArr
& GetDisplayServiceArray() { return aDisplayServiceArr
; }
539 const sal_uLong
& GetDisplayServiceCount() const { return nDisplayServices
; }
540 void SetDisplayServiceCount( sal_uLong nVal
) { nDisplayServices
= nVal
; }
542 // returns the list of service implementation names for the specified
543 // language and service (TYPE_SPELL, TYPE_HYPH, TYPE_THES) sorted in
544 // the proper order for the SvxEditModulesDlg (the ones from the
545 // configuration (keeping that order!) first and then the other ones.
546 // I.e. the ones available but not configured in arbitrary order).
547 // They available ones may contain names that do not(!) support that
549 Sequence
< OUString
> GetSortedImplNames( sal_Int16 nLang
, sal_uInt8 nType
);
551 ServiceInfo_Impl
* GetInfoByImplName( const OUString
&rSvcImplName
);
555 static sal_Int32
lcl_SeqGetIndex( const Sequence
< OUString
> &rSeq
, const OUString
&rTxt
)
558 sal_Int32 nLen
= rSeq
.getLength();
559 const OUString
*pString
= rSeq
.getConstArray();
560 for (sal_Int32 i
= 0; i
< nLen
&& nRes
== -1; ++i
)
562 if (pString
[i
] == rTxt
)
569 Sequence
< OUString
> SvxLinguData_Impl::GetSortedImplNames( sal_Int16 nLang
, sal_uInt8 nType
)
571 LangImplNameTable
*pTable
= 0;
574 case TYPE_SPELL
: pTable
= &aCfgSpellTable
; break;
575 case TYPE_HYPH
: pTable
= &aCfgHyphTable
; break;
576 case TYPE_THES
: pTable
= &aCfgThesTable
; break;
577 case TYPE_GRAMMAR
: pTable
= &aCfgGrammarTable
; break;
579 Sequence
< OUString
> aRes
;
582 SAL_WARN( "cui.options", "unknown linguistic type" );
585 if (pTable
->count( nLang
))
586 aRes
= (*pTable
)[ nLang
]; // add configured services
587 sal_Int32 nIdx
= aRes
.getLength();
588 DBG_ASSERT( (sal_Int32
) nDisplayServices
>= nIdx
, "size mismatch" );
589 aRes
.realloc( nDisplayServices
);
590 OUString
*pRes
= aRes
.getArray();
592 // add not configured services
593 for (sal_Int32 i
= 0; i
< (sal_Int32
) nDisplayServices
; ++i
)
595 const ServiceInfo_Impl
&rInfo
= aDisplayServiceArr
[ i
];
599 case TYPE_SPELL
: aImplName
= rInfo
.sSpellImplName
; break;
600 case TYPE_HYPH
: aImplName
= rInfo
.sHyphImplName
; break;
601 case TYPE_THES
: aImplName
= rInfo
.sThesImplName
; break;
602 case TYPE_GRAMMAR
: aImplName
= rInfo
.sGrammarImplName
; break;
605 if (!aImplName
.isEmpty() && (lcl_SeqGetIndex( aRes
, aImplName
) == -1)) // name not yet added
607 DBG_ASSERT( nIdx
< aRes
.getLength(), "index out of range" );
608 if (nIdx
< aRes
.getLength())
609 pRes
[ nIdx
++ ] = aImplName
;
612 // don't forget to put aRes back to its actual size just in case you allocated too much
613 // since all of the names may have already been added
614 // otherwise you get duplicate entries in the edit dialog
615 aRes
.realloc( nIdx
);
620 ServiceInfo_Impl
* SvxLinguData_Impl::GetInfoByImplName( const OUString
&rSvcImplName
)
622 ServiceInfo_Impl
* pInfo
= 0;
623 for (sal_uLong i
= 0; i
< nDisplayServices
&& !pInfo
; ++i
)
625 ServiceInfo_Impl
&rTmp
= aDisplayServiceArr
[ i
];
626 if (rTmp
.sSpellImplName
== rSvcImplName
||
627 rTmp
.sHyphImplName
== rSvcImplName
||
628 rTmp
.sThesImplName
== rSvcImplName
||
629 rTmp
.sGrammarImplName
== rSvcImplName
)
638 static void lcl_MergeLocales(Sequence
< Locale
>& aAllLocales
, const Sequence
< Locale
>& rAdd
)
640 const Locale
* pAdd
= rAdd
.getConstArray();
641 Sequence
<Locale
> aLocToAdd(rAdd
.getLength());
642 const Locale
* pAllLocales
= aAllLocales
.getConstArray();
643 Locale
* pLocToAdd
= aLocToAdd
.getArray();
644 sal_Int32 nFound
= 0;
646 for(i
= 0; i
< rAdd
.getLength(); i
++)
649 for(sal_Int32 j
= 0; j
< aAllLocales
.getLength() && !bFound
; j
++)
651 bFound
= pAdd
[i
].Language
== pAllLocales
[j
].Language
&&
652 pAdd
[i
].Country
== pAllLocales
[j
].Country
&&
653 pAdd
[i
].Variant
== pAllLocales
[j
].Variant
;
657 pLocToAdd
[nFound
++] = pAdd
[i
];
660 sal_Int32 nLength
= aAllLocales
.getLength();
661 aAllLocales
.realloc( nLength
+ nFound
);
662 Locale
* pAllLocales2
= aAllLocales
.getArray();
663 for(i
= 0; i
< nFound
; i
++)
664 pAllLocales2
[nLength
++] = pLocToAdd
[i
];
667 static void lcl_MergeDisplayArray(
668 SvxLinguData_Impl
&rData
,
669 const ServiceInfo_Impl
&rToAdd
)
673 ServiceInfoArr
&rSvcInfoArr
= rData
.GetDisplayServiceArray();
674 sal_uLong nEntries
= rData
.GetDisplayServiceCount();
676 ServiceInfo_Impl
* pEntry
;
677 for (sal_uLong i
= 0; i
< nEntries
; ++i
)
679 pEntry
= &rSvcInfoArr
[i
];
680 if (pEntry
&& pEntry
->sDisplayName
== rToAdd
.sDisplayName
)
682 if(rToAdd
.xSpell
.is())
684 DBG_ASSERT( !pEntry
->xSpell
.is() &&
685 pEntry
->sSpellImplName
.isEmpty(),
687 pEntry
->sSpellImplName
= rToAdd
.sSpellImplName
;
688 pEntry
->xSpell
= rToAdd
.xSpell
;
690 if(rToAdd
.xGrammar
.is())
692 DBG_ASSERT( !pEntry
->xGrammar
.is() &&
693 pEntry
->sGrammarImplName
.isEmpty(),
695 pEntry
->sGrammarImplName
= rToAdd
.sGrammarImplName
;
696 pEntry
->xGrammar
= rToAdd
.xGrammar
;
698 if(rToAdd
.xHyph
.is())
700 DBG_ASSERT( !pEntry
->xHyph
.is() &&
701 pEntry
->sHyphImplName
.isEmpty(),
703 pEntry
->sHyphImplName
= rToAdd
.sHyphImplName
;
704 pEntry
->xHyph
= rToAdd
.xHyph
;
706 if(rToAdd
.xThes
.is())
708 DBG_ASSERT( !pEntry
->xThes
.is() &&
709 pEntry
->sThesImplName
.isEmpty(),
711 pEntry
->sThesImplName
= rToAdd
.sThesImplName
;
712 pEntry
->xThes
= rToAdd
.xThes
;
718 rData
.GetDisplayServiceArray().push_back( rToAdd
);
719 rData
.SetDisplayServiceCount( nCnt
+ 1 );
722 SvxLinguData_Impl::SvxLinguData_Impl() :
725 uno::Reference
< XComponentContext
> xContext
= ::comphelper::getProcessComponentContext();
726 xLinguSrvcMgr
= LinguServiceManager::create(xContext
);
728 const Locale
& rCurrentLocale
= Application::GetSettings().GetLanguageTag().getLocale();
729 Sequence
<Any
> aArgs(2);//second arguments has to be empty!
730 aArgs
.getArray()[0] <<= SvxGetLinguPropertySet();
733 Sequence
< OUString
> aSpellNames
= xLinguSrvcMgr
->getAvailableServices(
735 const OUString
* pSpellNames
= aSpellNames
.getConstArray();
738 for(nIdx
= 0; nIdx
< aSpellNames
.getLength(); nIdx
++)
740 ServiceInfo_Impl aInfo
;
741 aInfo
.sSpellImplName
= pSpellNames
[nIdx
];
742 aInfo
.xSpell
= uno::Reference
<XSpellChecker
>(
743 xContext
->getServiceManager()->createInstanceWithArgumentsAndContext(aInfo
.sSpellImplName
, aArgs
, xContext
), UNO_QUERY
);
745 uno::Reference
<XServiceDisplayName
> xDispName(aInfo
.xSpell
, UNO_QUERY
);
747 aInfo
.sDisplayName
= xDispName
->getServiceDisplayName( rCurrentLocale
);
749 const Sequence
< Locale
> aLocales( aInfo
.xSpell
->getLocales() );
750 //! suppress display of entries with no supported languages (see feature 110994)
751 if (aLocales
.getLength())
753 lcl_MergeLocales( aAllServiceLocales
, aLocales
);
754 lcl_MergeDisplayArray( *this, aInfo
);
758 //read grammar checker
759 Sequence
< OUString
> aGrammarNames
= xLinguSrvcMgr
->getAvailableServices(
760 cGrammar
, Locale() );
761 const OUString
* pGrammarNames
= aGrammarNames
.getConstArray();
762 for(nIdx
= 0; nIdx
< aGrammarNames
.getLength(); nIdx
++)
764 ServiceInfo_Impl aInfo
;
765 aInfo
.sGrammarImplName
= pGrammarNames
[nIdx
];
766 aInfo
.xGrammar
= uno::Reference
<XProofreader
>(
767 xContext
->getServiceManager()->createInstanceWithArgumentsAndContext(aInfo
.sGrammarImplName
, aArgs
, xContext
), UNO_QUERY
);
769 uno::Reference
<XServiceDisplayName
> xDispName(aInfo
.xGrammar
, UNO_QUERY
);
771 aInfo
.sDisplayName
= xDispName
->getServiceDisplayName( rCurrentLocale
);
773 const Sequence
< Locale
> aLocales( aInfo
.xGrammar
->getLocales() );
774 //! suppress display of entries with no supported languages (see feature 110994)
775 if (aLocales
.getLength())
777 lcl_MergeLocales( aAllServiceLocales
, aLocales
);
778 lcl_MergeDisplayArray( *this, aInfo
);
783 Sequence
< OUString
> aHyphNames
= xLinguSrvcMgr
->getAvailableServices(
785 const OUString
* pHyphNames
= aHyphNames
.getConstArray();
786 for(nIdx
= 0; nIdx
< aHyphNames
.getLength(); nIdx
++)
788 ServiceInfo_Impl aInfo
;
789 aInfo
.sHyphImplName
= pHyphNames
[nIdx
];
790 aInfo
.xHyph
= uno::Reference
<XHyphenator
>(
791 xContext
->getServiceManager()->createInstanceWithArgumentsAndContext(aInfo
.sHyphImplName
, aArgs
, xContext
), UNO_QUERY
);
793 uno::Reference
<XServiceDisplayName
> xDispName(aInfo
.xHyph
, UNO_QUERY
);
795 aInfo
.sDisplayName
= xDispName
->getServiceDisplayName( rCurrentLocale
);
797 const Sequence
< Locale
> aLocales( aInfo
.xHyph
->getLocales() );
798 //! suppress display of entries with no supported languages (see feature 110994)
799 if (aLocales
.getLength())
801 lcl_MergeLocales( aAllServiceLocales
, aLocales
);
802 lcl_MergeDisplayArray( *this, aInfo
);
807 Sequence
< OUString
> aThesNames
= xLinguSrvcMgr
->getAvailableServices(
809 const OUString
* pThesNames
= aThesNames
.getConstArray();
810 for(nIdx
= 0; nIdx
< aThesNames
.getLength(); nIdx
++)
812 ServiceInfo_Impl aInfo
;
813 aInfo
.sThesImplName
= pThesNames
[nIdx
];
814 aInfo
.xThes
= uno::Reference
<XThesaurus
>(
815 xContext
->getServiceManager()->createInstanceWithArgumentsAndContext(aInfo
.sThesImplName
, aArgs
, xContext
), UNO_QUERY
);
817 uno::Reference
<XServiceDisplayName
> xDispName(aInfo
.xThes
, UNO_QUERY
);
819 aInfo
.sDisplayName
= xDispName
->getServiceDisplayName( rCurrentLocale
);
821 const Sequence
< Locale
> aLocales( aInfo
.xThes
->getLocales() );
822 //! suppress display of entries with no supported languages (see feature 110994)
823 if (aLocales
.getLength())
825 lcl_MergeLocales( aAllServiceLocales
, aLocales
);
826 lcl_MergeDisplayArray( *this, aInfo
);
830 Sequence
< OUString
> aCfgSvcs
;
831 const Locale
* pAllLocales
= aAllServiceLocales
.getConstArray();
832 for(sal_Int32 nLocale
= 0; nLocale
< aAllServiceLocales
.getLength(); nLocale
++)
834 sal_Int16 nLang
= LanguageTag::convertToLanguageType( pAllLocales
[nLocale
] );
836 aCfgSvcs
= xLinguSrvcMgr
->getConfiguredServices(cSpell
, pAllLocales
[nLocale
]);
837 SetChecked( aCfgSvcs
);
838 if (aCfgSvcs
.getLength())
839 aCfgSpellTable
[ nLang
] = aCfgSvcs
;
841 aCfgSvcs
= xLinguSrvcMgr
->getConfiguredServices(cGrammar
, pAllLocales
[nLocale
]);
842 SetChecked( aCfgSvcs
);
843 if (aCfgSvcs
.getLength())
844 aCfgGrammarTable
[ nLang
] = aCfgSvcs
;
846 aCfgSvcs
= xLinguSrvcMgr
->getConfiguredServices(cHyph
, pAllLocales
[nLocale
]);
847 SetChecked( aCfgSvcs
);
848 if (aCfgSvcs
.getLength())
849 aCfgHyphTable
[ nLang
] = aCfgSvcs
;
851 aCfgSvcs
= xLinguSrvcMgr
->getConfiguredServices(cThes
, pAllLocales
[nLocale
]);
852 SetChecked( aCfgSvcs
);
853 if (aCfgSvcs
.getLength())
854 aCfgThesTable
[ nLang
] = aCfgSvcs
;
858 SvxLinguData_Impl::SvxLinguData_Impl( const SvxLinguData_Impl
&rData
) :
859 aDisplayServiceArr (rData
.aDisplayServiceArr
),
860 nDisplayServices (rData
.nDisplayServices
),
861 aAllServiceLocales (rData
.aAllServiceLocales
),
862 aCfgSpellTable (rData
.aCfgSpellTable
),
863 aCfgHyphTable (rData
.aCfgHyphTable
),
864 aCfgThesTable (rData
.aCfgThesTable
),
865 aCfgGrammarTable (rData
.aCfgGrammarTable
),
866 xLinguSrvcMgr (rData
.xLinguSrvcMgr
)
870 SvxLinguData_Impl
& SvxLinguData_Impl::operator = (const SvxLinguData_Impl
&rData
)
872 xLinguSrvcMgr
= rData
.xLinguSrvcMgr
;
873 aAllServiceLocales
= rData
.aAllServiceLocales
;
874 aCfgSpellTable
= rData
.aCfgSpellTable
;
875 aCfgHyphTable
= rData
.aCfgHyphTable
;
876 aCfgThesTable
= rData
.aCfgThesTable
;
877 aCfgGrammarTable
= rData
.aCfgGrammarTable
;
878 aDisplayServiceArr
= rData
.aDisplayServiceArr
;
879 nDisplayServices
= rData
.nDisplayServices
;
883 SvxLinguData_Impl::~SvxLinguData_Impl()
887 void SvxLinguData_Impl::SetChecked(const Sequence
<OUString
>& rConfiguredServices
)
889 const OUString
* pConfiguredServices
= rConfiguredServices
.getConstArray();
890 for(sal_Int32 n
= 0; n
< rConfiguredServices
.getLength(); n
++)
892 ServiceInfo_Impl
* pEntry
;
893 for (sal_uLong i
= 0; i
< nDisplayServices
; ++i
)
895 pEntry
= &aDisplayServiceArr
[i
];
896 if (pEntry
&& !pEntry
->bConfigured
)
898 const OUString
&rSrvcImplName
= pConfiguredServices
[n
];
899 if (!rSrvcImplName
.isEmpty() &&
900 (pEntry
->sSpellImplName
== rSrvcImplName
||
901 pEntry
->sGrammarImplName
== rSrvcImplName
||
902 pEntry
->sHyphImplName
== rSrvcImplName
||
903 pEntry
->sThesImplName
== rSrvcImplName
))
905 pEntry
->bConfigured
= true;
913 bool SvxLinguData_Impl::AddRemove(
914 Sequence
< OUString
> &rConfigured
,
915 const OUString
&rImplName
, bool bAdd
)
917 bool bRet
= false; // modified?
919 sal_Int32 nEntries
= rConfigured
.getLength();
920 sal_Int32 nPos
= lcl_SeqGetEntryPos(rConfigured
, rImplName
);
921 if (bAdd
&& nPos
< 0) // add new entry
923 rConfigured
.realloc( ++nEntries
);
924 OUString
*pConfigured
= rConfigured
.getArray();
925 pConfigured
[nEntries
- 1] = rImplName
;
928 else if (!bAdd
&& nPos
>= 0) // remove existing entry
930 OUString
*pConfigured
= rConfigured
.getArray();
931 for (sal_Int32 i
= nPos
; i
< nEntries
- 1; ++i
)
932 pConfigured
[i
] = pConfigured
[i
+ 1];
933 rConfigured
.realloc(--nEntries
);
941 void SvxLinguData_Impl::Reconfigure( const OUString
&rDisplayName
, bool bEnable
)
943 DBG_ASSERT( !rDisplayName
.isEmpty(), "empty DisplayName" );
945 ServiceInfo_Impl
*pInfo
= 0;
946 ServiceInfo_Impl
*pTmp
= 0;
947 for (sal_uLong i
= 0; i
< nDisplayServices
; ++i
)
949 pTmp
= &aDisplayServiceArr
[i
];
950 if (pTmp
&& pTmp
->sDisplayName
== rDisplayName
)
956 DBG_ASSERT( pInfo
, "DisplayName entry not found" );
959 pInfo
->bConfigured
= bEnable
;
961 Sequence
< Locale
> aLocales
;
962 const Locale
*pLocale
= 0;
963 sal_Int32 nLocales
= 0;
966 // update configured spellchecker entries
967 if (pInfo
->xSpell
.is())
969 aLocales
= pInfo
->xSpell
->getLocales();
970 pLocale
= aLocales
.getConstArray();
971 nLocales
= aLocales
.getLength();
972 for (i
= 0; i
< nLocales
; ++i
)
974 sal_Int16 nLang
= LanguageTag::convertToLanguageType( pLocale
[i
] );
975 if (!aCfgSpellTable
.count( nLang
) && bEnable
)
976 aCfgSpellTable
[ nLang
] = Sequence
< OUString
>();
977 if (aCfgSpellTable
.count( nLang
))
978 AddRemove( aCfgSpellTable
[ nLang
], pInfo
->sSpellImplName
, bEnable
);
982 // update configured grammar checker entries
983 if (pInfo
->xGrammar
.is())
985 aLocales
= pInfo
->xGrammar
->getLocales();
986 pLocale
= aLocales
.getConstArray();
987 nLocales
= aLocales
.getLength();
988 for (i
= 0; i
< nLocales
; ++i
)
990 sal_Int16 nLang
= LanguageTag::convertToLanguageType( pLocale
[i
] );
991 if (!aCfgGrammarTable
.count( nLang
) && bEnable
)
992 aCfgGrammarTable
[ nLang
] = Sequence
< OUString
>();
993 if (aCfgGrammarTable
.count( nLang
))
994 AddRemove( aCfgGrammarTable
[ nLang
], pInfo
->sGrammarImplName
, bEnable
);
998 // update configured hyphenator entries
999 if (pInfo
->xHyph
.is())
1001 aLocales
= pInfo
->xHyph
->getLocales();
1002 pLocale
= aLocales
.getConstArray();
1003 nLocales
= aLocales
.getLength();
1004 for (i
= 0; i
< nLocales
; ++i
)
1006 sal_Int16 nLang
= LanguageTag::convertToLanguageType( pLocale
[i
] );
1007 if (!aCfgHyphTable
.count( nLang
) && bEnable
)
1008 aCfgHyphTable
[ nLang
] = Sequence
< OUString
>();
1009 if (aCfgHyphTable
.count( nLang
))
1010 AddRemove( aCfgHyphTable
[ nLang
], pInfo
->sHyphImplName
, bEnable
);
1014 // update configured spellchecker entries
1015 if (pInfo
->xThes
.is())
1017 aLocales
= pInfo
->xThes
->getLocales();
1018 pLocale
= aLocales
.getConstArray();
1019 nLocales
= aLocales
.getLength();
1020 for (i
= 0; i
< nLocales
; ++i
)
1022 sal_Int16 nLang
= LanguageTag::convertToLanguageType( pLocale
[i
] );
1023 if (!aCfgThesTable
.count( nLang
) && bEnable
)
1024 aCfgThesTable
[ nLang
] = Sequence
< OUString
>();
1025 if (aCfgThesTable
.count( nLang
))
1026 AddRemove( aCfgThesTable
[ nLang
], pInfo
->sThesImplName
, bEnable
);
1033 // class SvxLinguTabPage -------------------------------------------------
1035 SvxLinguTabPage::SvxLinguTabPage( Window
* pParent
, const SfxItemSet
& rSet
) :
1036 SfxTabPage(pParent
, "OptLinguPage", "cui/ui/optlingupage.ui", rSet
),
1038 sCapitalWords (CUI_RES(RID_SVXSTR_CAPITAL_WORDS
)),
1039 sWordsWithDigits(CUI_RES(RID_SVXSTR_WORDS_WITH_DIGITS
)),
1040 sSpellSpecial (CUI_RES(RID_SVXSTR_SPELL_SPECIAL
)),
1041 sSpellAuto (CUI_RES(RID_SVXSTR_SPELL_AUTO
)),
1042 sGrammarAuto (CUI_RES(RID_SVXSTR_GRAMMAR_AUTO
)),
1043 sNumMinWordlen (CUI_RES(RID_SVXSTR_NUM_MIN_WORDLEN
)),
1044 sNumPreBreak (CUI_RES(RID_SVXSTR_NUM_PRE_BREAK
)),
1045 sNumPostBreak (CUI_RES(RID_SVXSTR_NUM_POST_BREAK
)),
1046 sHyphAuto (CUI_RES(RID_SVXSTR_HYPH_AUTO
)),
1047 sHyphSpecial (CUI_RES(RID_SVXSTR_HYPH_SPECIAL
)),
1051 get(m_pLinguModulesFT
, "lingumodulesft");
1052 get(m_pLinguModulesCLB
, "lingumodules");
1053 get(m_pLinguModulesEditPB
, "lingumodulesedit");
1054 get(m_pLinguDicsFT
, "lingudictsft");
1055 get(m_pLinguDicsCLB
, "lingudicts");
1056 get(m_pLinguDicsNewPB
, "lingudictsnew");
1057 get(m_pLinguDicsEditPB
, "lingudictsedit");
1058 get(m_pLinguDicsDelPB
, "lingudictsdelete");
1059 get(m_pLinguOptionsCLB
, "linguoptions");
1060 get(m_pLinguOptionsEditPB
, "linguoptionsedit");
1061 get(m_pMoreDictsLink
, "moredictslink");
1063 m_pLinguModulesCLB
->set_height_request(m_pLinguModulesCLB
->GetTextHeight() * 3);
1064 m_pLinguDicsCLB
->set_height_request(m_pLinguDicsCLB
->GetTextHeight() * 5);
1065 m_pLinguOptionsCLB
->set_height_request(m_pLinguOptionsCLB
->GetTextHeight() * 5);
1067 pCheckButtonData
= NULL
;
1069 m_pLinguModulesCLB
->SetStyle( m_pLinguModulesCLB
->GetStyle()|WB_CLIPCHILDREN
|WB_HSCROLL
|WB_FORCE_MAKEVISIBLE
);
1070 m_pLinguModulesCLB
->SetHighlightRange();
1071 m_pLinguModulesCLB
->SetSelectHdl( LINK( this, SvxLinguTabPage
, SelectHdl_Impl
));
1072 m_pLinguModulesCLB
->SetDoubleClickHdl(LINK(this, SvxLinguTabPage
, BoxDoubleClickHdl_Impl
));
1073 m_pLinguModulesCLB
->SetCheckButtonHdl(LINK(this, SvxLinguTabPage
, BoxCheckButtonHdl_Impl
));
1075 m_pLinguModulesEditPB
->SetClickHdl( LINK( this, SvxLinguTabPage
, ClickHdl_Impl
));
1076 m_pLinguOptionsEditPB
->SetClickHdl( LINK( this, SvxLinguTabPage
, ClickHdl_Impl
));
1078 m_pLinguDicsCLB
->SetStyle( m_pLinguDicsCLB
->GetStyle()|WB_CLIPCHILDREN
|WB_HSCROLL
|WB_FORCE_MAKEVISIBLE
);
1079 m_pLinguDicsCLB
->SetHighlightRange();
1080 m_pLinguDicsCLB
->SetSelectHdl( LINK( this, SvxLinguTabPage
, SelectHdl_Impl
));
1081 m_pLinguDicsCLB
->SetCheckButtonHdl(LINK(this, SvxLinguTabPage
, BoxCheckButtonHdl_Impl
));
1083 m_pLinguDicsNewPB
->SetClickHdl( LINK( this, SvxLinguTabPage
, ClickHdl_Impl
));
1084 m_pLinguDicsEditPB
->SetClickHdl( LINK( this, SvxLinguTabPage
, ClickHdl_Impl
));
1085 m_pLinguDicsDelPB
->SetClickHdl( LINK( this, SvxLinguTabPage
, ClickHdl_Impl
));
1087 m_pLinguOptionsCLB
->SetStyle( m_pLinguOptionsCLB
->GetStyle()|WB_CLIPCHILDREN
|WB_HSCROLL
|WB_FORCE_MAKEVISIBLE
);
1088 m_pLinguOptionsCLB
->SetHighlightRange();
1089 m_pLinguOptionsCLB
->SetSelectHdl( LINK( this, SvxLinguTabPage
, SelectHdl_Impl
));
1090 m_pLinguOptionsCLB
->SetDoubleClickHdl(LINK(this, SvxLinguTabPage
, BoxDoubleClickHdl_Impl
));
1092 if ( SvtExtendedSecurityOptions().GetOpenHyperlinkMode()
1093 != SvtExtendedSecurityOptions::OPEN_NEVER
)
1095 m_pMoreDictsLink
->SetClickHdl( LINK( this, SvxLinguTabPage
, OpenURLHdl_Impl
) );
1098 m_pMoreDictsLink
->Hide();
1100 OUString
sAccessibleNameModuleEdit(CUI_RES(RID_SVXSTR_LINGU_MODULES_EDIT
));
1101 OUString
sAccessibleNameDicsEdit (CUI_RES(RID_SVXSTR_LINGU_DICS_EDIT_DIC
));
1102 OUString
sAccessibleNameOptionEdit(CUI_RES(RID_SVXSTR_LINGU_OPTIONS_EDIT
));
1104 m_pLinguModulesEditPB
->SetAccessibleName(sAccessibleNameModuleEdit
);
1105 m_pLinguDicsEditPB
->SetAccessibleName(sAccessibleNameDicsEdit
);
1106 m_pLinguOptionsEditPB
->SetAccessibleName(sAccessibleNameOptionEdit
);
1108 xProp
= SvxGetLinguPropertySet();
1109 xDicList
= uno::Reference
< XDictionaryList
>( SvxGetDictionaryList(), UNO_QUERY
);
1112 // keep references to all **currently** available dictionaries,
1113 // since the diclist may get changed meanwhile (e.g. through the API).
1114 // We want the dialog to operate on the same set of dictionaries it
1115 // was started with.
1116 // Also we have to take care to not lose the last reference when
1117 // someone else removes a dictionary from the list.
1118 // removed dics will be replaced by NULL new entries be added to the end
1119 // Thus we may use indices as consistent references.
1120 aDics
= xDicList
->getDictionaries();
1122 UpdateDicBox_Impl();
1126 m_pLinguDicsFT
->Disable();
1127 m_pLinguDicsCLB
->Disable();
1128 m_pLinguDicsNewPB
->Disable();
1129 m_pLinguDicsEditPB
->Disable();
1130 m_pLinguDicsDelPB
->Disable();
1134 SvxLinguTabPage::~SvxLinguTabPage()
1142 // don't throw away overloaded
1143 const sal_uInt16
* SvxLinguTabPage::GetRanges()
1151 SfxTabPage
* SvxLinguTabPage::Create( Window
* pParent
,
1152 const SfxItemSet
& rAttrSet
)
1154 return ( new SvxLinguTabPage( pParent
, rAttrSet
) );
1159 bool SvxLinguTabPage::FillItemSet( SfxItemSet
& rCoreSet
)
1161 bool bModified
= true; // !!!!
1163 // if not HideGroups was called with GROUP_MODULES...
1164 if (m_pLinguModulesCLB
->IsVisible())
1166 DBG_ASSERT( pLinguData
, "pLinguData not yet initialized" );
1168 pLinguData
= new SvxLinguData_Impl
;
1170 LangImplNameTable::const_iterator aIt
;
1172 // update spellchecker configuration entries
1173 const LangImplNameTable
*pTable
= &pLinguData
->GetSpellTable();
1174 for (aIt
= pTable
->begin(); aIt
!= pTable
->end(); ++aIt
)
1176 sal_Int16 nLang
= aIt
->first
;
1177 const Sequence
< OUString
> aImplNames( aIt
->second
);
1178 uno::Reference
< XLinguServiceManager2
> xMgr( pLinguData
->GetManager() );
1179 Locale
aLocale( LanguageTag::convertToLocale(nLang
) );
1181 xMgr
->setConfiguredServices( cSpell
, aLocale
, aImplNames
);
1184 // update grammar checker configuration entries
1185 pTable
= &pLinguData
->GetGrammarTable();
1186 for (aIt
= pTable
->begin(); aIt
!= pTable
->end(); ++aIt
)
1188 sal_Int16 nLang
= aIt
->first
;
1189 const Sequence
< OUString
> aImplNames( aIt
->second
);
1190 uno::Reference
< XLinguServiceManager2
> xMgr( pLinguData
->GetManager() );
1191 Locale
aLocale( LanguageTag::convertToLocale(nLang
) );
1193 xMgr
->setConfiguredServices( cGrammar
, aLocale
, aImplNames
);
1196 // update hyphenator configuration entries
1197 pTable
= &pLinguData
->GetHyphTable();
1198 for (aIt
= pTable
->begin(); aIt
!= pTable
->end(); ++aIt
)
1200 sal_Int16 nLang
= aIt
->first
;
1201 const Sequence
< OUString
> aImplNames( aIt
->second
);
1202 uno::Reference
< XLinguServiceManager2
> xMgr( pLinguData
->GetManager() );
1203 Locale
aLocale( LanguageTag::convertToLocale(nLang
) );
1205 xMgr
->setConfiguredServices( cHyph
, aLocale
, aImplNames
);
1208 // update thesaurus configuration entries
1209 pTable
= &pLinguData
->GetThesTable();
1210 for (aIt
= pTable
->begin(); aIt
!= pTable
->end(); ++aIt
)
1212 sal_Int16 nLang
= aIt
->first
;
1213 const Sequence
< OUString
> aImplNames( aIt
->second
);
1214 uno::Reference
< XLinguServiceManager2
> xMgr( pLinguData
->GetManager() );
1215 Locale
aLocale( LanguageTag::convertToLocale(nLang
) );
1217 xMgr
->setConfiguredServices( cThes
, aLocale
, aImplNames
);
1223 // activate dictionaries according to checkbox state
1225 Sequence
< OUString
> aActiveDics
;
1226 sal_Int32 nActiveDics
= 0;
1227 sal_uLong nEntries
= m_pLinguDicsCLB
->GetEntryCount();
1228 for (sal_uLong i
= 0; i
< nEntries
; ++i
)
1230 sal_Int32 nDics
= aDics
.getLength();
1232 aActiveDics
.realloc( nDics
);
1233 OUString
*pActiveDic
= aActiveDics
.getArray();
1235 SvTreeListEntry
*pEntry
= m_pLinguDicsCLB
->GetEntry( i
);
1238 DicUserData
aData( (sal_uLong
)pEntry
->GetUserData() );
1239 if (aData
.GetEntryId() < nDics
)
1241 bool bChecked
= m_pLinguDicsCLB
->IsChecked( i
);
1242 uno::Reference
< XDictionary
> xDic( aDics
.getConstArray()[ i
] );
1245 if (SvxGetIgnoreAllList() == xDic
)
1247 xDic
->setActive( bChecked
);
1251 OUString
aDicName( xDic
->getName() );
1252 pActiveDic
[ nActiveDics
++ ] = aDicName
;
1259 aActiveDics
.realloc( nActiveDics
);
1261 aTmp
<<= aActiveDics
;
1262 SvtLinguConfig aLngCfg
;
1263 aLngCfg
.SetProperty( UPH_ACTIVE_DICTIONARIES
, aTmp
);
1266 nEntries
= m_pLinguOptionsCLB
->GetEntryCount();
1267 for (sal_uLong j
= 0; j
< nEntries
; ++j
)
1269 SvTreeListEntry
*pEntry
= m_pLinguOptionsCLB
->GetEntry( j
);
1271 OptionsUserData
aData( (sal_uLong
)pEntry
->GetUserData() );
1272 OUString
aPropName( lcl_GetPropertyName( (EID_OPTIONS
) aData
.GetEntryId() ) );
1275 if (aData
.IsCheckable())
1277 bool bChecked
= m_pLinguOptionsCLB
->IsChecked( j
);
1280 else if (aData
.HasNumericValue())
1282 sal_Int16 nVal
= aData
.GetNumericValue();
1287 xProp
->setPropertyValue( aPropName
, aAny
);
1288 aLngCfg
.SetProperty( aPropName
, aAny
);
1291 SvTreeListEntry
*pPreBreakEntry
= m_pLinguOptionsCLB
->GetEntry( (sal_uLong
) EID_NUM_PRE_BREAK
);
1292 SvTreeListEntry
*pPostBreakEntry
= m_pLinguOptionsCLB
->GetEntry( (sal_uLong
) EID_NUM_POST_BREAK
);
1293 DBG_ASSERT( pPreBreakEntry
, "NULL Pointer" );
1294 DBG_ASSERT( pPostBreakEntry
, "NULL Pointer" );
1295 if (pPreBreakEntry
&& pPostBreakEntry
)
1297 OptionsUserData
aPreBreakData( (sal_uLong
)pPreBreakEntry
->GetUserData() );
1298 OptionsUserData
aPostBreakData( (sal_uLong
)pPostBreakEntry
->GetUserData() );
1299 if ( aPreBreakData
.IsModified() || aPostBreakData
.IsModified() )
1301 SfxHyphenRegionItem
aHyp( GetWhich( SID_ATTR_HYPHENREGION
) );
1302 aHyp
.GetMinLead() = (sal_uInt8
) aPreBreakData
.GetNumericValue();
1303 aHyp
.GetMinTrail() = (sal_uInt8
) aPostBreakData
.GetNumericValue();
1304 rCoreSet
.Put( aHyp
);
1309 // automatic spell checking
1310 bool bNewAutoCheck
= m_pLinguOptionsCLB
->IsChecked( (sal_uLong
) EID_SPELL_AUTO
);
1311 const SfxPoolItem
* pOld
= GetOldItem( rCoreSet
, SID_AUTOSPELL_CHECK
);
1312 if ( !pOld
|| ( (SfxBoolItem
*)pOld
)->GetValue() != bNewAutoCheck
)
1314 rCoreSet
.Put( SfxBoolItem( GetWhich( SID_AUTOSPELL_CHECK
),
1324 sal_uLong
SvxLinguTabPage::GetDicUserData( const uno::Reference
< XDictionary
> &rxDic
, sal_uInt16 nIdx
)
1327 DBG_ASSERT( rxDic
.is(), "dictionary not supplied" );
1330 uno::Reference
< frame::XStorable
> xStor( rxDic
, UNO_QUERY
);
1332 bool bChecked
= rxDic
->isActive();
1333 bool bEditable
= !xStor
.is() || !xStor
->isReadonly();
1334 bool bDeletable
= bEditable
;
1336 nRes
= DicUserData( nIdx
,
1337 bChecked
, bEditable
, bDeletable
).GetUserData();
1343 void SvxLinguTabPage::AddDicBoxEntry(
1344 const uno::Reference
< XDictionary
> &rxDic
,
1347 m_pLinguDicsCLB
->SetUpdateMode(false);
1349 OUString
aTxt( ::GetDicInfoStr( rxDic
->getName(),
1350 LanguageTag( rxDic
->getLocale() ).getLanguageType(),
1351 DictionaryType_NEGATIVE
== rxDic
->getDictionaryType() ) );
1352 m_pLinguDicsCLB
->InsertEntry( aTxt
, TREELIST_APPEND
); // append at end
1353 SvTreeListEntry
* pEntry
= m_pLinguDicsCLB
->GetEntry( m_pLinguDicsCLB
->GetEntryCount() - 1 );
1354 DBG_ASSERT( pEntry
, "failed to add entry" );
1357 DicUserData
aData( GetDicUserData( rxDic
, nIdx
) );
1358 pEntry
->SetUserData( (void *) aData
.GetUserData() );
1359 lcl_SetCheckButton( pEntry
, aData
.IsChecked() );
1362 m_pLinguDicsCLB
->SetUpdateMode(true);
1367 void SvxLinguTabPage::UpdateDicBox_Impl()
1369 m_pLinguDicsCLB
->SetUpdateMode(false);
1370 m_pLinguDicsCLB
->Clear();
1372 sal_Int32 nDics
= aDics
.getLength();
1373 const uno::Reference
< XDictionary
> *pDic
= aDics
.getConstArray();
1374 for (sal_Int32 i
= 0; i
< nDics
; ++i
)
1376 const uno::Reference
< XDictionary
> &rDic
= pDic
[i
];
1378 AddDicBoxEntry( rDic
, (sal_uInt16
)i
);
1381 m_pLinguDicsCLB
->SetUpdateMode(true);
1386 void SvxLinguTabPage::UpdateModulesBox_Impl()
1390 const ServiceInfoArr
&rAllDispSrvcArr
= pLinguData
->GetDisplayServiceArray();
1391 const sal_uLong nDispSrvcCount
= pLinguData
->GetDisplayServiceCount();
1393 m_pLinguModulesCLB
->Clear();
1395 for (sal_uLong i
= 0; i
< nDispSrvcCount
; ++i
)
1397 const ServiceInfo_Impl
&rInfo
= rAllDispSrvcArr
[i
];
1398 m_pLinguModulesCLB
->InsertEntry( rInfo
.sDisplayName
, TREELIST_APPEND
);
1399 SvTreeListEntry
* pEntry
= m_pLinguModulesCLB
->GetEntry(i
);
1400 pEntry
->SetUserData( (void *) &rInfo
);
1401 m_pLinguModulesCLB
->CheckEntryPos( i
, rInfo
.bConfigured
);
1403 m_pLinguModulesEditPB
->Enable( nDispSrvcCount
> 0 );
1409 void SvxLinguTabPage::Reset( const SfxItemSet
& rSet
)
1411 // if not HideGroups was called with GROUP_MODULES...
1412 if (m_pLinguModulesCLB
->IsVisible())
1415 pLinguData
= new SvxLinguData_Impl
;
1416 UpdateModulesBox_Impl();
1421 // get data from configuration
1424 SvtLinguConfig aLngCfg
;
1426 m_pLinguOptionsCLB
->SetUpdateMode(false);
1427 m_pLinguOptionsCLB
->Clear();
1429 SvTreeList
*pModel
= m_pLinguOptionsCLB
->GetModel();
1430 SvTreeListEntry
* pEntry
= NULL
;
1434 sal_uLong nUserData
= 0;
1436 pEntry
= CreateEntry( sSpellAuto
, CBCOL_FIRST
);
1437 aLngCfg
.GetProperty( UPN_IS_SPELL_AUTO
) >>= bVal
;
1438 const SfxPoolItem
* pItem
= GetItem( rSet
, SID_AUTOSPELL_CHECK
);
1440 bVal
= ((SfxBoolItem
*) pItem
)->GetValue();
1441 nUserData
= OptionsUserData( EID_SPELL_AUTO
, false, 0, true, bVal
).GetUserData();
1442 pEntry
->SetUserData( (void *)nUserData
);
1443 pModel
->Insert( pEntry
);
1444 lcl_SetCheckButton( pEntry
, bVal
);
1446 pEntry
= CreateEntry( sGrammarAuto
, CBCOL_FIRST
);
1447 aLngCfg
.GetProperty( UPN_IS_GRAMMAR_AUTO
) >>= bVal
;
1448 nUserData
= OptionsUserData( EID_GRAMMAR_AUTO
, false, 0, true, bVal
).GetUserData();
1449 pEntry
->SetUserData( (void *)nUserData
);
1450 pModel
->Insert( pEntry
);
1451 lcl_SetCheckButton( pEntry
, bVal
);
1453 pEntry
= CreateEntry( sCapitalWords
, CBCOL_FIRST
);
1454 aLngCfg
.GetProperty( UPN_IS_SPELL_UPPER_CASE
) >>= bVal
;
1455 nUserData
= OptionsUserData( EID_CAPITAL_WORDS
, false, 0, true, bVal
).GetUserData();
1456 pEntry
->SetUserData( (void *)nUserData
);
1457 pModel
->Insert( pEntry
);
1458 lcl_SetCheckButton( pEntry
, bVal
);
1460 pEntry
= CreateEntry( sWordsWithDigits
, CBCOL_FIRST
);
1461 aLngCfg
.GetProperty( UPN_IS_SPELL_WITH_DIGITS
) >>= bVal
;
1462 nUserData
= OptionsUserData( EID_WORDS_WITH_DIGITS
, false, 0, true, bVal
).GetUserData();
1463 pEntry
->SetUserData( (void *)nUserData
);
1464 pModel
->Insert( pEntry
);
1465 lcl_SetCheckButton( pEntry
, bVal
);
1467 pEntry
= CreateEntry( sSpellSpecial
, CBCOL_FIRST
);
1468 aLngCfg
.GetProperty( UPN_IS_SPELL_SPECIAL
) >>= bVal
;
1469 nUserData
= OptionsUserData( EID_SPELL_SPECIAL
, false, 0, true, bVal
).GetUserData();
1470 pEntry
->SetUserData( (void *)nUserData
);
1471 pModel
->Insert( pEntry
);
1472 lcl_SetCheckButton( pEntry
, bVal
);
1474 pEntry
= CreateEntry( sNumMinWordlen
, CBCOL_SECOND
);
1475 aLngCfg
.GetProperty( UPN_HYPH_MIN_WORD_LENGTH
) >>= nVal
;
1476 nUserData
= OptionsUserData( EID_NUM_MIN_WORDLEN
, true, (sal_uInt16
)nVal
, false, false).GetUserData();
1477 pEntry
->SetUserData( (void *)nUserData
);
1478 pModel
->Insert( pEntry
);
1480 const SfxHyphenRegionItem
*pHyp
= NULL
;
1481 sal_uInt16 nWhich
= GetWhich( SID_ATTR_HYPHENREGION
);
1482 if ( rSet
.GetItemState( nWhich
, false ) == SFX_ITEM_SET
)
1483 pHyp
= &( (const SfxHyphenRegionItem
&) rSet
.Get( nWhich
) );
1485 pEntry
= CreateEntry( sNumPreBreak
, CBCOL_SECOND
);
1486 aLngCfg
.GetProperty( UPN_HYPH_MIN_LEADING
) >>= nVal
;
1488 nVal
= (sal_Int16
) pHyp
->GetMinLead();
1489 nUserData
= OptionsUserData( EID_NUM_PRE_BREAK
, true, (sal_uInt16
)nVal
, false, false).GetUserData();
1490 pEntry
->SetUserData( (void *)nUserData
);
1491 pModel
->Insert( pEntry
);
1493 pEntry
= CreateEntry( sNumPostBreak
, CBCOL_SECOND
);
1494 aLngCfg
.GetProperty( UPN_HYPH_MIN_TRAILING
) >>= nVal
;
1496 nVal
= (sal_Int16
) pHyp
->GetMinTrail();
1497 nUserData
= OptionsUserData( EID_NUM_POST_BREAK
, true, (sal_uInt16
)nVal
, false, false).GetUserData();
1498 pEntry
->SetUserData( (void *)nUserData
);
1499 pModel
->Insert( pEntry
);
1501 pEntry
= CreateEntry( sHyphAuto
, CBCOL_FIRST
);
1502 aLngCfg
.GetProperty( UPN_IS_HYPH_AUTO
) >>= bVal
;
1503 nUserData
= OptionsUserData( EID_HYPH_AUTO
, false, 0, true, bVal
).GetUserData();
1504 pEntry
->SetUserData( (void *)nUserData
);
1505 pModel
->Insert( pEntry
);
1506 lcl_SetCheckButton( pEntry
, bVal
);
1508 pEntry
= CreateEntry( sHyphSpecial
, CBCOL_FIRST
);
1509 aLngCfg
.GetProperty( UPN_IS_HYPH_SPECIAL
) >>= bVal
;
1510 nUserData
= OptionsUserData( EID_HYPH_SPECIAL
, false, 0, true, bVal
).GetUserData();
1511 pEntry
->SetUserData( (void *)nUserData
);
1512 pModel
->Insert( pEntry
);
1513 lcl_SetCheckButton( pEntry
, bVal
);
1515 m_pLinguOptionsCLB
->SetUpdateMode(true);
1520 IMPL_LINK( SvxLinguTabPage
, BoxDoubleClickHdl_Impl
, SvTreeListBox
*, pBox
)
1522 if (pBox
== m_pLinguModulesCLB
)
1524 //! in order to avoid a bug causing a GPF when double clicking
1525 //! on a module entry and exiting the "Edit Modules" dialog
1527 Application::PostUserEvent( LINK(
1528 this, SvxLinguTabPage
, PostDblClickHdl_Impl
) );
1530 else if (pBox
== m_pLinguOptionsCLB
)
1532 ClickHdl_Impl(m_pLinguOptionsEditPB
);
1539 IMPL_LINK_NOARG(SvxLinguTabPage
, PostDblClickHdl_Impl
)
1541 ClickHdl_Impl(m_pLinguModulesEditPB
);
1547 IMPL_LINK_NOARG(SvxLinguTabPage
, OpenURLHdl_Impl
)
1549 OUString
sURL( m_pMoreDictsLink
->GetURL() );
1550 lcl_OpenURL( sURL
);
1556 IMPL_LINK( SvxLinguTabPage
, BoxCheckButtonHdl_Impl
, SvTreeListBox
*, pBox
)
1558 if (pBox
== m_pLinguModulesCLB
)
1560 DBG_ASSERT( pLinguData
, "NULL pointer, LinguData missing" );
1561 sal_uLong nPos
= m_pLinguModulesCLB
->GetSelectEntryPos();
1562 if (nPos
!= TREELIST_ENTRY_NOTFOUND
&& pLinguData
)
1564 pLinguData
->Reconfigure( m_pLinguModulesCLB
->GetText( nPos
),
1565 m_pLinguModulesCLB
->IsChecked( nPos
) );
1568 else if (pBox
== m_pLinguDicsCLB
)
1570 sal_uLong nPos
= m_pLinguDicsCLB
->GetSelectEntryPos();
1571 if (nPos
!= TREELIST_ENTRY_NOTFOUND
)
1573 const uno::Reference
< XDictionary
> &rDic
= aDics
.getConstArray()[ nPos
];
1574 if (SvxGetIgnoreAllList() == rDic
)
1576 SvTreeListEntry
* pEntry
= m_pLinguDicsCLB
->GetEntry( nPos
);
1578 lcl_SetCheckButton( pEntry
, true );
1587 IMPL_LINK( SvxLinguTabPage
, ClickHdl_Impl
, PushButton
*, pBtn
)
1589 if (m_pLinguModulesEditPB
== pBtn
)
1592 pLinguData
= new SvxLinguData_Impl
;
1594 SvxLinguData_Impl
aOldLinguData( *pLinguData
);
1595 SvxEditModulesDlg
aDlg( this, *pLinguData
);
1596 if (aDlg
.Execute() != RET_OK
)
1597 *pLinguData
= aOldLinguData
;
1599 // evaluate new status of 'bConfigured' flag
1600 sal_uLong nLen
= pLinguData
->GetDisplayServiceCount();
1601 for (sal_uLong i
= 0; i
< nLen
; ++i
)
1602 pLinguData
->GetDisplayServiceArray()[i
].bConfigured
= false;
1603 const Locale
* pAllLocales
= pLinguData
->GetAllSupportedLocales().getConstArray();
1604 sal_Int32 nLocales
= pLinguData
->GetAllSupportedLocales().getLength();
1605 for (sal_Int32 k
= 0; k
< nLocales
; ++k
)
1607 sal_Int16 nLang
= LanguageTag::convertToLanguageType( pAllLocales
[k
] );
1608 if (pLinguData
->GetSpellTable().count( nLang
))
1609 pLinguData
->SetChecked( pLinguData
->GetSpellTable()[ nLang
] );
1610 if (pLinguData
->GetGrammarTable().count( nLang
))
1611 pLinguData
->SetChecked( pLinguData
->GetGrammarTable()[ nLang
] );
1612 if (pLinguData
->GetHyphTable().count( nLang
))
1613 pLinguData
->SetChecked( pLinguData
->GetHyphTable()[ nLang
] );
1614 if (pLinguData
->GetThesTable().count( nLang
))
1615 pLinguData
->SetChecked( pLinguData
->GetThesTable()[ nLang
] );
1618 // show new status of modules
1619 UpdateModulesBox_Impl();
1621 else if (m_pLinguDicsNewPB
== pBtn
)
1623 uno::Reference
< XSpellChecker1
> xSpellChecker1
;
1624 SvxAbstractDialogFactory
* pFact
= SvxAbstractDialogFactory::Create();
1627 AbstractSvxNewDictionaryDialog
* aDlg
= pFact
->CreateSvxNewDictionaryDialog( this, xSpellChecker1
);
1628 DBG_ASSERT(aDlg
, "Dialogdiet fail!");
1629 uno::Reference
< XDictionary
> xNewDic
;
1630 if ( aDlg
->Execute() == RET_OK
)
1631 xNewDic
= uno::Reference
< XDictionary
>( aDlg
->GetNewDictionary(), UNO_QUERY
);
1634 // add new dics to the end
1635 sal_Int32 nLen
= aDics
.getLength();
1636 aDics
.realloc( nLen
+ 1 );
1638 aDics
.getArray()[ nLen
] = xNewDic
;
1640 AddDicBoxEntry( xNewDic
, (sal_uInt16
) nLen
);
1645 else if (m_pLinguDicsEditPB
== pBtn
)
1647 SvTreeListEntry
*pEntry
= m_pLinguDicsCLB
->GetCurEntry();
1650 DicUserData
aData( (sal_uLong
) pEntry
->GetUserData() );
1651 sal_uInt16 nDicPos
= aData
.GetEntryId();
1652 sal_Int32 nDics
= aDics
.getLength();
1653 if (nDicPos
< nDics
)
1655 uno::Reference
< XDictionary
> xDic
;
1656 xDic
= aDics
.getConstArray()[ nDicPos
];
1659 uno::Reference
< XSpellChecker1
> xSpellChecker1
;
1660 SvxAbstractDialogFactory
* pFact
= SvxAbstractDialogFactory::Create();
1663 VclAbstractDialog
* aDlg
= pFact
->CreateSvxEditDictionaryDialog( this, xDic
->getName(), xSpellChecker1
, RID_SFXDLG_EDITDICT
);
1664 DBG_ASSERT(aDlg
, "Dialogdiet fail!");
1672 else if (m_pLinguDicsDelPB
== pBtn
)
1674 MessageDialog
aQuery(this, "QueryDeleteDictionaryDialog",
1675 "cui/ui/querydeletedictionarydialog.ui");
1676 if (RET_NO
== aQuery
.Execute())
1679 SvTreeListEntry
*pEntry
= m_pLinguDicsCLB
->GetCurEntry();
1682 DicUserData
aData( (sal_uLong
) pEntry
->GetUserData() );
1683 sal_uInt16 nDicPos
= aData
.GetEntryId();
1684 sal_Int32 nDics
= aDics
.getLength();
1685 if (nDicPos
< nDics
)
1687 uno::Reference
< XDictionary
> xDic
;
1688 xDic
= aDics
.getConstArray()[ nDicPos
];
1691 if (SvxGetIgnoreAllList() == xDic
)
1696 xDicList
->removeDictionary( xDic
);
1698 uno::Reference
< frame::XStorable
> xStor( xDic
, UNO_QUERY
);
1699 if ( xStor
->hasLocation() && !xStor
->isReadonly() )
1701 OUString sURL
= xStor
->getLocation();
1702 INetURLObject
aObj(sURL
);
1703 DBG_ASSERT( aObj
.GetProtocol() == INET_PROT_FILE
,
1704 "non-file URLs cannot be deleted" );
1705 if ( aObj
.GetProtocol() == INET_PROT_FILE
)
1707 KillFile_Impl( aObj
.GetMainURL( INetURLObject::NO_DECODE
) );
1711 aDics
.getArray()[ nDicPos
] = 0;
1713 // remove entry from checklistbox
1714 sal_uLong nCnt
= m_pLinguDicsCLB
->GetEntryCount();
1715 for (sal_uLong i
= 0; i
< nCnt
; ++i
)
1717 SvTreeListEntry
*pDicEntry
= m_pLinguDicsCLB
->GetEntry( i
);
1718 DBG_ASSERT( pDicEntry
, "missing entry" );
1721 DicUserData
aDicData( (sal_uLong
) pDicEntry
->GetUserData() );
1722 if (aDicData
.GetEntryId() == nDicPos
)
1724 m_pLinguDicsCLB
->RemoveEntry( i
);
1729 DBG_ASSERT( nCnt
> m_pLinguDicsCLB
->GetEntryCount(),
1736 else if (m_pLinguOptionsEditPB
== pBtn
)
1738 SvTreeListEntry
*pEntry
= m_pLinguOptionsCLB
->GetCurEntry();
1739 DBG_ASSERT( pEntry
, "no entry selected" );
1742 OptionsUserData
aData( (sal_uLong
)pEntry
->GetUserData() );
1743 if(aData
.HasNumericValue())
1745 sal_uInt16 nRID
= aData
.GetEntryId();
1746 OptionsBreakSet
aDlg( this, nRID
);
1747 aDlg
.GetNumericFld().SetValue( aData
.GetNumericValue() );
1748 if (RET_OK
== aDlg
.Execute() )
1750 long nVal
= static_cast<long>(aDlg
.GetNumericFld().GetValue());
1751 if (-1 != nVal
&& aData
.GetNumericValue() != nVal
)
1753 aData
.SetNumericValue( (sal_uInt8
)nVal
); //! sets IsModified !
1754 pEntry
->SetUserData( (void *) aData
.GetUserData() );
1755 m_pLinguOptionsCLB
->Invalidate();
1763 OSL_FAIL( "pBtn unexpected value" );
1771 IMPL_LINK( SvxLinguTabPage
, SelectHdl_Impl
, SvxCheckListBox
*, pBox
)
1773 if (m_pLinguModulesCLB
== pBox
)
1776 else if (m_pLinguDicsCLB
== pBox
)
1778 SvTreeListEntry
*pEntry
= pBox
->GetCurEntry();
1781 DicUserData
aData( (sal_uLong
) pEntry
->GetUserData() );
1783 // always allow to edit (i.e. at least view the content of the dictionary)
1784 m_pLinguDicsEditPB
->Enable( true/*aData.IsEditable()*/ );
1785 m_pLinguDicsDelPB
->Enable( aData
.IsDeletable() );
1788 else if (m_pLinguOptionsCLB
== pBox
)
1790 SvTreeListEntry
*pEntry
= pBox
->GetCurEntry();
1793 OptionsUserData
aData( (sal_uLong
) pEntry
->GetUserData() );
1794 m_pLinguOptionsEditPB
->Enable( aData
.HasNumericValue() );
1799 OSL_FAIL( "pBox unexpected value" );
1807 SvTreeListEntry
* SvxLinguTabPage::CreateEntry( OUString
& rTxt
, sal_uInt16 nCol
)
1809 SvTreeListEntry
* pEntry
= new SvTreeListEntry
;
1811 if( !pCheckButtonData
)
1812 pCheckButtonData
= new SvLBoxButtonData(m_pLinguOptionsCLB
);
1815 if (CBCOL_FIRST
== nCol
)
1816 pEntry
->AddItem( new SvLBoxButton( pEntry
, SvLBoxButtonKind_enabledCheckbox
, 0, pCheckButtonData
) );
1817 if (CBCOL_SECOND
== nCol
)
1818 pEntry
->AddItem( new SvLBoxString( pEntry
, 0, sEmpty
) ); // empty column
1819 pEntry
->AddItem( new SvLBoxContextBmp( pEntry
, 0, Image(), Image(), false));
1820 pEntry
->AddItem( new BrwString_Impl( pEntry
, 0, rTxt
) );
1827 void SvxLinguTabPage::HideGroups( sal_uInt16 nGrp
)
1829 if ( 0 != ( GROUP_MODULES
& nGrp
) )
1831 m_pLinguModulesFT
->Hide();
1832 m_pLinguModulesCLB
->Hide();
1833 m_pLinguModulesEditPB
->Hide();
1835 if ( SvtExtendedSecurityOptions().GetOpenHyperlinkMode()
1836 != SvtExtendedSecurityOptions::OPEN_NEVER
)
1838 m_pMoreDictsLink
->Show();
1843 SvxEditModulesDlg::SvxEditModulesDlg(Window
* pParent
, SvxLinguData_Impl
& rData
)
1844 : ModalDialog( pParent
, "EditModulesDialog",
1845 "cui/ui/editmodulesdialog.ui")
1846 , sSpell(CUI_RES(RID_SVXSTR_SPELL
))
1847 , sHyph(CUI_RES(RID_SVXSTR_HYPH
))
1848 , sThes(CUI_RES(RID_SVXSTR_THES
))
1849 , sGrammar(CUI_RES(RID_SVXSTR_GRAMMAR
))
1852 get(m_pClosePB
, "close");
1853 get(m_pMoreDictsLink
, "moredictslink");
1854 get(m_pBackPB
, "back");
1855 get(m_pPrioDownPB
, "down");
1856 get(m_pPrioUpPB
, "up");
1857 get(m_pModulesCLB
, "lingudicts");
1858 Size
aListSize(m_pModulesCLB
->LogicToPixel(Size(166, 120), MAP_APPFONT
));
1859 m_pModulesCLB
->set_height_request(aListSize
.Height());
1860 m_pModulesCLB
->set_width_request(aListSize
.Width());
1861 get(m_pLanguageLB
, "language");
1862 m_pLanguageLB
->SetStyle(m_pLanguageLB
->GetStyle() | WB_SORT
);
1864 pCheckButtonData
= NULL
;
1866 pDefaultLinguData
= new SvxLinguData_Impl( rLinguData
);
1868 m_pModulesCLB
->SetStyle( m_pModulesCLB
->GetStyle()|WB_CLIPCHILDREN
|WB_HSCROLL
|WB_FORCE_MAKEVISIBLE
);
1869 m_pModulesCLB
->SetHighlightRange();
1870 m_pModulesCLB
->SetSelectHdl( LINK( this, SvxEditModulesDlg
, SelectHdl_Impl
));
1871 m_pModulesCLB
->SetCheckButtonHdl( LINK( this, SvxEditModulesDlg
, BoxCheckButtonHdl_Impl
) );
1873 m_pClosePB
->SetClickHdl( LINK( this, SvxEditModulesDlg
, ClickHdl_Impl
));
1874 m_pPrioUpPB
->SetClickHdl( LINK( this, SvxEditModulesDlg
, UpDownHdl_Impl
));
1875 m_pPrioDownPB
->SetClickHdl( LINK( this, SvxEditModulesDlg
, UpDownHdl_Impl
));
1876 m_pBackPB
->SetClickHdl( LINK( this, SvxEditModulesDlg
, BackHdl_Impl
));
1877 // in case of not installed language modules
1878 m_pPrioUpPB
->Enable( false );
1879 m_pPrioDownPB
->Enable( false );
1881 if ( SvtExtendedSecurityOptions().GetOpenHyperlinkMode()
1882 != SvtExtendedSecurityOptions::OPEN_NEVER
)
1884 m_pMoreDictsLink
->SetClickHdl( LINK( this, SvxEditModulesDlg
, OpenURLHdl_Impl
) );
1888 m_pMoreDictsLink
->Hide();
1892 Sequence
< sal_Int16
> aAvailLang
;
1893 uno::Reference
< XAvailableLocales
> xAvail( rLinguData
.GetManager(), UNO_QUERY
);
1896 aAvailLang
= lcl_LocaleSeqToLangSeq(
1897 xAvail
->getAvailableLocales( cSpell
) );
1899 const Sequence
< Locale
>& rLoc
= rLinguData
.GetAllSupportedLocales();
1900 const Locale
* pLocales
= rLoc
.getConstArray();
1901 m_pLanguageLB
->Clear();
1902 for(long i
= 0; i
< rLoc
.getLength(); i
++)
1904 sal_Int16 nLang
= LanguageTag::convertToLanguageType( pLocales
[i
] );
1905 m_pLanguageLB
->InsertLanguage( nLang
, lcl_SeqHasLang( aAvailLang
, nLang
) );
1907 LanguageType eSysLang
= MsLangId::getSystemLanguage();
1908 m_pLanguageLB
->SelectLanguage( eSysLang
);
1909 if(!m_pLanguageLB
->IsLanguageSelected( eSysLang
) )
1910 m_pLanguageLB
->SelectEntryPos(0);
1912 m_pLanguageLB
->SetSelectHdl( LINK( this, SvxEditModulesDlg
, LangSelectHdl_Impl
));
1913 LangSelectHdl_Impl(m_pLanguageLB
);
1917 SvxEditModulesDlg::~SvxEditModulesDlg()
1919 delete pDefaultLinguData
;
1923 SvTreeListEntry
* SvxEditModulesDlg::CreateEntry( OUString
& rTxt
, sal_uInt16 nCol
)
1925 SvTreeListEntry
* pEntry
= new SvTreeListEntry
;
1926 if( !pCheckButtonData
)
1928 pCheckButtonData
= new SvLBoxButtonData(m_pModulesCLB
);
1929 pCheckButtonData
->SetLink( m_pModulesCLB
->GetCheckButtonHdl() );
1933 if (CBCOL_FIRST
== nCol
)
1934 pEntry
->AddItem( new SvLBoxButton( pEntry
, SvLBoxButtonKind_enabledCheckbox
, 0, pCheckButtonData
) );
1935 if (CBCOL_SECOND
== nCol
)
1936 pEntry
->AddItem( new SvLBoxString( pEntry
, 0, sEmpty
) ); // empty column
1937 pEntry
->AddItem( new SvLBoxContextBmp( pEntry
, 0, Image(), Image(), false));
1938 pEntry
->AddItem( new BrwStringDic_Impl( pEntry
, 0, rTxt
) );
1943 IMPL_LINK( SvxEditModulesDlg
, SelectHdl_Impl
, SvxCheckListBox
*, pBox
)
1945 if (m_pModulesCLB
== pBox
)
1947 bool bDisableUp
= true;
1948 bool bDisableDown
= true;
1949 SvTreeListEntry
*pEntry
= pBox
->GetCurEntry();
1952 ModuleUserData_Impl
* pData
= (ModuleUserData_Impl
*)pEntry
->GetUserData();
1953 if(!pData
->IsParent() && pData
->GetType() != TYPE_HYPH
)
1955 sal_uLong nCurPos
= pBox
->GetSelectEntryPos();
1956 if(nCurPos
< pBox
->GetEntryCount() - 1)
1958 bDisableDown
= ((ModuleUserData_Impl
*)pBox
->
1959 GetEntry(nCurPos
+ 1)->GetUserData())->IsParent();
1963 bDisableUp
= ((ModuleUserData_Impl
*)pBox
->
1964 GetEntry(nCurPos
- 1)->GetUserData())->IsParent();
1967 m_pPrioUpPB
->Enable(!bDisableUp
);
1968 m_pPrioDownPB
->Enable(!bDisableDown
);
1973 OSL_FAIL( "pBox unexpected value" );
1979 IMPL_LINK( SvxEditModulesDlg
, BoxCheckButtonHdl_Impl
, SvTreeListBox
*, pBox
)
1981 pBox
= m_pModulesCLB
;
1982 SvTreeListEntry
*pCurEntry
= pBox
->GetCurEntry();
1985 ModuleUserData_Impl
* pData
= (ModuleUserData_Impl
*)
1986 pCurEntry
->GetUserData();
1987 if (!pData
->IsParent() && pData
->GetType() == TYPE_HYPH
)
1989 // make hyphenator checkboxes function as radio-buttons
1990 // (at most one box may be checked)
1991 SvTreeListEntry
*pEntry
= pBox
->First();
1994 pData
= (ModuleUserData_Impl
*) pEntry
->GetUserData();
1995 if (!pData
->IsParent() &&
1996 pData
->GetType() == TYPE_HYPH
&&
1997 pEntry
!= pCurEntry
)
1999 lcl_SetCheckButton( pEntry
, false );
2000 pBox
->InvalidateEntry( pEntry
);
2002 pEntry
= pBox
->Next( pEntry
);
2009 IMPL_LINK( SvxEditModulesDlg
, LangSelectHdl_Impl
, ListBox
*, pBox
)
2011 LanguageType eCurLanguage
= m_pLanguageLB
->GetSelectLanguage();
2012 static Locale aLastLocale
;
2013 Locale
aCurLocale( LanguageTag::convertToLocale( eCurLanguage
));
2014 SvTreeList
*pModel
= m_pModulesCLB
->GetModel();
2018 // save old probably changed settings
2019 // before switching to new language entries
2021 sal_Int16 nLang
= LanguageTag::convertToLanguageType( aLastLocale
);
2023 sal_Int32 nStart
= 0, nLocalIndex
= 0;
2024 Sequence
< OUString
> aChange
;
2025 bool bChanged
= false;
2026 for(sal_uLong i
= 0; i
< m_pModulesCLB
->GetEntryCount(); i
++)
2028 SvTreeListEntry
*pEntry
= m_pModulesCLB
->GetEntry(i
);
2029 ModuleUserData_Impl
* pData
= (ModuleUserData_Impl
*)pEntry
->GetUserData();
2030 if(pData
->IsParent())
2034 LangImplNameTable
*pTable
= 0;
2035 sal_uInt8 nType
= pData
->GetType();
2038 case TYPE_SPELL
: pTable
= &rLinguData
.GetSpellTable(); break;
2039 case TYPE_GRAMMAR
: pTable
= &rLinguData
.GetGrammarTable(); break;
2040 case TYPE_HYPH
: pTable
= &rLinguData
.GetHyphTable(); break;
2041 case TYPE_THES
: pTable
= &rLinguData
.GetThesTable(); break;
2045 aChange
.realloc(nStart
);
2046 (*pTable
)[ nLang
] = aChange
;
2049 nLocalIndex
= nStart
= 0;
2050 aChange
.realloc(m_pModulesCLB
->GetEntryCount());
2055 OUString
* pChange
= aChange
.getArray();
2056 pChange
[nStart
] = pData
->GetImplName();
2057 bChanged
|= pData
->GetIndex() != nLocalIndex
||
2058 pData
->IsChecked() != m_pModulesCLB
->IsChecked(i
);
2059 if(m_pModulesCLB
->IsChecked(i
))
2066 aChange
.realloc(nStart
);
2067 rLinguData
.GetThesTable()[ nLang
] = aChange
;
2071 for(sal_uLong i
= 0; i
< m_pModulesCLB
->GetEntryCount(); i
++)
2072 delete (ModuleUserData_Impl
*)m_pModulesCLB
->GetEntry(i
)->GetUserData();
2075 // display entries for new selected language
2077 m_pModulesCLB
->Clear();
2078 if(LANGUAGE_DONTKNOW
!= eCurLanguage
)
2081 ServiceInfo_Impl
* pInfo
;
2084 // spellchecker entries
2086 SvTreeListEntry
* pEntry
= CreateEntry( sSpell
, CBCOL_SECOND
);
2087 ModuleUserData_Impl
* pUserData
= new ModuleUserData_Impl(
2088 OUString(), true, false, TYPE_SPELL
, 0 );
2089 pEntry
->SetUserData( (void *)pUserData
);
2090 pModel
->Insert( pEntry
);
2092 Sequence
< OUString
> aNames( rLinguData
.GetSortedImplNames( eCurLanguage
, TYPE_SPELL
) );
2093 const OUString
*pName
= aNames
.getConstArray();
2094 sal_uLong nNames
= (sal_uLong
) aNames
.getLength();
2095 sal_Int32 nLocalIndex
= 0; // index relative to parent
2096 for (n
= 0; n
< nNames
; ++n
)
2099 bool bIsSuppLang
= false;
2101 pInfo
= rLinguData
.GetInfoByImplName( pName
[n
] );
2104 bIsSuppLang
= pInfo
->xSpell
.is() &&
2105 pInfo
->xSpell
->hasLocale( aCurLocale
);
2106 aImplName
= pInfo
->sSpellImplName
;
2108 if (!aImplName
.isEmpty() && bIsSuppLang
)
2110 OUString
aTxt( pInfo
->sDisplayName
);
2111 SvTreeListEntry
* pNewEntry
= CreateEntry( aTxt
, CBCOL_FIRST
);
2113 LangImplNameTable
&rTable
= rLinguData
.GetSpellTable();
2114 const bool bHasLang
= rTable
.count( eCurLanguage
);
2117 DBG_WARNING( "language entry missing" ); // only relevant if all languages found should be supported
2119 const bool bCheck
= bHasLang
&& lcl_SeqGetEntryPos( rTable
[ eCurLanguage
], aImplName
) >= 0;
2120 lcl_SetCheckButton( pNewEntry
, bCheck
);
2121 pUserData
= new ModuleUserData_Impl( aImplName
, false,
2122 bCheck
, TYPE_SPELL
, (sal_uInt8
)nLocalIndex
++ );
2123 pNewEntry
->SetUserData( (void *)pUserData
);
2124 pModel
->Insert( pNewEntry
);
2129 // grammar checker entries
2131 pEntry
= CreateEntry( sGrammar
, CBCOL_SECOND
);
2132 pUserData
= new ModuleUserData_Impl( OUString(), true, false, TYPE_GRAMMAR
, 0 );
2133 pEntry
->SetUserData( (void *)pUserData
);
2134 pModel
->Insert( pEntry
);
2136 aNames
= rLinguData
.GetSortedImplNames( eCurLanguage
, TYPE_GRAMMAR
);
2137 pName
= aNames
.getConstArray();
2138 nNames
= (sal_uLong
) aNames
.getLength();
2140 for (n
= 0; n
< nNames
; ++n
)
2143 bool bIsSuppLang
= false;
2145 pInfo
= rLinguData
.GetInfoByImplName( pName
[n
] );
2148 bIsSuppLang
= pInfo
->xGrammar
.is() &&
2149 pInfo
->xGrammar
->hasLocale( aCurLocale
);
2150 aImplName
= pInfo
->sGrammarImplName
;
2152 if (!aImplName
.isEmpty() && bIsSuppLang
)
2154 OUString
aTxt( pInfo
->sDisplayName
);
2155 SvTreeListEntry
* pNewEntry
= CreateEntry( aTxt
, CBCOL_FIRST
);
2157 LangImplNameTable
&rTable
= rLinguData
.GetGrammarTable();
2158 const bool bHasLang
= rTable
.count( eCurLanguage
);
2161 DBG_WARNING( "language entry missing" ); // only relevant if all languages found should be supported
2163 const bool bCheck
= bHasLang
&& lcl_SeqGetEntryPos( rTable
[ eCurLanguage
], aImplName
) >= 0;
2164 lcl_SetCheckButton( pNewEntry
, bCheck
);
2165 pUserData
= new ModuleUserData_Impl( aImplName
, false,
2166 bCheck
, TYPE_GRAMMAR
, (sal_uInt8
)nLocalIndex
++ );
2167 pNewEntry
->SetUserData( (void *)pUserData
);
2168 pModel
->Insert( pNewEntry
);
2173 // hyphenator entries
2175 pEntry
= CreateEntry( sHyph
, CBCOL_SECOND
);
2176 pUserData
= new ModuleUserData_Impl( OUString(), true, false, TYPE_HYPH
, 0 );
2177 pEntry
->SetUserData( (void *)pUserData
);
2178 pModel
->Insert( pEntry
);
2180 aNames
= rLinguData
.GetSortedImplNames( eCurLanguage
, TYPE_HYPH
);
2181 pName
= aNames
.getConstArray();
2182 nNames
= (sal_uLong
) aNames
.getLength();
2184 for (n
= 0; n
< nNames
; ++n
)
2187 bool bIsSuppLang
= false;
2189 pInfo
= rLinguData
.GetInfoByImplName( pName
[n
] );
2192 bIsSuppLang
= pInfo
->xHyph
.is() &&
2193 pInfo
->xHyph
->hasLocale( aCurLocale
);
2194 aImplName
= pInfo
->sHyphImplName
;
2196 if (!aImplName
.isEmpty() && bIsSuppLang
)
2198 OUString
aTxt( pInfo
->sDisplayName
);
2199 SvTreeListEntry
* pNewEntry
= CreateEntry( aTxt
, CBCOL_FIRST
);
2201 LangImplNameTable
&rTable
= rLinguData
.GetHyphTable();
2202 const bool bHasLang
= rTable
.count( eCurLanguage
);
2205 DBG_WARNING( "language entry missing" ); // only relevant if all languages found should be supported
2207 const bool bCheck
= bHasLang
&& lcl_SeqGetEntryPos( rTable
[ eCurLanguage
], aImplName
) >= 0;
2208 lcl_SetCheckButton( pNewEntry
, bCheck
);
2209 pUserData
= new ModuleUserData_Impl( aImplName
, false,
2210 bCheck
, TYPE_HYPH
, (sal_uInt8
)nLocalIndex
++ );
2211 pNewEntry
->SetUserData( (void *)pUserData
);
2212 pModel
->Insert( pNewEntry
);
2217 // thesaurus entries
2219 pEntry
= CreateEntry( sThes
, CBCOL_SECOND
);
2220 pUserData
= new ModuleUserData_Impl( OUString(), true, false, TYPE_THES
, 0 );
2221 pEntry
->SetUserData( (void *)pUserData
);
2222 pModel
->Insert( pEntry
);
2224 aNames
= rLinguData
.GetSortedImplNames( eCurLanguage
, TYPE_THES
);
2225 pName
= aNames
.getConstArray();
2226 nNames
= (sal_uLong
) aNames
.getLength();
2228 for (n
= 0; n
< nNames
; ++n
)
2231 bool bIsSuppLang
= false;
2233 pInfo
= rLinguData
.GetInfoByImplName( pName
[n
] );
2236 bIsSuppLang
= pInfo
->xThes
.is() &&
2237 pInfo
->xThes
->hasLocale( aCurLocale
);
2238 aImplName
= pInfo
->sThesImplName
;
2240 if (!aImplName
.isEmpty() && bIsSuppLang
)
2242 OUString
aTxt( pInfo
->sDisplayName
);
2243 SvTreeListEntry
* pNewEntry
= CreateEntry( aTxt
, CBCOL_FIRST
);
2245 LangImplNameTable
&rTable
= rLinguData
.GetThesTable();
2246 const bool bHasLang
= rTable
.count( eCurLanguage
);
2249 DBG_WARNING( "language entry missing" ); // only relevant if all languages found should be supported
2251 const bool bCheck
= bHasLang
&& lcl_SeqGetEntryPos( rTable
[ eCurLanguage
], aImplName
) >= 0;
2252 lcl_SetCheckButton( pNewEntry
, bCheck
);
2253 pUserData
= new ModuleUserData_Impl( aImplName
, false,
2254 bCheck
, TYPE_THES
, (sal_uInt8
)nLocalIndex
++ );
2255 pNewEntry
->SetUserData( (void *)pUserData
);
2256 pModel
->Insert( pNewEntry
);
2260 aLastLocale
= aCurLocale
;
2264 IMPL_LINK( SvxEditModulesDlg
, UpDownHdl_Impl
, PushButton
*, pBtn
)
2266 bool bUp
= m_pPrioUpPB
== pBtn
;
2267 sal_uLong nCurPos
= m_pModulesCLB
->GetSelectEntryPos();
2268 SvTreeListEntry
* pEntry
;
2269 if (nCurPos
!= TREELIST_ENTRY_NOTFOUND
&&
2270 0 != (pEntry
= m_pModulesCLB
->GetEntry(nCurPos
)))
2272 m_pModulesCLB
->SetUpdateMode(false);
2273 SvTreeList
*pModel
= m_pModulesCLB
->GetModel();
2275 ModuleUserData_Impl
* pData
= (ModuleUserData_Impl
*)pEntry
->GetUserData();
2276 OUString
aStr(m_pModulesCLB
->GetEntryText(pEntry
));
2277 SvTreeListEntry
* pToInsert
= CreateEntry( aStr
, CBCOL_FIRST
);
2278 pToInsert
->SetUserData( (void *)pData
);
2279 bool bIsChecked
= m_pModulesCLB
->IsChecked(nCurPos
);
2281 pModel
->Remove(pEntry
);
2283 sal_uLong nDestPos
= bUp
? nCurPos
- 1 : nCurPos
+ 1;
2284 pModel
->Insert(pToInsert
, nDestPos
);
2285 m_pModulesCLB
->CheckEntryPos(nDestPos
, bIsChecked
);
2286 m_pModulesCLB
->SelectEntryPos(nDestPos
);
2287 SelectHdl_Impl(m_pModulesCLB
);
2288 m_pModulesCLB
->SetUpdateMode(true);
2293 IMPL_LINK_NOARG(SvxEditModulesDlg
, ClickHdl_Impl
)
2295 // store language config
2296 LangSelectHdl_Impl(m_pLanguageLB
);
2297 EndDialog( RET_OK
);
2301 IMPL_LINK_NOARG(SvxEditModulesDlg
, BackHdl_Impl
)
2303 rLinguData
= *pDefaultLinguData
;
2304 LangSelectHdl_Impl(0);
2310 IMPL_LINK_NOARG(SvxEditModulesDlg
, OpenURLHdl_Impl
)
2312 OUString
sURL( m_pMoreDictsLink
->GetURL() );
2313 lcl_OpenURL( sURL
);
2317 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */