Version 4.0.0.1, tag libreoffice-4.0.0.1
[LibreOffice.git] / cui / source / options / optlingu.cxx
blob21c04140f0055262781aa1e6a5dbb24eeaaf1f9b
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 <i18npool/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 #define _SVX_OPTLINGU_CXX
59 #include "optlingu.hrc"
61 #include <svx/svxdlg.hxx>
62 #include <editeng/optitems.hxx>
63 #include "optlingu.hxx"
64 #include <dialmgr.hxx>
65 #include <cuires.hrc>
66 #include "helpid.hrc"
68 #include <comphelper/componentcontext.hxx>
69 #include <ucbhelper/content.hxx>
71 #include <vector>
72 #include <map>
75 using namespace ::ucbhelper;
76 using namespace ::rtl;
77 using namespace ::com::sun::star;
78 using namespace ::com::sun::star::lang;
79 using namespace ::com::sun::star::uno;
80 using namespace ::com::sun::star::linguistic2;
81 using namespace ::com::sun::star::beans;
83 #define CBCOL_FIRST 0
84 #define CBCOL_SECOND 1
85 #define CBCOL_BOTH 2
87 static const sal_Char cSpell[] = SN_SPELLCHECKER;
88 static const sal_Char cGrammar[] = SN_GRAMMARCHECKER;
89 static const sal_Char cHyph[] = SN_HYPHENATOR;
90 static const sal_Char cThes[] = SN_THESAURUS;
92 // static ----------------------------------------------------------------
94 static Sequence< sal_Int16 > lcl_LocaleSeqToLangSeq( const Sequence< Locale > &rSeq )
96 sal_Int32 nLen = rSeq.getLength();
97 Sequence< sal_Int16 > aRes( nLen );
98 sal_Int16 *pRes = aRes.getArray();
99 const Locale *pSeq = rSeq.getConstArray();
100 for (sal_Int32 i = 0; i < nLen; ++i)
102 pRes[i] = LanguageTag( pSeq[i] ).getLanguageType();
104 return aRes;
108 static sal_Bool lcl_SeqHasLang( const Sequence< sal_Int16 > &rSeq, sal_Int16 nLang )
110 sal_Int32 nLen = rSeq.getLength();
111 const sal_Int16 *pLang = rSeq.getConstArray();
112 sal_Int32 nPos = -1;
113 for (sal_Int32 i = 0; i < nLen && nPos < 0; ++i)
115 if (nLang == pLang[i])
116 nPos = i;
118 return nPos < 0 ? sal_False : sal_True;
122 static sal_Int32 lcl_SeqGetEntryPos(
123 const Sequence< OUString > &rSeq, const OUString &rEntry )
125 sal_Int32 i;
126 sal_Int32 nLen = rSeq.getLength();
127 const OUString *pItem = rSeq.getConstArray();
128 for (i = 0; i < nLen; ++i)
130 if (rEntry == pItem[i])
131 break;
133 return i < nLen ? i : -1;
136 static void lcl_OpenURL( ::rtl::OUString sURL )
138 if ( !sURL.isEmpty() )
140 localizeWebserviceURI(sURL);
143 uno::Reference< uno::XComponentContext > xContext =
144 ::comphelper::getProcessComponentContext();
145 uno::Reference< css::system::XSystemShellExecute > xSystemShell(
146 css::system::SystemShellExecute::create(xContext) );
147 xSystemShell->execute( sURL, ::rtl::OUString(), css::system::SystemShellExecuteFlags::URIS_ONLY );
149 catch( const uno::Exception& e )
151 OSL_TRACE( "Caught exception: %s\n thread terminated.\n",
152 rtl::OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8).getStr());
157 static sal_uInt16 pRanges[] =
159 SID_ATTR_SPELL,
160 SID_ATTR_SPELL,
164 sal_Bool KillFile_Impl( const String& rURL )
166 sal_Bool bRet = sal_True;
169 Content aCnt( rURL, uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >(), comphelper::getProcessComponentContext() );
170 aCnt.executeCommand( OUString("delete"), makeAny( sal_Bool( sal_True ) ) );
172 catch( ::com::sun::star::ucb::CommandAbortedException& )
174 SAL_WARN( "cui.options", "KillFile: CommandAbortedException" );
175 bRet = sal_False;
177 catch( ... )
179 SAL_WARN( "cui.options", "KillFile: Any other exception" );
180 bRet = sal_False;
183 return bRet;
186 // 0x 0p 0t 0c nn
187 // p: 1 -> parent
188 // t: 1 -> spell, 2 -> hyph, 3 -> thes, 4 -> grammar
189 // c: 1 -> checked 0 -> unchecked
190 // n: index
192 #define TYPE_SPELL (sal_uInt8)1
193 #define TYPE_GRAMMAR (sal_uInt8)2
194 #define TYPE_HYPH (sal_uInt8)3
195 #define TYPE_THES (sal_uInt8)4
197 class ModuleUserData_Impl
199 sal_Bool bParent;
200 sal_Bool bIsChecked;
201 sal_uInt8 nType;
202 sal_uInt8 nIndex;
203 String sImplName;
205 public:
206 ModuleUserData_Impl( String sImpName, sal_Bool bIsParent, sal_Bool bChecked, sal_uInt8 nSetType, sal_uInt8 nSetIndex ) :
207 bParent(bIsParent),
208 bIsChecked(bChecked),
209 nType(nSetType),
210 nIndex(nSetIndex),
211 sImplName(sImpName)
214 sal_Bool IsParent() const {return bParent;}
215 sal_uInt8 GetType() const {return nType;}
216 sal_Bool IsChecked() const {return bIsChecked;}
217 sal_uInt8 GetIndex() const {return nIndex;}
218 void SetIndex(sal_uInt8 nSet) {nIndex = nSet;}
219 const String& GetImplName() const {return sImplName;}
224 // User for user-dictionaries (XDictionary interface)
226 class DicUserData
228 sal_uLong nVal;
230 public:
231 DicUserData( sal_uLong nUserData ) : nVal( nUserData ) {}
232 DicUserData( sal_uInt16 nEID,
233 sal_Bool bChecked, sal_Bool bEditable, sal_Bool bDeletable );
235 sal_uLong GetUserData() const { return nVal; }
236 sal_uInt16 GetEntryId() const { return (sal_uInt16)(nVal >> 16); }
237 sal_Bool IsChecked() const { return (sal_Bool)(nVal >> 8) & 0x01; }
238 sal_Bool IsEditable() const { return (sal_Bool)(nVal >> 9) & 0x01; }
239 sal_Bool IsDeletable() const { return (sal_Bool)(nVal >> 10) & 0x01; }
241 void SetChecked( sal_Bool bVal );
245 DicUserData::DicUserData(
246 sal_uInt16 nEID,
247 sal_Bool bChecked, sal_Bool bEditable, sal_Bool bDeletable )
249 DBG_ASSERT( nEID < 65000, "Entry Id out of range" );
250 nVal = ((sal_uLong)(0xFFFF & nEID) << 16) |
251 ((sal_uLong)(bChecked ? 1 : 0) << 8) |
252 ((sal_uLong)(bEditable ? 1 : 0) << 9) |
253 ((sal_uLong)(bDeletable ? 1 : 0) << 10);
257 void DicUserData::SetChecked( sal_Bool bVal )
259 nVal &= ~(1UL << 8);
260 nVal |= (sal_uLong)(bVal ? 1 : 0) << 8;
264 // class BrwString_Impl -------------------------------------------------
266 static void lcl_SetCheckButton( SvTreeListEntry* pEntry, sal_Bool bCheck )
268 SvLBoxButton* pItem = (SvLBoxButton*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXBUTTON));
270 DBG_ASSERT(pItem,"SetCheckButton:Item not found");
271 if (pItem->GetType() == SV_ITEM_ID_LBOXBUTTON)
273 if (bCheck)
274 pItem->SetStateChecked();
275 else
276 pItem->SetStateUnchecked();
281 class BrwStringDic_Impl : public SvLBoxString
283 public:
285 BrwStringDic_Impl( SvTreeListEntry* pEntry, sal_uInt16 nFlags,
286 const String& rStr ) : SvLBoxString( pEntry, nFlags, rStr ) {}
288 virtual void Paint(
289 const Point& rPos, SvTreeListBox& rOutDev, const SvViewDataEntry* pView, const SvTreeListEntry* pEntry);
292 void BrwStringDic_Impl::Paint(
293 const Point& rPos, SvTreeListBox& rDev, const SvViewDataEntry* /*pView*/,
294 const SvTreeListEntry* pEntry)
296 ModuleUserData_Impl* pData = (ModuleUserData_Impl*)pEntry->GetUserData();
297 Point aPos(rPos);
298 Font aOldFont( rDev.GetFont());
299 if(pData->IsParent())
301 Font aFont( aOldFont );
302 aFont.SetWeight( WEIGHT_BOLD );
303 rDev.SetFont( aFont );
304 aPos.X() = 0;
306 else
307 aPos.X() += 5;
308 rDev.DrawText( aPos, GetText() );
309 rDev.SetFont( aOldFont );
312 class OptionsBreakSet : public ModalDialog
314 OKButton aOKPB;
315 CancelButton aCancelPB;
316 FixedLine aValFL;
317 NumericField aValNF;
319 public:
320 OptionsBreakSet(Window* pParent, int nRID) :
321 ModalDialog(pParent, CUI_RES(RID_SVXDLG_LNG_ED_NUM_PREBREAK )),
322 aOKPB (this, CUI_RES(BT_OK_PREBREAK)),
323 aCancelPB (this, CUI_RES(BT_CANCEL_PREBREAK)),
324 aValFL (this, CUI_RES(FL_NUMVAL_PREBREAK)),
325 aValNF (this, CUI_RES(ED_PREBREAK))
327 DBG_ASSERT( STR_NUM_PRE_BREAK_DLG == nRID ||
328 STR_NUM_POST_BREAK_DLG == nRID ||
329 STR_NUM_MIN_WORDLEN_DLG == nRID, "unexpected RID" );
331 if (nRID != -1)
332 aValFL.SetText( String( CUI_RES(nRID) ) );
333 FreeResource();
336 NumericField& GetNumericFld() { return aValNF; }
340 /*--------------------------------------------------
341 Entry IDs for options listbox of dialog
342 --------------------------------------------------*/
344 enum EID_OPTIONS
346 EID_SPELL_AUTO,
347 EID_GRAMMAR_AUTO,
348 EID_CAPITAL_WORDS,
349 EID_WORDS_WITH_DIGITS,
350 EID_SPELL_SPECIAL,
351 EID_NUM_MIN_WORDLEN,
352 EID_NUM_PRE_BREAK,
353 EID_NUM_POST_BREAK,
354 EID_HYPH_AUTO,
355 EID_HYPH_SPECIAL
358 //! this array must have an entry for every value of EID_OPTIONS.
359 // It is used to get the respective property name.
360 static const char * aEidToPropName[] =
362 UPN_IS_SPELL_AUTO, // EID_SPELL_AUTO
363 UPN_IS_GRAMMAR_AUTO, // EID_GRAMMAR_AUTO
364 UPN_IS_SPELL_UPPER_CASE, // EID_CAPITAL_WORDS
365 UPN_IS_SPELL_WITH_DIGITS, // EID_WORDS_WITH_DIGITS
366 UPN_IS_SPELL_SPECIAL, // EID_SPELL_SPECIAL
367 UPN_HYPH_MIN_WORD_LENGTH, // EID_NUM_MIN_WORDLEN,
368 UPN_HYPH_MIN_LEADING, // EID_NUM_PRE_BREAK
369 UPN_HYPH_MIN_TRAILING, // EID_NUM_POST_BREAK
370 UPN_IS_HYPH_AUTO, // EID_HYPH_AUTO
371 UPN_IS_HYPH_SPECIAL // EID_HYPH_SPECIAL
375 static inline String lcl_GetPropertyName( EID_OPTIONS eEntryId )
377 DBG_ASSERT( (unsigned int) eEntryId < SAL_N_ELEMENTS(aEidToPropName), "index out of range" );
378 return rtl::OUString::createFromAscii( aEidToPropName[ (int) eEntryId ] );
381 // class OptionsUserData -------------------------------------------------
383 class OptionsUserData
385 sal_uLong nVal;
387 void SetModified();
389 public:
390 OptionsUserData( sal_uLong nUserData ) : nVal( nUserData ) {}
391 OptionsUserData( sal_uInt16 nEID,
392 sal_Bool bHasNV, sal_uInt16 nNumVal,
393 sal_Bool bCheckable, sal_Bool bChecked );
395 sal_uLong GetUserData() const { return nVal; }
396 sal_uInt16 GetEntryId() const { return (sal_uInt16)(nVal >> 16); }
397 sal_Bool HasNumericValue() const { return (sal_Bool)(nVal >> 10) & 0x01; }
398 sal_uInt16 GetNumericValue() const { return (sal_uInt16)(nVal & 0xFF); }
399 sal_Bool IsChecked() const { return (sal_Bool)(nVal >> 8) & 0x01; }
400 sal_Bool IsCheckable() const { return (sal_Bool)(nVal >> 9) & 0x01; }
401 sal_Bool IsModified() const { return (sal_Bool)(nVal >> 11) & 0x01; }
403 void SetChecked( sal_Bool bVal );
404 void SetNumericValue( sal_uInt8 nNumVal );
407 OptionsUserData::OptionsUserData( sal_uInt16 nEID,
408 sal_Bool bHasNV, sal_uInt16 nNumVal,
409 sal_Bool bCheckable, sal_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::SetChecked( sal_Bool bVal )
422 if (IsCheckable() && (IsChecked() != bVal))
424 nVal &= ~(1UL << 8);
425 nVal |= (sal_uLong)(bVal ? 1 : 0) << 8;
426 SetModified();
430 void OptionsUserData::SetNumericValue( sal_uInt8 nNumVal )
432 if (HasNumericValue() && (GetNumericValue() != nNumVal))
434 nVal &= 0xffffff00;
435 nVal |= (nNumVal);
436 SetModified();
440 void OptionsUserData::SetModified()
442 nVal |= (sal_uLong)1 << 11;
445 // class BrwString_Impl -------------------------------------------------
447 class BrwString_Impl : public SvLBoxString
449 public:
451 BrwString_Impl( SvTreeListEntry* pEntry, sal_uInt16 nFlags,
452 const String& rStr ) : SvLBoxString( pEntry, nFlags, rStr ) {}
454 virtual void Paint(
455 const Point& rPos, SvTreeListBox& rOutDev, const SvViewDataEntry* pView, const SvTreeListEntry* pEntry);
458 void BrwString_Impl::Paint(
459 const Point& rPos, SvTreeListBox& rDev, const SvViewDataEntry* /*pView*/,
460 const SvTreeListEntry* pEntry)
462 Point aPos(rPos);
463 aPos.X() += 20;
464 rDev.DrawText( aPos, GetText() );
465 if(pEntry->GetUserData())
467 Point aNewPos(aPos);
468 aNewPos.X() += rDev.GetTextWidth(GetText());
469 Font aOldFont( rDev.GetFont());
470 Font aFont( aOldFont );
471 aFont.SetWeight( WEIGHT_BOLD );
473 //??? convert the lower byte from the user date into a string
474 OptionsUserData aData( (sal_uLong) pEntry->GetUserData() );
475 if(aData.HasNumericValue())
477 rtl::OUStringBuffer sTxt;
478 sTxt.append(' ').append(static_cast<sal_Int32>(aData.GetNumericValue()));
479 rDev.SetFont( aFont );
480 rDev.DrawText( aNewPos, sTxt.makeStringAndClear() );
483 rDev.SetFont( aOldFont );
487 // ServiceInfo_Impl ----------------------------------------------------
489 struct ServiceInfo_Impl
491 OUString sDisplayName;
492 OUString sSpellImplName;
493 OUString sHyphImplName;
494 OUString sThesImplName;
495 OUString sGrammarImplName;
496 uno::Reference< XSpellChecker > xSpell;
497 uno::Reference< XHyphenator > xHyph;
498 uno::Reference< XThesaurus > xThes;
499 uno::Reference< XProofreader > xGrammar;
500 sal_Bool bConfigured;
502 ServiceInfo_Impl() : bConfigured(sal_False) {}
505 typedef std::vector< ServiceInfo_Impl > ServiceInfoArr;
506 typedef std::map< sal_Int16 /*LanguageType*/, Sequence< OUString > > LangImplNameTable;
509 // SvxLinguData_Impl ----------------------------------------------------
511 class SvxLinguData_Impl
513 //contains services and implementation names sorted by implementation names
514 ServiceInfoArr aDisplayServiceArr;
515 sal_uLong nDisplayServices;
517 Sequence< Locale > aAllServiceLocales;
518 LangImplNameTable aCfgSpellTable;
519 LangImplNameTable aCfgHyphTable;
520 LangImplNameTable aCfgThesTable;
521 LangImplNameTable aCfgGrammarTable;
522 uno::Reference< XMultiServiceFactory > xMSF;
523 uno::Reference< XLinguServiceManager2 > xLinguSrvcMgr;
526 sal_Bool AddRemove( Sequence< OUString > &rConfigured,
527 const OUString &rImplName, sal_Bool bAdd );
529 public:
530 SvxLinguData_Impl();
531 SvxLinguData_Impl( const SvxLinguData_Impl &rData );
532 ~SvxLinguData_Impl();
534 SvxLinguData_Impl & operator = (const SvxLinguData_Impl &rData);
536 uno::Reference<XLinguServiceManager2> & GetManager() { return xLinguSrvcMgr; }
538 void SetChecked( const Sequence< OUString > &rConfiguredServices );
539 void Reconfigure( const OUString &rDisplayName, sal_Bool bEnable );
541 const Sequence<Locale> & GetAllSupportedLocales() const { return aAllServiceLocales; }
543 const LangImplNameTable & GetSpellTable() const { return aCfgSpellTable; }
544 LangImplNameTable & GetSpellTable() { return aCfgSpellTable; }
545 const LangImplNameTable & GetHyphTable() const { return aCfgHyphTable; }
546 LangImplNameTable & GetHyphTable() { return aCfgHyphTable; }
547 const LangImplNameTable & GetThesTable() const { return aCfgThesTable; }
548 LangImplNameTable & GetThesTable() { return aCfgThesTable; }
549 const LangImplNameTable & GetGrammarTable() const { return aCfgGrammarTable; }
550 LangImplNameTable & GetGrammarTable() { return aCfgGrammarTable; }
552 const ServiceInfoArr & GetDisplayServiceArray() const { return aDisplayServiceArr; }
553 ServiceInfoArr & GetDisplayServiceArray() { return aDisplayServiceArr; }
555 const sal_uLong & GetDisplayServiceCount() const { return nDisplayServices; }
556 void SetDisplayServiceCount( sal_uLong nVal ) { nDisplayServices = nVal; }
558 // returns the list of service implementation names for the specified
559 // language and service (TYPE_SPELL, TYPE_HYPH, TYPE_THES) sorted in
560 // the proper order for the SvxEditModulesDlg (the ones from the
561 // configuration (keeping that order!) first and then the other ones.
562 // I.e. the ones available but not configured in arbitrary order).
563 // They available ones may contain names that do not(!) support that
564 // language.
565 Sequence< OUString > GetSortedImplNames( sal_Int16 nLang, sal_uInt8 nType );
567 ServiceInfo_Impl * GetInfoByImplName( const OUString &rSvcImplName );
571 static sal_Int32 lcl_SeqGetIndex( const Sequence< OUString > &rSeq, const OUString &rTxt )
573 sal_Int32 nRes = -1;
574 sal_Int32 nLen = rSeq.getLength();
575 const OUString *pString = rSeq.getConstArray();
576 for (sal_Int32 i = 0; i < nLen && nRes == -1; ++i)
578 if (pString[i] == rTxt)
579 nRes = i;
581 return nRes;
585 Sequence< OUString > SvxLinguData_Impl::GetSortedImplNames( sal_Int16 nLang, sal_uInt8 nType )
587 LangImplNameTable *pTable = 0;
588 switch (nType)
590 case TYPE_SPELL : pTable = &aCfgSpellTable; break;
591 case TYPE_HYPH : pTable = &aCfgHyphTable; break;
592 case TYPE_THES : pTable = &aCfgThesTable; break;
593 case TYPE_GRAMMAR : pTable = &aCfgGrammarTable; break;
595 Sequence< OUString > aRes;
596 if (pTable->count( nLang ))
597 aRes = (*pTable)[ nLang ]; // add configured services
598 sal_Int32 nIdx = aRes.getLength();
599 DBG_ASSERT( (sal_Int32) nDisplayServices >= nIdx, "size mismatch" );
600 aRes.realloc( nDisplayServices );
601 OUString *pRes = aRes.getArray();
603 // add not configured services
604 for (sal_Int32 i = 0; i < (sal_Int32) nDisplayServices; ++i)
606 const ServiceInfo_Impl &rInfo = aDisplayServiceArr[ i ];
607 OUString aImplName;
608 switch (nType)
610 case TYPE_SPELL : aImplName = rInfo.sSpellImplName; break;
611 case TYPE_HYPH : aImplName = rInfo.sHyphImplName; break;
612 case TYPE_THES : aImplName = rInfo.sThesImplName; break;
613 case TYPE_GRAMMAR : aImplName = rInfo.sGrammarImplName; break;
616 if (!aImplName.isEmpty() && (lcl_SeqGetIndex( aRes, aImplName) == -1)) // name not yet added
618 DBG_ASSERT( nIdx < aRes.getLength(), "index out of range" );
619 if (nIdx < aRes.getLength())
620 pRes[ nIdx++ ] = aImplName;
623 // don't forget to put aRes back to its actual size just in case you allocated too much
624 // since all of the names may have already been added
625 // otherwise you get duplicate entries in the edit dialog
626 aRes.realloc( nIdx );
627 return aRes;
631 ServiceInfo_Impl * SvxLinguData_Impl::GetInfoByImplName( const OUString &rSvcImplName )
633 ServiceInfo_Impl* pInfo = 0;
634 for (sal_uLong i = 0; i < nDisplayServices && !pInfo; ++i)
636 ServiceInfo_Impl &rTmp = aDisplayServiceArr[ i ];
637 if (rTmp.sSpellImplName == rSvcImplName ||
638 rTmp.sHyphImplName == rSvcImplName ||
639 rTmp.sThesImplName == rSvcImplName ||
640 rTmp.sGrammarImplName == rSvcImplName)
641 pInfo = &rTmp;
643 return pInfo;
647 //-----------------------------------------------------------------------------
649 static void lcl_MergeLocales(Sequence< Locale >& aAllLocales, const Sequence< Locale >& rAdd)
651 const Locale* pAdd = rAdd.getConstArray();
652 Sequence<Locale> aLocToAdd(rAdd.getLength());
653 const Locale* pAllLocales = aAllLocales.getConstArray();
654 Locale* pLocToAdd = aLocToAdd.getArray();
655 sal_Int32 nFound = 0;
656 sal_Int32 i;
657 for(i = 0; i < rAdd.getLength(); i++)
659 sal_Bool bFound = sal_False;
660 for(sal_Int32 j = 0; j < aAllLocales.getLength() && !bFound; j++)
662 bFound = pAdd[i].Language == pAllLocales[j].Language &&
663 pAdd[i].Country == pAllLocales[j].Country;
665 if(!bFound)
667 pLocToAdd[nFound++] = pAdd[i];
670 sal_Int32 nLength = aAllLocales.getLength();
671 aAllLocales.realloc( nLength + nFound);
672 Locale* pAllLocales2 = aAllLocales.getArray();
673 for(i = 0; i < nFound; i++)
674 pAllLocales2[nLength++] = pLocToAdd[i];
677 static void lcl_MergeDisplayArray(
678 SvxLinguData_Impl &rData,
679 const ServiceInfo_Impl &rToAdd )
681 sal_uLong nCnt = 0;
683 ServiceInfoArr &rSvcInfoArr = rData.GetDisplayServiceArray();
684 sal_uLong nEntries = rData.GetDisplayServiceCount();
686 ServiceInfo_Impl* pEntry;
687 for (sal_uLong i = 0; i < nEntries; ++i)
689 pEntry = &rSvcInfoArr[i];
690 if (pEntry && pEntry->sDisplayName == rToAdd.sDisplayName)
692 if(rToAdd.xSpell.is())
694 DBG_ASSERT( !pEntry->xSpell.is() &&
695 pEntry->sSpellImplName.isEmpty(),
696 "merge conflict" );
697 pEntry->sSpellImplName = rToAdd.sSpellImplName;
698 pEntry->xSpell = rToAdd.xSpell;
700 if(rToAdd.xGrammar.is())
702 DBG_ASSERT( !pEntry->xGrammar.is() &&
703 pEntry->sGrammarImplName.isEmpty(),
704 "merge conflict" );
705 pEntry->sGrammarImplName = rToAdd.sGrammarImplName;
706 pEntry->xGrammar = rToAdd.xGrammar;
708 if(rToAdd.xHyph.is())
710 DBG_ASSERT( !pEntry->xHyph.is() &&
711 pEntry->sHyphImplName.isEmpty(),
712 "merge conflict" );
713 pEntry->sHyphImplName = rToAdd.sHyphImplName;
714 pEntry->xHyph = rToAdd.xHyph;
716 if(rToAdd.xThes.is())
718 DBG_ASSERT( !pEntry->xThes.is() &&
719 pEntry->sThesImplName.isEmpty(),
720 "merge conflict" );
721 pEntry->sThesImplName = rToAdd.sThesImplName;
722 pEntry->xThes = rToAdd.xThes;
724 return ;
726 ++nCnt;
728 rData.GetDisplayServiceArray().push_back( rToAdd );
729 rData.SetDisplayServiceCount( nCnt + 1 );
732 SvxLinguData_Impl::SvxLinguData_Impl() :
733 nDisplayServices (0)
735 xMSF = ::comphelper::getProcessServiceFactory();
736 xLinguSrvcMgr = LinguServiceManager::create(comphelper::getComponentContext(xMSF));
738 const Locale& rCurrentLocale = Application::GetSettings().GetLanguageTag().getLocale();
739 Sequence<Any> aArgs(2);//second arguments has to be empty!
740 aArgs.getArray()[0] <<= SvxGetLinguPropertySet();
742 //read spell checker
743 Sequence< OUString > aSpellNames = xLinguSrvcMgr->getAvailableServices(
744 cSpell, Locale() );
745 const OUString* pSpellNames = aSpellNames.getConstArray();
747 sal_Int32 nIdx;
748 for(nIdx = 0; nIdx < aSpellNames.getLength(); nIdx++)
750 ServiceInfo_Impl aInfo;
751 aInfo.sSpellImplName = pSpellNames[nIdx];
752 aInfo.xSpell = uno::Reference<XSpellChecker>(
753 xMSF->createInstanceWithArguments(aInfo.sSpellImplName, aArgs), UNO_QUERY);
755 uno::Reference<XServiceDisplayName> xDispName(aInfo.xSpell, UNO_QUERY);
756 if(xDispName.is())
757 aInfo.sDisplayName = xDispName->getServiceDisplayName( rCurrentLocale );
759 const Sequence< Locale > aLocales( aInfo.xSpell->getLocales() );
760 //! suppress display of entries with no supported languages (see feature 110994)
761 if (aLocales.getLength())
763 lcl_MergeLocales( aAllServiceLocales, aLocales );
764 lcl_MergeDisplayArray( *this, aInfo );
768 //read grammar checker
769 Sequence< OUString > aGrammarNames = xLinguSrvcMgr->getAvailableServices(
770 cGrammar, Locale() );
771 const OUString* pGrammarNames = aGrammarNames.getConstArray();
772 for(nIdx = 0; nIdx < aGrammarNames.getLength(); nIdx++)
774 ServiceInfo_Impl aInfo;
775 aInfo.sGrammarImplName = pGrammarNames[nIdx];
776 aInfo.xGrammar = uno::Reference<XProofreader>(
777 xMSF->createInstanceWithArguments(aInfo.sGrammarImplName, aArgs), UNO_QUERY);
779 uno::Reference<XServiceDisplayName> xDispName(aInfo.xGrammar, UNO_QUERY);
780 if(xDispName.is())
781 aInfo.sDisplayName = xDispName->getServiceDisplayName( rCurrentLocale );
783 const Sequence< Locale > aLocales( aInfo.xGrammar->getLocales() );
784 //! suppress display of entries with no supported languages (see feature 110994)
785 if (aLocales.getLength())
787 lcl_MergeLocales( aAllServiceLocales, aLocales );
788 lcl_MergeDisplayArray( *this, aInfo );
792 //read hyphenator
793 Sequence< OUString > aHyphNames = xLinguSrvcMgr->getAvailableServices(
794 cHyph, Locale() );
795 const OUString* pHyphNames = aHyphNames.getConstArray();
796 for(nIdx = 0; nIdx < aHyphNames.getLength(); nIdx++)
798 ServiceInfo_Impl aInfo;
799 aInfo.sHyphImplName = pHyphNames[nIdx];
800 aInfo.xHyph = uno::Reference<XHyphenator>(
801 xMSF->createInstanceWithArguments(aInfo.sHyphImplName, aArgs), UNO_QUERY);
803 uno::Reference<XServiceDisplayName> xDispName(aInfo.xHyph, UNO_QUERY);
804 if(xDispName.is())
805 aInfo.sDisplayName = xDispName->getServiceDisplayName( rCurrentLocale );
807 const Sequence< Locale > aLocales( aInfo.xHyph->getLocales() );
808 //! suppress display of entries with no supported languages (see feature 110994)
809 if (aLocales.getLength())
811 lcl_MergeLocales( aAllServiceLocales, aLocales );
812 lcl_MergeDisplayArray( *this, aInfo );
816 //read thesauri
817 Sequence< OUString > aThesNames = xLinguSrvcMgr->getAvailableServices(
818 cThes, Locale() );
819 const OUString* pThesNames = aThesNames.getConstArray();
820 for(nIdx = 0; nIdx < aThesNames.getLength(); nIdx++)
822 ServiceInfo_Impl aInfo;
823 aInfo.sThesImplName = pThesNames[nIdx];
824 aInfo.xThes = uno::Reference<XThesaurus>(
825 xMSF->createInstanceWithArguments(aInfo.sThesImplName, aArgs), UNO_QUERY);
827 uno::Reference<XServiceDisplayName> xDispName(aInfo.xThes, UNO_QUERY);
828 if(xDispName.is())
829 aInfo.sDisplayName = xDispName->getServiceDisplayName( rCurrentLocale );
831 const Sequence< Locale > aLocales( aInfo.xThes->getLocales() );
832 //! suppress display of entries with no supported languages (see feature 110994)
833 if (aLocales.getLength())
835 lcl_MergeLocales( aAllServiceLocales, aLocales );
836 lcl_MergeDisplayArray( *this, aInfo );
840 Sequence< OUString > aCfgSvcs;
841 const Locale* pAllLocales = aAllServiceLocales.getConstArray();
842 for(sal_Int32 nLocale = 0; nLocale < aAllServiceLocales.getLength(); nLocale++)
844 sal_Int16 nLang = LanguageTag( pAllLocales[nLocale] ).getLanguageType();
846 aCfgSvcs = xLinguSrvcMgr->getConfiguredServices(cSpell, pAllLocales[nLocale]);
847 SetChecked( aCfgSvcs );
848 if (aCfgSvcs.getLength())
849 aCfgSpellTable[ nLang ] = aCfgSvcs;
851 aCfgSvcs = xLinguSrvcMgr->getConfiguredServices(cGrammar, pAllLocales[nLocale]);
852 SetChecked( aCfgSvcs );
853 if (aCfgSvcs.getLength())
854 aCfgGrammarTable[ nLang ] = aCfgSvcs;
856 aCfgSvcs = xLinguSrvcMgr->getConfiguredServices(cHyph, pAllLocales[nLocale]);
857 SetChecked( aCfgSvcs );
858 if (aCfgSvcs.getLength())
859 aCfgHyphTable[ nLang ] = aCfgSvcs;
861 aCfgSvcs = xLinguSrvcMgr->getConfiguredServices(cThes, pAllLocales[nLocale]);
862 SetChecked( aCfgSvcs );
863 if (aCfgSvcs.getLength())
864 aCfgThesTable[ nLang ] = aCfgSvcs;
868 SvxLinguData_Impl::SvxLinguData_Impl( const SvxLinguData_Impl &rData ) :
869 aDisplayServiceArr (rData.aDisplayServiceArr),
870 nDisplayServices (rData.nDisplayServices),
871 aAllServiceLocales (rData.aAllServiceLocales),
872 aCfgSpellTable (rData.aCfgSpellTable),
873 aCfgHyphTable (rData.aCfgHyphTable),
874 aCfgThesTable (rData.aCfgThesTable),
875 aCfgGrammarTable (rData.aCfgGrammarTable),
876 xMSF (rData.xMSF),
877 xLinguSrvcMgr (rData.xLinguSrvcMgr)
881 SvxLinguData_Impl & SvxLinguData_Impl::operator = (const SvxLinguData_Impl &rData)
883 xMSF = rData.xMSF;
884 xLinguSrvcMgr = rData.xLinguSrvcMgr;
885 aAllServiceLocales = rData.aAllServiceLocales;
886 aCfgSpellTable = rData.aCfgSpellTable;
887 aCfgHyphTable = rData.aCfgHyphTable;
888 aCfgThesTable = rData.aCfgThesTable;
889 aCfgGrammarTable = rData.aCfgGrammarTable;
890 aDisplayServiceArr = rData.aDisplayServiceArr;
891 nDisplayServices = rData.nDisplayServices;
892 return *this;
895 SvxLinguData_Impl::~SvxLinguData_Impl()
899 void SvxLinguData_Impl::SetChecked(const Sequence<OUString>& rConfiguredServices)
901 const OUString* pConfiguredServices = rConfiguredServices.getConstArray();
902 for(sal_Int32 n = 0; n < rConfiguredServices.getLength(); n++)
904 ServiceInfo_Impl* pEntry;
905 for (sal_uLong i = 0; i < nDisplayServices; ++i)
907 pEntry = &aDisplayServiceArr[i];
908 if (pEntry && !pEntry->bConfigured)
910 const OUString &rSrvcImplName = pConfiguredServices[n];
911 if (!rSrvcImplName.isEmpty() &&
912 (pEntry->sSpellImplName == rSrvcImplName ||
913 pEntry->sGrammarImplName == rSrvcImplName ||
914 pEntry->sHyphImplName == rSrvcImplName ||
915 pEntry->sThesImplName == rSrvcImplName))
917 pEntry->bConfigured = sal_True;
918 break;
925 sal_Bool SvxLinguData_Impl::AddRemove(
926 Sequence< OUString > &rConfigured,
927 const OUString &rImplName, sal_Bool bAdd )
929 sal_Bool bRet = sal_False; // modified?
931 sal_Int32 nEntries = rConfigured.getLength();
932 sal_Int32 nPos = lcl_SeqGetEntryPos(rConfigured, rImplName);
933 if (bAdd && nPos < 0) // add new entry
935 rConfigured.realloc( ++nEntries );
936 OUString *pConfigured = rConfigured.getArray();
937 pConfigured = rConfigured.getArray();
938 pConfigured[nEntries - 1] = rImplName;
939 bRet = sal_True;
941 else if (!bAdd && nPos >= 0) // remove existing entry
943 OUString *pConfigured = rConfigured.getArray();
944 for (sal_Int32 i = nPos; i < nEntries - 1; ++i)
945 pConfigured[i] = pConfigured[i + 1];
946 rConfigured.realloc(--nEntries);
947 bRet = sal_True;
950 return bRet;
954 void SvxLinguData_Impl::Reconfigure( const OUString &rDisplayName, sal_Bool bEnable )
956 DBG_ASSERT( !rDisplayName.isEmpty(), "empty DisplayName" );
958 ServiceInfo_Impl *pInfo = 0;
959 ServiceInfo_Impl *pTmp = 0;
960 for (sal_uLong i = 0; i < nDisplayServices; ++i)
962 pTmp = &aDisplayServiceArr[i];
963 if (pTmp && pTmp->sDisplayName == rDisplayName)
965 pInfo = pTmp;
966 break;
969 DBG_ASSERT( pInfo, "DisplayName entry not found" );
970 if (pInfo)
972 pInfo->bConfigured = bEnable;
974 Sequence< Locale > aLocales;
975 const Locale *pLocale = 0;
976 sal_Int32 nLocales = 0;
977 sal_Int32 i;
979 // update configured spellchecker entries
980 if (pInfo->xSpell.is())
982 aLocales = pInfo->xSpell->getLocales();
983 pLocale = aLocales.getConstArray();
984 nLocales = aLocales.getLength();
985 for (i = 0; i < nLocales; ++i)
987 sal_Int16 nLang = LanguageTag( pLocale[i] ).getLanguageType();
988 if (!aCfgSpellTable.count( nLang ) && bEnable)
989 aCfgSpellTable[ nLang ] = Sequence< OUString >();
990 if (aCfgSpellTable.count( nLang ))
991 AddRemove( aCfgSpellTable[ nLang ], pInfo->sSpellImplName, bEnable );
995 // update configured grammar checker entries
996 if (pInfo->xGrammar.is())
998 aLocales = pInfo->xGrammar->getLocales();
999 pLocale = aLocales.getConstArray();
1000 nLocales = aLocales.getLength();
1001 for (i = 0; i < nLocales; ++i)
1003 sal_Int16 nLang = LanguageTag( pLocale[i] ).getLanguageType();
1004 if (!aCfgGrammarTable.count( nLang ) && bEnable)
1005 aCfgGrammarTable[ nLang ] = Sequence< OUString >();
1006 if (aCfgGrammarTable.count( nLang ))
1007 AddRemove( aCfgGrammarTable[ nLang ], pInfo->sGrammarImplName, bEnable );
1011 // update configured hyphenator entries
1012 if (pInfo->xHyph.is())
1014 aLocales = pInfo->xHyph->getLocales();
1015 pLocale = aLocales.getConstArray();
1016 nLocales = aLocales.getLength();
1017 for (i = 0; i < nLocales; ++i)
1019 sal_Int16 nLang = LanguageTag( pLocale[i] ).getLanguageType();
1020 if (!aCfgHyphTable.count( nLang ) && bEnable)
1021 aCfgHyphTable[ nLang ] = Sequence< OUString >();
1022 if (aCfgHyphTable.count( nLang ))
1023 AddRemove( aCfgHyphTable[ nLang ], pInfo->sHyphImplName, bEnable );
1027 // update configured spellchecker entries
1028 if (pInfo->xThes.is())
1030 aLocales = pInfo->xThes->getLocales();
1031 pLocale = aLocales.getConstArray();
1032 nLocales = aLocales.getLength();
1033 for (i = 0; i < nLocales; ++i)
1035 sal_Int16 nLang = LanguageTag( pLocale[i] ).getLanguageType();
1036 if (!aCfgThesTable.count( nLang ) && bEnable)
1037 aCfgThesTable[ nLang ] = Sequence< OUString >();
1038 if (aCfgThesTable.count( nLang ))
1039 AddRemove( aCfgThesTable[ nLang ], pInfo->sThesImplName, bEnable );
1046 // class SvxLinguTabPage -------------------------------------------------
1048 SvxLinguTabPage::SvxLinguTabPage( Window* pParent,
1049 const SfxItemSet& rSet ):
1051 SfxTabPage( pParent, CUI_RES( RID_SFXPAGE_LINGU ), rSet ),
1053 aLinguisticFL ( this, CUI_RES( FL_LINGUISTIC ) ),
1054 aLinguModulesFT ( this, CUI_RES( FT_LINGU_MODULES ) ),
1055 aLinguModulesCLB ( this, CUI_RES( CLB_LINGU_MODULES ) ),
1056 aLinguModulesEditPB ( this, CUI_RES( PB_LINGU_MODULES_EDIT ) ),
1057 aLinguDicsFT ( this, CUI_RES( FT_LINGU_DICS ) ),
1058 aLinguDicsCLB ( this, CUI_RES( CLB_LINGU_DICS ) ),
1059 aLinguDicsNewPB ( this, CUI_RES( PB_LINGU_DICS_NEW_DIC ) ),
1060 aLinguDicsEditPB ( this, CUI_RES( PB_LINGU_DICS_EDIT_DIC ) ),
1061 aLinguDicsDelPB ( this, CUI_RES( PB_LINGU_DICS_DEL_DIC ) ),
1062 aLinguOptionsFT ( this, CUI_RES( FT_LINGU_OPTIONS ) ),
1063 aLinguOptionsCLB ( this, CUI_RES( CLB_LINGU_OPTIONS ) ),
1064 aLinguOptionsEditPB ( this, CUI_RES( PB_LINGU_OPTIONS_EDIT ) ),
1065 aMoreDictsLink ( this, CUI_RES( FT_LINGU_OPTIONS_MOREDICTS ) ),
1066 sCapitalWords ( CUI_RES( STR_CAPITAL_WORDS ) ),
1067 sWordsWithDigits ( CUI_RES( STR_WORDS_WITH_DIGITS ) ),
1068 sSpellSpecial ( CUI_RES( STR_SPELL_SPECIAL ) ),
1069 sSpellAuto ( CUI_RES( STR_SPELL_AUTO ) ),
1070 sGrammarAuto ( CUI_RES( STR_GRAMMAR_AUTO ) ),
1071 sNumMinWordlen ( CUI_RES( STR_NUM_MIN_WORDLEN ) ),
1072 sNumPreBreak ( CUI_RES( STR_NUM_PRE_BREAK ) ),
1073 sNumPostBreak ( CUI_RES( STR_NUM_POST_BREAK ) ),
1074 sHyphAuto ( CUI_RES( STR_HYPH_AUTO ) ),
1075 sHyphSpecial ( CUI_RES( STR_HYPH_SPECIAL ) ),
1077 pLinguData ( NULL )
1079 pCheckButtonData = NULL;
1081 aLinguModulesCLB.SetStyle( aLinguModulesCLB.GetStyle()|WB_CLIPCHILDREN|WB_HSCROLL|WB_FORCE_MAKEVISIBLE );
1082 aLinguModulesCLB.SetHelpId(HID_CLB_LINGU_MODULES );
1083 aLinguModulesCLB.SetHighlightRange();
1084 aLinguModulesCLB.SetSelectHdl( LINK( this, SvxLinguTabPage, SelectHdl_Impl ));
1085 aLinguModulesCLB.SetDoubleClickHdl(LINK(this, SvxLinguTabPage, BoxDoubleClickHdl_Impl));
1086 aLinguModulesCLB.SetCheckButtonHdl(LINK(this, SvxLinguTabPage, BoxCheckButtonHdl_Impl));
1088 aLinguModulesEditPB.SetClickHdl( LINK( this, SvxLinguTabPage, ClickHdl_Impl ));
1089 aLinguOptionsEditPB.SetClickHdl( LINK( this, SvxLinguTabPage, ClickHdl_Impl ));
1091 aLinguDicsCLB.SetStyle( aLinguDicsCLB.GetStyle()|WB_CLIPCHILDREN|WB_HSCROLL|WB_FORCE_MAKEVISIBLE );
1092 aLinguDicsCLB.SetHelpId(HID_CLB_EDIT_MODULES_DICS );
1093 aLinguDicsCLB.SetHighlightRange();
1094 aLinguDicsCLB.SetSelectHdl( LINK( this, SvxLinguTabPage, SelectHdl_Impl ));
1095 aLinguDicsCLB.SetCheckButtonHdl(LINK(this, SvxLinguTabPage, BoxCheckButtonHdl_Impl));
1097 aLinguDicsNewPB.SetClickHdl( LINK( this, SvxLinguTabPage, ClickHdl_Impl ));
1098 aLinguDicsEditPB.SetClickHdl( LINK( this, SvxLinguTabPage, ClickHdl_Impl ));
1099 aLinguDicsDelPB.SetClickHdl( LINK( this, SvxLinguTabPage, ClickHdl_Impl ));
1101 aLinguOptionsCLB.SetStyle( aLinguOptionsCLB.GetStyle()|WB_CLIPCHILDREN|WB_HSCROLL|WB_FORCE_MAKEVISIBLE );
1102 aLinguOptionsCLB.SetHelpId(HID_CLB_LINGU_OPTIONS );
1103 aLinguOptionsCLB.SetHighlightRange();
1104 aLinguOptionsCLB.SetSelectHdl( LINK( this, SvxLinguTabPage, SelectHdl_Impl ));
1105 aLinguOptionsCLB.SetDoubleClickHdl(LINK(this, SvxLinguTabPage, BoxDoubleClickHdl_Impl));
1107 if ( SvtExtendedSecurityOptions().GetOpenHyperlinkMode()
1108 != SvtExtendedSecurityOptions::OPEN_NEVER )
1110 aMoreDictsLink.SetURL( String(
1111 RTL_CONSTASCII_USTRINGPARAM( "http://extensions.libreoffice.org/dictionaries/" ) ) );
1112 aMoreDictsLink.SetClickHdl( LINK( this, SvxLinguTabPage, OpenURLHdl_Impl ) );
1114 else
1115 aMoreDictsLink.Hide();
1117 String sAccessibleNameModuleEdit( CUI_RES( STR_LINGU_MODULES_EDIT ) );
1118 String sAccessibleNameDicsEdit ( CUI_RES( STR_LINGU_DICS_EDIT_DIC ) );
1119 String sAccessibleNameOptionEdit( CUI_RES( STR_LINGU_OPTIONS_EDIT ) );
1121 aLinguModulesEditPB.SetAccessibleName(sAccessibleNameModuleEdit);
1122 aLinguDicsEditPB.SetAccessibleName(sAccessibleNameDicsEdit);
1123 aLinguOptionsEditPB.SetAccessibleName(sAccessibleNameOptionEdit);
1125 xProp = uno::Reference< XPropertySet >( SvxGetLinguPropertySet(), UNO_QUERY );
1126 xDicList = uno::Reference< XDictionaryList >( SvxGetDictionaryList(), UNO_QUERY );
1127 if (xDicList.is())
1129 // keep references to all **currently** available dictionaries,
1130 // since the diclist may get changed meanwhile (e.g. through the API).
1131 // We want the dialog to operate on the same set of dictionaries it
1132 // was started with.
1133 // Also we have to take care to not loose the last reference when
1134 // someone else removes a dictionary from the list.
1135 // removed dics will be replaced by NULL new entries be added to the end
1136 // Thus we may use indizes as consistent references.
1137 aDics = xDicList->getDictionaries();
1139 UpdateDicBox_Impl();
1141 else
1143 aLinguDicsFT.Disable();
1144 aLinguDicsCLB.Disable();
1145 aLinguDicsNewPB.Disable();
1146 aLinguDicsEditPB.Disable();
1147 aLinguDicsDelPB.Disable();
1150 const SfxSpellCheckItem* pItem = 0;
1151 SfxItemState eItemState = SFX_ITEM_UNKNOWN;
1153 eItemState = rSet.GetItemState( GetWhich( SID_ATTR_SPELL ),
1154 sal_False, (const SfxPoolItem**)&pItem );
1156 // is it about a default-item?
1157 if ( eItemState == SFX_ITEM_DEFAULT )
1158 pItem = (const SfxSpellCheckItem*)&(rSet.Get( GetWhich( SID_ATTR_SPELL ) ) );
1159 else if ( eItemState == SFX_ITEM_DONTCARE )
1160 pItem = NULL;
1162 FreeResource();
1165 // -----------------------------------------------------------------------
1167 SvxLinguTabPage::~SvxLinguTabPage()
1169 if (pLinguData)
1170 delete pLinguData;
1173 //------------------------------------------------------------------------
1175 // don't throw away overloaded
1176 sal_uInt16* SvxLinguTabPage::GetRanges()
1178 //TL???
1179 return pRanges;
1182 //------------------------------------------------------------------------
1184 SfxTabPage* SvxLinguTabPage::Create( Window* pParent,
1185 const SfxItemSet& rAttrSet )
1187 return ( new SvxLinguTabPage( pParent, rAttrSet ) );
1190 //------------------------------------------------------------------------
1192 sal_Bool SvxLinguTabPage::FillItemSet( SfxItemSet& rCoreSet )
1194 sal_Bool bModified = sal_True; // !!!!
1196 // if not HideGroups was called with GROUP_MODULES...
1197 if (aLinguModulesCLB.IsVisible())
1199 DBG_ASSERT( pLinguData, "pLinguData not yet initialized" );
1200 if (!pLinguData)
1201 pLinguData = new SvxLinguData_Impl;
1203 LangImplNameTable::const_iterator aIt;
1205 // update spellchecker configuration entries
1206 const LangImplNameTable *pTable = &pLinguData->GetSpellTable();
1207 for (aIt = pTable->begin(); aIt != pTable->end(); ++aIt)
1209 sal_Int16 nLang = aIt->first;
1210 const Sequence< OUString > aImplNames( aIt->second );
1211 uno::Reference< XLinguServiceManager2 > xMgr( pLinguData->GetManager() );
1212 Locale aLocale( LanguageTag(nLang).getLocale() );
1213 if (xMgr.is())
1214 xMgr->setConfiguredServices( cSpell, aLocale, aImplNames );
1217 // update grammar checker configuration entries
1218 pTable = &pLinguData->GetGrammarTable();
1219 for (aIt = pTable->begin(); aIt != pTable->end(); ++aIt)
1221 sal_Int16 nLang = aIt->first;
1222 const Sequence< OUString > aImplNames( aIt->second );
1223 uno::Reference< XLinguServiceManager2 > xMgr( pLinguData->GetManager() );
1224 Locale aLocale( LanguageTag(nLang).getLocale() );
1225 if (xMgr.is())
1226 xMgr->setConfiguredServices( cGrammar, aLocale, aImplNames );
1229 // update hyphenator configuration entries
1230 pTable = &pLinguData->GetHyphTable();
1231 for (aIt = pTable->begin(); aIt != pTable->end(); ++aIt)
1233 sal_Int16 nLang = aIt->first;
1234 const Sequence< OUString > aImplNames( aIt->second );
1235 uno::Reference< XLinguServiceManager2 > xMgr( pLinguData->GetManager() );
1236 Locale aLocale( LanguageTag(nLang).getLocale() );
1237 if (xMgr.is())
1238 xMgr->setConfiguredServices( cHyph, aLocale, aImplNames );
1241 // update thesaurus configuration entries
1242 pTable = &pLinguData->GetThesTable();
1243 for (aIt = pTable->begin(); aIt != pTable->end(); ++aIt)
1245 sal_Int16 nLang = aIt->first;
1246 const Sequence< OUString > aImplNames( aIt->second );
1247 uno::Reference< XLinguServiceManager2 > xMgr( pLinguData->GetManager() );
1248 Locale aLocale( LanguageTag(nLang).getLocale() );
1249 if (xMgr.is())
1250 xMgr->setConfiguredServices( cThes, aLocale, aImplNames );
1256 // activate dictionaries according to checkbox state
1258 Sequence< OUString > aActiveDics;
1259 sal_Int32 nActiveDics = 0;
1260 sal_uLong nEntries = aLinguDicsCLB.GetEntryCount();
1261 for (sal_uLong i = 0; i < nEntries; ++i)
1263 sal_Int32 nDics = aDics.getLength();
1265 aActiveDics.realloc( nDics );
1266 OUString *pActiveDic = aActiveDics.getArray();
1268 SvTreeListEntry *pEntry = aLinguDicsCLB.GetEntry( i );
1269 if (pEntry)
1271 DicUserData aData( (sal_uLong)pEntry->GetUserData() );
1272 if (aData.GetEntryId() < nDics)
1274 sal_Bool bChecked = aLinguDicsCLB.IsChecked( (sal_uInt16) i );
1275 uno::Reference< XDictionary > xDic( aDics.getConstArray()[ i ] );
1276 if (xDic.is())
1278 if (SvxGetIgnoreAllList() == xDic)
1279 bChecked = sal_True;
1280 xDic->setActive( bChecked );
1282 if (bChecked)
1284 String aDicName( xDic->getName() );
1285 pActiveDic[ nActiveDics++ ] = aDicName;
1292 aActiveDics.realloc( nActiveDics );
1293 Any aTmp;
1294 aTmp <<= aActiveDics;
1295 SvtLinguConfig aLngCfg;
1296 aLngCfg.SetProperty( UPH_ACTIVE_DICTIONARIES, aTmp );
1299 nEntries = aLinguOptionsCLB.GetEntryCount();
1300 for (sal_uInt16 j = 0; j < nEntries; ++j)
1302 SvTreeListEntry *pEntry = aLinguOptionsCLB.GetEntry( j );
1304 OptionsUserData aData( (sal_uLong)pEntry->GetUserData() );
1305 String aPropName( lcl_GetPropertyName( (EID_OPTIONS) aData.GetEntryId() ) );
1307 Any aAny;
1308 if (aData.IsCheckable())
1310 sal_Bool bChecked = aLinguOptionsCLB.IsChecked( j );
1311 aAny <<= bChecked;
1313 else if (aData.HasNumericValue())
1315 sal_Int16 nVal = aData.GetNumericValue();
1316 aAny <<= nVal;
1319 if (xProp.is())
1320 xProp->setPropertyValue( aPropName, aAny );
1321 aLngCfg.SetProperty( aPropName, aAny );
1324 SvTreeListEntry *pPreBreakEntry = aLinguOptionsCLB.GetEntry( (sal_uInt16) EID_NUM_PRE_BREAK );
1325 SvTreeListEntry *pPostBreakEntry = aLinguOptionsCLB.GetEntry( (sal_uInt16) EID_NUM_POST_BREAK );
1326 DBG_ASSERT( pPreBreakEntry, "NULL Pointer" );
1327 DBG_ASSERT( pPostBreakEntry, "NULL Pointer" );
1328 if (pPreBreakEntry && pPostBreakEntry)
1330 OptionsUserData aPreBreakData( (sal_uLong)pPreBreakEntry->GetUserData() );
1331 OptionsUserData aPostBreakData( (sal_uLong)pPostBreakEntry->GetUserData() );
1332 if ( aPreBreakData.IsModified() || aPostBreakData.IsModified() )
1334 SfxHyphenRegionItem aHyp( GetWhich( SID_ATTR_HYPHENREGION ) );
1335 aHyp.GetMinLead() = (sal_uInt8) aPreBreakData.GetNumericValue();
1336 aHyp.GetMinTrail() = (sal_uInt8) aPostBreakData.GetNumericValue();
1337 rCoreSet.Put( aHyp );
1342 // automatic spell checking
1343 sal_Bool bNewAutoCheck = aLinguOptionsCLB.IsChecked( (sal_uInt16) EID_SPELL_AUTO );
1344 const SfxPoolItem* pOld = GetOldItem( rCoreSet, SID_AUTOSPELL_CHECK );
1345 if ( !pOld || ( (SfxBoolItem*)pOld )->GetValue() != bNewAutoCheck )
1347 rCoreSet.Put( SfxBoolItem( GetWhich( SID_AUTOSPELL_CHECK ),
1348 bNewAutoCheck ) );
1349 bModified |= sal_True;
1352 return bModified;
1355 // ----------------------------------------------------------------------
1357 sal_uLong SvxLinguTabPage::GetDicUserData( const uno::Reference< XDictionary > &rxDic, sal_uInt16 nIdx )
1359 sal_uLong nRes = 0;
1360 DBG_ASSERT( rxDic.is(), "dictionary not supplied" );
1361 if (rxDic.is())
1363 uno::Reference< frame::XStorable > xStor( rxDic, UNO_QUERY );
1365 sal_Bool bChecked = rxDic->isActive();
1366 sal_Bool bEditable = !xStor.is() || !xStor->isReadonly();
1367 sal_Bool bDeletable = bEditable;
1369 nRes = DicUserData( nIdx,
1370 bChecked, bEditable, bDeletable ).GetUserData();
1372 return nRes;
1376 void SvxLinguTabPage::AddDicBoxEntry(
1377 const uno::Reference< XDictionary > &rxDic,
1378 sal_uInt16 nIdx )
1380 aLinguDicsCLB.SetUpdateMode(sal_False);
1382 String aTxt( ::GetDicInfoStr( rxDic->getName(),
1383 LanguageTag( rxDic->getLocale() ).getLanguageType(),
1384 DictionaryType_NEGATIVE == rxDic->getDictionaryType() ) );
1385 aLinguDicsCLB.InsertEntry( aTxt, (sal_uInt16)LISTBOX_APPEND ); // append at end
1386 SvTreeListEntry* pEntry = aLinguDicsCLB.GetEntry( aLinguDicsCLB.GetEntryCount() - 1 );
1387 DBG_ASSERT( pEntry, "failed to add entry" );
1388 if (pEntry)
1390 DicUserData aData( GetDicUserData( rxDic, nIdx ) );
1391 pEntry->SetUserData( (void *) aData.GetUserData() );
1392 lcl_SetCheckButton( pEntry, aData.IsChecked() );
1395 aLinguDicsCLB.SetUpdateMode(sal_True);
1398 // ----------------------------------------------------------------------
1400 void SvxLinguTabPage::UpdateDicBox_Impl()
1402 aLinguDicsCLB.SetUpdateMode(sal_False);
1403 aLinguDicsCLB.Clear();
1405 sal_Int32 nDics = aDics.getLength();
1406 const uno::Reference< XDictionary > *pDic = aDics.getConstArray();
1407 for (sal_Int32 i = 0; i < nDics; ++i)
1409 const uno::Reference< XDictionary > &rDic = pDic[i];
1410 if (rDic.is())
1411 AddDicBoxEntry( rDic, (sal_uInt16)i );
1414 aLinguDicsCLB.SetUpdateMode(sal_True);
1417 // ----------------------------------------------------------------------
1419 void SvxLinguTabPage::UpdateModulesBox_Impl()
1421 if (pLinguData)
1423 const ServiceInfoArr &rAllDispSrvcArr = pLinguData->GetDisplayServiceArray();
1424 const sal_uLong nDispSrvcCount = pLinguData->GetDisplayServiceCount();
1426 aLinguModulesCLB.Clear();
1428 for (sal_uInt16 i = 0; i < nDispSrvcCount; ++i)
1430 const ServiceInfo_Impl &rInfo = rAllDispSrvcArr[i];
1431 aLinguModulesCLB.InsertEntry( rInfo.sDisplayName, (sal_uInt16)LISTBOX_APPEND );
1432 SvTreeListEntry* pEntry = aLinguModulesCLB.GetEntry(i);
1433 pEntry->SetUserData( (void *) &rInfo );
1434 aLinguModulesCLB.CheckEntryPos( i, rInfo.bConfigured );
1436 aLinguModulesEditPB.Enable( nDispSrvcCount > 0 );
1440 //------------------------------------------------------------------------
1442 void SvxLinguTabPage::Reset( const SfxItemSet& rSet )
1444 // if not HideGroups was called with GROUP_MODULES...
1445 if (aLinguModulesCLB.IsVisible())
1447 if (!pLinguData)
1448 pLinguData = new SvxLinguData_Impl;
1449 UpdateModulesBox_Impl();
1454 // get data from configuration
1457 SvtLinguConfig aLngCfg;
1459 aLinguOptionsCLB.SetUpdateMode(sal_False);
1460 aLinguOptionsCLB.Clear();
1462 SvTreeList *pModel = aLinguOptionsCLB.GetModel();
1463 SvTreeListEntry* pEntry = NULL;
1465 sal_Int16 nVal = 0;
1466 sal_Bool bVal = sal_False;
1467 sal_uLong nUserData = 0;
1469 pEntry = CreateEntry( sSpellAuto, CBCOL_FIRST );
1470 aLngCfg.GetProperty( UPN_IS_SPELL_AUTO ) >>= bVal;
1471 const SfxPoolItem* pItem = GetItem( rSet, SID_AUTOSPELL_CHECK );
1472 if (pItem)
1473 bVal = ((SfxBoolItem *) pItem)->GetValue();
1474 nUserData = OptionsUserData( EID_SPELL_AUTO, sal_False, 0, sal_True, bVal).GetUserData();
1475 pEntry->SetUserData( (void *)nUserData );
1476 pModel->Insert( pEntry );
1477 lcl_SetCheckButton( pEntry, bVal );
1479 pEntry = CreateEntry( sGrammarAuto, CBCOL_FIRST );
1480 aLngCfg.GetProperty( UPN_IS_GRAMMAR_AUTO ) >>= bVal;
1481 nUserData = OptionsUserData( EID_GRAMMAR_AUTO, sal_False, 0, sal_True, bVal).GetUserData();
1482 pEntry->SetUserData( (void *)nUserData );
1483 pModel->Insert( pEntry );
1484 lcl_SetCheckButton( pEntry, bVal );
1486 pEntry = CreateEntry( sCapitalWords, CBCOL_FIRST );
1487 aLngCfg.GetProperty( UPN_IS_SPELL_UPPER_CASE ) >>= bVal;
1488 nUserData = OptionsUserData( EID_CAPITAL_WORDS, sal_False, 0, sal_True, bVal).GetUserData();
1489 pEntry->SetUserData( (void *)nUserData );
1490 pModel->Insert( pEntry );
1491 lcl_SetCheckButton( pEntry, bVal );
1493 pEntry = CreateEntry( sWordsWithDigits, CBCOL_FIRST );
1494 aLngCfg.GetProperty( UPN_IS_SPELL_WITH_DIGITS ) >>= bVal;
1495 nUserData = OptionsUserData( EID_WORDS_WITH_DIGITS, sal_False, 0, sal_True, bVal).GetUserData();
1496 pEntry->SetUserData( (void *)nUserData );
1497 pModel->Insert( pEntry );
1498 lcl_SetCheckButton( pEntry, bVal );
1500 pEntry = CreateEntry( sSpellSpecial, CBCOL_FIRST );
1501 aLngCfg.GetProperty( UPN_IS_SPELL_SPECIAL ) >>= bVal;
1502 nUserData = OptionsUserData( EID_SPELL_SPECIAL, sal_False, 0, sal_True, bVal).GetUserData();
1503 pEntry->SetUserData( (void *)nUserData );
1504 pModel->Insert( pEntry );
1505 lcl_SetCheckButton( pEntry, bVal );
1507 pEntry = CreateEntry( sNumMinWordlen, CBCOL_SECOND );
1508 aLngCfg.GetProperty( UPN_HYPH_MIN_WORD_LENGTH ) >>= nVal;
1509 nUserData = OptionsUserData( EID_NUM_MIN_WORDLEN, sal_True, (sal_uInt16)nVal, sal_False, sal_False).GetUserData();
1510 pEntry->SetUserData( (void *)nUserData );
1511 pModel->Insert( pEntry );
1513 const SfxHyphenRegionItem *pHyp = NULL;
1514 sal_uInt16 nWhich = GetWhich( SID_ATTR_HYPHENREGION );
1515 if ( rSet.GetItemState( nWhich, sal_False ) == SFX_ITEM_SET )
1516 pHyp = &( (const SfxHyphenRegionItem &) rSet.Get( nWhich ) );
1518 pEntry = CreateEntry( sNumPreBreak, CBCOL_SECOND );
1519 aLngCfg.GetProperty( UPN_HYPH_MIN_LEADING ) >>= nVal;
1520 if (pHyp)
1521 nVal = (sal_Int16) pHyp->GetMinLead();
1522 nUserData = OptionsUserData( EID_NUM_PRE_BREAK, sal_True, (sal_uInt16)nVal, sal_False, sal_False).GetUserData();
1523 pEntry->SetUserData( (void *)nUserData );
1524 pModel->Insert( pEntry );
1526 pEntry = CreateEntry( sNumPostBreak, CBCOL_SECOND );
1527 aLngCfg.GetProperty( UPN_HYPH_MIN_TRAILING ) >>= nVal;
1528 if (pHyp)
1529 nVal = (sal_Int16) pHyp->GetMinTrail();
1530 nUserData = OptionsUserData( EID_NUM_POST_BREAK, sal_True, (sal_uInt16)nVal, sal_False, sal_False).GetUserData();
1531 pEntry->SetUserData( (void *)nUserData );
1532 pModel->Insert( pEntry );
1534 pEntry = CreateEntry( sHyphAuto, CBCOL_FIRST );
1535 aLngCfg.GetProperty( UPN_IS_HYPH_AUTO ) >>= bVal;
1536 nUserData = OptionsUserData( EID_HYPH_AUTO, sal_False, 0, sal_True, bVal).GetUserData();
1537 pEntry->SetUserData( (void *)nUserData );
1538 pModel->Insert( pEntry );
1539 lcl_SetCheckButton( pEntry, bVal );
1541 pEntry = CreateEntry( sHyphSpecial, CBCOL_FIRST );
1542 aLngCfg.GetProperty( UPN_IS_HYPH_SPECIAL ) >>= bVal;
1543 nUserData = OptionsUserData( EID_HYPH_SPECIAL, sal_False, 0, sal_True, bVal).GetUserData();
1544 pEntry->SetUserData( (void *)nUserData );
1545 pModel->Insert( pEntry );
1546 lcl_SetCheckButton( pEntry, bVal );
1548 aLinguOptionsCLB.SetUpdateMode(sal_True);
1551 // -----------------------------------------------------------------------
1553 IMPL_LINK( SvxLinguTabPage, BoxDoubleClickHdl_Impl, SvTreeListBox *, pBox )
1555 if (pBox == &aLinguModulesCLB)
1557 //! in order to avoid a bug causing a GPF when double clicking
1558 //! on a module entry and exiting the "Edit Modules" dialog
1559 //! after that.
1560 Application::PostUserEvent( LINK(
1561 this, SvxLinguTabPage, PostDblClickHdl_Impl ) );
1563 else if (pBox == &aLinguOptionsCLB)
1565 ClickHdl_Impl(&aLinguOptionsEditPB);
1567 return 0;
1570 // -----------------------------------------------------------------------
1572 IMPL_LINK_NOARG(SvxLinguTabPage, PostDblClickHdl_Impl)
1574 ClickHdl_Impl(&aLinguModulesEditPB);
1575 return 0;
1578 // -----------------------------------------------------------------------
1580 IMPL_LINK_NOARG(SvxLinguTabPage, OpenURLHdl_Impl)
1582 ::rtl::OUString sURL( aMoreDictsLink.GetURL() );
1583 lcl_OpenURL( sURL );
1584 return 0;
1587 // -----------------------------------------------------------------------
1589 IMPL_LINK( SvxLinguTabPage, BoxCheckButtonHdl_Impl, SvTreeListBox *, pBox )
1591 if (pBox == &aLinguModulesCLB)
1593 DBG_ASSERT( pLinguData, "NULL pointer, LinguData missing" );
1594 sal_uInt16 nPos = aLinguModulesCLB.GetSelectEntryPos();
1595 if (nPos != LISTBOX_ENTRY_NOTFOUND && pLinguData)
1597 pLinguData->Reconfigure( aLinguModulesCLB.GetText( nPos ),
1598 aLinguModulesCLB.IsChecked( nPos ) );
1601 else if (pBox == &aLinguDicsCLB)
1603 sal_uInt16 nPos = aLinguDicsCLB.GetSelectEntryPos();
1604 if (nPos != LISTBOX_ENTRY_NOTFOUND)
1606 const uno::Reference< XDictionary > &rDic = aDics.getConstArray()[ nPos ];
1607 if (SvxGetIgnoreAllList() == rDic)
1609 SvTreeListEntry* pEntry = aLinguDicsCLB.GetEntry( nPos );
1610 if (pEntry)
1611 lcl_SetCheckButton( pEntry, sal_True );
1615 return 0;
1618 // -----------------------------------------------------------------------
1620 IMPL_LINK( SvxLinguTabPage, ClickHdl_Impl, PushButton *, pBtn )
1622 if (&aLinguModulesEditPB == pBtn)
1624 if (!pLinguData)
1625 pLinguData = new SvxLinguData_Impl;
1627 SvxLinguData_Impl aOldLinguData( *pLinguData );
1628 SvxEditModulesDlg aDlg( this, *pLinguData );
1629 if (aDlg.Execute() != RET_OK)
1630 *pLinguData = aOldLinguData;
1632 // evaluate new status of 'bConfigured' flag
1633 sal_uLong nLen = pLinguData->GetDisplayServiceCount();
1634 for (sal_uLong i = 0; i < nLen; ++i)
1635 pLinguData->GetDisplayServiceArray()[i].bConfigured = sal_False;
1636 const Locale* pAllLocales = pLinguData->GetAllSupportedLocales().getConstArray();
1637 sal_Int32 nLocales = pLinguData->GetAllSupportedLocales().getLength();
1638 for (sal_Int32 k = 0; k < nLocales; ++k)
1640 sal_Int16 nLang = LanguageTag( pAllLocales[k] ).getLanguageType();
1641 if (pLinguData->GetSpellTable().count( nLang ))
1642 pLinguData->SetChecked( pLinguData->GetSpellTable()[ nLang ] );
1643 if (pLinguData->GetGrammarTable().count( nLang ))
1644 pLinguData->SetChecked( pLinguData->GetGrammarTable()[ nLang ] );
1645 if (pLinguData->GetHyphTable().count( nLang ))
1646 pLinguData->SetChecked( pLinguData->GetHyphTable()[ nLang ] );
1647 if (pLinguData->GetThesTable().count( nLang ))
1648 pLinguData->SetChecked( pLinguData->GetThesTable()[ nLang ] );
1651 // show new status of modules
1652 UpdateModulesBox_Impl();
1654 else if (&aLinguDicsNewPB == pBtn)
1656 uno::Reference< XSpellChecker1 > xSpellChecker1;
1657 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
1658 if(pFact)
1660 AbstractSvxNewDictionaryDialog* aDlg = pFact->CreateSvxNewDictionaryDialog( this, xSpellChecker1, RID_SFXDLG_NEWDICT );
1661 DBG_ASSERT(aDlg, "Dialogdiet fail!");
1662 uno::Reference< XDictionary > xNewDic;
1663 if ( aDlg->Execute() == RET_OK )
1664 xNewDic = uno::Reference< XDictionary >( aDlg->GetNewDictionary(), UNO_QUERY );
1665 if ( xNewDic.is() )
1667 // add new dics to the end
1668 sal_Int32 nLen = aDics.getLength();
1669 aDics.realloc( nLen + 1 );
1671 aDics.getArray()[ nLen ] = xNewDic;
1673 AddDicBoxEntry( xNewDic, (sal_uInt16) nLen );
1675 delete aDlg;
1678 else if (&aLinguDicsEditPB == pBtn)
1680 SvTreeListEntry *pEntry = aLinguDicsCLB.GetCurEntry();
1681 if (pEntry)
1683 DicUserData aData( (sal_uLong) pEntry->GetUserData() );
1684 sal_uInt16 nDicPos = aData.GetEntryId();
1685 sal_Int32 nDics = aDics.getLength();
1686 if (nDicPos < nDics)
1688 uno::Reference< XDictionary > xDic;
1689 xDic = aDics.getConstArray()[ nDicPos ];
1690 if (xDic.is())
1692 uno::Reference< XSpellChecker1 > xSpellChecker1;
1693 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
1694 if(pFact)
1696 VclAbstractDialog* aDlg = pFact->CreateSvxEditDictionaryDialog( this, xDic->getName(), xSpellChecker1, RID_SFXDLG_EDITDICT );
1697 DBG_ASSERT(aDlg, "Dialogdiet fail!");
1698 aDlg->Execute();
1699 delete aDlg;
1705 else if (&aLinguDicsDelPB == pBtn)
1707 if ( RET_NO ==
1708 QueryBox( this, CUI_RES( RID_SFXQB_DELDICT ) ).Execute() )
1709 return 0;
1711 SvTreeListEntry *pEntry = aLinguDicsCLB.GetCurEntry();
1712 if (pEntry)
1714 DicUserData aData( (sal_uLong) pEntry->GetUserData() );
1715 sal_uInt16 nDicPos = aData.GetEntryId();
1716 sal_Int32 nDics = aDics.getLength();
1717 if (nDicPos < nDics)
1719 uno::Reference< XDictionary > xDic;
1720 xDic = aDics.getConstArray()[ nDicPos ];
1721 if (xDic.is())
1723 if (SvxGetIgnoreAllList() == xDic)
1724 xDic->clear();
1725 else
1727 if (xDicList.is())
1728 xDicList->removeDictionary( xDic );
1730 uno::Reference< frame::XStorable > xStor( xDic, UNO_QUERY );
1731 if ( xStor->hasLocation() && !xStor->isReadonly() )
1733 String sURL = xStor->getLocation();
1734 INetURLObject aObj(sURL);
1735 DBG_ASSERT( aObj.GetProtocol() == INET_PROT_FILE,
1736 "non-file URLs cannot be deleted" );
1737 if ( aObj.GetProtocol() == INET_PROT_FILE )
1739 KillFile_Impl( aObj.GetMainURL( INetURLObject::NO_DECODE ) );
1743 aDics.getArray()[ nDicPos ] = 0;
1745 // remove entry from checklistbox
1746 sal_uLong nCnt = aLinguDicsCLB.GetEntryCount();
1747 for (sal_uLong i = 0; i < nCnt; ++i)
1749 SvTreeListEntry *pDicEntry = aLinguDicsCLB.GetEntry( i );
1750 DBG_ASSERT( pDicEntry, "missing entry" );
1751 if (pDicEntry)
1753 DicUserData aDicData( (sal_uLong) pDicEntry->GetUserData() );
1754 if (aDicData.GetEntryId() == nDicPos )
1756 aLinguDicsCLB.RemoveEntry( (sal_uInt16) i );
1757 break;
1761 DBG_ASSERT( nCnt > aLinguDicsCLB.GetEntryCount(),
1762 "remove failed ?");
1768 else if (&aLinguOptionsEditPB == pBtn)
1770 SvTreeListEntry *pEntry = aLinguOptionsCLB.GetCurEntry();
1771 DBG_ASSERT( pEntry, "no entry selected" );
1772 if (pEntry)
1774 OptionsUserData aData( (sal_uLong)pEntry->GetUserData() );
1775 if(aData.HasNumericValue())
1777 int nRID = -1;
1778 switch (aData.GetEntryId())
1780 case EID_NUM_PRE_BREAK : nRID = STR_NUM_PRE_BREAK_DLG; break;
1781 case EID_NUM_POST_BREAK : nRID = STR_NUM_POST_BREAK_DLG; break;
1782 case EID_NUM_MIN_WORDLEN: nRID = STR_NUM_MIN_WORDLEN_DLG; break;
1783 default:
1784 OSL_FAIL( "unexpected case" );
1787 OptionsBreakSet aDlg( this, nRID );
1788 aDlg.GetNumericFld().SetValue( aData.GetNumericValue() );
1789 if (RET_OK == aDlg.Execute() )
1791 long nVal = static_cast<long>(aDlg.GetNumericFld().GetValue());
1792 if (-1 != nVal && aData.GetNumericValue() != nVal)
1794 aData.SetNumericValue( (sal_uInt8)nVal ); //! sets IsModified !
1795 pEntry->SetUserData( (void *) aData.GetUserData() );
1796 aLinguOptionsCLB.Invalidate();
1802 else
1804 OSL_FAIL( "pBtn unexpected value" );
1807 return 0;
1810 // -----------------------------------------------------------------------
1812 IMPL_LINK( SvxLinguTabPage, SelectHdl_Impl, SvxCheckListBox *, pBox )
1814 if (&aLinguModulesCLB == pBox)
1817 else if (&aLinguDicsCLB == pBox)
1819 SvTreeListEntry *pEntry = pBox->GetCurEntry();
1820 if (pEntry)
1822 DicUserData aData( (sal_uLong) pEntry->GetUserData() );
1824 // always allow to edit (i.e. at least view the content of the dictionary)
1825 aLinguDicsEditPB.Enable( true/*aData.IsEditable()*/ );
1826 aLinguDicsDelPB .Enable( aData.IsDeletable() );
1829 else if (&aLinguOptionsCLB == pBox)
1831 SvTreeListEntry *pEntry = pBox->GetCurEntry();
1832 if (pEntry)
1834 OptionsUserData aData( (sal_uLong) pEntry->GetUserData() );
1835 aLinguOptionsEditPB.Enable( aData.HasNumericValue() );
1838 else
1840 OSL_FAIL( "pBox unexpected value" );
1843 return 0;
1846 // -----------------------------------------------------------------------
1848 SvTreeListEntry* SvxLinguTabPage::CreateEntry( String& rTxt, sal_uInt16 nCol )
1850 SvTreeListEntry* pEntry = new SvTreeListEntry;
1852 if( !pCheckButtonData )
1853 pCheckButtonData = new SvLBoxButtonData( &aLinguOptionsCLB );
1855 String sEmpty;
1856 if (CBCOL_FIRST == nCol)
1857 pEntry->AddItem( new SvLBoxButton( pEntry, SvLBoxButtonKind_enabledCheckbox, 0, pCheckButtonData ) );
1858 if (CBCOL_SECOND == nCol)
1859 pEntry->AddItem( new SvLBoxString( pEntry, 0, sEmpty) ); // empty column
1860 pEntry->AddItem( new SvLBoxContextBmp( pEntry, 0, Image(), Image(), 0));
1861 pEntry->AddItem( new BrwString_Impl( pEntry, 0, rTxt ) );
1863 return pEntry;
1866 // -----------------------------------------------------------------------
1868 void SvxLinguTabPage::HideGroups( sal_uInt16 nGrp )
1870 if ( 0 != ( GROUP_MODULES & nGrp ) )
1872 aLinguModulesFT.Hide();
1873 aLinguModulesCLB.Hide();
1874 aLinguModulesEditPB.Hide();
1876 // reposition / resize remaining controls
1877 long nDeltaY = aLinguDicsFT.GetPosPixel().Y() -
1878 aLinguModulesFT.GetPosPixel().Y();
1879 DBG_ASSERT( nDeltaY >= 0, "move/resize value is negative" );
1880 Point aPos;
1882 aPos = aLinguDicsFT.GetPosPixel();
1883 aPos.Y() -= nDeltaY;
1884 aLinguDicsFT.SetPosPixel( aPos );
1885 aPos = aLinguDicsCLB.GetPosPixel();
1886 aPos.Y() -= nDeltaY;
1887 aLinguDicsCLB.SetPosPixel( aPos );
1888 aPos = aLinguDicsNewPB.GetPosPixel();
1889 aPos.Y() -= nDeltaY;
1890 aLinguDicsNewPB.SetPosPixel( aPos );
1891 aPos = aLinguDicsEditPB.GetPosPixel();
1892 aPos.Y() -= nDeltaY;
1893 aLinguDicsEditPB.SetPosPixel( aPos );
1894 aPos = aLinguDicsDelPB.GetPosPixel();
1895 aPos.Y() -= nDeltaY;
1896 aLinguDicsDelPB.SetPosPixel( aPos );
1898 aPos = aLinguOptionsFT.GetPosPixel();
1899 aPos.Y() -= nDeltaY;
1900 aLinguOptionsFT.SetPosPixel( aPos );
1901 aPos = aLinguOptionsCLB.GetPosPixel();
1902 aPos.Y() -= nDeltaY;
1903 aLinguOptionsCLB.SetPosPixel( aPos );
1904 aPos = aLinguOptionsEditPB.GetPosPixel();
1905 aPos.Y() -= nDeltaY;
1906 aLinguOptionsEditPB.SetPosPixel( aPos );
1908 Size aSize( aLinguOptionsCLB.GetSizePixel() );
1909 aSize.Height() += nDeltaY;
1910 aLinguOptionsCLB.SetSizePixel( aSize );
1912 if ( SvtExtendedSecurityOptions().GetOpenHyperlinkMode()
1913 != SvtExtendedSecurityOptions::OPEN_NEVER )
1915 aSize = GetOutputSizePixel();
1916 aSize.Height() += ( aMoreDictsLink.GetSizePixel().Height() * 11 / 8 );
1917 SetSizePixel( aSize );
1918 aMoreDictsLink.Show();
1923 SvxEditModulesDlg::SvxEditModulesDlg(Window* pParent, SvxLinguData_Impl& rData) :
1924 ModalDialog( pParent, CUI_RES(RID_SVXDLG_EDIT_MODULES ) ),
1925 aModulesFL ( this, CUI_RES( FL_EDIT_MODULES_OPTIONS ) ),
1926 aLanguageFT ( this, CUI_RES( FT_EDIT_MODULES_LANGUAGE ) ),
1927 aLanguageLB ( this, CUI_RES( LB_EDIT_MODULES_LANGUAGE ), sal_False ),
1928 aModulesCLB ( this, CUI_RES( CLB_EDIT_MODULES_MODULES ) ),
1929 aPrioUpPB ( this, CUI_RES( PB_EDIT_MODULES_PRIO_UP ) ),
1930 aPrioDownPB ( this, CUI_RES( PB_EDIT_MODULES_PRIO_DOWN ) ),
1931 aBackPB ( this, CUI_RES( PB_EDIT_MODULES_PRIO_BACK ) ),
1932 aMoreDictsLink ( this, CUI_RES( FT_EDIT_MODULES_NEWDICTSLINK ) ),
1933 aButtonsFL ( this, CUI_RES( FL_EDIT_MODULES_BUTTONS ) ),
1934 aHelpPB ( this, CUI_RES( PB_HELP ) ),
1935 aClosePB ( this, CUI_RES( PB_OK ) ),
1936 sSpell ( CUI_RES( ST_SPELL ) ),
1937 sHyph ( CUI_RES( ST_HYPH ) ),
1938 sThes ( CUI_RES( ST_THES ) ),
1939 sGrammar ( CUI_RES( ST_GRAMMAR ) ),
1940 rLinguData ( rData )
1942 pCheckButtonData = NULL;
1943 FreeResource();
1945 pDefaultLinguData = new SvxLinguData_Impl( rLinguData );
1947 aModulesCLB.SetStyle( aModulesCLB.GetStyle()|WB_CLIPCHILDREN|WB_HSCROLL|WB_FORCE_MAKEVISIBLE );
1948 aModulesCLB.SetHighlightRange();
1949 aModulesCLB.SetHelpId(HID_CLB_EDIT_MODULES_MODULES );
1950 aModulesCLB.SetSelectHdl( LINK( this, SvxEditModulesDlg, SelectHdl_Impl ));
1951 aModulesCLB.SetCheckButtonHdl( LINK( this, SvxEditModulesDlg, BoxCheckButtonHdl_Impl) );
1953 aClosePB .SetClickHdl( LINK( this, SvxEditModulesDlg, ClickHdl_Impl ));
1954 aPrioUpPB .SetClickHdl( LINK( this, SvxEditModulesDlg, UpDownHdl_Impl ));
1955 aPrioDownPB.SetClickHdl( LINK( this, SvxEditModulesDlg, UpDownHdl_Impl ));
1956 aBackPB .SetClickHdl( LINK( this, SvxEditModulesDlg, BackHdl_Impl ));
1957 // in case of not installed language modules
1958 aPrioUpPB .Enable( sal_False );
1959 aPrioDownPB.Enable( sal_False );
1961 if ( SvtExtendedSecurityOptions().GetOpenHyperlinkMode()
1962 != SvtExtendedSecurityOptions::OPEN_NEVER )
1964 aMoreDictsLink.SetURL( String(
1965 RTL_CONSTASCII_USTRINGPARAM( "http://extensions.libreoffice.org/dictionaries/" ) ) );
1966 aMoreDictsLink.SetClickHdl( LINK( this, SvxEditModulesDlg, OpenURLHdl_Impl ) );
1968 else
1970 aMoreDictsLink.Hide();
1971 long nPos = aMoreDictsLink.GetPosPixel().Y() + aMoreDictsLink.GetSizePixel().Height();
1972 Size aSize = aModulesCLB.GetSizePixel();
1973 aSize.Height() += ( nPos - ( aModulesCLB.GetPosPixel().Y() + aSize.Height() ) );
1974 aModulesCLB.SetSizePixel( aSize );
1978 //fill language box
1980 Sequence< sal_Int16 > aAvailLang;
1981 uno::Reference< XAvailableLocales > xAvail( rLinguData.GetManager(), UNO_QUERY );
1982 if (xAvail.is())
1984 aAvailLang = lcl_LocaleSeqToLangSeq(
1985 xAvail->getAvailableLocales( cSpell ) );
1987 const Sequence< Locale >& rLoc = rLinguData.GetAllSupportedLocales();
1988 const Locale* pLocales = rLoc.getConstArray();
1989 aLanguageLB.Clear();
1990 for(long i = 0; i < rLoc.getLength(); i++)
1992 sal_Int16 nLang = LanguageTag( pLocales[i] ).getLanguageType();
1993 aLanguageLB.InsertLanguage( nLang, lcl_SeqHasLang( aAvailLang, nLang ) );
1995 LanguageType eSysLang = MsLangId::getSystemLanguage();
1996 aLanguageLB.SelectLanguage( eSysLang );
1997 if(!aLanguageLB.IsLanguageSelected( eSysLang ) )
1998 aLanguageLB.SelectEntryPos(0);
2000 aLanguageLB.SetSelectHdl( LINK( this, SvxEditModulesDlg, LangSelectHdl_Impl ));
2001 LangSelectHdl_Impl(&aLanguageLB);
2005 SvxEditModulesDlg::~SvxEditModulesDlg()
2007 delete pDefaultLinguData;
2011 SvTreeListEntry* SvxEditModulesDlg::CreateEntry( String& rTxt, sal_uInt16 nCol )
2013 SvTreeListEntry* pEntry = new SvTreeListEntry;
2014 if( !pCheckButtonData )
2016 pCheckButtonData = new SvLBoxButtonData( &aModulesCLB );
2017 pCheckButtonData->SetLink( aModulesCLB.GetCheckButtonHdl() );
2020 String sEmpty;
2021 if (CBCOL_FIRST == nCol)
2022 pEntry->AddItem( new SvLBoxButton( pEntry, SvLBoxButtonKind_enabledCheckbox, 0, pCheckButtonData ) );
2023 if (CBCOL_SECOND == nCol)
2024 pEntry->AddItem( new SvLBoxString( pEntry, 0, sEmpty) ); // empty column
2025 pEntry->AddItem( new SvLBoxContextBmp( pEntry, 0, Image(), Image(), 0));
2026 pEntry->AddItem( new BrwStringDic_Impl( pEntry, 0, rTxt ) );
2028 return pEntry;
2031 IMPL_LINK( SvxEditModulesDlg, SelectHdl_Impl, SvxCheckListBox *, pBox )
2033 if (&aModulesCLB == pBox)
2035 sal_Bool bDisableUp = sal_True;
2036 sal_Bool bDisableDown = sal_True;
2037 SvTreeListEntry *pEntry = pBox->GetCurEntry();
2038 if (pEntry)
2040 ModuleUserData_Impl* pData = (ModuleUserData_Impl*)pEntry->GetUserData();
2041 if(!pData->IsParent() && pData->GetType() != TYPE_HYPH)
2043 sal_uInt16 nCurPos = pBox->GetSelectEntryPos();
2044 if(nCurPos < pBox->GetEntryCount() - 1)
2046 bDisableDown = ((ModuleUserData_Impl*)pBox->
2047 GetEntry(nCurPos + 1)->GetUserData())->IsParent();
2049 if(nCurPos > 1)
2051 bDisableUp = ((ModuleUserData_Impl*)pBox->
2052 GetEntry(nCurPos - 1)->GetUserData())->IsParent();
2055 aPrioUpPB.Enable(!bDisableUp);
2056 aPrioDownPB.Enable(!bDisableDown);
2059 else
2061 OSL_FAIL( "pBox unexpected value" );
2064 return 0;
2067 IMPL_LINK( SvxEditModulesDlg, BoxCheckButtonHdl_Impl, SvTreeListBox *, pBox )
2069 pBox = &aModulesCLB;
2070 SvTreeListEntry *pCurEntry = pBox->GetCurEntry();
2071 if (pCurEntry)
2073 ModuleUserData_Impl* pData = (ModuleUserData_Impl *)
2074 pCurEntry->GetUserData();
2075 if (!pData->IsParent() && pData->GetType() == TYPE_HYPH)
2077 // make hyphenator checkboxes function as radio-buttons
2078 // (at most one box may be checked)
2079 SvTreeListEntry *pEntry = pBox->First();
2080 while (pEntry)
2082 pData = (ModuleUserData_Impl *) pEntry->GetUserData();
2083 if (!pData->IsParent() &&
2084 pData->GetType() == TYPE_HYPH &&
2085 pEntry != pCurEntry)
2087 lcl_SetCheckButton( pEntry, sal_False );
2088 pBox->InvalidateEntry( pEntry );
2090 pEntry = pBox->Next( pEntry );
2094 return 0;
2097 IMPL_LINK( SvxEditModulesDlg, LangSelectHdl_Impl, ListBox *, pBox )
2099 LanguageType eCurLanguage = aLanguageLB.GetSelectLanguage();
2100 static Locale aLastLocale;
2101 Locale aCurLocale( LanguageTag( eCurLanguage).getLocale());
2102 SvTreeList *pModel = aModulesCLB.GetModel();
2104 if (pBox)
2106 // save old probably changed settings
2107 // before switching to new language entries
2109 sal_Int16 nLang = LanguageTag( aLastLocale ).getLanguageType();
2111 sal_Int32 nStart = 0, nLocalIndex = 0;
2112 Sequence< OUString > aChange;
2113 sal_Bool bChanged = sal_False;
2114 for(sal_uInt16 i = 0; i < aModulesCLB.GetEntryCount(); i++)
2116 SvTreeListEntry *pEntry = aModulesCLB.GetEntry(i);
2117 ModuleUserData_Impl* pData = (ModuleUserData_Impl*)pEntry->GetUserData();
2118 if(pData->IsParent())
2120 if(bChanged)
2122 LangImplNameTable *pTable = 0;
2123 sal_uInt8 nType = pData->GetType();
2124 switch (nType - 1)
2126 case TYPE_SPELL : pTable = &rLinguData.GetSpellTable(); break;
2127 case TYPE_GRAMMAR : pTable = &rLinguData.GetGrammarTable(); break;
2128 case TYPE_HYPH : pTable = &rLinguData.GetHyphTable(); break;
2129 case TYPE_THES : pTable = &rLinguData.GetThesTable(); break;
2131 if (pTable)
2133 aChange.realloc(nStart);
2134 (*pTable)[ nLang ] = aChange;
2137 nLocalIndex = nStart = 0;
2138 aChange.realloc(aModulesCLB.GetEntryCount());
2139 bChanged = sal_False;
2141 else
2143 OUString* pChange = aChange.getArray();
2144 pChange[nStart] = pData->GetImplName();
2145 bChanged |= pData->GetIndex() != nLocalIndex ||
2146 pData->IsChecked() != aModulesCLB.IsChecked(i);
2147 if(aModulesCLB.IsChecked(i))
2148 nStart++;
2149 ++nLocalIndex;
2152 if(bChanged)
2154 aChange.realloc(nStart);
2155 rLinguData.GetThesTable()[ nLang ] = aChange;
2159 for(sal_uLong i = 0; i < aModulesCLB.GetEntryCount(); i++)
2160 delete (ModuleUserData_Impl*)aModulesCLB.GetEntry(i)->GetUserData();
2163 // display entries for new selected language
2165 aModulesCLB.Clear();
2166 if(LANGUAGE_DONTKNOW != eCurLanguage)
2168 sal_uLong n;
2169 ServiceInfo_Impl* pInfo;
2172 // spellchecker entries
2174 SvTreeListEntry* pEntry = CreateEntry( sSpell, CBCOL_SECOND );
2175 ModuleUserData_Impl* pUserData = new ModuleUserData_Impl(
2176 String(), sal_True, sal_False, TYPE_SPELL, 0 );
2177 pEntry->SetUserData( (void *)pUserData );
2178 pModel->Insert( pEntry );
2180 Sequence< OUString > aNames( rLinguData.GetSortedImplNames( eCurLanguage, TYPE_SPELL ) );
2181 const OUString *pName = aNames.getConstArray();
2182 sal_uLong nNames = (sal_uLong) aNames.getLength();
2183 sal_Int32 nLocalIndex = 0; // index relative to parent
2184 for (n = 0; n < nNames; ++n)
2186 OUString aImplName;
2187 sal_Bool bIsSuppLang = sal_False;
2189 pInfo = rLinguData.GetInfoByImplName( pName[n] );
2190 if (pInfo)
2192 bIsSuppLang = pInfo->xSpell.is() &&
2193 pInfo->xSpell->hasLocale( aCurLocale );
2194 aImplName = pInfo->sSpellImplName;
2196 if (!aImplName.isEmpty() && bIsSuppLang)
2198 String aTxt( pInfo->sDisplayName );
2199 SvTreeListEntry* pNewEntry = CreateEntry( aTxt, CBCOL_FIRST );
2201 LangImplNameTable &rTable = rLinguData.GetSpellTable();
2202 const bool bHasLang = rTable.count( eCurLanguage );
2203 if (!bHasLang)
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, sal_False,
2210 bCheck, TYPE_SPELL, (sal_uInt8)nLocalIndex++ );
2211 pNewEntry->SetUserData( (void *)pUserData );
2212 pModel->Insert( pNewEntry );
2217 // grammar checker entries
2219 pEntry = CreateEntry( sGrammar, CBCOL_SECOND );
2220 pUserData = new ModuleUserData_Impl( String(), sal_True, sal_False, TYPE_GRAMMAR, 0 );
2221 pEntry->SetUserData( (void *)pUserData );
2222 pModel->Insert( pEntry );
2224 aNames = rLinguData.GetSortedImplNames( eCurLanguage, TYPE_GRAMMAR );
2225 pName = aNames.getConstArray();
2226 nNames = (sal_uLong) aNames.getLength();
2227 nLocalIndex = 0;
2228 for (n = 0; n < nNames; ++n)
2230 OUString aImplName;
2231 sal_Bool bIsSuppLang = sal_False;
2233 pInfo = rLinguData.GetInfoByImplName( pName[n] );
2234 if (pInfo)
2236 bIsSuppLang = pInfo->xGrammar.is() &&
2237 pInfo->xGrammar->hasLocale( aCurLocale );
2238 aImplName = pInfo->sGrammarImplName;
2240 if (!aImplName.isEmpty() && bIsSuppLang)
2242 String aTxt( pInfo->sDisplayName );
2243 SvTreeListEntry* pNewEntry = CreateEntry( aTxt, CBCOL_FIRST );
2245 LangImplNameTable &rTable = rLinguData.GetGrammarTable();
2246 const bool bHasLang = rTable.count( eCurLanguage );
2247 if (!bHasLang)
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, sal_False,
2254 bCheck, TYPE_GRAMMAR, (sal_uInt8)nLocalIndex++ );
2255 pNewEntry->SetUserData( (void *)pUserData );
2256 pModel->Insert( pNewEntry );
2261 // hyphenator entries
2263 pEntry = CreateEntry( sHyph, CBCOL_SECOND );
2264 pUserData = new ModuleUserData_Impl( String(), sal_True, sal_False, TYPE_HYPH, 0 );
2265 pEntry->SetUserData( (void *)pUserData );
2266 pModel->Insert( pEntry );
2268 aNames = rLinguData.GetSortedImplNames( eCurLanguage, TYPE_HYPH );
2269 pName = aNames.getConstArray();
2270 nNames = (sal_uLong) aNames.getLength();
2271 nLocalIndex = 0;
2272 for (n = 0; n < nNames; ++n)
2274 OUString aImplName;
2275 sal_Bool bIsSuppLang = sal_False;
2277 pInfo = rLinguData.GetInfoByImplName( pName[n] );
2278 if (pInfo)
2280 bIsSuppLang = pInfo->xHyph.is() &&
2281 pInfo->xHyph->hasLocale( aCurLocale );
2282 aImplName = pInfo->sHyphImplName;
2284 if (!aImplName.isEmpty() && bIsSuppLang)
2286 String aTxt( pInfo->sDisplayName );
2287 SvTreeListEntry* pNewEntry = CreateEntry( aTxt, CBCOL_FIRST );
2289 LangImplNameTable &rTable = rLinguData.GetHyphTable();
2290 const bool bHasLang = rTable.count( eCurLanguage );
2291 if (!bHasLang)
2293 DBG_WARNING( "language entry missing" ); // only relevant if all languages found should be supported
2295 const bool bCheck = bHasLang && lcl_SeqGetEntryPos( rTable[ eCurLanguage ], aImplName ) >= 0;
2296 lcl_SetCheckButton( pNewEntry, bCheck );
2297 pUserData = new ModuleUserData_Impl( aImplName, sal_False,
2298 bCheck, TYPE_HYPH, (sal_uInt8)nLocalIndex++ );
2299 pNewEntry->SetUserData( (void *)pUserData );
2300 pModel->Insert( pNewEntry );
2305 // thesaurus entries
2307 pEntry = CreateEntry( sThes, CBCOL_SECOND );
2308 pUserData = new ModuleUserData_Impl( String(), sal_True, sal_False, TYPE_THES, 0 );
2309 pEntry->SetUserData( (void *)pUserData );
2310 pModel->Insert( pEntry );
2312 aNames = rLinguData.GetSortedImplNames( eCurLanguage, TYPE_THES );
2313 pName = aNames.getConstArray();
2314 nNames = (sal_uLong) aNames.getLength();
2315 nLocalIndex = 0;
2316 for (n = 0; n < nNames; ++n)
2318 OUString aImplName;
2319 sal_Bool bIsSuppLang = sal_False;
2321 pInfo = rLinguData.GetInfoByImplName( pName[n] );
2322 if (pInfo)
2324 bIsSuppLang = pInfo->xThes.is() &&
2325 pInfo->xThes->hasLocale( aCurLocale );
2326 aImplName = pInfo->sThesImplName;
2328 if (!aImplName.isEmpty() && bIsSuppLang)
2330 String aTxt( pInfo->sDisplayName );
2331 SvTreeListEntry* pNewEntry = CreateEntry( aTxt, CBCOL_FIRST );
2333 LangImplNameTable &rTable = rLinguData.GetThesTable();
2334 const bool bHasLang = rTable.count( eCurLanguage );
2335 if (!bHasLang)
2337 DBG_WARNING( "language entry missing" ); // only relevant if all languages found should be supported
2339 const bool bCheck = bHasLang && lcl_SeqGetEntryPos( rTable[ eCurLanguage ], aImplName ) >= 0;
2340 lcl_SetCheckButton( pNewEntry, bCheck );
2341 pUserData = new ModuleUserData_Impl( aImplName, sal_False,
2342 bCheck, TYPE_THES, (sal_uInt8)nLocalIndex++ );
2343 pNewEntry->SetUserData( (void *)pUserData );
2344 pModel->Insert( pNewEntry );
2348 aLastLocale = aCurLocale;
2349 return 0;
2352 IMPL_LINK( SvxEditModulesDlg, UpDownHdl_Impl, PushButton *, pBtn )
2354 sal_Bool bUp = &aPrioUpPB == pBtn;
2355 sal_uInt16 nCurPos = aModulesCLB.GetSelectEntryPos();
2356 SvTreeListEntry* pEntry;
2357 if (nCurPos != LISTBOX_ENTRY_NOTFOUND &&
2358 0 != (pEntry = aModulesCLB.GetEntry(nCurPos)))
2360 aModulesCLB.SetUpdateMode(sal_False);
2361 SvTreeList *pModel = aModulesCLB.GetModel();
2363 ModuleUserData_Impl* pData = (ModuleUserData_Impl*)pEntry->GetUserData();
2364 String aStr(aModulesCLB.GetEntryText(pEntry));
2365 SvTreeListEntry* pToInsert = CreateEntry( aStr, CBCOL_FIRST );
2366 pToInsert->SetUserData( (void *)pData);
2367 sal_Bool bIsChecked = aModulesCLB.IsChecked(nCurPos);
2369 pModel->Remove(pEntry);
2371 sal_uInt16 nDestPos = bUp ? nCurPos - 1 : nCurPos + 1;
2372 pModel->Insert(pToInsert, nDestPos);
2373 aModulesCLB.CheckEntryPos(nDestPos, bIsChecked );
2374 aModulesCLB.SelectEntryPos(nDestPos );
2375 SelectHdl_Impl(&aModulesCLB);
2376 aModulesCLB.SetUpdateMode(sal_True);
2378 return 0;
2381 IMPL_LINK( SvxEditModulesDlg, ClickHdl_Impl, PushButton *, pBtn )
2383 if (&aClosePB == pBtn)
2385 // store language config
2386 LangSelectHdl_Impl(&aLanguageLB);
2387 EndDialog( RET_OK );
2389 else
2391 OSL_FAIL( "pBtn unexpected value" );
2394 return 0;
2397 IMPL_LINK_NOARG(SvxEditModulesDlg, BackHdl_Impl)
2399 rLinguData = *pDefaultLinguData;
2400 LangSelectHdl_Impl(0);
2401 return 0;
2404 // -----------------------------------------------------------------------
2406 IMPL_LINK_NOARG(SvxEditModulesDlg, OpenURLHdl_Impl)
2408 ::rtl::OUString sURL( aMoreDictsLink.GetURL() );
2409 lcl_OpenURL( sURL );
2410 return 0;
2413 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */