bump product version to 4.1.6.2
[LibreOffice.git] / cui / source / options / optlingu.cxx
blob303a89f986e8022eedc1007bd29f6ade4f07f4fd
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 .
20 #include <vcl/msgbox.hxx>
21 #include <vcl/field.hxx>
22 #include <vcl/fixed.hxx>
23 #include <tools/shl.hxx>
24 #include <i18nlangtag/mslangid.hxx>
25 #include <unotools/lingucfg.hxx>
26 #include <editeng/unolingu.hxx>
27 #include <svx/dlgutil.hxx>
28 #include <linguistic/lngprops.hxx>
29 #include <linguistic/misc.hxx>
30 #include <sfx2/sfxuno.hxx>
31 #include <sfx2/dispatch.hxx>
32 #include <tools/urlobj.hxx>
33 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
34 #include <comphelper/processfactory.hxx>
35 #include <com/sun/star/linguistic2/LinguServiceManager.hpp>
36 #include <com/sun/star/linguistic2/XSpellChecker.hpp>
37 #include <com/sun/star/linguistic2/XProofreader.hpp>
38 #include <com/sun/star/linguistic2/XHyphenator.hpp>
39 #include <com/sun/star/linguistic2/XThesaurus.hpp>
40 #include <com/sun/star/linguistic2/XAvailableLocales.hpp>
41 #include <com/sun/star/lang/XServiceDisplayName.hpp>
42 #include <com/sun/star/linguistic2/DictionaryListEventFlags.hpp>
43 #include <com/sun/star/linguistic2/DictionaryListEvent.hpp>
44 #include <com/sun/star/linguistic2/XDictionaryListEventListener.hpp>
45 #include <com/sun/star/linguistic2/XDictionaryList.hpp>
46 #include <com/sun/star/frame/XStorable.hpp>
47 #include <com/sun/star/ucb/CommandAbortedException.hpp>
48 #include <com/sun/star/system/SystemShellExecute.hpp>
49 #include <com/sun/star/system/SystemShellExecuteFlags.hpp>
50 #include <unotools/extendedsecurityoptions.hxx>
51 #include <svtools/treelistbox.hxx>
52 #include "svtools/treelistentry.hxx"
53 #include <svtools/langhelp.hxx>
54 #include <svl/eitem.hxx>
55 #include <svl/intitem.hxx>
56 #include <sfx2/viewfrm.hxx>
57 #include <vcl/svapp.hxx>
58 #include "optlingu.hrc"
60 #include <svx/svxdlg.hxx>
61 #include <editeng/optitems.hxx>
62 #include "optlingu.hxx"
63 #include <dialmgr.hxx>
64 #include <cuires.hrc>
65 #include "helpid.hrc"
67 #include <comphelper/componentcontext.hxx>
68 #include <ucbhelper/content.hxx>
70 #include <vector>
71 #include <map>
74 using namespace ::ucbhelper;
75 using namespace ::rtl;
76 using namespace ::com::sun::star;
77 using namespace ::com::sun::star::lang;
78 using namespace ::com::sun::star::uno;
79 using namespace ::com::sun::star::linguistic2;
80 using namespace ::com::sun::star::beans;
82 #define CBCOL_FIRST 0
83 #define CBCOL_SECOND 1
85 static const sal_Char cSpell[] = SN_SPELLCHECKER;
86 static const sal_Char cGrammar[] = SN_GRAMMARCHECKER;
87 static const sal_Char cHyph[] = SN_HYPHENATOR;
88 static const sal_Char cThes[] = SN_THESAURUS;
90 // static ----------------------------------------------------------------
92 static Sequence< sal_Int16 > lcl_LocaleSeqToLangSeq( const Sequence< Locale > &rSeq )
94 sal_Int32 nLen = rSeq.getLength();
95 Sequence< sal_Int16 > aRes( nLen );
96 sal_Int16 *pRes = aRes.getArray();
97 const Locale *pSeq = rSeq.getConstArray();
98 for (sal_Int32 i = 0; i < nLen; ++i)
100 pRes[i] = LanguageTag( pSeq[i] ).getLanguageType();
102 return aRes;
106 static sal_Bool lcl_SeqHasLang( const Sequence< sal_Int16 > &rSeq, sal_Int16 nLang )
108 sal_Int32 nLen = rSeq.getLength();
109 const sal_Int16 *pLang = rSeq.getConstArray();
110 sal_Int32 nPos = -1;
111 for (sal_Int32 i = 0; i < nLen && nPos < 0; ++i)
113 if (nLang == pLang[i])
114 nPos = i;
116 return nPos < 0 ? sal_False : sal_True;
120 static sal_Int32 lcl_SeqGetEntryPos(
121 const Sequence< OUString > &rSeq, const OUString &rEntry )
123 sal_Int32 i;
124 sal_Int32 nLen = rSeq.getLength();
125 const OUString *pItem = rSeq.getConstArray();
126 for (i = 0; i < nLen; ++i)
128 if (rEntry == pItem[i])
129 break;
131 return i < nLen ? i : -1;
134 static void lcl_OpenURL( OUString sURL )
136 if ( !sURL.isEmpty() )
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 sal_uInt16 pRanges[] =
157 SID_ATTR_SPELL,
158 SID_ATTR_SPELL,
162 sal_Bool KillFile_Impl( const String& rURL )
164 sal_Bool bRet = sal_True;
167 Content aCnt( rURL, uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >(), comphelper::getProcessComponentContext() );
168 aCnt.executeCommand( OUString("delete"), makeAny( sal_Bool( sal_True ) ) );
170 catch( ::com::sun::star::ucb::CommandAbortedException& )
172 SAL_WARN( "cui.options", "KillFile: CommandAbortedException" );
173 bRet = sal_False;
175 catch( ... )
177 SAL_WARN( "cui.options", "KillFile: Any other exception" );
178 bRet = sal_False;
181 return bRet;
184 // 0x 0p 0t 0c nn
185 // p: 1 -> parent
186 // t: 1 -> spell, 2 -> hyph, 3 -> thes, 4 -> grammar
187 // c: 1 -> checked 0 -> unchecked
188 // n: index
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
197 sal_Bool bParent;
198 sal_Bool bIsChecked;
199 sal_uInt8 nType;
200 sal_uInt8 nIndex;
201 String sImplName;
203 public:
204 ModuleUserData_Impl( String sImpName, sal_Bool bIsParent, sal_Bool bChecked, sal_uInt8 nSetType, sal_uInt8 nSetIndex ) :
205 bParent(bIsParent),
206 bIsChecked(bChecked),
207 nType(nSetType),
208 nIndex(nSetIndex),
209 sImplName(sImpName)
212 sal_Bool IsParent() const {return bParent;}
213 sal_uInt8 GetType() const {return nType;}
214 sal_Bool IsChecked() const {return bIsChecked;}
215 sal_uInt8 GetIndex() const {return nIndex;}
216 void SetIndex(sal_uInt8 nSet) {nIndex = nSet;}
217 const String& GetImplName() const {return sImplName;}
222 // User for user-dictionaries (XDictionary interface)
224 class DicUserData
226 sal_uLong nVal;
228 public:
229 DicUserData( sal_uLong nUserData ) : nVal( nUserData ) {}
230 DicUserData( sal_uInt16 nEID,
231 sal_Bool bChecked, sal_Bool bEditable, sal_Bool bDeletable );
233 sal_uLong GetUserData() const { return nVal; }
234 sal_uInt16 GetEntryId() const { return (sal_uInt16)(nVal >> 16); }
235 sal_Bool IsChecked() const { return (sal_Bool)(nVal >> 8) & 0x01; }
236 sal_Bool IsEditable() const { return (sal_Bool)(nVal >> 9) & 0x01; }
237 sal_Bool IsDeletable() const { return (sal_Bool)(nVal >> 10) & 0x01; }
239 void SetChecked( sal_Bool bVal );
243 DicUserData::DicUserData(
244 sal_uInt16 nEID,
245 sal_Bool bChecked, sal_Bool bEditable, sal_Bool bDeletable )
247 DBG_ASSERT( nEID < 65000, "Entry Id out of range" );
248 nVal = ((sal_uLong)(0xFFFF & nEID) << 16) |
249 ((sal_uLong)(bChecked ? 1 : 0) << 8) |
250 ((sal_uLong)(bEditable ? 1 : 0) << 9) |
251 ((sal_uLong)(bDeletable ? 1 : 0) << 10);
255 void DicUserData::SetChecked( sal_Bool bVal )
257 nVal &= ~(1UL << 8);
258 nVal |= (sal_uLong)(bVal ? 1 : 0) << 8;
262 // class BrwString_Impl -------------------------------------------------
264 static void lcl_SetCheckButton( SvTreeListEntry* pEntry, sal_Bool bCheck )
266 SvLBoxButton* pItem = (SvLBoxButton*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXBUTTON));
268 DBG_ASSERT(pItem,"SetCheckButton:Item not found");
269 if (pItem->GetType() == SV_ITEM_ID_LBOXBUTTON)
271 if (bCheck)
272 pItem->SetStateChecked();
273 else
274 pItem->SetStateUnchecked();
279 class BrwStringDic_Impl : public SvLBoxString
281 public:
283 BrwStringDic_Impl( SvTreeListEntry* pEntry, sal_uInt16 nFlags,
284 const String& rStr ) : SvLBoxString( pEntry, nFlags, rStr ) {}
286 virtual void Paint(
287 const Point& rPos, SvTreeListBox& rOutDev, const SvViewDataEntry* pView, const SvTreeListEntry* pEntry);
290 void BrwStringDic_Impl::Paint(
291 const Point& rPos, SvTreeListBox& rDev, const SvViewDataEntry* /*pView*/,
292 const SvTreeListEntry* pEntry)
294 ModuleUserData_Impl* pData = (ModuleUserData_Impl*)pEntry->GetUserData();
295 Point aPos(rPos);
296 Font aOldFont( rDev.GetFont());
297 if(pData->IsParent())
299 Font aFont( aOldFont );
300 aFont.SetWeight( WEIGHT_BOLD );
301 rDev.SetFont( aFont );
302 aPos.X() = 0;
304 else
305 aPos.X() += 5;
306 rDev.DrawText( aPos, GetText() );
307 rDev.SetFont( aOldFont );
310 class OptionsBreakSet : public ModalDialog
312 OKButton aOKPB;
313 CancelButton aCancelPB;
314 FixedLine aValFL;
315 NumericField aValNF;
317 public:
318 OptionsBreakSet(Window* pParent, int nRID) :
319 ModalDialog(pParent, CUI_RES(RID_SVXDLG_LNG_ED_NUM_PREBREAK )),
320 aOKPB (this, CUI_RES(BT_OK_PREBREAK)),
321 aCancelPB (this, CUI_RES(BT_CANCEL_PREBREAK)),
322 aValFL (this, CUI_RES(FL_NUMVAL_PREBREAK)),
323 aValNF (this, CUI_RES(ED_PREBREAK))
325 DBG_ASSERT( STR_NUM_PRE_BREAK_DLG == nRID ||
326 STR_NUM_POST_BREAK_DLG == nRID ||
327 STR_NUM_MIN_WORDLEN_DLG == nRID, "unexpected RID" );
329 if (nRID != -1)
330 aValFL.SetText( String( CUI_RES(nRID) ) );
331 FreeResource();
334 NumericField& GetNumericFld() { return aValNF; }
338 /*--------------------------------------------------
339 Entry IDs for options listbox of dialog
340 --------------------------------------------------*/
342 enum EID_OPTIONS
344 EID_SPELL_AUTO,
345 EID_GRAMMAR_AUTO,
346 EID_CAPITAL_WORDS,
347 EID_WORDS_WITH_DIGITS,
348 EID_SPELL_SPECIAL,
349 EID_NUM_MIN_WORDLEN,
350 EID_NUM_PRE_BREAK,
351 EID_NUM_POST_BREAK,
352 EID_HYPH_AUTO,
353 EID_HYPH_SPECIAL
356 //! this array must have an entry for every value of EID_OPTIONS.
357 // It is used to get the respective property name.
358 static const char * aEidToPropName[] =
360 UPN_IS_SPELL_AUTO, // EID_SPELL_AUTO
361 UPN_IS_GRAMMAR_AUTO, // EID_GRAMMAR_AUTO
362 UPN_IS_SPELL_UPPER_CASE, // EID_CAPITAL_WORDS
363 UPN_IS_SPELL_WITH_DIGITS, // EID_WORDS_WITH_DIGITS
364 UPN_IS_SPELL_SPECIAL, // EID_SPELL_SPECIAL
365 UPN_HYPH_MIN_WORD_LENGTH, // EID_NUM_MIN_WORDLEN,
366 UPN_HYPH_MIN_LEADING, // EID_NUM_PRE_BREAK
367 UPN_HYPH_MIN_TRAILING, // EID_NUM_POST_BREAK
368 UPN_IS_HYPH_AUTO, // EID_HYPH_AUTO
369 UPN_IS_HYPH_SPECIAL // EID_HYPH_SPECIAL
373 static inline String lcl_GetPropertyName( EID_OPTIONS eEntryId )
375 DBG_ASSERT( (unsigned int) eEntryId < SAL_N_ELEMENTS(aEidToPropName), "index out of range" );
376 return OUString::createFromAscii( aEidToPropName[ (int) eEntryId ] );
379 // class OptionsUserData -------------------------------------------------
381 class OptionsUserData
383 sal_uLong nVal;
385 void SetModified();
387 public:
388 OptionsUserData( sal_uLong nUserData ) : nVal( nUserData ) {}
389 OptionsUserData( sal_uInt16 nEID,
390 sal_Bool bHasNV, sal_uInt16 nNumVal,
391 sal_Bool bCheckable, sal_Bool bChecked );
393 sal_uLong GetUserData() const { return nVal; }
394 sal_uInt16 GetEntryId() const { return (sal_uInt16)(nVal >> 16); }
395 sal_Bool HasNumericValue() const { return (sal_Bool)(nVal >> 10) & 0x01; }
396 sal_uInt16 GetNumericValue() const { return (sal_uInt16)(nVal & 0xFF); }
397 sal_Bool IsChecked() const { return (sal_Bool)(nVal >> 8) & 0x01; }
398 sal_Bool IsCheckable() const { return (sal_Bool)(nVal >> 9) & 0x01; }
399 sal_Bool IsModified() const { return (sal_Bool)(nVal >> 11) & 0x01; }
401 void SetChecked( sal_Bool bVal );
402 void SetNumericValue( sal_uInt8 nNumVal );
405 OptionsUserData::OptionsUserData( sal_uInt16 nEID,
406 sal_Bool bHasNV, sal_uInt16 nNumVal,
407 sal_Bool bCheckable, sal_Bool bChecked )
409 DBG_ASSERT( nEID < 65000, "Entry Id out of range" );
410 DBG_ASSERT( nNumVal < 256, "value out of range" );
411 nVal = ((sal_uLong)(0xFFFF & nEID) << 16) |
412 ((sal_uLong)(bHasNV ? 1 : 0) << 10) |
413 ((sal_uLong)(bCheckable ? 1 : 0) << 9) |
414 ((sal_uLong)(bChecked ? 1 : 0) << 8) |
415 ((sal_uLong)(0xFF & nNumVal));
418 void OptionsUserData::SetChecked( sal_Bool bVal )
420 if (IsCheckable() && (IsChecked() != bVal))
422 nVal &= ~(1UL << 8);
423 nVal |= (sal_uLong)(bVal ? 1 : 0) << 8;
424 SetModified();
428 void OptionsUserData::SetNumericValue( sal_uInt8 nNumVal )
430 if (HasNumericValue() && (GetNumericValue() != nNumVal))
432 nVal &= 0xffffff00;
433 nVal |= (nNumVal);
434 SetModified();
438 void OptionsUserData::SetModified()
440 nVal |= (sal_uLong)1 << 11;
443 // class BrwString_Impl -------------------------------------------------
445 class BrwString_Impl : public SvLBoxString
447 public:
449 BrwString_Impl( SvTreeListEntry* pEntry, sal_uInt16 nFlags,
450 const String& rStr ) : SvLBoxString( pEntry, nFlags, rStr ) {}
452 virtual void Paint(
453 const Point& rPos, SvTreeListBox& rOutDev, const SvViewDataEntry* pView, const SvTreeListEntry* pEntry);
456 void BrwString_Impl::Paint(
457 const Point& rPos, SvTreeListBox& rDev, const SvViewDataEntry* /*pView*/,
458 const SvTreeListEntry* pEntry)
460 Point aPos(rPos);
461 aPos.X() += 20;
462 rDev.DrawText( aPos, GetText() );
463 if(pEntry->GetUserData())
465 Point aNewPos(aPos);
466 aNewPos.X() += rDev.GetTextWidth(GetText());
467 Font aOldFont( rDev.GetFont());
468 Font aFont( aOldFont );
469 aFont.SetWeight( WEIGHT_BOLD );
471 //??? convert the lower byte from the user date into a string
472 OptionsUserData aData( (sal_uLong) pEntry->GetUserData() );
473 if(aData.HasNumericValue())
475 OUStringBuffer sTxt;
476 sTxt.append(' ').append(static_cast<sal_Int32>(aData.GetNumericValue()));
477 rDev.SetFont( aFont );
478 rDev.DrawText( aNewPos, sTxt.makeStringAndClear() );
481 rDev.SetFont( aOldFont );
485 // ServiceInfo_Impl ----------------------------------------------------
487 struct ServiceInfo_Impl
489 OUString sDisplayName;
490 OUString sSpellImplName;
491 OUString sHyphImplName;
492 OUString sThesImplName;
493 OUString sGrammarImplName;
494 uno::Reference< XSpellChecker > xSpell;
495 uno::Reference< XHyphenator > xHyph;
496 uno::Reference< XThesaurus > xThes;
497 uno::Reference< XProofreader > xGrammar;
498 sal_Bool bConfigured;
500 ServiceInfo_Impl() : bConfigured(sal_False) {}
503 typedef std::vector< ServiceInfo_Impl > ServiceInfoArr;
504 typedef std::map< sal_Int16 /*LanguageType*/, Sequence< OUString > > LangImplNameTable;
507 // SvxLinguData_Impl ----------------------------------------------------
509 class SvxLinguData_Impl
511 //contains services and implementation names sorted by implementation names
512 ServiceInfoArr aDisplayServiceArr;
513 sal_uLong nDisplayServices;
515 Sequence< Locale > aAllServiceLocales;
516 LangImplNameTable aCfgSpellTable;
517 LangImplNameTable aCfgHyphTable;
518 LangImplNameTable aCfgThesTable;
519 LangImplNameTable aCfgGrammarTable;
520 uno::Reference< XLinguServiceManager2 > xLinguSrvcMgr;
523 sal_Bool AddRemove( Sequence< OUString > &rConfigured,
524 const OUString &rImplName, sal_Bool bAdd );
526 public:
527 SvxLinguData_Impl();
528 SvxLinguData_Impl( const SvxLinguData_Impl &rData );
529 ~SvxLinguData_Impl();
531 SvxLinguData_Impl & operator = (const SvxLinguData_Impl &rData);
533 uno::Reference<XLinguServiceManager2> & GetManager() { return xLinguSrvcMgr; }
535 void SetChecked( const Sequence< OUString > &rConfiguredServices );
536 void Reconfigure( const OUString &rDisplayName, sal_Bool bEnable );
538 const Sequence<Locale> & GetAllSupportedLocales() const { return aAllServiceLocales; }
540 const LangImplNameTable & GetSpellTable() const { return aCfgSpellTable; }
541 LangImplNameTable & GetSpellTable() { return aCfgSpellTable; }
542 const LangImplNameTable & GetHyphTable() const { return aCfgHyphTable; }
543 LangImplNameTable & GetHyphTable() { return aCfgHyphTable; }
544 const LangImplNameTable & GetThesTable() const { return aCfgThesTable; }
545 LangImplNameTable & GetThesTable() { return aCfgThesTable; }
546 const LangImplNameTable & GetGrammarTable() const { return aCfgGrammarTable; }
547 LangImplNameTable & GetGrammarTable() { return aCfgGrammarTable; }
549 const ServiceInfoArr & GetDisplayServiceArray() const { return aDisplayServiceArr; }
550 ServiceInfoArr & GetDisplayServiceArray() { return aDisplayServiceArr; }
552 const sal_uLong & GetDisplayServiceCount() const { return nDisplayServices; }
553 void SetDisplayServiceCount( sal_uLong nVal ) { nDisplayServices = nVal; }
555 // returns the list of service implementation names for the specified
556 // language and service (TYPE_SPELL, TYPE_HYPH, TYPE_THES) sorted in
557 // the proper order for the SvxEditModulesDlg (the ones from the
558 // configuration (keeping that order!) first and then the other ones.
559 // I.e. the ones available but not configured in arbitrary order).
560 // They available ones may contain names that do not(!) support that
561 // language.
562 Sequence< OUString > GetSortedImplNames( sal_Int16 nLang, sal_uInt8 nType );
564 ServiceInfo_Impl * GetInfoByImplName( const OUString &rSvcImplName );
568 static sal_Int32 lcl_SeqGetIndex( const Sequence< OUString > &rSeq, const OUString &rTxt )
570 sal_Int32 nRes = -1;
571 sal_Int32 nLen = rSeq.getLength();
572 const OUString *pString = rSeq.getConstArray();
573 for (sal_Int32 i = 0; i < nLen && nRes == -1; ++i)
575 if (pString[i] == rTxt)
576 nRes = i;
578 return nRes;
582 Sequence< OUString > SvxLinguData_Impl::GetSortedImplNames( sal_Int16 nLang, sal_uInt8 nType )
584 LangImplNameTable *pTable = 0;
585 switch (nType)
587 case TYPE_SPELL : pTable = &aCfgSpellTable; break;
588 case TYPE_HYPH : pTable = &aCfgHyphTable; break;
589 case TYPE_THES : pTable = &aCfgThesTable; break;
590 case TYPE_GRAMMAR : pTable = &aCfgGrammarTable; break;
592 Sequence< OUString > aRes;
593 if (pTable->count( nLang ))
594 aRes = (*pTable)[ nLang ]; // add configured services
595 sal_Int32 nIdx = aRes.getLength();
596 DBG_ASSERT( (sal_Int32) nDisplayServices >= nIdx, "size mismatch" );
597 aRes.realloc( nDisplayServices );
598 OUString *pRes = aRes.getArray();
600 // add not configured services
601 for (sal_Int32 i = 0; i < (sal_Int32) nDisplayServices; ++i)
603 const ServiceInfo_Impl &rInfo = aDisplayServiceArr[ i ];
604 OUString aImplName;
605 switch (nType)
607 case TYPE_SPELL : aImplName = rInfo.sSpellImplName; break;
608 case TYPE_HYPH : aImplName = rInfo.sHyphImplName; break;
609 case TYPE_THES : aImplName = rInfo.sThesImplName; break;
610 case TYPE_GRAMMAR : aImplName = rInfo.sGrammarImplName; break;
613 if (!aImplName.isEmpty() && (lcl_SeqGetIndex( aRes, aImplName) == -1)) // name not yet added
615 DBG_ASSERT( nIdx < aRes.getLength(), "index out of range" );
616 if (nIdx < aRes.getLength())
617 pRes[ nIdx++ ] = aImplName;
620 // don't forget to put aRes back to its actual size just in case you allocated too much
621 // since all of the names may have already been added
622 // otherwise you get duplicate entries in the edit dialog
623 aRes.realloc( nIdx );
624 return aRes;
628 ServiceInfo_Impl * SvxLinguData_Impl::GetInfoByImplName( const OUString &rSvcImplName )
630 ServiceInfo_Impl* pInfo = 0;
631 for (sal_uLong i = 0; i < nDisplayServices && !pInfo; ++i)
633 ServiceInfo_Impl &rTmp = aDisplayServiceArr[ i ];
634 if (rTmp.sSpellImplName == rSvcImplName ||
635 rTmp.sHyphImplName == rSvcImplName ||
636 rTmp.sThesImplName == rSvcImplName ||
637 rTmp.sGrammarImplName == rSvcImplName)
638 pInfo = &rTmp;
640 return pInfo;
644 //-----------------------------------------------------------------------------
646 static void lcl_MergeLocales(Sequence< Locale >& aAllLocales, const Sequence< Locale >& rAdd)
648 const Locale* pAdd = rAdd.getConstArray();
649 Sequence<Locale> aLocToAdd(rAdd.getLength());
650 const Locale* pAllLocales = aAllLocales.getConstArray();
651 Locale* pLocToAdd = aLocToAdd.getArray();
652 sal_Int32 nFound = 0;
653 sal_Int32 i;
654 for(i = 0; i < rAdd.getLength(); i++)
656 sal_Bool bFound = sal_False;
657 for(sal_Int32 j = 0; j < aAllLocales.getLength() && !bFound; j++)
659 bFound = pAdd[i].Language == pAllLocales[j].Language &&
660 pAdd[i].Country == pAllLocales[j].Country;
662 if(!bFound)
664 pLocToAdd[nFound++] = pAdd[i];
667 sal_Int32 nLength = aAllLocales.getLength();
668 aAllLocales.realloc( nLength + nFound);
669 Locale* pAllLocales2 = aAllLocales.getArray();
670 for(i = 0; i < nFound; i++)
671 pAllLocales2[nLength++] = pLocToAdd[i];
674 static void lcl_MergeDisplayArray(
675 SvxLinguData_Impl &rData,
676 const ServiceInfo_Impl &rToAdd )
678 sal_uLong nCnt = 0;
680 ServiceInfoArr &rSvcInfoArr = rData.GetDisplayServiceArray();
681 sal_uLong nEntries = rData.GetDisplayServiceCount();
683 ServiceInfo_Impl* pEntry;
684 for (sal_uLong i = 0; i < nEntries; ++i)
686 pEntry = &rSvcInfoArr[i];
687 if (pEntry && pEntry->sDisplayName == rToAdd.sDisplayName)
689 if(rToAdd.xSpell.is())
691 DBG_ASSERT( !pEntry->xSpell.is() &&
692 pEntry->sSpellImplName.isEmpty(),
693 "merge conflict" );
694 pEntry->sSpellImplName = rToAdd.sSpellImplName;
695 pEntry->xSpell = rToAdd.xSpell;
697 if(rToAdd.xGrammar.is())
699 DBG_ASSERT( !pEntry->xGrammar.is() &&
700 pEntry->sGrammarImplName.isEmpty(),
701 "merge conflict" );
702 pEntry->sGrammarImplName = rToAdd.sGrammarImplName;
703 pEntry->xGrammar = rToAdd.xGrammar;
705 if(rToAdd.xHyph.is())
707 DBG_ASSERT( !pEntry->xHyph.is() &&
708 pEntry->sHyphImplName.isEmpty(),
709 "merge conflict" );
710 pEntry->sHyphImplName = rToAdd.sHyphImplName;
711 pEntry->xHyph = rToAdd.xHyph;
713 if(rToAdd.xThes.is())
715 DBG_ASSERT( !pEntry->xThes.is() &&
716 pEntry->sThesImplName.isEmpty(),
717 "merge conflict" );
718 pEntry->sThesImplName = rToAdd.sThesImplName;
719 pEntry->xThes = rToAdd.xThes;
721 return ;
723 ++nCnt;
725 rData.GetDisplayServiceArray().push_back( rToAdd );
726 rData.SetDisplayServiceCount( nCnt + 1 );
729 SvxLinguData_Impl::SvxLinguData_Impl() :
730 nDisplayServices (0)
732 uno::Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
733 xLinguSrvcMgr = LinguServiceManager::create(xContext);
735 const Locale& rCurrentLocale = Application::GetSettings().GetLanguageTag().getLocale();
736 Sequence<Any> aArgs(2);//second arguments has to be empty!
737 aArgs.getArray()[0] <<= SvxGetLinguPropertySet();
739 //read spell checker
740 Sequence< OUString > aSpellNames = xLinguSrvcMgr->getAvailableServices(
741 cSpell, Locale() );
742 const OUString* pSpellNames = aSpellNames.getConstArray();
744 sal_Int32 nIdx;
745 for(nIdx = 0; nIdx < aSpellNames.getLength(); nIdx++)
747 ServiceInfo_Impl aInfo;
748 aInfo.sSpellImplName = pSpellNames[nIdx];
749 aInfo.xSpell = uno::Reference<XSpellChecker>(
750 xContext->getServiceManager()->createInstanceWithArgumentsAndContext(aInfo.sSpellImplName, aArgs, xContext), UNO_QUERY);
752 uno::Reference<XServiceDisplayName> xDispName(aInfo.xSpell, UNO_QUERY);
753 if(xDispName.is())
754 aInfo.sDisplayName = xDispName->getServiceDisplayName( rCurrentLocale );
756 const Sequence< Locale > aLocales( aInfo.xSpell->getLocales() );
757 //! suppress display of entries with no supported languages (see feature 110994)
758 if (aLocales.getLength())
760 lcl_MergeLocales( aAllServiceLocales, aLocales );
761 lcl_MergeDisplayArray( *this, aInfo );
765 //read grammar checker
766 Sequence< OUString > aGrammarNames = xLinguSrvcMgr->getAvailableServices(
767 cGrammar, Locale() );
768 const OUString* pGrammarNames = aGrammarNames.getConstArray();
769 for(nIdx = 0; nIdx < aGrammarNames.getLength(); nIdx++)
771 ServiceInfo_Impl aInfo;
772 aInfo.sGrammarImplName = pGrammarNames[nIdx];
773 aInfo.xGrammar = uno::Reference<XProofreader>(
774 xContext->getServiceManager()->createInstanceWithArgumentsAndContext(aInfo.sGrammarImplName, aArgs, xContext), UNO_QUERY);
776 uno::Reference<XServiceDisplayName> xDispName(aInfo.xGrammar, UNO_QUERY);
777 if(xDispName.is())
778 aInfo.sDisplayName = xDispName->getServiceDisplayName( rCurrentLocale );
780 const Sequence< Locale > aLocales( aInfo.xGrammar->getLocales() );
781 //! suppress display of entries with no supported languages (see feature 110994)
782 if (aLocales.getLength())
784 lcl_MergeLocales( aAllServiceLocales, aLocales );
785 lcl_MergeDisplayArray( *this, aInfo );
789 //read hyphenator
790 Sequence< OUString > aHyphNames = xLinguSrvcMgr->getAvailableServices(
791 cHyph, Locale() );
792 const OUString* pHyphNames = aHyphNames.getConstArray();
793 for(nIdx = 0; nIdx < aHyphNames.getLength(); nIdx++)
795 ServiceInfo_Impl aInfo;
796 aInfo.sHyphImplName = pHyphNames[nIdx];
797 aInfo.xHyph = uno::Reference<XHyphenator>(
798 xContext->getServiceManager()->createInstanceWithArgumentsAndContext(aInfo.sHyphImplName, aArgs, xContext), UNO_QUERY);
800 uno::Reference<XServiceDisplayName> xDispName(aInfo.xHyph, UNO_QUERY);
801 if(xDispName.is())
802 aInfo.sDisplayName = xDispName->getServiceDisplayName( rCurrentLocale );
804 const Sequence< Locale > aLocales( aInfo.xHyph->getLocales() );
805 //! suppress display of entries with no supported languages (see feature 110994)
806 if (aLocales.getLength())
808 lcl_MergeLocales( aAllServiceLocales, aLocales );
809 lcl_MergeDisplayArray( *this, aInfo );
813 //read thesauri
814 Sequence< OUString > aThesNames = xLinguSrvcMgr->getAvailableServices(
815 cThes, Locale() );
816 const OUString* pThesNames = aThesNames.getConstArray();
817 for(nIdx = 0; nIdx < aThesNames.getLength(); nIdx++)
819 ServiceInfo_Impl aInfo;
820 aInfo.sThesImplName = pThesNames[nIdx];
821 aInfo.xThes = uno::Reference<XThesaurus>(
822 xContext->getServiceManager()->createInstanceWithArgumentsAndContext(aInfo.sThesImplName, aArgs, xContext), UNO_QUERY);
824 uno::Reference<XServiceDisplayName> xDispName(aInfo.xThes, UNO_QUERY);
825 if(xDispName.is())
826 aInfo.sDisplayName = xDispName->getServiceDisplayName( rCurrentLocale );
828 const Sequence< Locale > aLocales( aInfo.xThes->getLocales() );
829 //! suppress display of entries with no supported languages (see feature 110994)
830 if (aLocales.getLength())
832 lcl_MergeLocales( aAllServiceLocales, aLocales );
833 lcl_MergeDisplayArray( *this, aInfo );
837 Sequence< OUString > aCfgSvcs;
838 const Locale* pAllLocales = aAllServiceLocales.getConstArray();
839 for(sal_Int32 nLocale = 0; nLocale < aAllServiceLocales.getLength(); nLocale++)
841 sal_Int16 nLang = LanguageTag( pAllLocales[nLocale] ).getLanguageType();
843 aCfgSvcs = xLinguSrvcMgr->getConfiguredServices(cSpell, pAllLocales[nLocale]);
844 SetChecked( aCfgSvcs );
845 if (aCfgSvcs.getLength())
846 aCfgSpellTable[ nLang ] = aCfgSvcs;
848 aCfgSvcs = xLinguSrvcMgr->getConfiguredServices(cGrammar, pAllLocales[nLocale]);
849 SetChecked( aCfgSvcs );
850 if (aCfgSvcs.getLength())
851 aCfgGrammarTable[ nLang ] = aCfgSvcs;
853 aCfgSvcs = xLinguSrvcMgr->getConfiguredServices(cHyph, pAllLocales[nLocale]);
854 SetChecked( aCfgSvcs );
855 if (aCfgSvcs.getLength())
856 aCfgHyphTable[ nLang ] = aCfgSvcs;
858 aCfgSvcs = xLinguSrvcMgr->getConfiguredServices(cThes, pAllLocales[nLocale]);
859 SetChecked( aCfgSvcs );
860 if (aCfgSvcs.getLength())
861 aCfgThesTable[ nLang ] = aCfgSvcs;
865 SvxLinguData_Impl::SvxLinguData_Impl( const SvxLinguData_Impl &rData ) :
866 aDisplayServiceArr (rData.aDisplayServiceArr),
867 nDisplayServices (rData.nDisplayServices),
868 aAllServiceLocales (rData.aAllServiceLocales),
869 aCfgSpellTable (rData.aCfgSpellTable),
870 aCfgHyphTable (rData.aCfgHyphTable),
871 aCfgThesTable (rData.aCfgThesTable),
872 aCfgGrammarTable (rData.aCfgGrammarTable),
873 xLinguSrvcMgr (rData.xLinguSrvcMgr)
877 SvxLinguData_Impl & SvxLinguData_Impl::operator = (const SvxLinguData_Impl &rData)
879 xLinguSrvcMgr = rData.xLinguSrvcMgr;
880 aAllServiceLocales = rData.aAllServiceLocales;
881 aCfgSpellTable = rData.aCfgSpellTable;
882 aCfgHyphTable = rData.aCfgHyphTable;
883 aCfgThesTable = rData.aCfgThesTable;
884 aCfgGrammarTable = rData.aCfgGrammarTable;
885 aDisplayServiceArr = rData.aDisplayServiceArr;
886 nDisplayServices = rData.nDisplayServices;
887 return *this;
890 SvxLinguData_Impl::~SvxLinguData_Impl()
894 void SvxLinguData_Impl::SetChecked(const Sequence<OUString>& rConfiguredServices)
896 const OUString* pConfiguredServices = rConfiguredServices.getConstArray();
897 for(sal_Int32 n = 0; n < rConfiguredServices.getLength(); n++)
899 ServiceInfo_Impl* pEntry;
900 for (sal_uLong i = 0; i < nDisplayServices; ++i)
902 pEntry = &aDisplayServiceArr[i];
903 if (pEntry && !pEntry->bConfigured)
905 const OUString &rSrvcImplName = pConfiguredServices[n];
906 if (!rSrvcImplName.isEmpty() &&
907 (pEntry->sSpellImplName == rSrvcImplName ||
908 pEntry->sGrammarImplName == rSrvcImplName ||
909 pEntry->sHyphImplName == rSrvcImplName ||
910 pEntry->sThesImplName == rSrvcImplName))
912 pEntry->bConfigured = sal_True;
913 break;
920 sal_Bool SvxLinguData_Impl::AddRemove(
921 Sequence< OUString > &rConfigured,
922 const OUString &rImplName, sal_Bool bAdd )
924 sal_Bool bRet = sal_False; // modified?
926 sal_Int32 nEntries = rConfigured.getLength();
927 sal_Int32 nPos = lcl_SeqGetEntryPos(rConfigured, rImplName);
928 if (bAdd && nPos < 0) // add new entry
930 rConfigured.realloc( ++nEntries );
931 OUString *pConfigured = rConfigured.getArray();
932 pConfigured = rConfigured.getArray();
933 pConfigured[nEntries - 1] = rImplName;
934 bRet = sal_True;
936 else if (!bAdd && nPos >= 0) // remove existing entry
938 OUString *pConfigured = rConfigured.getArray();
939 for (sal_Int32 i = nPos; i < nEntries - 1; ++i)
940 pConfigured[i] = pConfigured[i + 1];
941 rConfigured.realloc(--nEntries);
942 bRet = sal_True;
945 return bRet;
949 void SvxLinguData_Impl::Reconfigure( const OUString &rDisplayName, sal_Bool bEnable )
951 DBG_ASSERT( !rDisplayName.isEmpty(), "empty DisplayName" );
953 ServiceInfo_Impl *pInfo = 0;
954 ServiceInfo_Impl *pTmp = 0;
955 for (sal_uLong i = 0; i < nDisplayServices; ++i)
957 pTmp = &aDisplayServiceArr[i];
958 if (pTmp && pTmp->sDisplayName == rDisplayName)
960 pInfo = pTmp;
961 break;
964 DBG_ASSERT( pInfo, "DisplayName entry not found" );
965 if (pInfo)
967 pInfo->bConfigured = bEnable;
969 Sequence< Locale > aLocales;
970 const Locale *pLocale = 0;
971 sal_Int32 nLocales = 0;
972 sal_Int32 i;
974 // update configured spellchecker entries
975 if (pInfo->xSpell.is())
977 aLocales = pInfo->xSpell->getLocales();
978 pLocale = aLocales.getConstArray();
979 nLocales = aLocales.getLength();
980 for (i = 0; i < nLocales; ++i)
982 sal_Int16 nLang = LanguageTag( pLocale[i] ).getLanguageType();
983 if (!aCfgSpellTable.count( nLang ) && bEnable)
984 aCfgSpellTable[ nLang ] = Sequence< OUString >();
985 if (aCfgSpellTable.count( nLang ))
986 AddRemove( aCfgSpellTable[ nLang ], pInfo->sSpellImplName, bEnable );
990 // update configured grammar checker entries
991 if (pInfo->xGrammar.is())
993 aLocales = pInfo->xGrammar->getLocales();
994 pLocale = aLocales.getConstArray();
995 nLocales = aLocales.getLength();
996 for (i = 0; i < nLocales; ++i)
998 sal_Int16 nLang = LanguageTag( pLocale[i] ).getLanguageType();
999 if (!aCfgGrammarTable.count( nLang ) && bEnable)
1000 aCfgGrammarTable[ nLang ] = Sequence< OUString >();
1001 if (aCfgGrammarTable.count( nLang ))
1002 AddRemove( aCfgGrammarTable[ nLang ], pInfo->sGrammarImplName, bEnable );
1006 // update configured hyphenator entries
1007 if (pInfo->xHyph.is())
1009 aLocales = pInfo->xHyph->getLocales();
1010 pLocale = aLocales.getConstArray();
1011 nLocales = aLocales.getLength();
1012 for (i = 0; i < nLocales; ++i)
1014 sal_Int16 nLang = LanguageTag( pLocale[i] ).getLanguageType();
1015 if (!aCfgHyphTable.count( nLang ) && bEnable)
1016 aCfgHyphTable[ nLang ] = Sequence< OUString >();
1017 if (aCfgHyphTable.count( nLang ))
1018 AddRemove( aCfgHyphTable[ nLang ], pInfo->sHyphImplName, bEnable );
1022 // update configured spellchecker entries
1023 if (pInfo->xThes.is())
1025 aLocales = pInfo->xThes->getLocales();
1026 pLocale = aLocales.getConstArray();
1027 nLocales = aLocales.getLength();
1028 for (i = 0; i < nLocales; ++i)
1030 sal_Int16 nLang = LanguageTag( pLocale[i] ).getLanguageType();
1031 if (!aCfgThesTable.count( nLang ) && bEnable)
1032 aCfgThesTable[ nLang ] = Sequence< OUString >();
1033 if (aCfgThesTable.count( nLang ))
1034 AddRemove( aCfgThesTable[ nLang ], pInfo->sThesImplName, bEnable );
1041 // class SvxLinguTabPage -------------------------------------------------
1043 SvxLinguTabPage::SvxLinguTabPage( Window* pParent,
1044 const SfxItemSet& rSet ):
1046 SfxTabPage( pParent, CUI_RES( RID_SFXPAGE_LINGU ), rSet ),
1048 aLinguisticFL ( this, CUI_RES( FL_LINGUISTIC ) ),
1049 aLinguModulesFT ( this, CUI_RES( FT_LINGU_MODULES ) ),
1050 aLinguModulesCLB ( this, CUI_RES( CLB_LINGU_MODULES ) ),
1051 aLinguModulesEditPB ( this, CUI_RES( PB_LINGU_MODULES_EDIT ) ),
1052 aLinguDicsFT ( this, CUI_RES( FT_LINGU_DICS ) ),
1053 aLinguDicsCLB ( this, CUI_RES( CLB_LINGU_DICS ) ),
1054 aLinguDicsNewPB ( this, CUI_RES( PB_LINGU_DICS_NEW_DIC ) ),
1055 aLinguDicsEditPB ( this, CUI_RES( PB_LINGU_DICS_EDIT_DIC ) ),
1056 aLinguDicsDelPB ( this, CUI_RES( PB_LINGU_DICS_DEL_DIC ) ),
1057 aLinguOptionsFT ( this, CUI_RES( FT_LINGU_OPTIONS ) ),
1058 aLinguOptionsCLB ( this, CUI_RES( CLB_LINGU_OPTIONS ) ),
1059 aLinguOptionsEditPB ( this, CUI_RES( PB_LINGU_OPTIONS_EDIT ) ),
1060 aMoreDictsLink ( this, CUI_RES( FT_LINGU_OPTIONS_MOREDICTS ) ),
1061 sCapitalWords ( CUI_RES( STR_CAPITAL_WORDS ) ),
1062 sWordsWithDigits ( CUI_RES( STR_WORDS_WITH_DIGITS ) ),
1063 sSpellSpecial ( CUI_RES( STR_SPELL_SPECIAL ) ),
1064 sSpellAuto ( CUI_RES( STR_SPELL_AUTO ) ),
1065 sGrammarAuto ( CUI_RES( STR_GRAMMAR_AUTO ) ),
1066 sNumMinWordlen ( CUI_RES( STR_NUM_MIN_WORDLEN ) ),
1067 sNumPreBreak ( CUI_RES( STR_NUM_PRE_BREAK ) ),
1068 sNumPostBreak ( CUI_RES( STR_NUM_POST_BREAK ) ),
1069 sHyphAuto ( CUI_RES( STR_HYPH_AUTO ) ),
1070 sHyphSpecial ( CUI_RES( STR_HYPH_SPECIAL ) ),
1072 pLinguData ( NULL )
1074 pCheckButtonData = NULL;
1076 aLinguModulesCLB.SetStyle( aLinguModulesCLB.GetStyle()|WB_CLIPCHILDREN|WB_HSCROLL|WB_FORCE_MAKEVISIBLE );
1077 aLinguModulesCLB.SetHelpId(HID_CLB_LINGU_MODULES );
1078 aLinguModulesCLB.SetHighlightRange();
1079 aLinguModulesCLB.SetSelectHdl( LINK( this, SvxLinguTabPage, SelectHdl_Impl ));
1080 aLinguModulesCLB.SetDoubleClickHdl(LINK(this, SvxLinguTabPage, BoxDoubleClickHdl_Impl));
1081 aLinguModulesCLB.SetCheckButtonHdl(LINK(this, SvxLinguTabPage, BoxCheckButtonHdl_Impl));
1083 aLinguModulesEditPB.SetClickHdl( LINK( this, SvxLinguTabPage, ClickHdl_Impl ));
1084 aLinguOptionsEditPB.SetClickHdl( LINK( this, SvxLinguTabPage, ClickHdl_Impl ));
1086 aLinguDicsCLB.SetStyle( aLinguDicsCLB.GetStyle()|WB_CLIPCHILDREN|WB_HSCROLL|WB_FORCE_MAKEVISIBLE );
1087 aLinguDicsCLB.SetHelpId(HID_CLB_EDIT_MODULES_DICS );
1088 aLinguDicsCLB.SetHighlightRange();
1089 aLinguDicsCLB.SetSelectHdl( LINK( this, SvxLinguTabPage, SelectHdl_Impl ));
1090 aLinguDicsCLB.SetCheckButtonHdl(LINK(this, SvxLinguTabPage, BoxCheckButtonHdl_Impl));
1092 aLinguDicsNewPB.SetClickHdl( LINK( this, SvxLinguTabPage, ClickHdl_Impl ));
1093 aLinguDicsEditPB.SetClickHdl( LINK( this, SvxLinguTabPage, ClickHdl_Impl ));
1094 aLinguDicsDelPB.SetClickHdl( LINK( this, SvxLinguTabPage, ClickHdl_Impl ));
1096 aLinguOptionsCLB.SetStyle( aLinguOptionsCLB.GetStyle()|WB_CLIPCHILDREN|WB_HSCROLL|WB_FORCE_MAKEVISIBLE );
1097 aLinguOptionsCLB.SetHelpId(HID_CLB_LINGU_OPTIONS );
1098 aLinguOptionsCLB.SetHighlightRange();
1099 aLinguOptionsCLB.SetSelectHdl( LINK( this, SvxLinguTabPage, SelectHdl_Impl ));
1100 aLinguOptionsCLB.SetDoubleClickHdl(LINK(this, SvxLinguTabPage, BoxDoubleClickHdl_Impl));
1102 if ( SvtExtendedSecurityOptions().GetOpenHyperlinkMode()
1103 != SvtExtendedSecurityOptions::OPEN_NEVER )
1105 aMoreDictsLink.SetURL( String(
1106 "http://extensions.libreoffice.org/dictionaries/" ) );
1107 aMoreDictsLink.SetClickHdl( LINK( this, SvxLinguTabPage, OpenURLHdl_Impl ) );
1109 else
1110 aMoreDictsLink.Hide();
1112 String sAccessibleNameModuleEdit( CUI_RES( STR_LINGU_MODULES_EDIT ) );
1113 String sAccessibleNameDicsEdit ( CUI_RES( STR_LINGU_DICS_EDIT_DIC ) );
1114 String sAccessibleNameOptionEdit( CUI_RES( STR_LINGU_OPTIONS_EDIT ) );
1116 aLinguModulesEditPB.SetAccessibleName(sAccessibleNameModuleEdit);
1117 aLinguDicsEditPB.SetAccessibleName(sAccessibleNameDicsEdit);
1118 aLinguOptionsEditPB.SetAccessibleName(sAccessibleNameOptionEdit);
1120 xProp = SvxGetLinguPropertySet();
1121 xDicList = uno::Reference< XDictionaryList >( SvxGetDictionaryList(), UNO_QUERY );
1122 if (xDicList.is())
1124 // keep references to all **currently** available dictionaries,
1125 // since the diclist may get changed meanwhile (e.g. through the API).
1126 // We want the dialog to operate on the same set of dictionaries it
1127 // was started with.
1128 // Also we have to take care to not loose the last reference when
1129 // someone else removes a dictionary from the list.
1130 // removed dics will be replaced by NULL new entries be added to the end
1131 // Thus we may use indizes as consistent references.
1132 aDics = xDicList->getDictionaries();
1134 UpdateDicBox_Impl();
1136 else
1138 aLinguDicsFT.Disable();
1139 aLinguDicsCLB.Disable();
1140 aLinguDicsNewPB.Disable();
1141 aLinguDicsEditPB.Disable();
1142 aLinguDicsDelPB.Disable();
1145 const SfxSpellCheckItem* pItem = 0;
1147 SfxItemState eItemState = rSet.GetItemState( GetWhich( SID_ATTR_SPELL ),
1148 sal_False, (const SfxPoolItem**)&pItem );
1150 // is it about a default-item?
1151 if ( eItemState == SFX_ITEM_DEFAULT )
1152 pItem = (const SfxSpellCheckItem*)&(rSet.Get( GetWhich( SID_ATTR_SPELL ) ) );
1153 else if ( eItemState == SFX_ITEM_DONTCARE )
1154 pItem = NULL;
1156 FreeResource();
1159 // -----------------------------------------------------------------------
1161 SvxLinguTabPage::~SvxLinguTabPage()
1163 if (pLinguData)
1164 delete pLinguData;
1167 //------------------------------------------------------------------------
1169 // don't throw away overloaded
1170 sal_uInt16* SvxLinguTabPage::GetRanges()
1172 //TL???
1173 return pRanges;
1176 //------------------------------------------------------------------------
1178 SfxTabPage* SvxLinguTabPage::Create( Window* pParent,
1179 const SfxItemSet& rAttrSet )
1181 return ( new SvxLinguTabPage( pParent, rAttrSet ) );
1184 //------------------------------------------------------------------------
1186 sal_Bool SvxLinguTabPage::FillItemSet( SfxItemSet& rCoreSet )
1188 sal_Bool bModified = sal_True; // !!!!
1190 // if not HideGroups was called with GROUP_MODULES...
1191 if (aLinguModulesCLB.IsVisible())
1193 DBG_ASSERT( pLinguData, "pLinguData not yet initialized" );
1194 if (!pLinguData)
1195 pLinguData = new SvxLinguData_Impl;
1197 LangImplNameTable::const_iterator aIt;
1199 // update spellchecker configuration entries
1200 const LangImplNameTable *pTable = &pLinguData->GetSpellTable();
1201 for (aIt = pTable->begin(); aIt != pTable->end(); ++aIt)
1203 sal_Int16 nLang = aIt->first;
1204 const Sequence< OUString > aImplNames( aIt->second );
1205 uno::Reference< XLinguServiceManager2 > xMgr( pLinguData->GetManager() );
1206 Locale aLocale( LanguageTag(nLang).getLocale() );
1207 if (xMgr.is())
1208 xMgr->setConfiguredServices( cSpell, aLocale, aImplNames );
1211 // update grammar checker configuration entries
1212 pTable = &pLinguData->GetGrammarTable();
1213 for (aIt = pTable->begin(); aIt != pTable->end(); ++aIt)
1215 sal_Int16 nLang = aIt->first;
1216 const Sequence< OUString > aImplNames( aIt->second );
1217 uno::Reference< XLinguServiceManager2 > xMgr( pLinguData->GetManager() );
1218 Locale aLocale( LanguageTag(nLang).getLocale() );
1219 if (xMgr.is())
1220 xMgr->setConfiguredServices( cGrammar, aLocale, aImplNames );
1223 // update hyphenator configuration entries
1224 pTable = &pLinguData->GetHyphTable();
1225 for (aIt = pTable->begin(); aIt != pTable->end(); ++aIt)
1227 sal_Int16 nLang = aIt->first;
1228 const Sequence< OUString > aImplNames( aIt->second );
1229 uno::Reference< XLinguServiceManager2 > xMgr( pLinguData->GetManager() );
1230 Locale aLocale( LanguageTag(nLang).getLocale() );
1231 if (xMgr.is())
1232 xMgr->setConfiguredServices( cHyph, aLocale, aImplNames );
1235 // update thesaurus configuration entries
1236 pTable = &pLinguData->GetThesTable();
1237 for (aIt = pTable->begin(); aIt != pTable->end(); ++aIt)
1239 sal_Int16 nLang = aIt->first;
1240 const Sequence< OUString > aImplNames( aIt->second );
1241 uno::Reference< XLinguServiceManager2 > xMgr( pLinguData->GetManager() );
1242 Locale aLocale( LanguageTag(nLang).getLocale() );
1243 if (xMgr.is())
1244 xMgr->setConfiguredServices( cThes, aLocale, aImplNames );
1250 // activate dictionaries according to checkbox state
1252 Sequence< OUString > aActiveDics;
1253 sal_Int32 nActiveDics = 0;
1254 sal_uLong nEntries = aLinguDicsCLB.GetEntryCount();
1255 for (sal_uLong i = 0; i < nEntries; ++i)
1257 sal_Int32 nDics = aDics.getLength();
1259 aActiveDics.realloc( nDics );
1260 OUString *pActiveDic = aActiveDics.getArray();
1262 SvTreeListEntry *pEntry = aLinguDicsCLB.GetEntry( i );
1263 if (pEntry)
1265 DicUserData aData( (sal_uLong)pEntry->GetUserData() );
1266 if (aData.GetEntryId() < nDics)
1268 sal_Bool bChecked = aLinguDicsCLB.IsChecked( (sal_uInt16) i );
1269 uno::Reference< XDictionary > xDic( aDics.getConstArray()[ i ] );
1270 if (xDic.is())
1272 if (SvxGetIgnoreAllList() == xDic)
1273 bChecked = sal_True;
1274 xDic->setActive( bChecked );
1276 if (bChecked)
1278 String aDicName( xDic->getName() );
1279 pActiveDic[ nActiveDics++ ] = aDicName;
1286 aActiveDics.realloc( nActiveDics );
1287 Any aTmp;
1288 aTmp <<= aActiveDics;
1289 SvtLinguConfig aLngCfg;
1290 aLngCfg.SetProperty( UPH_ACTIVE_DICTIONARIES, aTmp );
1293 nEntries = aLinguOptionsCLB.GetEntryCount();
1294 for (sal_uInt16 j = 0; j < nEntries; ++j)
1296 SvTreeListEntry *pEntry = aLinguOptionsCLB.GetEntry( j );
1298 OptionsUserData aData( (sal_uLong)pEntry->GetUserData() );
1299 String aPropName( lcl_GetPropertyName( (EID_OPTIONS) aData.GetEntryId() ) );
1301 Any aAny;
1302 if (aData.IsCheckable())
1304 sal_Bool bChecked = aLinguOptionsCLB.IsChecked( j );
1305 aAny <<= bChecked;
1307 else if (aData.HasNumericValue())
1309 sal_Int16 nVal = aData.GetNumericValue();
1310 aAny <<= nVal;
1313 if (xProp.is())
1314 xProp->setPropertyValue( aPropName, aAny );
1315 aLngCfg.SetProperty( aPropName, aAny );
1318 SvTreeListEntry *pPreBreakEntry = aLinguOptionsCLB.GetEntry( (sal_uInt16) EID_NUM_PRE_BREAK );
1319 SvTreeListEntry *pPostBreakEntry = aLinguOptionsCLB.GetEntry( (sal_uInt16) EID_NUM_POST_BREAK );
1320 DBG_ASSERT( pPreBreakEntry, "NULL Pointer" );
1321 DBG_ASSERT( pPostBreakEntry, "NULL Pointer" );
1322 if (pPreBreakEntry && pPostBreakEntry)
1324 OptionsUserData aPreBreakData( (sal_uLong)pPreBreakEntry->GetUserData() );
1325 OptionsUserData aPostBreakData( (sal_uLong)pPostBreakEntry->GetUserData() );
1326 if ( aPreBreakData.IsModified() || aPostBreakData.IsModified() )
1328 SfxHyphenRegionItem aHyp( GetWhich( SID_ATTR_HYPHENREGION ) );
1329 aHyp.GetMinLead() = (sal_uInt8) aPreBreakData.GetNumericValue();
1330 aHyp.GetMinTrail() = (sal_uInt8) aPostBreakData.GetNumericValue();
1331 rCoreSet.Put( aHyp );
1336 // automatic spell checking
1337 sal_Bool bNewAutoCheck = aLinguOptionsCLB.IsChecked( (sal_uInt16) EID_SPELL_AUTO );
1338 const SfxPoolItem* pOld = GetOldItem( rCoreSet, SID_AUTOSPELL_CHECK );
1339 if ( !pOld || ( (SfxBoolItem*)pOld )->GetValue() != bNewAutoCheck )
1341 rCoreSet.Put( SfxBoolItem( GetWhich( SID_AUTOSPELL_CHECK ),
1342 bNewAutoCheck ) );
1343 bModified |= sal_True;
1346 return bModified;
1349 // ----------------------------------------------------------------------
1351 sal_uLong SvxLinguTabPage::GetDicUserData( const uno::Reference< XDictionary > &rxDic, sal_uInt16 nIdx )
1353 sal_uLong nRes = 0;
1354 DBG_ASSERT( rxDic.is(), "dictionary not supplied" );
1355 if (rxDic.is())
1357 uno::Reference< frame::XStorable > xStor( rxDic, UNO_QUERY );
1359 sal_Bool bChecked = rxDic->isActive();
1360 sal_Bool bEditable = !xStor.is() || !xStor->isReadonly();
1361 sal_Bool bDeletable = bEditable;
1363 nRes = DicUserData( nIdx,
1364 bChecked, bEditable, bDeletable ).GetUserData();
1366 return nRes;
1370 void SvxLinguTabPage::AddDicBoxEntry(
1371 const uno::Reference< XDictionary > &rxDic,
1372 sal_uInt16 nIdx )
1374 aLinguDicsCLB.SetUpdateMode(sal_False);
1376 String aTxt( ::GetDicInfoStr( rxDic->getName(),
1377 LanguageTag( rxDic->getLocale() ).getLanguageType(),
1378 DictionaryType_NEGATIVE == rxDic->getDictionaryType() ) );
1379 aLinguDicsCLB.InsertEntry( aTxt, (sal_uInt16)LISTBOX_APPEND ); // append at end
1380 SvTreeListEntry* pEntry = aLinguDicsCLB.GetEntry( aLinguDicsCLB.GetEntryCount() - 1 );
1381 DBG_ASSERT( pEntry, "failed to add entry" );
1382 if (pEntry)
1384 DicUserData aData( GetDicUserData( rxDic, nIdx ) );
1385 pEntry->SetUserData( (void *) aData.GetUserData() );
1386 lcl_SetCheckButton( pEntry, aData.IsChecked() );
1389 aLinguDicsCLB.SetUpdateMode(sal_True);
1392 // ----------------------------------------------------------------------
1394 void SvxLinguTabPage::UpdateDicBox_Impl()
1396 aLinguDicsCLB.SetUpdateMode(sal_False);
1397 aLinguDicsCLB.Clear();
1399 sal_Int32 nDics = aDics.getLength();
1400 const uno::Reference< XDictionary > *pDic = aDics.getConstArray();
1401 for (sal_Int32 i = 0; i < nDics; ++i)
1403 const uno::Reference< XDictionary > &rDic = pDic[i];
1404 if (rDic.is())
1405 AddDicBoxEntry( rDic, (sal_uInt16)i );
1408 aLinguDicsCLB.SetUpdateMode(sal_True);
1411 // ----------------------------------------------------------------------
1413 void SvxLinguTabPage::UpdateModulesBox_Impl()
1415 if (pLinguData)
1417 const ServiceInfoArr &rAllDispSrvcArr = pLinguData->GetDisplayServiceArray();
1418 const sal_uLong nDispSrvcCount = pLinguData->GetDisplayServiceCount();
1420 aLinguModulesCLB.Clear();
1422 for (sal_uInt16 i = 0; i < nDispSrvcCount; ++i)
1424 const ServiceInfo_Impl &rInfo = rAllDispSrvcArr[i];
1425 aLinguModulesCLB.InsertEntry( rInfo.sDisplayName, (sal_uInt16)LISTBOX_APPEND );
1426 SvTreeListEntry* pEntry = aLinguModulesCLB.GetEntry(i);
1427 pEntry->SetUserData( (void *) &rInfo );
1428 aLinguModulesCLB.CheckEntryPos( i, rInfo.bConfigured );
1430 aLinguModulesEditPB.Enable( nDispSrvcCount > 0 );
1434 //------------------------------------------------------------------------
1436 void SvxLinguTabPage::Reset( const SfxItemSet& rSet )
1438 // if not HideGroups was called with GROUP_MODULES...
1439 if (aLinguModulesCLB.IsVisible())
1441 if (!pLinguData)
1442 pLinguData = new SvxLinguData_Impl;
1443 UpdateModulesBox_Impl();
1448 // get data from configuration
1451 SvtLinguConfig aLngCfg;
1453 aLinguOptionsCLB.SetUpdateMode(sal_False);
1454 aLinguOptionsCLB.Clear();
1456 SvTreeList *pModel = aLinguOptionsCLB.GetModel();
1457 SvTreeListEntry* pEntry = NULL;
1459 sal_Int16 nVal = 0;
1460 sal_Bool bVal = sal_False;
1461 sal_uLong nUserData = 0;
1463 pEntry = CreateEntry( sSpellAuto, CBCOL_FIRST );
1464 aLngCfg.GetProperty( UPN_IS_SPELL_AUTO ) >>= bVal;
1465 const SfxPoolItem* pItem = GetItem( rSet, SID_AUTOSPELL_CHECK );
1466 if (pItem)
1467 bVal = ((SfxBoolItem *) pItem)->GetValue();
1468 nUserData = OptionsUserData( EID_SPELL_AUTO, sal_False, 0, sal_True, bVal).GetUserData();
1469 pEntry->SetUserData( (void *)nUserData );
1470 pModel->Insert( pEntry );
1471 lcl_SetCheckButton( pEntry, bVal );
1473 pEntry = CreateEntry( sGrammarAuto, CBCOL_FIRST );
1474 aLngCfg.GetProperty( UPN_IS_GRAMMAR_AUTO ) >>= bVal;
1475 nUserData = OptionsUserData( EID_GRAMMAR_AUTO, sal_False, 0, sal_True, bVal).GetUserData();
1476 pEntry->SetUserData( (void *)nUserData );
1477 pModel->Insert( pEntry );
1478 lcl_SetCheckButton( pEntry, bVal );
1480 pEntry = CreateEntry( sCapitalWords, CBCOL_FIRST );
1481 aLngCfg.GetProperty( UPN_IS_SPELL_UPPER_CASE ) >>= bVal;
1482 nUserData = OptionsUserData( EID_CAPITAL_WORDS, sal_False, 0, sal_True, bVal).GetUserData();
1483 pEntry->SetUserData( (void *)nUserData );
1484 pModel->Insert( pEntry );
1485 lcl_SetCheckButton( pEntry, bVal );
1487 pEntry = CreateEntry( sWordsWithDigits, CBCOL_FIRST );
1488 aLngCfg.GetProperty( UPN_IS_SPELL_WITH_DIGITS ) >>= bVal;
1489 nUserData = OptionsUserData( EID_WORDS_WITH_DIGITS, sal_False, 0, sal_True, bVal).GetUserData();
1490 pEntry->SetUserData( (void *)nUserData );
1491 pModel->Insert( pEntry );
1492 lcl_SetCheckButton( pEntry, bVal );
1494 pEntry = CreateEntry( sSpellSpecial, CBCOL_FIRST );
1495 aLngCfg.GetProperty( UPN_IS_SPELL_SPECIAL ) >>= bVal;
1496 nUserData = OptionsUserData( EID_SPELL_SPECIAL, sal_False, 0, sal_True, bVal).GetUserData();
1497 pEntry->SetUserData( (void *)nUserData );
1498 pModel->Insert( pEntry );
1499 lcl_SetCheckButton( pEntry, bVal );
1501 pEntry = CreateEntry( sNumMinWordlen, CBCOL_SECOND );
1502 aLngCfg.GetProperty( UPN_HYPH_MIN_WORD_LENGTH ) >>= nVal;
1503 nUserData = OptionsUserData( EID_NUM_MIN_WORDLEN, sal_True, (sal_uInt16)nVal, sal_False, sal_False).GetUserData();
1504 pEntry->SetUserData( (void *)nUserData );
1505 pModel->Insert( pEntry );
1507 const SfxHyphenRegionItem *pHyp = NULL;
1508 sal_uInt16 nWhich = GetWhich( SID_ATTR_HYPHENREGION );
1509 if ( rSet.GetItemState( nWhich, sal_False ) == SFX_ITEM_SET )
1510 pHyp = &( (const SfxHyphenRegionItem &) rSet.Get( nWhich ) );
1512 pEntry = CreateEntry( sNumPreBreak, CBCOL_SECOND );
1513 aLngCfg.GetProperty( UPN_HYPH_MIN_LEADING ) >>= nVal;
1514 if (pHyp)
1515 nVal = (sal_Int16) pHyp->GetMinLead();
1516 nUserData = OptionsUserData( EID_NUM_PRE_BREAK, sal_True, (sal_uInt16)nVal, sal_False, sal_False).GetUserData();
1517 pEntry->SetUserData( (void *)nUserData );
1518 pModel->Insert( pEntry );
1520 pEntry = CreateEntry( sNumPostBreak, CBCOL_SECOND );
1521 aLngCfg.GetProperty( UPN_HYPH_MIN_TRAILING ) >>= nVal;
1522 if (pHyp)
1523 nVal = (sal_Int16) pHyp->GetMinTrail();
1524 nUserData = OptionsUserData( EID_NUM_POST_BREAK, sal_True, (sal_uInt16)nVal, sal_False, sal_False).GetUserData();
1525 pEntry->SetUserData( (void *)nUserData );
1526 pModel->Insert( pEntry );
1528 pEntry = CreateEntry( sHyphAuto, CBCOL_FIRST );
1529 aLngCfg.GetProperty( UPN_IS_HYPH_AUTO ) >>= bVal;
1530 nUserData = OptionsUserData( EID_HYPH_AUTO, sal_False, 0, sal_True, bVal).GetUserData();
1531 pEntry->SetUserData( (void *)nUserData );
1532 pModel->Insert( pEntry );
1533 lcl_SetCheckButton( pEntry, bVal );
1535 pEntry = CreateEntry( sHyphSpecial, CBCOL_FIRST );
1536 aLngCfg.GetProperty( UPN_IS_HYPH_SPECIAL ) >>= bVal;
1537 nUserData = OptionsUserData( EID_HYPH_SPECIAL, sal_False, 0, sal_True, bVal).GetUserData();
1538 pEntry->SetUserData( (void *)nUserData );
1539 pModel->Insert( pEntry );
1540 lcl_SetCheckButton( pEntry, bVal );
1542 aLinguOptionsCLB.SetUpdateMode(sal_True);
1545 // -----------------------------------------------------------------------
1547 IMPL_LINK( SvxLinguTabPage, BoxDoubleClickHdl_Impl, SvTreeListBox *, pBox )
1549 if (pBox == &aLinguModulesCLB)
1551 //! in order to avoid a bug causing a GPF when double clicking
1552 //! on a module entry and exiting the "Edit Modules" dialog
1553 //! after that.
1554 Application::PostUserEvent( LINK(
1555 this, SvxLinguTabPage, PostDblClickHdl_Impl ) );
1557 else if (pBox == &aLinguOptionsCLB)
1559 ClickHdl_Impl(&aLinguOptionsEditPB);
1561 return 0;
1564 // -----------------------------------------------------------------------
1566 IMPL_LINK_NOARG(SvxLinguTabPage, PostDblClickHdl_Impl)
1568 ClickHdl_Impl(&aLinguModulesEditPB);
1569 return 0;
1572 // -----------------------------------------------------------------------
1574 IMPL_LINK_NOARG(SvxLinguTabPage, OpenURLHdl_Impl)
1576 OUString sURL( aMoreDictsLink.GetURL() );
1577 lcl_OpenURL( sURL );
1578 return 0;
1581 // -----------------------------------------------------------------------
1583 IMPL_LINK( SvxLinguTabPage, BoxCheckButtonHdl_Impl, SvTreeListBox *, pBox )
1585 if (pBox == &aLinguModulesCLB)
1587 DBG_ASSERT( pLinguData, "NULL pointer, LinguData missing" );
1588 sal_uInt16 nPos = aLinguModulesCLB.GetSelectEntryPos();
1589 if (nPos != LISTBOX_ENTRY_NOTFOUND && pLinguData)
1591 pLinguData->Reconfigure( aLinguModulesCLB.GetText( nPos ),
1592 aLinguModulesCLB.IsChecked( nPos ) );
1595 else if (pBox == &aLinguDicsCLB)
1597 sal_uInt16 nPos = aLinguDicsCLB.GetSelectEntryPos();
1598 if (nPos != LISTBOX_ENTRY_NOTFOUND)
1600 const uno::Reference< XDictionary > &rDic = aDics.getConstArray()[ nPos ];
1601 if (SvxGetIgnoreAllList() == rDic)
1603 SvTreeListEntry* pEntry = aLinguDicsCLB.GetEntry( nPos );
1604 if (pEntry)
1605 lcl_SetCheckButton( pEntry, sal_True );
1609 return 0;
1612 // -----------------------------------------------------------------------
1614 IMPL_LINK( SvxLinguTabPage, ClickHdl_Impl, PushButton *, pBtn )
1616 if (&aLinguModulesEditPB == pBtn)
1618 if (!pLinguData)
1619 pLinguData = new SvxLinguData_Impl;
1621 SvxLinguData_Impl aOldLinguData( *pLinguData );
1622 SvxEditModulesDlg aDlg( this, *pLinguData );
1623 if (aDlg.Execute() != RET_OK)
1624 *pLinguData = aOldLinguData;
1626 // evaluate new status of 'bConfigured' flag
1627 sal_uLong nLen = pLinguData->GetDisplayServiceCount();
1628 for (sal_uLong i = 0; i < nLen; ++i)
1629 pLinguData->GetDisplayServiceArray()[i].bConfigured = sal_False;
1630 const Locale* pAllLocales = pLinguData->GetAllSupportedLocales().getConstArray();
1631 sal_Int32 nLocales = pLinguData->GetAllSupportedLocales().getLength();
1632 for (sal_Int32 k = 0; k < nLocales; ++k)
1634 sal_Int16 nLang = LanguageTag( pAllLocales[k] ).getLanguageType();
1635 if (pLinguData->GetSpellTable().count( nLang ))
1636 pLinguData->SetChecked( pLinguData->GetSpellTable()[ nLang ] );
1637 if (pLinguData->GetGrammarTable().count( nLang ))
1638 pLinguData->SetChecked( pLinguData->GetGrammarTable()[ nLang ] );
1639 if (pLinguData->GetHyphTable().count( nLang ))
1640 pLinguData->SetChecked( pLinguData->GetHyphTable()[ nLang ] );
1641 if (pLinguData->GetThesTable().count( nLang ))
1642 pLinguData->SetChecked( pLinguData->GetThesTable()[ nLang ] );
1645 // show new status of modules
1646 UpdateModulesBox_Impl();
1648 else if (&aLinguDicsNewPB == pBtn)
1650 uno::Reference< XSpellChecker1 > xSpellChecker1;
1651 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
1652 if(pFact)
1654 AbstractSvxNewDictionaryDialog* aDlg = pFact->CreateSvxNewDictionaryDialog( this, xSpellChecker1, RID_SFXDLG_NEWDICT );
1655 DBG_ASSERT(aDlg, "Dialogdiet fail!");
1656 uno::Reference< XDictionary > xNewDic;
1657 if ( aDlg->Execute() == RET_OK )
1658 xNewDic = uno::Reference< XDictionary >( aDlg->GetNewDictionary(), UNO_QUERY );
1659 if ( xNewDic.is() )
1661 // add new dics to the end
1662 sal_Int32 nLen = aDics.getLength();
1663 aDics.realloc( nLen + 1 );
1665 aDics.getArray()[ nLen ] = xNewDic;
1667 AddDicBoxEntry( xNewDic, (sal_uInt16) nLen );
1669 delete aDlg;
1672 else if (&aLinguDicsEditPB == pBtn)
1674 SvTreeListEntry *pEntry = aLinguDicsCLB.GetCurEntry();
1675 if (pEntry)
1677 DicUserData aData( (sal_uLong) pEntry->GetUserData() );
1678 sal_uInt16 nDicPos = aData.GetEntryId();
1679 sal_Int32 nDics = aDics.getLength();
1680 if (nDicPos < nDics)
1682 uno::Reference< XDictionary > xDic;
1683 xDic = aDics.getConstArray()[ nDicPos ];
1684 if (xDic.is())
1686 uno::Reference< XSpellChecker1 > xSpellChecker1;
1687 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
1688 if(pFact)
1690 VclAbstractDialog* aDlg = pFact->CreateSvxEditDictionaryDialog( this, xDic->getName(), xSpellChecker1, RID_SFXDLG_EDITDICT );
1691 DBG_ASSERT(aDlg, "Dialogdiet fail!");
1692 aDlg->Execute();
1693 delete aDlg;
1699 else if (&aLinguDicsDelPB == pBtn)
1701 if ( RET_NO ==
1702 QueryBox( this, CUI_RES( RID_SFXQB_DELDICT ) ).Execute() )
1703 return 0;
1705 SvTreeListEntry *pEntry = aLinguDicsCLB.GetCurEntry();
1706 if (pEntry)
1708 DicUserData aData( (sal_uLong) pEntry->GetUserData() );
1709 sal_uInt16 nDicPos = aData.GetEntryId();
1710 sal_Int32 nDics = aDics.getLength();
1711 if (nDicPos < nDics)
1713 uno::Reference< XDictionary > xDic;
1714 xDic = aDics.getConstArray()[ nDicPos ];
1715 if (xDic.is())
1717 if (SvxGetIgnoreAllList() == xDic)
1718 xDic->clear();
1719 else
1721 if (xDicList.is())
1722 xDicList->removeDictionary( xDic );
1724 uno::Reference< frame::XStorable > xStor( xDic, UNO_QUERY );
1725 if ( xStor->hasLocation() && !xStor->isReadonly() )
1727 String sURL = xStor->getLocation();
1728 INetURLObject aObj(sURL);
1729 DBG_ASSERT( aObj.GetProtocol() == INET_PROT_FILE,
1730 "non-file URLs cannot be deleted" );
1731 if ( aObj.GetProtocol() == INET_PROT_FILE )
1733 KillFile_Impl( aObj.GetMainURL( INetURLObject::NO_DECODE ) );
1737 aDics.getArray()[ nDicPos ] = 0;
1739 // remove entry from checklistbox
1740 sal_uLong nCnt = aLinguDicsCLB.GetEntryCount();
1741 for (sal_uLong i = 0; i < nCnt; ++i)
1743 SvTreeListEntry *pDicEntry = aLinguDicsCLB.GetEntry( i );
1744 DBG_ASSERT( pDicEntry, "missing entry" );
1745 if (pDicEntry)
1747 DicUserData aDicData( (sal_uLong) pDicEntry->GetUserData() );
1748 if (aDicData.GetEntryId() == nDicPos )
1750 aLinguDicsCLB.RemoveEntry( (sal_uInt16) i );
1751 break;
1755 DBG_ASSERT( nCnt > aLinguDicsCLB.GetEntryCount(),
1756 "remove failed ?");
1762 else if (&aLinguOptionsEditPB == pBtn)
1764 SvTreeListEntry *pEntry = aLinguOptionsCLB.GetCurEntry();
1765 DBG_ASSERT( pEntry, "no entry selected" );
1766 if (pEntry)
1768 OptionsUserData aData( (sal_uLong)pEntry->GetUserData() );
1769 if(aData.HasNumericValue())
1771 int nRID = -1;
1772 switch (aData.GetEntryId())
1774 case EID_NUM_PRE_BREAK : nRID = STR_NUM_PRE_BREAK_DLG; break;
1775 case EID_NUM_POST_BREAK : nRID = STR_NUM_POST_BREAK_DLG; break;
1776 case EID_NUM_MIN_WORDLEN: nRID = STR_NUM_MIN_WORDLEN_DLG; break;
1777 default:
1778 OSL_FAIL( "unexpected case" );
1781 OptionsBreakSet aDlg( this, nRID );
1782 aDlg.GetNumericFld().SetValue( aData.GetNumericValue() );
1783 if (RET_OK == aDlg.Execute() )
1785 long nVal = static_cast<long>(aDlg.GetNumericFld().GetValue());
1786 if (-1 != nVal && aData.GetNumericValue() != nVal)
1788 aData.SetNumericValue( (sal_uInt8)nVal ); //! sets IsModified !
1789 pEntry->SetUserData( (void *) aData.GetUserData() );
1790 aLinguOptionsCLB.Invalidate();
1796 else
1798 OSL_FAIL( "pBtn unexpected value" );
1801 return 0;
1804 // -----------------------------------------------------------------------
1806 IMPL_LINK( SvxLinguTabPage, SelectHdl_Impl, SvxCheckListBox *, pBox )
1808 if (&aLinguModulesCLB == pBox)
1811 else if (&aLinguDicsCLB == pBox)
1813 SvTreeListEntry *pEntry = pBox->GetCurEntry();
1814 if (pEntry)
1816 DicUserData aData( (sal_uLong) pEntry->GetUserData() );
1818 // always allow to edit (i.e. at least view the content of the dictionary)
1819 aLinguDicsEditPB.Enable( true/*aData.IsEditable()*/ );
1820 aLinguDicsDelPB .Enable( aData.IsDeletable() );
1823 else if (&aLinguOptionsCLB == pBox)
1825 SvTreeListEntry *pEntry = pBox->GetCurEntry();
1826 if (pEntry)
1828 OptionsUserData aData( (sal_uLong) pEntry->GetUserData() );
1829 aLinguOptionsEditPB.Enable( aData.HasNumericValue() );
1832 else
1834 OSL_FAIL( "pBox unexpected value" );
1837 return 0;
1840 // -----------------------------------------------------------------------
1842 SvTreeListEntry* SvxLinguTabPage::CreateEntry( String& rTxt, sal_uInt16 nCol )
1844 SvTreeListEntry* pEntry = new SvTreeListEntry;
1846 if( !pCheckButtonData )
1847 pCheckButtonData = new SvLBoxButtonData( &aLinguOptionsCLB );
1849 String sEmpty;
1850 if (CBCOL_FIRST == nCol)
1851 pEntry->AddItem( new SvLBoxButton( pEntry, SvLBoxButtonKind_enabledCheckbox, 0, pCheckButtonData ) );
1852 if (CBCOL_SECOND == nCol)
1853 pEntry->AddItem( new SvLBoxString( pEntry, 0, sEmpty) ); // empty column
1854 pEntry->AddItem( new SvLBoxContextBmp( pEntry, 0, Image(), Image(), 0));
1855 pEntry->AddItem( new BrwString_Impl( pEntry, 0, rTxt ) );
1857 return pEntry;
1860 // -----------------------------------------------------------------------
1862 void SvxLinguTabPage::HideGroups( sal_uInt16 nGrp )
1864 if ( 0 != ( GROUP_MODULES & nGrp ) )
1866 aLinguModulesFT.Hide();
1867 aLinguModulesCLB.Hide();
1868 aLinguModulesEditPB.Hide();
1870 // reposition / resize remaining controls
1871 long nDeltaY = aLinguDicsFT.GetPosPixel().Y() -
1872 aLinguModulesFT.GetPosPixel().Y();
1873 DBG_ASSERT( nDeltaY >= 0, "move/resize value is negative" );
1874 Point aPos;
1876 aPos = aLinguDicsFT.GetPosPixel();
1877 aPos.Y() -= nDeltaY;
1878 aLinguDicsFT.SetPosPixel( aPos );
1879 aPos = aLinguDicsCLB.GetPosPixel();
1880 aPos.Y() -= nDeltaY;
1881 aLinguDicsCLB.SetPosPixel( aPos );
1882 aPos = aLinguDicsNewPB.GetPosPixel();
1883 aPos.Y() -= nDeltaY;
1884 aLinguDicsNewPB.SetPosPixel( aPos );
1885 aPos = aLinguDicsEditPB.GetPosPixel();
1886 aPos.Y() -= nDeltaY;
1887 aLinguDicsEditPB.SetPosPixel( aPos );
1888 aPos = aLinguDicsDelPB.GetPosPixel();
1889 aPos.Y() -= nDeltaY;
1890 aLinguDicsDelPB.SetPosPixel( aPos );
1892 aPos = aLinguOptionsFT.GetPosPixel();
1893 aPos.Y() -= nDeltaY;
1894 aLinguOptionsFT.SetPosPixel( aPos );
1895 aPos = aLinguOptionsCLB.GetPosPixel();
1896 aPos.Y() -= nDeltaY;
1897 aLinguOptionsCLB.SetPosPixel( aPos );
1898 aPos = aLinguOptionsEditPB.GetPosPixel();
1899 aPos.Y() -= nDeltaY;
1900 aLinguOptionsEditPB.SetPosPixel( aPos );
1902 Size aSize( aLinguOptionsCLB.GetSizePixel() );
1903 aSize.Height() += nDeltaY;
1904 aLinguOptionsCLB.SetSizePixel( aSize );
1906 if ( SvtExtendedSecurityOptions().GetOpenHyperlinkMode()
1907 != SvtExtendedSecurityOptions::OPEN_NEVER )
1909 aSize = GetOutputSizePixel();
1910 aSize.Height() += ( aMoreDictsLink.GetSizePixel().Height() * 11 / 8 );
1911 SetSizePixel( aSize );
1912 aMoreDictsLink.Show();
1917 SvxEditModulesDlg::SvxEditModulesDlg(Window* pParent, SvxLinguData_Impl& rData) :
1918 ModalDialog( pParent, CUI_RES(RID_SVXDLG_EDIT_MODULES ) ),
1919 aModulesFL ( this, CUI_RES( FL_EDIT_MODULES_OPTIONS ) ),
1920 aLanguageFT ( this, CUI_RES( FT_EDIT_MODULES_LANGUAGE ) ),
1921 aLanguageLB ( this, CUI_RES( LB_EDIT_MODULES_LANGUAGE ), sal_False ),
1922 aModulesCLB ( this, CUI_RES( CLB_EDIT_MODULES_MODULES ) ),
1923 aPrioUpPB ( this, CUI_RES( PB_EDIT_MODULES_PRIO_UP ) ),
1924 aPrioDownPB ( this, CUI_RES( PB_EDIT_MODULES_PRIO_DOWN ) ),
1925 aBackPB ( this, CUI_RES( PB_EDIT_MODULES_PRIO_BACK ) ),
1926 aMoreDictsLink ( this, CUI_RES( FT_EDIT_MODULES_NEWDICTSLINK ) ),
1927 aButtonsFL ( this, CUI_RES( FL_EDIT_MODULES_BUTTONS ) ),
1928 aHelpPB ( this, CUI_RES( PB_HELP ) ),
1929 aClosePB ( this, CUI_RES( PB_OK ) ),
1930 sSpell ( CUI_RES( ST_SPELL ) ),
1931 sHyph ( CUI_RES( ST_HYPH ) ),
1932 sThes ( CUI_RES( ST_THES ) ),
1933 sGrammar ( CUI_RES( ST_GRAMMAR ) ),
1934 rLinguData ( rData )
1936 pCheckButtonData = NULL;
1937 FreeResource();
1939 pDefaultLinguData = new SvxLinguData_Impl( rLinguData );
1941 aModulesCLB.SetStyle( aModulesCLB.GetStyle()|WB_CLIPCHILDREN|WB_HSCROLL|WB_FORCE_MAKEVISIBLE );
1942 aModulesCLB.SetHighlightRange();
1943 aModulesCLB.SetHelpId(HID_CLB_EDIT_MODULES_MODULES );
1944 aModulesCLB.SetSelectHdl( LINK( this, SvxEditModulesDlg, SelectHdl_Impl ));
1945 aModulesCLB.SetCheckButtonHdl( LINK( this, SvxEditModulesDlg, BoxCheckButtonHdl_Impl) );
1947 aClosePB .SetClickHdl( LINK( this, SvxEditModulesDlg, ClickHdl_Impl ));
1948 aPrioUpPB .SetClickHdl( LINK( this, SvxEditModulesDlg, UpDownHdl_Impl ));
1949 aPrioDownPB.SetClickHdl( LINK( this, SvxEditModulesDlg, UpDownHdl_Impl ));
1950 aBackPB .SetClickHdl( LINK( this, SvxEditModulesDlg, BackHdl_Impl ));
1951 // in case of not installed language modules
1952 aPrioUpPB .Enable( sal_False );
1953 aPrioDownPB.Enable( sal_False );
1955 if ( SvtExtendedSecurityOptions().GetOpenHyperlinkMode()
1956 != SvtExtendedSecurityOptions::OPEN_NEVER )
1958 aMoreDictsLink.SetURL( String(
1959 "http://extensions.libreoffice.org/dictionaries/" ) );
1960 aMoreDictsLink.SetClickHdl( LINK( this, SvxEditModulesDlg, OpenURLHdl_Impl ) );
1962 else
1964 aMoreDictsLink.Hide();
1965 long nPos = aMoreDictsLink.GetPosPixel().Y() + aMoreDictsLink.GetSizePixel().Height();
1966 Size aSize = aModulesCLB.GetSizePixel();
1967 aSize.Height() += ( nPos - ( aModulesCLB.GetPosPixel().Y() + aSize.Height() ) );
1968 aModulesCLB.SetSizePixel( aSize );
1972 //fill language box
1974 Sequence< sal_Int16 > aAvailLang;
1975 uno::Reference< XAvailableLocales > xAvail( rLinguData.GetManager(), UNO_QUERY );
1976 if (xAvail.is())
1978 aAvailLang = lcl_LocaleSeqToLangSeq(
1979 xAvail->getAvailableLocales( cSpell ) );
1981 const Sequence< Locale >& rLoc = rLinguData.GetAllSupportedLocales();
1982 const Locale* pLocales = rLoc.getConstArray();
1983 aLanguageLB.Clear();
1984 for(long i = 0; i < rLoc.getLength(); i++)
1986 sal_Int16 nLang = LanguageTag( pLocales[i] ).getLanguageType();
1987 aLanguageLB.InsertLanguage( nLang, lcl_SeqHasLang( aAvailLang, nLang ) );
1989 LanguageType eSysLang = MsLangId::getSystemLanguage();
1990 aLanguageLB.SelectLanguage( eSysLang );
1991 if(!aLanguageLB.IsLanguageSelected( eSysLang ) )
1992 aLanguageLB.SelectEntryPos(0);
1994 aLanguageLB.SetSelectHdl( LINK( this, SvxEditModulesDlg, LangSelectHdl_Impl ));
1995 LangSelectHdl_Impl(&aLanguageLB);
1999 SvxEditModulesDlg::~SvxEditModulesDlg()
2001 delete pDefaultLinguData;
2005 SvTreeListEntry* SvxEditModulesDlg::CreateEntry( String& rTxt, sal_uInt16 nCol )
2007 SvTreeListEntry* pEntry = new SvTreeListEntry;
2008 if( !pCheckButtonData )
2010 pCheckButtonData = new SvLBoxButtonData( &aModulesCLB );
2011 pCheckButtonData->SetLink( aModulesCLB.GetCheckButtonHdl() );
2014 String sEmpty;
2015 if (CBCOL_FIRST == nCol)
2016 pEntry->AddItem( new SvLBoxButton( pEntry, SvLBoxButtonKind_enabledCheckbox, 0, pCheckButtonData ) );
2017 if (CBCOL_SECOND == nCol)
2018 pEntry->AddItem( new SvLBoxString( pEntry, 0, sEmpty) ); // empty column
2019 pEntry->AddItem( new SvLBoxContextBmp( pEntry, 0, Image(), Image(), 0));
2020 pEntry->AddItem( new BrwStringDic_Impl( pEntry, 0, rTxt ) );
2022 return pEntry;
2025 IMPL_LINK( SvxEditModulesDlg, SelectHdl_Impl, SvxCheckListBox *, pBox )
2027 if (&aModulesCLB == pBox)
2029 sal_Bool bDisableUp = sal_True;
2030 sal_Bool bDisableDown = sal_True;
2031 SvTreeListEntry *pEntry = pBox->GetCurEntry();
2032 if (pEntry)
2034 ModuleUserData_Impl* pData = (ModuleUserData_Impl*)pEntry->GetUserData();
2035 if(!pData->IsParent() && pData->GetType() != TYPE_HYPH)
2037 sal_uInt16 nCurPos = pBox->GetSelectEntryPos();
2038 if(nCurPos < pBox->GetEntryCount() - 1)
2040 bDisableDown = ((ModuleUserData_Impl*)pBox->
2041 GetEntry(nCurPos + 1)->GetUserData())->IsParent();
2043 if(nCurPos > 1)
2045 bDisableUp = ((ModuleUserData_Impl*)pBox->
2046 GetEntry(nCurPos - 1)->GetUserData())->IsParent();
2049 aPrioUpPB.Enable(!bDisableUp);
2050 aPrioDownPB.Enable(!bDisableDown);
2053 else
2055 OSL_FAIL( "pBox unexpected value" );
2058 return 0;
2061 IMPL_LINK( SvxEditModulesDlg, BoxCheckButtonHdl_Impl, SvTreeListBox *, pBox )
2063 pBox = &aModulesCLB;
2064 SvTreeListEntry *pCurEntry = pBox->GetCurEntry();
2065 if (pCurEntry)
2067 ModuleUserData_Impl* pData = (ModuleUserData_Impl *)
2068 pCurEntry->GetUserData();
2069 if (!pData->IsParent() && pData->GetType() == TYPE_HYPH)
2071 // make hyphenator checkboxes function as radio-buttons
2072 // (at most one box may be checked)
2073 SvTreeListEntry *pEntry = pBox->First();
2074 while (pEntry)
2076 pData = (ModuleUserData_Impl *) pEntry->GetUserData();
2077 if (!pData->IsParent() &&
2078 pData->GetType() == TYPE_HYPH &&
2079 pEntry != pCurEntry)
2081 lcl_SetCheckButton( pEntry, sal_False );
2082 pBox->InvalidateEntry( pEntry );
2084 pEntry = pBox->Next( pEntry );
2088 return 0;
2091 IMPL_LINK( SvxEditModulesDlg, LangSelectHdl_Impl, ListBox *, pBox )
2093 LanguageType eCurLanguage = aLanguageLB.GetSelectLanguage();
2094 static Locale aLastLocale;
2095 Locale aCurLocale( LanguageTag( eCurLanguage).getLocale());
2096 SvTreeList *pModel = aModulesCLB.GetModel();
2098 if (pBox)
2100 // save old probably changed settings
2101 // before switching to new language entries
2103 sal_Int16 nLang = LanguageTag( aLastLocale ).getLanguageType();
2105 sal_Int32 nStart = 0, nLocalIndex = 0;
2106 Sequence< OUString > aChange;
2107 sal_Bool bChanged = sal_False;
2108 for(sal_uInt16 i = 0; i < aModulesCLB.GetEntryCount(); i++)
2110 SvTreeListEntry *pEntry = aModulesCLB.GetEntry(i);
2111 ModuleUserData_Impl* pData = (ModuleUserData_Impl*)pEntry->GetUserData();
2112 if(pData->IsParent())
2114 if(bChanged)
2116 LangImplNameTable *pTable = 0;
2117 sal_uInt8 nType = pData->GetType();
2118 switch (nType - 1)
2120 case TYPE_SPELL : pTable = &rLinguData.GetSpellTable(); break;
2121 case TYPE_GRAMMAR : pTable = &rLinguData.GetGrammarTable(); break;
2122 case TYPE_HYPH : pTable = &rLinguData.GetHyphTable(); break;
2123 case TYPE_THES : pTable = &rLinguData.GetThesTable(); break;
2125 if (pTable)
2127 aChange.realloc(nStart);
2128 (*pTable)[ nLang ] = aChange;
2131 nLocalIndex = nStart = 0;
2132 aChange.realloc(aModulesCLB.GetEntryCount());
2133 bChanged = sal_False;
2135 else
2137 OUString* pChange = aChange.getArray();
2138 pChange[nStart] = pData->GetImplName();
2139 bChanged |= pData->GetIndex() != nLocalIndex ||
2140 pData->IsChecked() != aModulesCLB.IsChecked(i);
2141 if(aModulesCLB.IsChecked(i))
2142 nStart++;
2143 ++nLocalIndex;
2146 if(bChanged)
2148 aChange.realloc(nStart);
2149 rLinguData.GetThesTable()[ nLang ] = aChange;
2153 for(sal_uLong i = 0; i < aModulesCLB.GetEntryCount(); i++)
2154 delete (ModuleUserData_Impl*)aModulesCLB.GetEntry(i)->GetUserData();
2157 // display entries for new selected language
2159 aModulesCLB.Clear();
2160 if(LANGUAGE_DONTKNOW != eCurLanguage)
2162 sal_uLong n;
2163 ServiceInfo_Impl* pInfo;
2166 // spellchecker entries
2168 SvTreeListEntry* pEntry = CreateEntry( sSpell, CBCOL_SECOND );
2169 ModuleUserData_Impl* pUserData = new ModuleUserData_Impl(
2170 String(), sal_True, sal_False, TYPE_SPELL, 0 );
2171 pEntry->SetUserData( (void *)pUserData );
2172 pModel->Insert( pEntry );
2174 Sequence< OUString > aNames( rLinguData.GetSortedImplNames( eCurLanguage, TYPE_SPELL ) );
2175 const OUString *pName = aNames.getConstArray();
2176 sal_uLong nNames = (sal_uLong) aNames.getLength();
2177 sal_Int32 nLocalIndex = 0; // index relative to parent
2178 for (n = 0; n < nNames; ++n)
2180 OUString aImplName;
2181 sal_Bool bIsSuppLang = sal_False;
2183 pInfo = rLinguData.GetInfoByImplName( pName[n] );
2184 if (pInfo)
2186 bIsSuppLang = pInfo->xSpell.is() &&
2187 pInfo->xSpell->hasLocale( aCurLocale );
2188 aImplName = pInfo->sSpellImplName;
2190 if (!aImplName.isEmpty() && bIsSuppLang)
2192 String aTxt( pInfo->sDisplayName );
2193 SvTreeListEntry* pNewEntry = CreateEntry( aTxt, CBCOL_FIRST );
2195 LangImplNameTable &rTable = rLinguData.GetSpellTable();
2196 const bool bHasLang = rTable.count( eCurLanguage );
2197 if (!bHasLang)
2199 DBG_WARNING( "language entry missing" ); // only relevant if all languages found should be supported
2201 const bool bCheck = bHasLang && lcl_SeqGetEntryPos( rTable[ eCurLanguage ], aImplName ) >= 0;
2202 lcl_SetCheckButton( pNewEntry, bCheck );
2203 pUserData = new ModuleUserData_Impl( aImplName, sal_False,
2204 bCheck, TYPE_SPELL, (sal_uInt8)nLocalIndex++ );
2205 pNewEntry->SetUserData( (void *)pUserData );
2206 pModel->Insert( pNewEntry );
2211 // grammar checker entries
2213 pEntry = CreateEntry( sGrammar, CBCOL_SECOND );
2214 pUserData = new ModuleUserData_Impl( String(), sal_True, sal_False, TYPE_GRAMMAR, 0 );
2215 pEntry->SetUserData( (void *)pUserData );
2216 pModel->Insert( pEntry );
2218 aNames = rLinguData.GetSortedImplNames( eCurLanguage, TYPE_GRAMMAR );
2219 pName = aNames.getConstArray();
2220 nNames = (sal_uLong) aNames.getLength();
2221 nLocalIndex = 0;
2222 for (n = 0; n < nNames; ++n)
2224 OUString aImplName;
2225 sal_Bool bIsSuppLang = sal_False;
2227 pInfo = rLinguData.GetInfoByImplName( pName[n] );
2228 if (pInfo)
2230 bIsSuppLang = pInfo->xGrammar.is() &&
2231 pInfo->xGrammar->hasLocale( aCurLocale );
2232 aImplName = pInfo->sGrammarImplName;
2234 if (!aImplName.isEmpty() && bIsSuppLang)
2236 String aTxt( pInfo->sDisplayName );
2237 SvTreeListEntry* pNewEntry = CreateEntry( aTxt, CBCOL_FIRST );
2239 LangImplNameTable &rTable = rLinguData.GetGrammarTable();
2240 const bool bHasLang = rTable.count( eCurLanguage );
2241 if (!bHasLang)
2243 DBG_WARNING( "language entry missing" ); // only relevant if all languages found should be supported
2245 const bool bCheck = bHasLang && lcl_SeqGetEntryPos( rTable[ eCurLanguage ], aImplName ) >= 0;
2246 lcl_SetCheckButton( pNewEntry, bCheck );
2247 pUserData = new ModuleUserData_Impl( aImplName, sal_False,
2248 bCheck, TYPE_GRAMMAR, (sal_uInt8)nLocalIndex++ );
2249 pNewEntry->SetUserData( (void *)pUserData );
2250 pModel->Insert( pNewEntry );
2255 // hyphenator entries
2257 pEntry = CreateEntry( sHyph, CBCOL_SECOND );
2258 pUserData = new ModuleUserData_Impl( String(), sal_True, sal_False, TYPE_HYPH, 0 );
2259 pEntry->SetUserData( (void *)pUserData );
2260 pModel->Insert( pEntry );
2262 aNames = rLinguData.GetSortedImplNames( eCurLanguage, TYPE_HYPH );
2263 pName = aNames.getConstArray();
2264 nNames = (sal_uLong) aNames.getLength();
2265 nLocalIndex = 0;
2266 for (n = 0; n < nNames; ++n)
2268 OUString aImplName;
2269 sal_Bool bIsSuppLang = sal_False;
2271 pInfo = rLinguData.GetInfoByImplName( pName[n] );
2272 if (pInfo)
2274 bIsSuppLang = pInfo->xHyph.is() &&
2275 pInfo->xHyph->hasLocale( aCurLocale );
2276 aImplName = pInfo->sHyphImplName;
2278 if (!aImplName.isEmpty() && bIsSuppLang)
2280 String aTxt( pInfo->sDisplayName );
2281 SvTreeListEntry* pNewEntry = CreateEntry( aTxt, CBCOL_FIRST );
2283 LangImplNameTable &rTable = rLinguData.GetHyphTable();
2284 const bool bHasLang = rTable.count( eCurLanguage );
2285 if (!bHasLang)
2287 DBG_WARNING( "language entry missing" ); // only relevant if all languages found should be supported
2289 const bool bCheck = bHasLang && lcl_SeqGetEntryPos( rTable[ eCurLanguage ], aImplName ) >= 0;
2290 lcl_SetCheckButton( pNewEntry, bCheck );
2291 pUserData = new ModuleUserData_Impl( aImplName, sal_False,
2292 bCheck, TYPE_HYPH, (sal_uInt8)nLocalIndex++ );
2293 pNewEntry->SetUserData( (void *)pUserData );
2294 pModel->Insert( pNewEntry );
2299 // thesaurus entries
2301 pEntry = CreateEntry( sThes, CBCOL_SECOND );
2302 pUserData = new ModuleUserData_Impl( String(), sal_True, sal_False, TYPE_THES, 0 );
2303 pEntry->SetUserData( (void *)pUserData );
2304 pModel->Insert( pEntry );
2306 aNames = rLinguData.GetSortedImplNames( eCurLanguage, TYPE_THES );
2307 pName = aNames.getConstArray();
2308 nNames = (sal_uLong) aNames.getLength();
2309 nLocalIndex = 0;
2310 for (n = 0; n < nNames; ++n)
2312 OUString aImplName;
2313 sal_Bool bIsSuppLang = sal_False;
2315 pInfo = rLinguData.GetInfoByImplName( pName[n] );
2316 if (pInfo)
2318 bIsSuppLang = pInfo->xThes.is() &&
2319 pInfo->xThes->hasLocale( aCurLocale );
2320 aImplName = pInfo->sThesImplName;
2322 if (!aImplName.isEmpty() && bIsSuppLang)
2324 String aTxt( pInfo->sDisplayName );
2325 SvTreeListEntry* pNewEntry = CreateEntry( aTxt, CBCOL_FIRST );
2327 LangImplNameTable &rTable = rLinguData.GetThesTable();
2328 const bool bHasLang = rTable.count( eCurLanguage );
2329 if (!bHasLang)
2331 DBG_WARNING( "language entry missing" ); // only relevant if all languages found should be supported
2333 const bool bCheck = bHasLang && lcl_SeqGetEntryPos( rTable[ eCurLanguage ], aImplName ) >= 0;
2334 lcl_SetCheckButton( pNewEntry, bCheck );
2335 pUserData = new ModuleUserData_Impl( aImplName, sal_False,
2336 bCheck, TYPE_THES, (sal_uInt8)nLocalIndex++ );
2337 pNewEntry->SetUserData( (void *)pUserData );
2338 pModel->Insert( pNewEntry );
2342 aLastLocale = aCurLocale;
2343 return 0;
2346 IMPL_LINK( SvxEditModulesDlg, UpDownHdl_Impl, PushButton *, pBtn )
2348 sal_Bool bUp = &aPrioUpPB == pBtn;
2349 sal_uInt16 nCurPos = aModulesCLB.GetSelectEntryPos();
2350 SvTreeListEntry* pEntry;
2351 if (nCurPos != LISTBOX_ENTRY_NOTFOUND &&
2352 0 != (pEntry = aModulesCLB.GetEntry(nCurPos)))
2354 aModulesCLB.SetUpdateMode(sal_False);
2355 SvTreeList *pModel = aModulesCLB.GetModel();
2357 ModuleUserData_Impl* pData = (ModuleUserData_Impl*)pEntry->GetUserData();
2358 String aStr(aModulesCLB.GetEntryText(pEntry));
2359 SvTreeListEntry* pToInsert = CreateEntry( aStr, CBCOL_FIRST );
2360 pToInsert->SetUserData( (void *)pData);
2361 sal_Bool bIsChecked = aModulesCLB.IsChecked(nCurPos);
2363 pModel->Remove(pEntry);
2365 sal_uInt16 nDestPos = bUp ? nCurPos - 1 : nCurPos + 1;
2366 pModel->Insert(pToInsert, nDestPos);
2367 aModulesCLB.CheckEntryPos(nDestPos, bIsChecked );
2368 aModulesCLB.SelectEntryPos(nDestPos );
2369 SelectHdl_Impl(&aModulesCLB);
2370 aModulesCLB.SetUpdateMode(sal_True);
2372 return 0;
2375 IMPL_LINK( SvxEditModulesDlg, ClickHdl_Impl, PushButton *, pBtn )
2377 if (&aClosePB == pBtn)
2379 // store language config
2380 LangSelectHdl_Impl(&aLanguageLB);
2381 EndDialog( RET_OK );
2383 else
2385 OSL_FAIL( "pBtn unexpected value" );
2388 return 0;
2391 IMPL_LINK_NOARG(SvxEditModulesDlg, BackHdl_Impl)
2393 rLinguData = *pDefaultLinguData;
2394 LangSelectHdl_Impl(0);
2395 return 0;
2398 // -----------------------------------------------------------------------
2400 IMPL_LINK_NOARG(SvxEditModulesDlg, OpenURLHdl_Impl)
2402 OUString sURL( aMoreDictsLink.GetURL() );
2403 lcl_OpenURL( sURL );
2404 return 0;
2407 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */