bump product version to 5.0.4.1
[LibreOffice.git] / cui / source / options / optlingu.cxx
blobcafbe1180debad2343d1e391be2af4bd9db517a0
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 <vcl/settings.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>
59 #include <svx/svxdlg.hxx>
60 #include <editeng/optitems.hxx>
61 #include "optlingu.hxx"
62 #include <dialmgr.hxx>
63 #include <cuires.hrc>
64 #include "helpid.hrc"
66 #include <ucbhelper/content.hxx>
68 #include <vector>
69 #include <map>
70 #include <boost/scoped_ptr.hpp>
72 using namespace ::ucbhelper;
73 using namespace ::com::sun::star;
74 using namespace ::com::sun::star::lang;
75 using namespace ::com::sun::star::uno;
76 using namespace ::com::sun::star::linguistic2;
77 using namespace ::com::sun::star::beans;
79 #define CBCOL_FIRST 0
80 #define CBCOL_SECOND 1
82 static const sal_Char cSpell[] = SN_SPELLCHECKER;
83 static const sal_Char cGrammar[] = SN_GRAMMARCHECKER;
84 static const sal_Char cHyph[] = SN_HYPHENATOR;
85 static const sal_Char cThes[] = SN_THESAURUS;
87 // static ----------------------------------------------------------------
89 static Sequence< sal_Int16 > lcl_LocaleSeqToLangSeq( const Sequence< Locale > &rSeq )
91 sal_Int32 nLen = rSeq.getLength();
92 Sequence< sal_Int16 > aRes( nLen );
93 sal_Int16 *pRes = aRes.getArray();
94 const Locale *pSeq = rSeq.getConstArray();
95 for (sal_Int32 i = 0; i < nLen; ++i)
97 pRes[i] = LanguageTag::convertToLanguageType( pSeq[i] );
99 return aRes;
103 static bool lcl_SeqHasLang( const Sequence< sal_Int16 > &rSeq, sal_Int16 nLang )
105 sal_Int32 nLen = rSeq.getLength();
106 const sal_Int16 *pLang = rSeq.getConstArray();
107 sal_Int32 nPos = -1;
108 for (sal_Int32 i = 0; i < nLen && nPos < 0; ++i)
110 if (nLang == pLang[i])
111 nPos = i;
113 return nPos >= 0;
117 static sal_Int32 lcl_SeqGetEntryPos(
118 const Sequence< OUString > &rSeq, const OUString &rEntry )
120 sal_Int32 i;
121 sal_Int32 nLen = rSeq.getLength();
122 const OUString *pItem = rSeq.getConstArray();
123 for (i = 0; i < nLen; ++i)
125 if (rEntry == pItem[i])
126 break;
128 return i < nLen ? i : -1;
131 static void lcl_OpenURL( const OUString& _sURL )
133 if ( !_sURL.isEmpty() )
135 OUString sURL = _sURL;
136 localizeWebserviceURI(sURL);
139 uno::Reference< uno::XComponentContext > xContext =
140 ::comphelper::getProcessComponentContext();
141 uno::Reference< css::system::XSystemShellExecute > xSystemShell(
142 css::system::SystemShellExecute::create(xContext) );
143 xSystemShell->execute( sURL, OUString(), css::system::SystemShellExecuteFlags::URIS_ONLY );
145 catch( const uno::Exception& e )
147 OSL_TRACE( "Caught exception: %s\n thread terminated.\n",
148 OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8).getStr());
153 bool KillFile_Impl( const OUString& rURL )
155 bool bRet = true;
158 Content aCnt( rURL, uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >(), comphelper::getProcessComponentContext() );
159 aCnt.executeCommand( OUString("delete"), makeAny( true ) );
161 catch( ::com::sun::star::ucb::CommandAbortedException& )
163 SAL_WARN( "cui.options", "KillFile: CommandAbortedException" );
164 bRet = false;
166 catch( ... )
168 SAL_WARN( "cui.options", "KillFile: Any other exception" );
169 bRet = false;
172 return bRet;
175 // 0x 0p 0t 0c nn
176 // p: 1 -> parent
177 // t: 1 -> spell, 2 -> hyph, 3 -> thes, 4 -> grammar
178 // c: 1 -> checked 0 -> unchecked
179 // n: index
181 #define TYPE_SPELL (sal_uInt8)1
182 #define TYPE_GRAMMAR (sal_uInt8)2
183 #define TYPE_HYPH (sal_uInt8)3
184 #define TYPE_THES (sal_uInt8)4
186 class ModuleUserData_Impl
188 bool bParent;
189 bool bIsChecked;
190 sal_uInt8 nType;
191 sal_uInt8 nIndex;
192 OUString sImplName;
194 public:
195 ModuleUserData_Impl( const OUString& sImpName, bool bIsParent, bool bChecked, sal_uInt8 nSetType, sal_uInt8 nSetIndex ) :
196 bParent(bIsParent),
197 bIsChecked(bChecked),
198 nType(nSetType),
199 nIndex(nSetIndex),
200 sImplName(sImpName)
203 bool IsParent() const {return bParent;}
204 sal_uInt8 GetType() const {return nType;}
205 bool IsChecked() const {return bIsChecked;}
206 sal_uInt8 GetIndex() const {return nIndex;}
207 const OUString& GetImplName() const {return sImplName;}
212 // User for user-dictionaries (XDictionary interface)
214 class DicUserData
216 sal_uLong nVal;
218 public:
219 DicUserData( sal_uLong nUserData ) : nVal( nUserData ) {}
220 DicUserData( sal_uInt16 nEID,
221 bool bChecked, bool bEditable, bool bDeletable );
223 sal_uLong GetUserData() const { return nVal; }
224 sal_uInt16 GetEntryId() const { return (sal_uInt16)(nVal >> 16); }
225 bool IsChecked() const { return (bool)((nVal >> 8) & 0x01); }
226 bool IsDeletable() const { return (bool)((nVal >> 10) & 0x01); }
230 DicUserData::DicUserData(
231 sal_uInt16 nEID,
232 bool bChecked, bool bEditable, bool bDeletable )
234 DBG_ASSERT( nEID < 65000, "Entry Id out of range" );
235 nVal = ((sal_uLong)(0xFFFF & nEID) << 16) |
236 ((sal_uLong)(bChecked ? 1 : 0) << 8) |
237 ((sal_uLong)(bEditable ? 1 : 0) << 9) |
238 ((sal_uLong)(bDeletable ? 1 : 0) << 10);
242 // class BrwString_Impl -------------------------------------------------
244 static void lcl_SetCheckButton( SvTreeListEntry* pEntry, bool bCheck )
246 SvLBoxButton* pItem = static_cast<SvLBoxButton*>(pEntry->GetFirstItem(SV_ITEM_ID_LBOXBUTTON));
248 DBG_ASSERT(pItem,"SetCheckButton:Item not found");
249 if (pItem->GetType() == SV_ITEM_ID_LBOXBUTTON)
251 if (bCheck)
252 pItem->SetStateChecked();
253 else
254 pItem->SetStateUnchecked();
259 class BrwStringDic_Impl : public SvLBoxString
261 public:
263 BrwStringDic_Impl( SvTreeListEntry* pEntry, sal_uInt16 nFlags,
264 const OUString& rStr ) : SvLBoxString( pEntry, nFlags, rStr ) {}
266 virtual void Paint(const Point& rPos, SvTreeListBox& rOutDev, vcl::RenderContext& rRenderContext,
267 const SvViewDataEntry* pView, const SvTreeListEntry* pEntry) SAL_OVERRIDE;
270 void BrwStringDic_Impl::Paint(const Point& rPos, SvTreeListBox& /*rDev*/, vcl::RenderContext& rRenderContext,
271 const SvViewDataEntry* /*pView*/, const SvTreeListEntry* pEntry)
273 ModuleUserData_Impl* pData = static_cast<ModuleUserData_Impl*>(pEntry->GetUserData());
274 Point aPos(rPos);
275 rRenderContext.Push(PushFlags::FONT);
276 if (pData->IsParent())
278 vcl::Font aFont(rRenderContext.GetFont());
279 aFont.SetWeight(WEIGHT_BOLD);
280 rRenderContext.SetFont(aFont);
281 aPos.X() = 0;
283 else
284 aPos.X() += 5;
285 rRenderContext.DrawText(aPos, GetText());
286 rRenderContext.Pop();
289 /*--------------------------------------------------
290 Entry IDs for options listbox of dialog
291 --------------------------------------------------*/
293 enum EID_OPTIONS
295 EID_SPELL_AUTO,
296 EID_GRAMMAR_AUTO,
297 EID_CAPITAL_WORDS,
298 EID_WORDS_WITH_DIGITS,
299 EID_SPELL_SPECIAL,
300 EID_NUM_MIN_WORDLEN,
301 EID_NUM_PRE_BREAK,
302 EID_NUM_POST_BREAK,
303 EID_HYPH_AUTO,
304 EID_HYPH_SPECIAL
307 //! this array must have an entry for every value of EID_OPTIONS.
308 // It is used to get the respective property name.
309 static const char * aEidToPropName[] =
311 UPN_IS_SPELL_AUTO, // EID_SPELL_AUTO
312 UPN_IS_GRAMMAR_AUTO, // EID_GRAMMAR_AUTO
313 UPN_IS_SPELL_UPPER_CASE, // EID_CAPITAL_WORDS
314 UPN_IS_SPELL_WITH_DIGITS, // EID_WORDS_WITH_DIGITS
315 UPN_IS_SPELL_SPECIAL, // EID_SPELL_SPECIAL
316 UPN_HYPH_MIN_WORD_LENGTH, // EID_NUM_MIN_WORDLEN,
317 UPN_HYPH_MIN_LEADING, // EID_NUM_PRE_BREAK
318 UPN_HYPH_MIN_TRAILING, // EID_NUM_POST_BREAK
319 UPN_IS_HYPH_AUTO, // EID_HYPH_AUTO
320 UPN_IS_HYPH_SPECIAL // EID_HYPH_SPECIAL
323 static inline OUString lcl_GetPropertyName( EID_OPTIONS eEntryId )
325 DBG_ASSERT( (unsigned int) eEntryId < SAL_N_ELEMENTS(aEidToPropName), "index out of range" );
326 return OUString::createFromAscii( aEidToPropName[ (int) eEntryId ] );
329 class OptionsBreakSet : public ModalDialog
331 VclPtr<VclFrame> m_pBeforeFrame;
332 VclPtr<VclFrame> m_pAfterFrame;
333 VclPtr<VclFrame> m_pMinimalFrame;
334 VclPtr<NumericField> m_pBreakNF;
336 public:
337 OptionsBreakSet(vcl::Window* pParent, sal_uInt16 nRID)
338 : ModalDialog(pParent, "BreakNumberOption",
339 "cui/ui/breaknumberoption.ui")
340 , m_pBreakNF(NULL)
342 get(m_pBeforeFrame, "beforeframe");
343 get(m_pAfterFrame, "afterframe");
344 get(m_pMinimalFrame, "miniframe");
346 assert(EID_NUM_PRE_BREAK == nRID ||
347 EID_NUM_POST_BREAK == nRID ||
348 EID_NUM_MIN_WORDLEN == nRID); //unexpected ID
350 if (nRID == EID_NUM_PRE_BREAK)
352 m_pBeforeFrame->Show();
353 get(m_pBreakNF, "beforebreak");
355 else if(nRID == EID_NUM_POST_BREAK)
357 m_pAfterFrame->Show();
358 get(m_pBreakNF, "afterbreak");
360 else if(nRID == EID_NUM_MIN_WORDLEN)
362 m_pMinimalFrame->Show();
363 get(m_pBreakNF, "wordlength");
366 virtual ~OptionsBreakSet() { disposeOnce(); }
367 virtual void dispose() SAL_OVERRIDE
369 m_pBeforeFrame.clear();
370 m_pAfterFrame.clear();
371 m_pMinimalFrame.clear();
372 m_pBreakNF.clear();
373 ModalDialog::dispose();
376 NumericField& GetNumericFld()
378 return *m_pBreakNF;
382 // class OptionsUserData -------------------------------------------------
384 class OptionsUserData
386 sal_uLong nVal;
388 void SetModified();
390 public:
391 OptionsUserData( sal_uLong nUserData ) : nVal( nUserData ) {}
392 OptionsUserData( sal_uInt16 nEID,
393 bool bHasNV, sal_uInt16 nNumVal,
394 bool bCheckable, bool bChecked );
396 sal_uLong GetUserData() const { return nVal; }
397 sal_uInt16 GetEntryId() const { return (sal_uInt16)(nVal >> 16); }
398 bool HasNumericValue() const { return (bool)((nVal >> 10) & 0x01); }
399 sal_uInt16 GetNumericValue() const { return (sal_uInt16)(nVal & 0xFF); }
400 bool IsCheckable() const { return (bool)((nVal >> 9) & 0x01); }
401 bool IsModified() const { return (bool)((nVal >> 11) & 0x01); }
403 void SetNumericValue( sal_uInt8 nNumVal );
406 OptionsUserData::OptionsUserData( sal_uInt16 nEID,
407 bool bHasNV, sal_uInt16 nNumVal,
408 bool bCheckable, bool bChecked )
410 DBG_ASSERT( nEID < 65000, "Entry Id out of range" );
411 DBG_ASSERT( nNumVal < 256, "value out of range" );
412 nVal = ((sal_uLong)(0xFFFF & nEID) << 16) |
413 ((sal_uLong)(bHasNV ? 1 : 0) << 10) |
414 ((sal_uLong)(bCheckable ? 1 : 0) << 9) |
415 ((sal_uLong)(bChecked ? 1 : 0) << 8) |
416 ((sal_uLong)(0xFF & nNumVal));
419 void OptionsUserData::SetNumericValue( sal_uInt8 nNumVal )
421 if (HasNumericValue() && (GetNumericValue() != nNumVal))
423 nVal &= 0xffffff00;
424 nVal |= (nNumVal);
425 SetModified();
429 void OptionsUserData::SetModified()
431 nVal |= (sal_uLong)1 << 11;
434 // class BrwString_Impl -------------------------------------------------
436 class BrwString_Impl : public SvLBoxString
438 public:
440 BrwString_Impl( SvTreeListEntry* pEntry, sal_uInt16 nFlags,
441 const OUString& rStr ) : SvLBoxString( pEntry, nFlags, rStr ) {}
443 virtual void Paint(const Point& rPos, SvTreeListBox& rOutDev, vcl::RenderContext& rRenderContext,
444 const SvViewDataEntry* pView, const SvTreeListEntry* pEntry) SAL_OVERRIDE;
447 void BrwString_Impl::Paint(const Point& rPos, SvTreeListBox& /*rDev*/, vcl::RenderContext& rRenderContext,
448 const SvViewDataEntry* /*pView*/, const SvTreeListEntry* pEntry)
450 Point aPos(rPos);
451 aPos.X() += 20;
452 rRenderContext.DrawText(aPos, GetText());
453 if (pEntry->GetUserData())
455 Point aNewPos(aPos);
456 aNewPos.X() += rRenderContext.GetTextWidth(GetText());
457 rRenderContext.Push(PushFlags::FONT);
458 vcl::Font aFont(rRenderContext.GetFont());
459 aFont.SetWeight(WEIGHT_BOLD);
461 //??? convert the lower byte from the user date into a string
462 OptionsUserData aData(reinterpret_cast<sal_uLong>(pEntry->GetUserData()));
463 if (aData.HasNumericValue())
465 OUStringBuffer sTxt;
466 sTxt.append(' ').append(static_cast<sal_Int32>(aData.GetNumericValue()));
467 rRenderContext.SetFont(aFont);
468 rRenderContext.DrawText(aNewPos, sTxt.makeStringAndClear());
471 rRenderContext.Pop();
475 // ServiceInfo_Impl ----------------------------------------------------
477 struct ServiceInfo_Impl
479 OUString sDisplayName;
480 OUString sSpellImplName;
481 OUString sHyphImplName;
482 OUString sThesImplName;
483 OUString sGrammarImplName;
484 uno::Reference< XSpellChecker > xSpell;
485 uno::Reference< XHyphenator > xHyph;
486 uno::Reference< XThesaurus > xThes;
487 uno::Reference< XProofreader > xGrammar;
488 bool bConfigured;
490 ServiceInfo_Impl() : bConfigured(false) {}
493 typedef std::vector< ServiceInfo_Impl > ServiceInfoArr;
494 typedef std::map< sal_Int16 /*LanguageType*/, Sequence< OUString > > LangImplNameTable;
497 // SvxLinguData_Impl ----------------------------------------------------
499 class SvxLinguData_Impl
501 //contains services and implementation names sorted by implementation names
502 ServiceInfoArr aDisplayServiceArr;
503 sal_uLong nDisplayServices;
505 Sequence< Locale > aAllServiceLocales;
506 LangImplNameTable aCfgSpellTable;
507 LangImplNameTable aCfgHyphTable;
508 LangImplNameTable aCfgThesTable;
509 LangImplNameTable aCfgGrammarTable;
510 uno::Reference< XLinguServiceManager2 > xLinguSrvcMgr;
513 static bool AddRemove( Sequence< OUString > &rConfigured,
514 const OUString &rImplName, bool bAdd );
516 public:
517 SvxLinguData_Impl();
518 SvxLinguData_Impl( const SvxLinguData_Impl &rData );
519 ~SvxLinguData_Impl();
521 SvxLinguData_Impl & operator = (const SvxLinguData_Impl &rData);
523 uno::Reference<XLinguServiceManager2> & GetManager() { return xLinguSrvcMgr; }
525 void SetChecked( const Sequence< OUString > &rConfiguredServices );
526 void Reconfigure( const OUString &rDisplayName, bool bEnable );
528 const Sequence<Locale> & GetAllSupportedLocales() const { return aAllServiceLocales; }
530 LangImplNameTable & GetSpellTable() { return aCfgSpellTable; }
531 LangImplNameTable & GetHyphTable() { return aCfgHyphTable; }
532 LangImplNameTable & GetThesTable() { return aCfgThesTable; }
533 LangImplNameTable & GetGrammarTable() { return aCfgGrammarTable; }
535 ServiceInfoArr & GetDisplayServiceArray() { return aDisplayServiceArr; }
537 const sal_uLong & GetDisplayServiceCount() const { return nDisplayServices; }
538 void SetDisplayServiceCount( sal_uLong nVal ) { nDisplayServices = nVal; }
540 // returns the list of service implementation names for the specified
541 // language and service (TYPE_SPELL, TYPE_HYPH, TYPE_THES) sorted in
542 // the proper order for the SvxEditModulesDlg (the ones from the
543 // configuration (keeping that order!) first and then the other ones.
544 // I.e. the ones available but not configured in arbitrary order).
545 // They available ones may contain names that do not(!) support that
546 // language.
547 Sequence< OUString > GetSortedImplNames( sal_Int16 nLang, sal_uInt8 nType );
549 ServiceInfo_Impl * GetInfoByImplName( const OUString &rSvcImplName );
553 static sal_Int32 lcl_SeqGetIndex( const Sequence< OUString > &rSeq, const OUString &rTxt )
555 sal_Int32 nRes = -1;
556 sal_Int32 nLen = rSeq.getLength();
557 const OUString *pString = rSeq.getConstArray();
558 for (sal_Int32 i = 0; i < nLen && nRes == -1; ++i)
560 if (pString[i] == rTxt)
561 nRes = i;
563 return nRes;
567 Sequence< OUString > SvxLinguData_Impl::GetSortedImplNames( sal_Int16 nLang, sal_uInt8 nType )
569 LangImplNameTable *pTable = 0;
570 switch (nType)
572 case TYPE_SPELL : pTable = &aCfgSpellTable; break;
573 case TYPE_HYPH : pTable = &aCfgHyphTable; break;
574 case TYPE_THES : pTable = &aCfgThesTable; break;
575 case TYPE_GRAMMAR : pTable = &aCfgGrammarTable; break;
577 Sequence< OUString > aRes;
578 if (!pTable)
580 SAL_WARN( "cui.options", "unknown linguistic type" );
581 return aRes;
583 if (pTable->count( nLang ))
584 aRes = (*pTable)[ nLang ]; // add configured services
585 sal_Int32 nIdx = aRes.getLength();
586 DBG_ASSERT( (sal_Int32) nDisplayServices >= nIdx, "size mismatch" );
587 aRes.realloc( nDisplayServices );
588 OUString *pRes = aRes.getArray();
590 // add not configured services
591 for (sal_Int32 i = 0; i < (sal_Int32) nDisplayServices; ++i)
593 const ServiceInfo_Impl &rInfo = aDisplayServiceArr[ i ];
594 OUString aImplName;
595 switch (nType)
597 case TYPE_SPELL : aImplName = rInfo.sSpellImplName; break;
598 case TYPE_HYPH : aImplName = rInfo.sHyphImplName; break;
599 case TYPE_THES : aImplName = rInfo.sThesImplName; break;
600 case TYPE_GRAMMAR : aImplName = rInfo.sGrammarImplName; break;
603 if (!aImplName.isEmpty() && (lcl_SeqGetIndex( aRes, aImplName) == -1)) // name not yet added
605 DBG_ASSERT( nIdx < aRes.getLength(), "index out of range" );
606 if (nIdx < aRes.getLength())
607 pRes[ nIdx++ ] = aImplName;
610 // don't forget to put aRes back to its actual size just in case you allocated too much
611 // since all of the names may have already been added
612 // otherwise you get duplicate entries in the edit dialog
613 aRes.realloc( nIdx );
614 return aRes;
618 ServiceInfo_Impl * SvxLinguData_Impl::GetInfoByImplName( const OUString &rSvcImplName )
620 ServiceInfo_Impl* pInfo = 0;
621 for (sal_uLong i = 0; i < nDisplayServices && !pInfo; ++i)
623 ServiceInfo_Impl &rTmp = aDisplayServiceArr[ i ];
624 if (rTmp.sSpellImplName == rSvcImplName ||
625 rTmp.sHyphImplName == rSvcImplName ||
626 rTmp.sThesImplName == rSvcImplName ||
627 rTmp.sGrammarImplName == rSvcImplName)
628 pInfo = &rTmp;
630 return pInfo;
636 static void lcl_MergeLocales(Sequence< Locale >& aAllLocales, const Sequence< Locale >& rAdd)
638 const Locale* pAdd = rAdd.getConstArray();
639 Sequence<Locale> aLocToAdd(rAdd.getLength());
640 const Locale* pAllLocales = aAllLocales.getConstArray();
641 Locale* pLocToAdd = aLocToAdd.getArray();
642 sal_Int32 nFound = 0;
643 sal_Int32 i;
644 for(i = 0; i < rAdd.getLength(); i++)
646 bool bFound = false;
647 for(sal_Int32 j = 0; j < aAllLocales.getLength() && !bFound; j++)
649 bFound = pAdd[i].Language == pAllLocales[j].Language &&
650 pAdd[i].Country == pAllLocales[j].Country &&
651 pAdd[i].Variant == pAllLocales[j].Variant;
653 if(!bFound)
655 pLocToAdd[nFound++] = pAdd[i];
658 sal_Int32 nLength = aAllLocales.getLength();
659 aAllLocales.realloc( nLength + nFound);
660 Locale* pAllLocales2 = aAllLocales.getArray();
661 for(i = 0; i < nFound; i++)
662 pAllLocales2[nLength++] = pLocToAdd[i];
665 static void lcl_MergeDisplayArray(
666 SvxLinguData_Impl &rData,
667 const ServiceInfo_Impl &rToAdd )
669 sal_uLong nCnt = 0;
671 ServiceInfoArr &rSvcInfoArr = rData.GetDisplayServiceArray();
672 sal_uLong nEntries = rData.GetDisplayServiceCount();
674 for (sal_uLong i = 0; i < nEntries; ++i)
676 ServiceInfo_Impl* pEntry = &rSvcInfoArr[i];
677 if (pEntry && pEntry->sDisplayName == rToAdd.sDisplayName)
679 if(rToAdd.xSpell.is())
681 DBG_ASSERT( !pEntry->xSpell.is() &&
682 pEntry->sSpellImplName.isEmpty(),
683 "merge conflict" );
684 pEntry->sSpellImplName = rToAdd.sSpellImplName;
685 pEntry->xSpell = rToAdd.xSpell;
687 if(rToAdd.xGrammar.is())
689 DBG_ASSERT( !pEntry->xGrammar.is() &&
690 pEntry->sGrammarImplName.isEmpty(),
691 "merge conflict" );
692 pEntry->sGrammarImplName = rToAdd.sGrammarImplName;
693 pEntry->xGrammar = rToAdd.xGrammar;
695 if(rToAdd.xHyph.is())
697 DBG_ASSERT( !pEntry->xHyph.is() &&
698 pEntry->sHyphImplName.isEmpty(),
699 "merge conflict" );
700 pEntry->sHyphImplName = rToAdd.sHyphImplName;
701 pEntry->xHyph = rToAdd.xHyph;
703 if(rToAdd.xThes.is())
705 DBG_ASSERT( !pEntry->xThes.is() &&
706 pEntry->sThesImplName.isEmpty(),
707 "merge conflict" );
708 pEntry->sThesImplName = rToAdd.sThesImplName;
709 pEntry->xThes = rToAdd.xThes;
711 return ;
713 ++nCnt;
715 rData.GetDisplayServiceArray().push_back( rToAdd );
716 rData.SetDisplayServiceCount( nCnt + 1 );
719 SvxLinguData_Impl::SvxLinguData_Impl() :
720 nDisplayServices (0)
722 uno::Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
723 xLinguSrvcMgr = LinguServiceManager::create(xContext);
725 const Locale& rCurrentLocale = Application::GetSettings().GetLanguageTag().getLocale();
726 Sequence<Any> aArgs(2);//second arguments has to be empty!
727 aArgs.getArray()[0] <<= SvxGetLinguPropertySet();
729 //read spell checker
730 Sequence< OUString > aSpellNames = xLinguSrvcMgr->getAvailableServices(
731 cSpell, Locale() );
732 const OUString* pSpellNames = aSpellNames.getConstArray();
734 sal_Int32 nIdx;
735 for(nIdx = 0; nIdx < aSpellNames.getLength(); nIdx++)
737 ServiceInfo_Impl aInfo;
738 aInfo.sSpellImplName = pSpellNames[nIdx];
739 aInfo.xSpell = uno::Reference<XSpellChecker>(
740 xContext->getServiceManager()->createInstanceWithArgumentsAndContext(aInfo.sSpellImplName, aArgs, xContext), UNO_QUERY);
742 uno::Reference<XServiceDisplayName> xDispName(aInfo.xSpell, UNO_QUERY);
743 if(xDispName.is())
744 aInfo.sDisplayName = xDispName->getServiceDisplayName( rCurrentLocale );
746 const Sequence< Locale > aLocales( aInfo.xSpell->getLocales() );
747 //! suppress display of entries with no supported languages (see feature 110994)
748 if (aLocales.getLength())
750 lcl_MergeLocales( aAllServiceLocales, aLocales );
751 lcl_MergeDisplayArray( *this, aInfo );
755 //read grammar checker
756 Sequence< OUString > aGrammarNames = xLinguSrvcMgr->getAvailableServices(
757 cGrammar, Locale() );
758 const OUString* pGrammarNames = aGrammarNames.getConstArray();
759 for(nIdx = 0; nIdx < aGrammarNames.getLength(); nIdx++)
761 ServiceInfo_Impl aInfo;
762 aInfo.sGrammarImplName = pGrammarNames[nIdx];
763 aInfo.xGrammar = uno::Reference<XProofreader>(
764 xContext->getServiceManager()->createInstanceWithArgumentsAndContext(aInfo.sGrammarImplName, aArgs, xContext), UNO_QUERY);
766 uno::Reference<XServiceDisplayName> xDispName(aInfo.xGrammar, UNO_QUERY);
767 if(xDispName.is())
768 aInfo.sDisplayName = xDispName->getServiceDisplayName( rCurrentLocale );
770 const Sequence< Locale > aLocales( aInfo.xGrammar->getLocales() );
771 //! suppress display of entries with no supported languages (see feature 110994)
772 if (aLocales.getLength())
774 lcl_MergeLocales( aAllServiceLocales, aLocales );
775 lcl_MergeDisplayArray( *this, aInfo );
779 //read hyphenator
780 Sequence< OUString > aHyphNames = xLinguSrvcMgr->getAvailableServices(
781 cHyph, Locale() );
782 const OUString* pHyphNames = aHyphNames.getConstArray();
783 for(nIdx = 0; nIdx < aHyphNames.getLength(); nIdx++)
785 ServiceInfo_Impl aInfo;
786 aInfo.sHyphImplName = pHyphNames[nIdx];
787 aInfo.xHyph = uno::Reference<XHyphenator>(
788 xContext->getServiceManager()->createInstanceWithArgumentsAndContext(aInfo.sHyphImplName, aArgs, xContext), UNO_QUERY);
790 uno::Reference<XServiceDisplayName> xDispName(aInfo.xHyph, UNO_QUERY);
791 if(xDispName.is())
792 aInfo.sDisplayName = xDispName->getServiceDisplayName( rCurrentLocale );
794 const Sequence< Locale > aLocales( aInfo.xHyph->getLocales() );
795 //! suppress display of entries with no supported languages (see feature 110994)
796 if (aLocales.getLength())
798 lcl_MergeLocales( aAllServiceLocales, aLocales );
799 lcl_MergeDisplayArray( *this, aInfo );
803 //read thesauri
804 Sequence< OUString > aThesNames = xLinguSrvcMgr->getAvailableServices(
805 cThes, Locale() );
806 const OUString* pThesNames = aThesNames.getConstArray();
807 for(nIdx = 0; nIdx < aThesNames.getLength(); nIdx++)
809 ServiceInfo_Impl aInfo;
810 aInfo.sThesImplName = pThesNames[nIdx];
811 aInfo.xThes = uno::Reference<XThesaurus>(
812 xContext->getServiceManager()->createInstanceWithArgumentsAndContext(aInfo.sThesImplName, aArgs, xContext), UNO_QUERY);
814 uno::Reference<XServiceDisplayName> xDispName(aInfo.xThes, UNO_QUERY);
815 if(xDispName.is())
816 aInfo.sDisplayName = xDispName->getServiceDisplayName( rCurrentLocale );
818 const Sequence< Locale > aLocales( aInfo.xThes->getLocales() );
819 //! suppress display of entries with no supported languages (see feature 110994)
820 if (aLocales.getLength())
822 lcl_MergeLocales( aAllServiceLocales, aLocales );
823 lcl_MergeDisplayArray( *this, aInfo );
827 Sequence< OUString > aCfgSvcs;
828 const Locale* pAllLocales = aAllServiceLocales.getConstArray();
829 for(sal_Int32 nLocale = 0; nLocale < aAllServiceLocales.getLength(); nLocale++)
831 sal_Int16 nLang = LanguageTag::convertToLanguageType( pAllLocales[nLocale] );
833 aCfgSvcs = xLinguSrvcMgr->getConfiguredServices(cSpell, pAllLocales[nLocale]);
834 SetChecked( aCfgSvcs );
835 if (aCfgSvcs.getLength())
836 aCfgSpellTable[ nLang ] = aCfgSvcs;
838 aCfgSvcs = xLinguSrvcMgr->getConfiguredServices(cGrammar, pAllLocales[nLocale]);
839 SetChecked( aCfgSvcs );
840 if (aCfgSvcs.getLength())
841 aCfgGrammarTable[ nLang ] = aCfgSvcs;
843 aCfgSvcs = xLinguSrvcMgr->getConfiguredServices(cHyph, pAllLocales[nLocale]);
844 SetChecked( aCfgSvcs );
845 if (aCfgSvcs.getLength())
846 aCfgHyphTable[ nLang ] = aCfgSvcs;
848 aCfgSvcs = xLinguSrvcMgr->getConfiguredServices(cThes, pAllLocales[nLocale]);
849 SetChecked( aCfgSvcs );
850 if (aCfgSvcs.getLength())
851 aCfgThesTable[ nLang ] = aCfgSvcs;
855 SvxLinguData_Impl::SvxLinguData_Impl( const SvxLinguData_Impl &rData ) :
856 aDisplayServiceArr (rData.aDisplayServiceArr),
857 nDisplayServices (rData.nDisplayServices),
858 aAllServiceLocales (rData.aAllServiceLocales),
859 aCfgSpellTable (rData.aCfgSpellTable),
860 aCfgHyphTable (rData.aCfgHyphTable),
861 aCfgThesTable (rData.aCfgThesTable),
862 aCfgGrammarTable (rData.aCfgGrammarTable),
863 xLinguSrvcMgr (rData.xLinguSrvcMgr)
867 SvxLinguData_Impl & SvxLinguData_Impl::operator = (const SvxLinguData_Impl &rData)
869 xLinguSrvcMgr = rData.xLinguSrvcMgr;
870 aAllServiceLocales = rData.aAllServiceLocales;
871 aCfgSpellTable = rData.aCfgSpellTable;
872 aCfgHyphTable = rData.aCfgHyphTable;
873 aCfgThesTable = rData.aCfgThesTable;
874 aCfgGrammarTable = rData.aCfgGrammarTable;
875 aDisplayServiceArr = rData.aDisplayServiceArr;
876 nDisplayServices = rData.nDisplayServices;
877 return *this;
880 SvxLinguData_Impl::~SvxLinguData_Impl()
884 void SvxLinguData_Impl::SetChecked(const Sequence<OUString>& rConfiguredServices)
886 const OUString* pConfiguredServices = rConfiguredServices.getConstArray();
887 for(sal_Int32 n = 0; n < rConfiguredServices.getLength(); n++)
889 for (sal_uLong i = 0; i < nDisplayServices; ++i)
891 ServiceInfo_Impl* pEntry = &aDisplayServiceArr[i];
892 if (pEntry && !pEntry->bConfigured)
894 const OUString &rSrvcImplName = pConfiguredServices[n];
895 if (!rSrvcImplName.isEmpty() &&
896 (pEntry->sSpellImplName == rSrvcImplName ||
897 pEntry->sGrammarImplName == rSrvcImplName ||
898 pEntry->sHyphImplName == rSrvcImplName ||
899 pEntry->sThesImplName == rSrvcImplName))
901 pEntry->bConfigured = true;
902 break;
909 bool SvxLinguData_Impl::AddRemove(
910 Sequence< OUString > &rConfigured,
911 const OUString &rImplName, bool bAdd )
913 bool bRet = false; // modified?
915 sal_Int32 nEntries = rConfigured.getLength();
916 sal_Int32 nPos = lcl_SeqGetEntryPos(rConfigured, rImplName);
917 if (bAdd && nPos < 0) // add new entry
919 rConfigured.realloc( ++nEntries );
920 OUString *pConfigured = rConfigured.getArray();
921 pConfigured[nEntries - 1] = rImplName;
922 bRet = true;
924 else if (!bAdd && nPos >= 0) // remove existing entry
926 OUString *pConfigured = rConfigured.getArray();
927 for (sal_Int32 i = nPos; i < nEntries - 1; ++i)
928 pConfigured[i] = pConfigured[i + 1];
929 rConfigured.realloc(--nEntries);
930 bRet = true;
933 return bRet;
937 void SvxLinguData_Impl::Reconfigure( const OUString &rDisplayName, bool bEnable )
939 DBG_ASSERT( !rDisplayName.isEmpty(), "empty DisplayName" );
941 ServiceInfo_Impl *pInfo = 0;
942 ServiceInfo_Impl *pTmp = 0;
943 for (sal_uLong i = 0; i < nDisplayServices; ++i)
945 pTmp = &aDisplayServiceArr[i];
946 if (pTmp && pTmp->sDisplayName == rDisplayName)
948 pInfo = pTmp;
949 break;
952 DBG_ASSERT( pInfo, "DisplayName entry not found" );
953 if (pInfo)
955 pInfo->bConfigured = bEnable;
957 Sequence< Locale > aLocales;
958 const Locale *pLocale = 0;
959 sal_Int32 nLocales = 0;
960 sal_Int32 i;
962 // update configured spellchecker entries
963 if (pInfo->xSpell.is())
965 aLocales = pInfo->xSpell->getLocales();
966 pLocale = aLocales.getConstArray();
967 nLocales = aLocales.getLength();
968 for (i = 0; i < nLocales; ++i)
970 sal_Int16 nLang = LanguageTag::convertToLanguageType( pLocale[i] );
971 if (!aCfgSpellTable.count( nLang ) && bEnable)
972 aCfgSpellTable[ nLang ] = Sequence< OUString >();
973 if (aCfgSpellTable.count( nLang ))
974 AddRemove( aCfgSpellTable[ nLang ], pInfo->sSpellImplName, bEnable );
978 // update configured grammar checker entries
979 if (pInfo->xGrammar.is())
981 aLocales = pInfo->xGrammar->getLocales();
982 pLocale = aLocales.getConstArray();
983 nLocales = aLocales.getLength();
984 for (i = 0; i < nLocales; ++i)
986 sal_Int16 nLang = LanguageTag::convertToLanguageType( pLocale[i] );
987 if (!aCfgGrammarTable.count( nLang ) && bEnable)
988 aCfgGrammarTable[ nLang ] = Sequence< OUString >();
989 if (aCfgGrammarTable.count( nLang ))
990 AddRemove( aCfgGrammarTable[ nLang ], pInfo->sGrammarImplName, bEnable );
994 // update configured hyphenator entries
995 if (pInfo->xHyph.is())
997 aLocales = pInfo->xHyph->getLocales();
998 pLocale = aLocales.getConstArray();
999 nLocales = aLocales.getLength();
1000 for (i = 0; i < nLocales; ++i)
1002 sal_Int16 nLang = LanguageTag::convertToLanguageType( pLocale[i] );
1003 if (!aCfgHyphTable.count( nLang ) && bEnable)
1004 aCfgHyphTable[ nLang ] = Sequence< OUString >();
1005 if (aCfgHyphTable.count( nLang ))
1006 AddRemove( aCfgHyphTable[ nLang ], pInfo->sHyphImplName, bEnable );
1010 // update configured spellchecker entries
1011 if (pInfo->xThes.is())
1013 aLocales = pInfo->xThes->getLocales();
1014 pLocale = aLocales.getConstArray();
1015 nLocales = aLocales.getLength();
1016 for (i = 0; i < nLocales; ++i)
1018 sal_Int16 nLang = LanguageTag::convertToLanguageType( pLocale[i] );
1019 if (!aCfgThesTable.count( nLang ) && bEnable)
1020 aCfgThesTable[ nLang ] = Sequence< OUString >();
1021 if (aCfgThesTable.count( nLang ))
1022 AddRemove( aCfgThesTable[ nLang ], pInfo->sThesImplName, bEnable );
1029 // class SvxLinguTabPage -------------------------------------------------
1031 SvxLinguTabPage::SvxLinguTabPage( vcl::Window* pParent, const SfxItemSet& rSet ) :
1032 SfxTabPage(pParent, "OptLinguPage", "cui/ui/optlingupage.ui", &rSet),
1034 sCapitalWords (CUI_RES(RID_SVXSTR_CAPITAL_WORDS)),
1035 sWordsWithDigits(CUI_RES(RID_SVXSTR_WORDS_WITH_DIGITS)),
1036 sSpellSpecial (CUI_RES(RID_SVXSTR_SPELL_SPECIAL)),
1037 sSpellAuto (CUI_RES(RID_SVXSTR_SPELL_AUTO)),
1038 sGrammarAuto (CUI_RES(RID_SVXSTR_GRAMMAR_AUTO)),
1039 sNumMinWordlen (CUI_RES(RID_SVXSTR_NUM_MIN_WORDLEN)),
1040 sNumPreBreak (CUI_RES(RID_SVXSTR_NUM_PRE_BREAK)),
1041 sNumPostBreak (CUI_RES(RID_SVXSTR_NUM_POST_BREAK)),
1042 sHyphAuto (CUI_RES(RID_SVXSTR_HYPH_AUTO)),
1043 sHyphSpecial (CUI_RES(RID_SVXSTR_HYPH_SPECIAL)),
1045 pLinguData(NULL)
1047 get(m_pLinguModulesFT, "lingumodulesft");
1048 get(m_pLinguModulesCLB, "lingumodules");
1049 get(m_pLinguModulesEditPB, "lingumodulesedit");
1050 get(m_pLinguDicsFT, "lingudictsft");
1051 get(m_pLinguDicsCLB, "lingudicts");
1052 get(m_pLinguDicsNewPB, "lingudictsnew");
1053 get(m_pLinguDicsEditPB, "lingudictsedit");
1054 get(m_pLinguDicsDelPB, "lingudictsdelete");
1055 get(m_pLinguOptionsCLB, "linguoptions");
1056 get(m_pLinguOptionsEditPB, "linguoptionsedit");
1057 get(m_pMoreDictsLink, "moredictslink");
1059 m_pLinguModulesCLB->set_height_request(m_pLinguModulesCLB->GetTextHeight() * 3);
1060 m_pLinguDicsCLB->set_height_request(m_pLinguDicsCLB->GetTextHeight() * 5);
1061 m_pLinguOptionsCLB->set_height_request(m_pLinguOptionsCLB->GetTextHeight() * 5);
1063 pCheckButtonData = NULL;
1065 m_pLinguModulesCLB->SetStyle( m_pLinguModulesCLB->GetStyle()|WB_CLIPCHILDREN|WB_HSCROLL|WB_FORCE_MAKEVISIBLE );
1066 m_pLinguModulesCLB->SetHighlightRange();
1067 m_pLinguModulesCLB->SetSelectHdl( LINK( this, SvxLinguTabPage, SelectHdl_Impl ));
1068 m_pLinguModulesCLB->SetDoubleClickHdl(LINK(this, SvxLinguTabPage, BoxDoubleClickHdl_Impl));
1069 m_pLinguModulesCLB->SetCheckButtonHdl(LINK(this, SvxLinguTabPage, BoxCheckButtonHdl_Impl));
1071 m_pLinguModulesEditPB->SetClickHdl( LINK( this, SvxLinguTabPage, ClickHdl_Impl ));
1072 m_pLinguOptionsEditPB->SetClickHdl( LINK( this, SvxLinguTabPage, ClickHdl_Impl ));
1074 m_pLinguDicsCLB->SetStyle( m_pLinguDicsCLB->GetStyle()|WB_CLIPCHILDREN|WB_HSCROLL|WB_FORCE_MAKEVISIBLE );
1075 m_pLinguDicsCLB->SetHighlightRange();
1076 m_pLinguDicsCLB->SetSelectHdl( LINK( this, SvxLinguTabPage, SelectHdl_Impl ));
1077 m_pLinguDicsCLB->SetCheckButtonHdl(LINK(this, SvxLinguTabPage, BoxCheckButtonHdl_Impl));
1079 m_pLinguDicsNewPB->SetClickHdl( LINK( this, SvxLinguTabPage, ClickHdl_Impl ));
1080 m_pLinguDicsEditPB->SetClickHdl( LINK( this, SvxLinguTabPage, ClickHdl_Impl ));
1081 m_pLinguDicsDelPB->SetClickHdl( LINK( this, SvxLinguTabPage, ClickHdl_Impl ));
1083 m_pLinguOptionsCLB->SetStyle( m_pLinguOptionsCLB->GetStyle()|WB_CLIPCHILDREN|WB_HSCROLL|WB_FORCE_MAKEVISIBLE );
1084 m_pLinguOptionsCLB->SetHighlightRange();
1085 m_pLinguOptionsCLB->SetSelectHdl( LINK( this, SvxLinguTabPage, SelectHdl_Impl ));
1086 m_pLinguOptionsCLB->SetDoubleClickHdl(LINK(this, SvxLinguTabPage, BoxDoubleClickHdl_Impl));
1088 if ( SvtExtendedSecurityOptions().GetOpenHyperlinkMode()
1089 != SvtExtendedSecurityOptions::OPEN_NEVER )
1091 m_pMoreDictsLink->SetClickHdl( LINK( this, SvxLinguTabPage, OpenURLHdl_Impl ) );
1093 else
1094 m_pMoreDictsLink->Hide();
1096 OUString sAccessibleNameModuleEdit(CUI_RES(RID_SVXSTR_LINGU_MODULES_EDIT));
1097 OUString sAccessibleNameDicsEdit (CUI_RES(RID_SVXSTR_LINGU_DICS_EDIT_DIC));
1098 OUString sAccessibleNameOptionEdit(CUI_RES(RID_SVXSTR_LINGU_OPTIONS_EDIT));
1100 m_pLinguModulesEditPB->SetAccessibleName(sAccessibleNameModuleEdit);
1101 m_pLinguDicsEditPB->SetAccessibleName(sAccessibleNameDicsEdit);
1102 m_pLinguOptionsEditPB->SetAccessibleName(sAccessibleNameOptionEdit);
1104 xProp = SvxGetLinguPropertySet();
1105 xDicList = uno::Reference< XDictionaryList >( SvxGetDictionaryList(), UNO_QUERY );
1106 if (xDicList.is())
1108 // keep references to all **currently** available dictionaries,
1109 // since the diclist may get changed meanwhile (e.g. through the API).
1110 // We want the dialog to operate on the same set of dictionaries it
1111 // was started with.
1112 // Also we have to take care to not lose the last reference when
1113 // someone else removes a dictionary from the list.
1114 // removed dics will be replaced by NULL new entries be added to the end
1115 // Thus we may use indices as consistent references.
1116 aDics = xDicList->getDictionaries();
1118 UpdateDicBox_Impl();
1120 else
1122 m_pLinguDicsFT->Disable();
1123 m_pLinguDicsCLB->Disable();
1124 m_pLinguDicsNewPB->Disable();
1125 m_pLinguDicsEditPB->Disable();
1126 m_pLinguDicsDelPB->Disable();
1130 SvxLinguTabPage::~SvxLinguTabPage()
1132 disposeOnce();
1135 void SvxLinguTabPage::dispose()
1137 delete pLinguData;
1138 pLinguData = NULL;
1139 m_pLinguModulesFT.clear();
1140 m_pLinguModulesCLB.clear();
1141 m_pLinguModulesEditPB.clear();
1142 m_pLinguDicsFT.clear();
1143 m_pLinguDicsCLB.clear();
1144 m_pLinguDicsNewPB.clear();
1145 m_pLinguDicsEditPB.clear();
1146 m_pLinguDicsDelPB.clear();
1147 m_pLinguOptionsCLB.clear();
1148 m_pLinguOptionsEditPB.clear();
1149 m_pMoreDictsLink.clear();
1150 SfxTabPage::dispose();
1153 VclPtr<SfxTabPage> SvxLinguTabPage::Create( vcl::Window* pParent,
1154 const SfxItemSet* rAttrSet )
1156 return VclPtr<SvxLinguTabPage>::Create( pParent, *rAttrSet );
1161 bool SvxLinguTabPage::FillItemSet( SfxItemSet* rCoreSet )
1163 bool bModified = true; // !!!!
1165 // if not HideGroups was called with GROUP_MODULES...
1166 if (m_pLinguModulesCLB->IsVisible())
1168 DBG_ASSERT( pLinguData, "pLinguData not yet initialized" );
1169 if (!pLinguData)
1170 pLinguData = new SvxLinguData_Impl;
1172 LangImplNameTable::const_iterator aIt;
1174 // update spellchecker configuration entries
1175 const LangImplNameTable *pTable = &pLinguData->GetSpellTable();
1176 for (aIt = pTable->begin(); aIt != pTable->end(); ++aIt)
1178 sal_Int16 nLang = aIt->first;
1179 const Sequence< OUString > aImplNames( aIt->second );
1180 uno::Reference< XLinguServiceManager2 > xMgr( pLinguData->GetManager() );
1181 Locale aLocale( LanguageTag::convertToLocale(nLang) );
1182 if (xMgr.is())
1183 xMgr->setConfiguredServices( cSpell, aLocale, aImplNames );
1186 // update grammar checker configuration entries
1187 pTable = &pLinguData->GetGrammarTable();
1188 for (aIt = pTable->begin(); aIt != pTable->end(); ++aIt)
1190 sal_Int16 nLang = aIt->first;
1191 const Sequence< OUString > aImplNames( aIt->second );
1192 uno::Reference< XLinguServiceManager2 > xMgr( pLinguData->GetManager() );
1193 Locale aLocale( LanguageTag::convertToLocale(nLang) );
1194 if (xMgr.is())
1195 xMgr->setConfiguredServices( cGrammar, aLocale, aImplNames );
1198 // update hyphenator configuration entries
1199 pTable = &pLinguData->GetHyphTable();
1200 for (aIt = pTable->begin(); aIt != pTable->end(); ++aIt)
1202 sal_Int16 nLang = aIt->first;
1203 const Sequence< OUString > aImplNames( aIt->second );
1204 uno::Reference< XLinguServiceManager2 > xMgr( pLinguData->GetManager() );
1205 Locale aLocale( LanguageTag::convertToLocale(nLang) );
1206 if (xMgr.is())
1207 xMgr->setConfiguredServices( cHyph, aLocale, aImplNames );
1210 // update thesaurus configuration entries
1211 pTable = &pLinguData->GetThesTable();
1212 for (aIt = pTable->begin(); aIt != pTable->end(); ++aIt)
1214 sal_Int16 nLang = aIt->first;
1215 const Sequence< OUString > aImplNames( aIt->second );
1216 uno::Reference< XLinguServiceManager2 > xMgr( pLinguData->GetManager() );
1217 Locale aLocale( LanguageTag::convertToLocale(nLang) );
1218 if (xMgr.is())
1219 xMgr->setConfiguredServices( cThes, aLocale, aImplNames );
1225 // activate dictionaries according to checkbox state
1227 Sequence< OUString > aActiveDics;
1228 sal_Int32 nActiveDics = 0;
1229 sal_uLong nEntries = m_pLinguDicsCLB->GetEntryCount();
1230 for (sal_uLong i = 0; i < nEntries; ++i)
1232 sal_Int32 nDics = aDics.getLength();
1234 aActiveDics.realloc( nDics );
1235 OUString *pActiveDic = aActiveDics.getArray();
1237 SvTreeListEntry *pEntry = m_pLinguDicsCLB->GetEntry( i );
1238 if (pEntry)
1240 DicUserData aData( reinterpret_cast<sal_uLong>(pEntry->GetUserData()) );
1241 if (aData.GetEntryId() < nDics)
1243 bool bChecked = m_pLinguDicsCLB->IsChecked( i );
1244 uno::Reference< XDictionary > xDic( aDics.getConstArray()[ i ] );
1245 if (xDic.is())
1247 if (SvxGetIgnoreAllList() == xDic)
1248 bChecked = true;
1249 xDic->setActive( bChecked );
1251 if (bChecked)
1253 OUString aDicName( xDic->getName() );
1254 pActiveDic[ nActiveDics++ ] = aDicName;
1261 aActiveDics.realloc( nActiveDics );
1262 Any aTmp;
1263 aTmp <<= aActiveDics;
1264 SvtLinguConfig aLngCfg;
1265 aLngCfg.SetProperty( UPH_ACTIVE_DICTIONARIES, aTmp );
1268 nEntries = m_pLinguOptionsCLB->GetEntryCount();
1269 for (sal_uLong j = 0; j < nEntries; ++j)
1271 SvTreeListEntry *pEntry = m_pLinguOptionsCLB->GetEntry( j );
1273 OptionsUserData aData( reinterpret_cast<sal_uLong>(pEntry->GetUserData()) );
1274 OUString aPropName( lcl_GetPropertyName( (EID_OPTIONS) aData.GetEntryId() ) );
1276 Any aAny;
1277 if (aData.IsCheckable())
1279 bool bChecked = m_pLinguOptionsCLB->IsChecked( j );
1280 aAny <<= bChecked;
1282 else if (aData.HasNumericValue())
1284 sal_Int16 nVal = aData.GetNumericValue();
1285 aAny <<= nVal;
1288 if (xProp.is())
1289 xProp->setPropertyValue( aPropName, aAny );
1290 aLngCfg.SetProperty( aPropName, aAny );
1293 SvTreeListEntry *pPreBreakEntry = m_pLinguOptionsCLB->GetEntry( (sal_uLong) EID_NUM_PRE_BREAK );
1294 SvTreeListEntry *pPostBreakEntry = m_pLinguOptionsCLB->GetEntry( (sal_uLong) EID_NUM_POST_BREAK );
1295 DBG_ASSERT( pPreBreakEntry, "NULL Pointer" );
1296 DBG_ASSERT( pPostBreakEntry, "NULL Pointer" );
1297 if (pPreBreakEntry && pPostBreakEntry)
1299 OptionsUserData aPreBreakData( reinterpret_cast<sal_uLong>(pPreBreakEntry->GetUserData()) );
1300 OptionsUserData aPostBreakData( reinterpret_cast<sal_uLong>(pPostBreakEntry->GetUserData()) );
1301 if ( aPreBreakData.IsModified() || aPostBreakData.IsModified() )
1303 SfxHyphenRegionItem aHyp( GetWhich( SID_ATTR_HYPHENREGION ) );
1304 aHyp.GetMinLead() = (sal_uInt8) aPreBreakData.GetNumericValue();
1305 aHyp.GetMinTrail() = (sal_uInt8) aPostBreakData.GetNumericValue();
1306 rCoreSet->Put( aHyp );
1311 // automatic spell checking
1312 bool bNewAutoCheck = m_pLinguOptionsCLB->IsChecked( (sal_uLong) EID_SPELL_AUTO );
1313 const SfxPoolItem* pOld = GetOldItem( *rCoreSet, SID_AUTOSPELL_CHECK );
1314 if ( !pOld || static_cast<const SfxBoolItem*>(pOld)->GetValue() != bNewAutoCheck )
1316 rCoreSet->Put( SfxBoolItem( GetWhich( SID_AUTOSPELL_CHECK ),
1317 bNewAutoCheck ) );
1318 bModified |= true;
1321 return bModified;
1326 sal_uLong SvxLinguTabPage::GetDicUserData( const uno::Reference< XDictionary > &rxDic, sal_uInt16 nIdx )
1328 sal_uLong nRes = 0;
1329 DBG_ASSERT( rxDic.is(), "dictionary not supplied" );
1330 if (rxDic.is())
1332 uno::Reference< frame::XStorable > xStor( rxDic, UNO_QUERY );
1334 bool bChecked = rxDic->isActive();
1335 bool bEditable = !xStor.is() || !xStor->isReadonly();
1336 bool bDeletable = bEditable;
1338 nRes = DicUserData( nIdx,
1339 bChecked, bEditable, bDeletable ).GetUserData();
1341 return nRes;
1345 void SvxLinguTabPage::AddDicBoxEntry(
1346 const uno::Reference< XDictionary > &rxDic,
1347 sal_uInt16 nIdx )
1349 m_pLinguDicsCLB->SetUpdateMode(false);
1351 OUString aTxt( ::GetDicInfoStr( rxDic->getName(),
1352 LanguageTag( rxDic->getLocale() ).getLanguageType(),
1353 DictionaryType_NEGATIVE == rxDic->getDictionaryType() ) );
1354 m_pLinguDicsCLB->InsertEntry( aTxt, TREELIST_APPEND ); // append at end
1355 SvTreeListEntry* pEntry = m_pLinguDicsCLB->GetEntry( m_pLinguDicsCLB->GetEntryCount() - 1 );
1356 DBG_ASSERT( pEntry, "failed to add entry" );
1357 if (pEntry)
1359 DicUserData aData( GetDicUserData( rxDic, nIdx ) );
1360 pEntry->SetUserData( reinterpret_cast<void *>(aData.GetUserData()) );
1361 lcl_SetCheckButton( pEntry, aData.IsChecked() );
1364 m_pLinguDicsCLB->SetUpdateMode(true);
1369 void SvxLinguTabPage::UpdateDicBox_Impl()
1371 m_pLinguDicsCLB->SetUpdateMode(false);
1372 m_pLinguDicsCLB->Clear();
1374 sal_Int32 nDics = aDics.getLength();
1375 const uno::Reference< XDictionary > *pDic = aDics.getConstArray();
1376 for (sal_Int32 i = 0; i < nDics; ++i)
1378 const uno::Reference< XDictionary > &rDic = pDic[i];
1379 if (rDic.is())
1380 AddDicBoxEntry( rDic, (sal_uInt16)i );
1383 m_pLinguDicsCLB->SetUpdateMode(true);
1388 void SvxLinguTabPage::UpdateModulesBox_Impl()
1390 if (pLinguData)
1392 const ServiceInfoArr &rAllDispSrvcArr = pLinguData->GetDisplayServiceArray();
1393 const sal_uLong nDispSrvcCount = pLinguData->GetDisplayServiceCount();
1395 m_pLinguModulesCLB->Clear();
1397 for (sal_uLong i = 0; i < nDispSrvcCount; ++i)
1399 const ServiceInfo_Impl &rInfo = rAllDispSrvcArr[i];
1400 m_pLinguModulesCLB->InsertEntry( rInfo.sDisplayName, TREELIST_APPEND );
1401 SvTreeListEntry* pEntry = m_pLinguModulesCLB->GetEntry(i);
1402 pEntry->SetUserData( (void *) &rInfo );
1403 m_pLinguModulesCLB->CheckEntryPos( i, rInfo.bConfigured );
1405 m_pLinguModulesEditPB->Enable( nDispSrvcCount > 0 );
1411 void SvxLinguTabPage::Reset( const SfxItemSet* rSet )
1413 // if not HideGroups was called with GROUP_MODULES...
1414 if (m_pLinguModulesCLB->IsVisible())
1416 if (!pLinguData)
1417 pLinguData = new SvxLinguData_Impl;
1418 UpdateModulesBox_Impl();
1423 // get data from configuration
1426 SvtLinguConfig aLngCfg;
1428 m_pLinguOptionsCLB->SetUpdateMode(false);
1429 m_pLinguOptionsCLB->Clear();
1431 SvTreeList *pModel = m_pLinguOptionsCLB->GetModel();
1432 SvTreeListEntry* pEntry = NULL;
1434 sal_Int16 nVal = 0;
1435 bool bVal = false;
1436 sal_uLong nUserData = 0;
1438 pEntry = CreateEntry( sSpellAuto, CBCOL_FIRST );
1439 aLngCfg.GetProperty( UPN_IS_SPELL_AUTO ) >>= bVal;
1440 const SfxPoolItem* pItem = GetItem( *rSet, SID_AUTOSPELL_CHECK );
1441 if (pItem)
1442 bVal = static_cast<const SfxBoolItem *>(pItem)->GetValue();
1443 nUserData = OptionsUserData( EID_SPELL_AUTO, false, 0, true, bVal).GetUserData();
1444 pEntry->SetUserData( reinterpret_cast<void *>(nUserData) );
1445 pModel->Insert( pEntry );
1446 lcl_SetCheckButton( pEntry, bVal );
1448 pEntry = CreateEntry( sGrammarAuto, CBCOL_FIRST );
1449 aLngCfg.GetProperty( UPN_IS_GRAMMAR_AUTO ) >>= bVal;
1450 nUserData = OptionsUserData( EID_GRAMMAR_AUTO, false, 0, true, bVal).GetUserData();
1451 pEntry->SetUserData( reinterpret_cast<void *>(nUserData) );
1452 pModel->Insert( pEntry );
1453 lcl_SetCheckButton( pEntry, bVal );
1455 pEntry = CreateEntry( sCapitalWords, CBCOL_FIRST );
1456 aLngCfg.GetProperty( UPN_IS_SPELL_UPPER_CASE ) >>= bVal;
1457 nUserData = OptionsUserData( EID_CAPITAL_WORDS, false, 0, true, bVal).GetUserData();
1458 pEntry->SetUserData( reinterpret_cast<void *>(nUserData) );
1459 pModel->Insert( pEntry );
1460 lcl_SetCheckButton( pEntry, bVal );
1462 pEntry = CreateEntry( sWordsWithDigits, CBCOL_FIRST );
1463 aLngCfg.GetProperty( UPN_IS_SPELL_WITH_DIGITS ) >>= bVal;
1464 nUserData = OptionsUserData( EID_WORDS_WITH_DIGITS, false, 0, true, bVal).GetUserData();
1465 pEntry->SetUserData( reinterpret_cast<void *>(nUserData) );
1466 pModel->Insert( pEntry );
1467 lcl_SetCheckButton( pEntry, bVal );
1469 pEntry = CreateEntry( sSpellSpecial, CBCOL_FIRST );
1470 aLngCfg.GetProperty( UPN_IS_SPELL_SPECIAL ) >>= bVal;
1471 nUserData = OptionsUserData( EID_SPELL_SPECIAL, false, 0, true, bVal).GetUserData();
1472 pEntry->SetUserData( reinterpret_cast<void *>(nUserData) );
1473 pModel->Insert( pEntry );
1474 lcl_SetCheckButton( pEntry, bVal );
1476 pEntry = CreateEntry( sNumMinWordlen, CBCOL_SECOND );
1477 aLngCfg.GetProperty( UPN_HYPH_MIN_WORD_LENGTH ) >>= nVal;
1478 nUserData = OptionsUserData( EID_NUM_MIN_WORDLEN, true, (sal_uInt16)nVal, false, false).GetUserData();
1479 pEntry->SetUserData( reinterpret_cast<void *>(nUserData) );
1480 pModel->Insert( pEntry );
1482 const SfxHyphenRegionItem *pHyp = NULL;
1483 sal_uInt16 nWhich = GetWhich( SID_ATTR_HYPHENREGION );
1484 if ( rSet->GetItemState( nWhich, false ) == SfxItemState::SET )
1485 pHyp = &static_cast<const SfxHyphenRegionItem &>( rSet->Get( nWhich ) );
1487 pEntry = CreateEntry( sNumPreBreak, CBCOL_SECOND );
1488 aLngCfg.GetProperty( UPN_HYPH_MIN_LEADING ) >>= nVal;
1489 if (pHyp)
1490 nVal = (sal_Int16) pHyp->GetMinLead();
1491 nUserData = OptionsUserData( EID_NUM_PRE_BREAK, true, (sal_uInt16)nVal, false, false).GetUserData();
1492 pEntry->SetUserData( reinterpret_cast<void *>(nUserData) );
1493 pModel->Insert( pEntry );
1495 pEntry = CreateEntry( sNumPostBreak, CBCOL_SECOND );
1496 aLngCfg.GetProperty( UPN_HYPH_MIN_TRAILING ) >>= nVal;
1497 if (pHyp)
1498 nVal = (sal_Int16) pHyp->GetMinTrail();
1499 nUserData = OptionsUserData( EID_NUM_POST_BREAK, true, (sal_uInt16)nVal, false, false).GetUserData();
1500 pEntry->SetUserData( reinterpret_cast<void *>(nUserData) );
1501 pModel->Insert( pEntry );
1503 pEntry = CreateEntry( sHyphAuto, CBCOL_FIRST );
1504 aLngCfg.GetProperty( UPN_IS_HYPH_AUTO ) >>= bVal;
1505 nUserData = OptionsUserData( EID_HYPH_AUTO, false, 0, true, bVal).GetUserData();
1506 pEntry->SetUserData( reinterpret_cast<void *>(nUserData) );
1507 pModel->Insert( pEntry );
1508 lcl_SetCheckButton( pEntry, bVal );
1510 pEntry = CreateEntry( sHyphSpecial, CBCOL_FIRST );
1511 aLngCfg.GetProperty( UPN_IS_HYPH_SPECIAL ) >>= bVal;
1512 nUserData = OptionsUserData( EID_HYPH_SPECIAL, false, 0, true, bVal).GetUserData();
1513 pEntry->SetUserData( reinterpret_cast<void *>(nUserData) );
1514 pModel->Insert( pEntry );
1515 lcl_SetCheckButton( pEntry, bVal );
1517 m_pLinguOptionsCLB->SetUpdateMode(true);
1522 IMPL_LINK( SvxLinguTabPage, BoxDoubleClickHdl_Impl, SvTreeListBox *, pBox )
1524 if (pBox == m_pLinguModulesCLB)
1526 //! in order to avoid a bug causing a GPF when double clicking
1527 //! on a module entry and exiting the "Edit Modules" dialog
1528 //! after that.
1529 Application::PostUserEvent( LINK(
1530 this, SvxLinguTabPage, PostDblClickHdl_Impl ), NULL, true);
1532 else if (pBox == m_pLinguOptionsCLB)
1534 ClickHdl_Impl(m_pLinguOptionsEditPB);
1536 return 0;
1541 IMPL_LINK_NOARG(SvxLinguTabPage, PostDblClickHdl_Impl)
1543 ClickHdl_Impl(m_pLinguModulesEditPB);
1544 return 0;
1549 IMPL_LINK_NOARG(SvxLinguTabPage, OpenURLHdl_Impl)
1551 OUString sURL( m_pMoreDictsLink->GetURL() );
1552 lcl_OpenURL( sURL );
1553 return 0;
1558 IMPL_LINK( SvxLinguTabPage, BoxCheckButtonHdl_Impl, SvTreeListBox *, pBox )
1560 if (pBox == m_pLinguModulesCLB)
1562 DBG_ASSERT( pLinguData, "NULL pointer, LinguData missing" );
1563 sal_uLong nPos = m_pLinguModulesCLB->GetSelectEntryPos();
1564 if (nPos != TREELIST_ENTRY_NOTFOUND && pLinguData)
1566 pLinguData->Reconfigure( m_pLinguModulesCLB->GetText( nPos ),
1567 m_pLinguModulesCLB->IsChecked( nPos ) );
1570 else if (pBox == m_pLinguDicsCLB)
1572 sal_uLong nPos = m_pLinguDicsCLB->GetSelectEntryPos();
1573 if (nPos != TREELIST_ENTRY_NOTFOUND)
1575 const uno::Reference< XDictionary > &rDic = aDics.getConstArray()[ nPos ];
1576 if (SvxGetIgnoreAllList() == rDic)
1578 SvTreeListEntry* pEntry = m_pLinguDicsCLB->GetEntry( nPos );
1579 if (pEntry)
1580 lcl_SetCheckButton( pEntry, true );
1584 return 0;
1589 IMPL_LINK( SvxLinguTabPage, ClickHdl_Impl, PushButton *, pBtn )
1591 if (m_pLinguModulesEditPB == pBtn)
1593 if (!pLinguData)
1594 pLinguData = new SvxLinguData_Impl;
1596 SvxLinguData_Impl aOldLinguData( *pLinguData );
1597 ScopedVclPtrInstance< SvxEditModulesDlg > aDlg( this, *pLinguData );
1598 if (aDlg->Execute() != RET_OK)
1599 *pLinguData = aOldLinguData;
1601 // evaluate new status of 'bConfigured' flag
1602 sal_uLong nLen = pLinguData->GetDisplayServiceCount();
1603 for (sal_uLong i = 0; i < nLen; ++i)
1604 pLinguData->GetDisplayServiceArray()[i].bConfigured = false;
1605 const Locale* pAllLocales = pLinguData->GetAllSupportedLocales().getConstArray();
1606 sal_Int32 nLocales = pLinguData->GetAllSupportedLocales().getLength();
1607 for (sal_Int32 k = 0; k < nLocales; ++k)
1609 sal_Int16 nLang = LanguageTag::convertToLanguageType( pAllLocales[k] );
1610 if (pLinguData->GetSpellTable().count( nLang ))
1611 pLinguData->SetChecked( pLinguData->GetSpellTable()[ nLang ] );
1612 if (pLinguData->GetGrammarTable().count( nLang ))
1613 pLinguData->SetChecked( pLinguData->GetGrammarTable()[ nLang ] );
1614 if (pLinguData->GetHyphTable().count( nLang ))
1615 pLinguData->SetChecked( pLinguData->GetHyphTable()[ nLang ] );
1616 if (pLinguData->GetThesTable().count( nLang ))
1617 pLinguData->SetChecked( pLinguData->GetThesTable()[ nLang ] );
1620 // show new status of modules
1621 UpdateModulesBox_Impl();
1623 else if (m_pLinguDicsNewPB == pBtn)
1625 uno::Reference< XSpellChecker1 > xSpellChecker1;
1626 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
1627 if(pFact)
1629 boost::scoped_ptr<AbstractSvxNewDictionaryDialog> aDlg(pFact->CreateSvxNewDictionaryDialog( this, xSpellChecker1 ));
1630 DBG_ASSERT(aDlg, "Dialog creation failed!");
1631 uno::Reference< XDictionary > xNewDic;
1632 if ( aDlg->Execute() == RET_OK )
1633 xNewDic = uno::Reference< XDictionary >( aDlg->GetNewDictionary(), UNO_QUERY );
1634 if ( xNewDic.is() )
1636 // add new dics to the end
1637 sal_Int32 nLen = aDics.getLength();
1638 aDics.realloc( nLen + 1 );
1640 aDics.getArray()[ nLen ] = xNewDic;
1642 AddDicBoxEntry( xNewDic, (sal_uInt16) nLen );
1646 else if (m_pLinguDicsEditPB == pBtn)
1648 SvTreeListEntry *pEntry = m_pLinguDicsCLB->GetCurEntry();
1649 if (pEntry)
1651 DicUserData aData( reinterpret_cast<sal_uLong>(pEntry->GetUserData()) );
1652 sal_uInt16 nDicPos = aData.GetEntryId();
1653 sal_Int32 nDics = aDics.getLength();
1654 if (nDicPos < nDics)
1656 uno::Reference< XDictionary > xDic;
1657 xDic = aDics.getConstArray()[ nDicPos ];
1658 if (xDic.is())
1660 uno::Reference< XSpellChecker1 > xSpellChecker1;
1661 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
1662 if(pFact)
1664 boost::scoped_ptr<VclAbstractDialog> aDlg(pFact->CreateSvxEditDictionaryDialog( this, xDic->getName(), xSpellChecker1, RID_SFXDLG_EDITDICT ));
1665 DBG_ASSERT(aDlg, "Dialog creation failed!");
1666 aDlg->Execute();
1672 else if (m_pLinguDicsDelPB == pBtn)
1674 ScopedVclPtrInstance<MessageDialog> aQuery(this, "QueryDeleteDictionaryDialog",
1675 "cui/ui/querydeletedictionarydialog.ui");
1676 if (RET_NO == aQuery->Execute())
1677 return 0;
1679 SvTreeListEntry *pEntry = m_pLinguDicsCLB->GetCurEntry();
1680 if (pEntry)
1682 DicUserData aData( reinterpret_cast<sal_uLong>(pEntry->GetUserData()) );
1683 sal_uInt16 nDicPos = aData.GetEntryId();
1684 sal_Int32 nDics = aDics.getLength();
1685 if (nDicPos < nDics)
1687 uno::Reference< XDictionary > xDic;
1688 xDic = aDics.getConstArray()[ nDicPos ];
1689 if (xDic.is())
1691 if (SvxGetIgnoreAllList() == xDic)
1692 xDic->clear();
1693 else
1695 if (xDicList.is())
1696 xDicList->removeDictionary( xDic );
1698 uno::Reference< frame::XStorable > xStor( xDic, UNO_QUERY );
1699 if ( xStor->hasLocation() && !xStor->isReadonly() )
1701 OUString sURL = xStor->getLocation();
1702 INetURLObject aObj(sURL);
1703 DBG_ASSERT( aObj.GetProtocol() == INetProtocol::File,
1704 "non-file URLs cannot be deleted" );
1705 if ( aObj.GetProtocol() == INetProtocol::File )
1707 KillFile_Impl( aObj.GetMainURL( INetURLObject::NO_DECODE ) );
1711 aDics.getArray()[ nDicPos ] = 0;
1713 // remove entry from checklistbox
1714 sal_uLong nCnt = m_pLinguDicsCLB->GetEntryCount();
1715 for (sal_uLong i = 0; i < nCnt; ++i)
1717 SvTreeListEntry *pDicEntry = m_pLinguDicsCLB->GetEntry( i );
1718 DBG_ASSERT( pDicEntry, "missing entry" );
1719 if (pDicEntry)
1721 DicUserData aDicData( reinterpret_cast<sal_uLong>(pDicEntry->GetUserData()) );
1722 if (aDicData.GetEntryId() == nDicPos )
1724 m_pLinguDicsCLB->RemoveEntry( i );
1725 break;
1729 DBG_ASSERT( nCnt > m_pLinguDicsCLB->GetEntryCount(),
1730 "remove failed ?");
1736 else if (m_pLinguOptionsEditPB == pBtn)
1738 SvTreeListEntry *pEntry = m_pLinguOptionsCLB->GetCurEntry();
1739 DBG_ASSERT( pEntry, "no entry selected" );
1740 if (pEntry)
1742 OptionsUserData aData( reinterpret_cast<sal_uLong>(pEntry->GetUserData()) );
1743 if(aData.HasNumericValue())
1745 sal_uInt16 nRID = aData.GetEntryId();
1746 ScopedVclPtrInstance< OptionsBreakSet > aDlg(this, nRID);
1747 aDlg->GetNumericFld().SetValue( aData.GetNumericValue() );
1748 if (RET_OK == aDlg->Execute() )
1750 long nVal = static_cast<long>(aDlg->GetNumericFld().GetValue());
1751 if (-1 != nVal && aData.GetNumericValue() != nVal)
1753 aData.SetNumericValue( (sal_uInt8)nVal ); //! sets IsModified !
1754 pEntry->SetUserData( reinterpret_cast<void *>(aData.GetUserData()) );
1755 m_pLinguOptionsCLB->Invalidate();
1761 else
1763 OSL_FAIL( "pBtn unexpected value" );
1766 return 0;
1771 IMPL_LINK( SvxLinguTabPage, SelectHdl_Impl, SvxCheckListBox *, pBox )
1773 if (m_pLinguModulesCLB == pBox)
1776 else if (m_pLinguDicsCLB == pBox)
1778 SvTreeListEntry *pEntry = pBox->GetCurEntry();
1779 if (pEntry)
1781 DicUserData aData( reinterpret_cast<sal_uLong>( pEntry->GetUserData() ) );
1783 // always allow to edit (i.e. at least view the content of the dictionary)
1784 m_pLinguDicsEditPB->Enable( true/*aData.IsEditable()*/ );
1785 m_pLinguDicsDelPB->Enable( aData.IsDeletable() );
1788 else if (m_pLinguOptionsCLB == pBox)
1790 SvTreeListEntry *pEntry = pBox->GetCurEntry();
1791 if (pEntry)
1793 OptionsUserData aData( reinterpret_cast<sal_uLong>( pEntry->GetUserData() ) );
1794 m_pLinguOptionsEditPB->Enable( aData.HasNumericValue() );
1797 else
1799 OSL_FAIL( "pBox unexpected value" );
1802 return 0;
1807 SvTreeListEntry* SvxLinguTabPage::CreateEntry( OUString& rTxt, sal_uInt16 nCol )
1809 SvTreeListEntry* pEntry = new SvTreeListEntry;
1811 if( !pCheckButtonData )
1812 pCheckButtonData = new SvLBoxButtonData(m_pLinguOptionsCLB);
1814 OUString sEmpty;
1815 if (CBCOL_FIRST == nCol)
1816 pEntry->AddItem( new SvLBoxButton( pEntry, SvLBoxButtonKind_enabledCheckbox, 0, pCheckButtonData ) );
1817 if (CBCOL_SECOND == nCol)
1818 pEntry->AddItem( new SvLBoxString( pEntry, 0, sEmpty) ); // empty column
1819 pEntry->AddItem( new SvLBoxContextBmp( pEntry, 0, Image(), Image(), false));
1820 pEntry->AddItem( new BrwString_Impl( pEntry, 0, rTxt ) );
1822 return pEntry;
1827 void SvxLinguTabPage::HideGroups( sal_uInt16 nGrp )
1829 if ( 0 != ( GROUP_MODULES & nGrp ) )
1831 m_pLinguModulesFT->Hide();
1832 m_pLinguModulesCLB->Hide();
1833 m_pLinguModulesEditPB->Hide();
1835 if ( SvtExtendedSecurityOptions().GetOpenHyperlinkMode()
1836 != SvtExtendedSecurityOptions::OPEN_NEVER )
1838 m_pMoreDictsLink->Show();
1843 SvxEditModulesDlg::SvxEditModulesDlg(vcl::Window* pParent, SvxLinguData_Impl& rData)
1844 : ModalDialog( pParent, "EditModulesDialog",
1845 "cui/ui/editmodulesdialog.ui")
1846 , sSpell(CUI_RES(RID_SVXSTR_SPELL))
1847 , sHyph(CUI_RES(RID_SVXSTR_HYPH))
1848 , sThes(CUI_RES(RID_SVXSTR_THES))
1849 , sGrammar(CUI_RES(RID_SVXSTR_GRAMMAR))
1850 , rLinguData(rData)
1852 get(m_pClosePB, "close");
1853 get(m_pMoreDictsLink, "moredictslink");
1854 get(m_pBackPB, "back");
1855 get(m_pPrioDownPB, "down");
1856 get(m_pPrioUpPB, "up");
1857 get(m_pModulesCLB, "lingudicts");
1858 Size aListSize(m_pModulesCLB->LogicToPixel(Size(166, 120), MAP_APPFONT));
1859 m_pModulesCLB->set_height_request(aListSize.Height());
1860 m_pModulesCLB->set_width_request(aListSize.Width());
1861 get(m_pLanguageLB, "language");
1862 m_pLanguageLB->SetStyle(m_pLanguageLB->GetStyle() | WB_SORT);
1864 pCheckButtonData = NULL;
1866 pDefaultLinguData = new SvxLinguData_Impl( rLinguData );
1868 m_pModulesCLB->SetStyle( m_pModulesCLB->GetStyle()|WB_CLIPCHILDREN|WB_HSCROLL|WB_FORCE_MAKEVISIBLE );
1869 m_pModulesCLB->SetHighlightRange();
1870 m_pModulesCLB->SetSelectHdl( LINK( this, SvxEditModulesDlg, SelectHdl_Impl ));
1871 m_pModulesCLB->SetCheckButtonHdl( LINK( this, SvxEditModulesDlg, BoxCheckButtonHdl_Impl) );
1873 m_pClosePB->SetClickHdl( LINK( this, SvxEditModulesDlg, ClickHdl_Impl ));
1874 m_pPrioUpPB->SetClickHdl( LINK( this, SvxEditModulesDlg, UpDownHdl_Impl ));
1875 m_pPrioDownPB->SetClickHdl( LINK( this, SvxEditModulesDlg, UpDownHdl_Impl ));
1876 m_pBackPB->SetClickHdl( LINK( this, SvxEditModulesDlg, BackHdl_Impl ));
1877 // in case of not installed language modules
1878 m_pPrioUpPB->Enable( false );
1879 m_pPrioDownPB->Enable( false );
1881 if ( SvtExtendedSecurityOptions().GetOpenHyperlinkMode()
1882 != SvtExtendedSecurityOptions::OPEN_NEVER )
1884 m_pMoreDictsLink->SetClickHdl( LINK( this, SvxEditModulesDlg, OpenURLHdl_Impl ) );
1886 else
1888 m_pMoreDictsLink->Hide();
1891 //fill language box
1892 Sequence< sal_Int16 > aAvailLang;
1893 uno::Reference< XAvailableLocales > xAvail( rLinguData.GetManager(), UNO_QUERY );
1894 if (xAvail.is())
1896 aAvailLang = lcl_LocaleSeqToLangSeq(
1897 xAvail->getAvailableLocales( cSpell ) );
1899 const Sequence< Locale >& rLoc = rLinguData.GetAllSupportedLocales();
1900 const Locale* pLocales = rLoc.getConstArray();
1901 m_pLanguageLB->Clear();
1902 for(long i = 0; i < rLoc.getLength(); i++)
1904 sal_Int16 nLang = LanguageTag::convertToLanguageType( pLocales[i] );
1905 m_pLanguageLB->InsertLanguage( nLang, lcl_SeqHasLang( aAvailLang, nLang ) );
1907 LanguageType eSysLang = MsLangId::getSystemLanguage();
1908 m_pLanguageLB->SelectLanguage( eSysLang );
1909 if(!m_pLanguageLB->IsLanguageSelected( eSysLang ) )
1910 m_pLanguageLB->SelectEntryPos(0);
1912 m_pLanguageLB->SetSelectHdl( LINK( this, SvxEditModulesDlg, LangSelectHdl_Impl ));
1913 LangSelectHdl_Impl(m_pLanguageLB);
1917 SvxEditModulesDlg::~SvxEditModulesDlg()
1919 disposeOnce();
1922 void SvxEditModulesDlg::dispose()
1924 delete pDefaultLinguData;
1925 pDefaultLinguData = NULL;
1926 m_pLanguageLB.clear();
1927 m_pModulesCLB.clear();
1928 m_pPrioUpPB.clear();
1929 m_pPrioDownPB.clear();
1930 m_pBackPB.clear();
1931 m_pMoreDictsLink.clear();
1932 m_pClosePB.clear();
1933 ModalDialog::dispose();
1936 SvTreeListEntry* SvxEditModulesDlg::CreateEntry( OUString& rTxt, sal_uInt16 nCol )
1938 SvTreeListEntry* pEntry = new SvTreeListEntry;
1939 if( !pCheckButtonData )
1941 pCheckButtonData = new SvLBoxButtonData(m_pModulesCLB);
1942 pCheckButtonData->SetLink( m_pModulesCLB->GetCheckButtonHdl() );
1945 OUString sEmpty;
1946 if (CBCOL_FIRST == nCol)
1947 pEntry->AddItem( new SvLBoxButton( pEntry, SvLBoxButtonKind_enabledCheckbox, 0, pCheckButtonData ) );
1948 if (CBCOL_SECOND == nCol)
1949 pEntry->AddItem( new SvLBoxString( pEntry, 0, sEmpty) ); // empty column
1950 pEntry->AddItem( new SvLBoxContextBmp( pEntry, 0, Image(), Image(), false));
1951 pEntry->AddItem( new BrwStringDic_Impl( pEntry, 0, rTxt ) );
1953 return pEntry;
1956 IMPL_LINK( SvxEditModulesDlg, SelectHdl_Impl, SvxCheckListBox *, pBox )
1958 if (m_pModulesCLB == pBox)
1960 SvTreeListEntry *pEntry = pBox->GetCurEntry();
1961 if (pEntry)
1963 bool bDisableUp = true;
1964 bool bDisableDown = true;
1965 ModuleUserData_Impl* pData = static_cast<ModuleUserData_Impl*>(pEntry->GetUserData());
1966 if(!pData->IsParent() && pData->GetType() != TYPE_HYPH)
1968 sal_uLong nCurPos = pBox->GetSelectEntryPos();
1969 if(nCurPos < pBox->GetEntryCount() - 1)
1971 bDisableDown = static_cast<ModuleUserData_Impl*>(pBox->
1972 GetEntry(nCurPos + 1)->GetUserData())->IsParent();
1974 if(nCurPos > 1)
1976 bDisableUp = static_cast<ModuleUserData_Impl*>(pBox->
1977 GetEntry(nCurPos - 1)->GetUserData())->IsParent();
1980 m_pPrioUpPB->Enable(!bDisableUp);
1981 m_pPrioDownPB->Enable(!bDisableDown);
1984 else
1986 OSL_FAIL( "pBox unexpected value" );
1989 return 0;
1992 IMPL_LINK( SvxEditModulesDlg, BoxCheckButtonHdl_Impl, SvTreeListBox *, pBox )
1994 pBox = m_pModulesCLB;
1995 SvTreeListEntry *pCurEntry = pBox->GetCurEntry();
1996 if (pCurEntry)
1998 ModuleUserData_Impl* pData = static_cast<ModuleUserData_Impl *>(
1999 pCurEntry->GetUserData());
2000 if (!pData->IsParent() && pData->GetType() == TYPE_HYPH)
2002 // make hyphenator checkboxes function as radio-buttons
2003 // (at most one box may be checked)
2004 SvTreeListEntry *pEntry = pBox->First();
2005 while (pEntry)
2007 pData = static_cast<ModuleUserData_Impl*>(pEntry->GetUserData());
2008 if (!pData->IsParent() &&
2009 pData->GetType() == TYPE_HYPH &&
2010 pEntry != pCurEntry)
2012 lcl_SetCheckButton( pEntry, false );
2013 pBox->InvalidateEntry( pEntry );
2015 pEntry = pBox->Next( pEntry );
2019 return 0;
2022 IMPL_LINK( SvxEditModulesDlg, LangSelectHdl_Impl, ListBox *, pBox )
2024 LanguageType eCurLanguage = m_pLanguageLB->GetSelectLanguage();
2025 static Locale aLastLocale;
2026 Locale aCurLocale( LanguageTag::convertToLocale( eCurLanguage));
2027 SvTreeList *pModel = m_pModulesCLB->GetModel();
2029 if (pBox)
2031 // save old probably changed settings
2032 // before switching to new language entries
2034 sal_Int16 nLang = LanguageTag::convertToLanguageType( aLastLocale );
2036 sal_Int32 nStart = 0, nLocalIndex = 0;
2037 Sequence< OUString > aChange;
2038 bool bChanged = false;
2039 for(sal_uLong i = 0; i < m_pModulesCLB->GetEntryCount(); i++)
2041 SvTreeListEntry *pEntry = m_pModulesCLB->GetEntry(i);
2042 ModuleUserData_Impl* pData = static_cast<ModuleUserData_Impl*>(pEntry->GetUserData());
2043 if(pData->IsParent())
2045 if(bChanged)
2047 LangImplNameTable *pTable = 0;
2048 sal_uInt8 nType = pData->GetType();
2049 switch (nType - 1)
2051 case TYPE_SPELL : pTable = &rLinguData.GetSpellTable(); break;
2052 case TYPE_GRAMMAR : pTable = &rLinguData.GetGrammarTable(); break;
2053 case TYPE_HYPH : pTable = &rLinguData.GetHyphTable(); break;
2054 case TYPE_THES : pTable = &rLinguData.GetThesTable(); break;
2056 if (pTable)
2058 aChange.realloc(nStart);
2059 (*pTable)[ nLang ] = aChange;
2062 nLocalIndex = nStart = 0;
2063 aChange.realloc(m_pModulesCLB->GetEntryCount());
2064 bChanged = false;
2066 else
2068 OUString* pChange = aChange.getArray();
2069 pChange[nStart] = pData->GetImplName();
2070 bChanged |= pData->GetIndex() != nLocalIndex ||
2071 pData->IsChecked() != m_pModulesCLB->IsChecked(i);
2072 if(m_pModulesCLB->IsChecked(i))
2073 nStart++;
2074 ++nLocalIndex;
2077 if(bChanged)
2079 aChange.realloc(nStart);
2080 rLinguData.GetThesTable()[ nLang ] = aChange;
2084 for(sal_uLong i = 0; i < m_pModulesCLB->GetEntryCount(); i++)
2085 delete static_cast<ModuleUserData_Impl*>(m_pModulesCLB->GetEntry(i)->GetUserData());
2088 // display entries for new selected language
2090 m_pModulesCLB->Clear();
2091 if(LANGUAGE_DONTKNOW != eCurLanguage)
2093 sal_uLong n;
2094 ServiceInfo_Impl* pInfo;
2097 // spellchecker entries
2099 SvTreeListEntry* pEntry = CreateEntry( sSpell, CBCOL_SECOND );
2100 ModuleUserData_Impl* pUserData = new ModuleUserData_Impl(
2101 OUString(), true, false, TYPE_SPELL, 0 );
2102 pEntry->SetUserData( (void *)pUserData );
2103 pModel->Insert( pEntry );
2105 Sequence< OUString > aNames( rLinguData.GetSortedImplNames( eCurLanguage, TYPE_SPELL ) );
2106 const OUString *pName = aNames.getConstArray();
2107 sal_uLong nNames = (sal_uLong) aNames.getLength();
2108 sal_Int32 nLocalIndex = 0; // index relative to parent
2109 for (n = 0; n < nNames; ++n)
2111 OUString aImplName;
2112 bool bIsSuppLang = false;
2114 pInfo = rLinguData.GetInfoByImplName( pName[n] );
2115 if (pInfo)
2117 bIsSuppLang = pInfo->xSpell.is() &&
2118 pInfo->xSpell->hasLocale( aCurLocale );
2119 aImplName = pInfo->sSpellImplName;
2121 if (!aImplName.isEmpty() && bIsSuppLang)
2123 OUString aTxt( pInfo->sDisplayName );
2124 SvTreeListEntry* pNewEntry = CreateEntry( aTxt, CBCOL_FIRST );
2126 LangImplNameTable &rTable = rLinguData.GetSpellTable();
2127 const bool bHasLang = rTable.count( eCurLanguage );
2128 if (!bHasLang)
2130 DBG_WARNING( "language entry missing" ); // only relevant if all languages found should be supported
2132 const bool bCheck = bHasLang && lcl_SeqGetEntryPos( rTable[ eCurLanguage ], aImplName ) >= 0;
2133 lcl_SetCheckButton( pNewEntry, bCheck );
2134 pUserData = new ModuleUserData_Impl( aImplName, false,
2135 bCheck, TYPE_SPELL, (sal_uInt8)nLocalIndex++ );
2136 pNewEntry->SetUserData( (void *)pUserData );
2137 pModel->Insert( pNewEntry );
2142 // grammar checker entries
2144 pEntry = CreateEntry( sGrammar, CBCOL_SECOND );
2145 pUserData = new ModuleUserData_Impl( OUString(), true, false, TYPE_GRAMMAR, 0 );
2146 pEntry->SetUserData( (void *)pUserData );
2147 pModel->Insert( pEntry );
2149 aNames = rLinguData.GetSortedImplNames( eCurLanguage, TYPE_GRAMMAR );
2150 pName = aNames.getConstArray();
2151 nNames = (sal_uLong) aNames.getLength();
2152 nLocalIndex = 0;
2153 for (n = 0; n < nNames; ++n)
2155 OUString aImplName;
2156 bool bIsSuppLang = false;
2158 pInfo = rLinguData.GetInfoByImplName( pName[n] );
2159 if (pInfo)
2161 bIsSuppLang = pInfo->xGrammar.is() &&
2162 pInfo->xGrammar->hasLocale( aCurLocale );
2163 aImplName = pInfo->sGrammarImplName;
2165 if (!aImplName.isEmpty() && bIsSuppLang)
2167 OUString aTxt( pInfo->sDisplayName );
2168 SvTreeListEntry* pNewEntry = CreateEntry( aTxt, CBCOL_FIRST );
2170 LangImplNameTable &rTable = rLinguData.GetGrammarTable();
2171 const bool bHasLang = rTable.count( eCurLanguage );
2172 if (!bHasLang)
2174 DBG_WARNING( "language entry missing" ); // only relevant if all languages found should be supported
2176 const bool bCheck = bHasLang && lcl_SeqGetEntryPos( rTable[ eCurLanguage ], aImplName ) >= 0;
2177 lcl_SetCheckButton( pNewEntry, bCheck );
2178 pUserData = new ModuleUserData_Impl( aImplName, false,
2179 bCheck, TYPE_GRAMMAR, (sal_uInt8)nLocalIndex++ );
2180 pNewEntry->SetUserData( (void *)pUserData );
2181 pModel->Insert( pNewEntry );
2186 // hyphenator entries
2188 pEntry = CreateEntry( sHyph, CBCOL_SECOND );
2189 pUserData = new ModuleUserData_Impl( OUString(), true, false, TYPE_HYPH, 0 );
2190 pEntry->SetUserData( (void *)pUserData );
2191 pModel->Insert( pEntry );
2193 aNames = rLinguData.GetSortedImplNames( eCurLanguage, TYPE_HYPH );
2194 pName = aNames.getConstArray();
2195 nNames = (sal_uLong) aNames.getLength();
2196 nLocalIndex = 0;
2197 for (n = 0; n < nNames; ++n)
2199 OUString aImplName;
2200 bool bIsSuppLang = false;
2202 pInfo = rLinguData.GetInfoByImplName( pName[n] );
2203 if (pInfo)
2205 bIsSuppLang = pInfo->xHyph.is() &&
2206 pInfo->xHyph->hasLocale( aCurLocale );
2207 aImplName = pInfo->sHyphImplName;
2209 if (!aImplName.isEmpty() && bIsSuppLang)
2211 OUString aTxt( pInfo->sDisplayName );
2212 SvTreeListEntry* pNewEntry = CreateEntry( aTxt, CBCOL_FIRST );
2214 LangImplNameTable &rTable = rLinguData.GetHyphTable();
2215 const bool bHasLang = rTable.count( eCurLanguage );
2216 if (!bHasLang)
2218 DBG_WARNING( "language entry missing" ); // only relevant if all languages found should be supported
2220 const bool bCheck = bHasLang && lcl_SeqGetEntryPos( rTable[ eCurLanguage ], aImplName ) >= 0;
2221 lcl_SetCheckButton( pNewEntry, bCheck );
2222 pUserData = new ModuleUserData_Impl( aImplName, false,
2223 bCheck, TYPE_HYPH, (sal_uInt8)nLocalIndex++ );
2224 pNewEntry->SetUserData( (void *)pUserData );
2225 pModel->Insert( pNewEntry );
2230 // thesaurus entries
2232 pEntry = CreateEntry( sThes, CBCOL_SECOND );
2233 pUserData = new ModuleUserData_Impl( OUString(), true, false, TYPE_THES, 0 );
2234 pEntry->SetUserData( (void *)pUserData );
2235 pModel->Insert( pEntry );
2237 aNames = rLinguData.GetSortedImplNames( eCurLanguage, TYPE_THES );
2238 pName = aNames.getConstArray();
2239 nNames = (sal_uLong) aNames.getLength();
2240 nLocalIndex = 0;
2241 for (n = 0; n < nNames; ++n)
2243 OUString aImplName;
2244 bool bIsSuppLang = false;
2246 pInfo = rLinguData.GetInfoByImplName( pName[n] );
2247 if (pInfo)
2249 bIsSuppLang = pInfo->xThes.is() &&
2250 pInfo->xThes->hasLocale( aCurLocale );
2251 aImplName = pInfo->sThesImplName;
2253 if (!aImplName.isEmpty() && bIsSuppLang)
2255 OUString aTxt( pInfo->sDisplayName );
2256 SvTreeListEntry* pNewEntry = CreateEntry( aTxt, CBCOL_FIRST );
2258 LangImplNameTable &rTable = rLinguData.GetThesTable();
2259 const bool bHasLang = rTable.count( eCurLanguage );
2260 if (!bHasLang)
2262 DBG_WARNING( "language entry missing" ); // only relevant if all languages found should be supported
2264 const bool bCheck = bHasLang && lcl_SeqGetEntryPos( rTable[ eCurLanguage ], aImplName ) >= 0;
2265 lcl_SetCheckButton( pNewEntry, bCheck );
2266 pUserData = new ModuleUserData_Impl( aImplName, false,
2267 bCheck, TYPE_THES, (sal_uInt8)nLocalIndex++ );
2268 pNewEntry->SetUserData( (void *)pUserData );
2269 pModel->Insert( pNewEntry );
2273 aLastLocale = aCurLocale;
2274 return 0;
2277 IMPL_LINK( SvxEditModulesDlg, UpDownHdl_Impl, PushButton *, pBtn )
2279 bool bUp = m_pPrioUpPB == pBtn;
2280 sal_uLong nCurPos = m_pModulesCLB->GetSelectEntryPos();
2281 SvTreeListEntry* pEntry;
2282 if (nCurPos != TREELIST_ENTRY_NOTFOUND &&
2283 0 != (pEntry = m_pModulesCLB->GetEntry(nCurPos)))
2285 m_pModulesCLB->SetUpdateMode(false);
2286 SvTreeList *pModel = m_pModulesCLB->GetModel();
2288 ModuleUserData_Impl* pData = static_cast<ModuleUserData_Impl*>(pEntry->GetUserData());
2289 OUString aStr(m_pModulesCLB->GetEntryText(pEntry));
2290 SvTreeListEntry* pToInsert = CreateEntry( aStr, CBCOL_FIRST );
2291 pToInsert->SetUserData( (void *)pData);
2292 bool bIsChecked = m_pModulesCLB->IsChecked(nCurPos);
2294 pModel->Remove(pEntry);
2296 sal_uLong nDestPos = bUp ? nCurPos - 1 : nCurPos + 1;
2297 pModel->Insert(pToInsert, nDestPos);
2298 m_pModulesCLB->CheckEntryPos(nDestPos, bIsChecked );
2299 m_pModulesCLB->SelectEntryPos(nDestPos );
2300 SelectHdl_Impl(m_pModulesCLB);
2301 m_pModulesCLB->SetUpdateMode(true);
2303 return 0;
2306 IMPL_LINK_NOARG(SvxEditModulesDlg, ClickHdl_Impl)
2308 // store language config
2309 LangSelectHdl_Impl(m_pLanguageLB);
2310 EndDialog( RET_OK );
2311 return 0;
2314 IMPL_LINK_NOARG(SvxEditModulesDlg, BackHdl_Impl)
2316 rLinguData = *pDefaultLinguData;
2317 LangSelectHdl_Impl(0);
2318 return 0;
2323 IMPL_LINK_NOARG(SvxEditModulesDlg, OpenURLHdl_Impl)
2325 OUString sURL( m_pMoreDictsLink->GetURL() );
2326 lcl_OpenURL( sURL );
2327 return 0;
2330 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */