Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
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"
60 :
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"
67 :
68 : #include <comphelper/componentcontext.hxx>
69 : #include <ucbhelper/content.hxx>
70 :
71 : #include <vector>
72 : #include <map>
73 :
74 :
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;
82 :
83 : #define CBCOL_FIRST 0
84 : #define CBCOL_SECOND 1
85 : #define CBCOL_BOTH 2
86 :
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;
91 :
92 : // static ----------------------------------------------------------------
93 :
94 0 : static Sequence< sal_Int16 > lcl_LocaleSeqToLangSeq( const Sequence< Locale > &rSeq )
95 : {
96 0 : sal_Int32 nLen = rSeq.getLength();
97 0 : Sequence< sal_Int16 > aRes( nLen );
98 0 : sal_Int16 *pRes = aRes.getArray();
99 0 : const Locale *pSeq = rSeq.getConstArray();
100 0 : for (sal_Int32 i = 0; i < nLen; ++i)
101 : {
102 0 : pRes[i] = LanguageTag( pSeq[i] ).getLanguageType();
103 : }
104 0 : return aRes;
105 : }
106 :
107 :
108 0 : static sal_Bool lcl_SeqHasLang( const Sequence< sal_Int16 > &rSeq, sal_Int16 nLang )
109 : {
110 0 : sal_Int32 nLen = rSeq.getLength();
111 0 : const sal_Int16 *pLang = rSeq.getConstArray();
112 0 : sal_Int32 nPos = -1;
113 0 : for (sal_Int32 i = 0; i < nLen && nPos < 0; ++i)
114 : {
115 0 : if (nLang == pLang[i])
116 0 : nPos = i;
117 : }
118 0 : return nPos < 0 ? sal_False : sal_True;
119 : }
120 :
121 :
122 0 : static sal_Int32 lcl_SeqGetEntryPos(
123 : const Sequence< OUString > &rSeq, const OUString &rEntry )
124 : {
125 : sal_Int32 i;
126 0 : sal_Int32 nLen = rSeq.getLength();
127 0 : const OUString *pItem = rSeq.getConstArray();
128 0 : for (i = 0; i < nLen; ++i)
129 : {
130 0 : if (rEntry == pItem[i])
131 0 : break;
132 : }
133 0 : return i < nLen ? i : -1;
134 : }
135 :
136 0 : static void lcl_OpenURL( ::rtl::OUString sURL )
137 : {
138 0 : if ( !sURL.isEmpty() )
139 : {
140 0 : localizeWebserviceURI(sURL);
141 : try
142 : {
143 : uno::Reference< uno::XComponentContext > xContext =
144 0 : ::comphelper::getProcessComponentContext();
145 : uno::Reference< css::system::XSystemShellExecute > xSystemShell(
146 0 : css::system::SystemShellExecute::create(xContext) );
147 0 : xSystemShell->execute( sURL, ::rtl::OUString(), css::system::SystemShellExecuteFlags::URIS_ONLY );
148 : }
149 0 : catch( const uno::Exception& e )
150 : {
151 : OSL_TRACE( "Caught exception: %s\n thread terminated.\n",
152 : rtl::OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8).getStr());
153 : }
154 : }
155 0 : }
156 :
157 : static sal_uInt16 pRanges[] =
158 : {
159 : SID_ATTR_SPELL,
160 : SID_ATTR_SPELL,
161 : 0
162 : };
163 :
164 0 : sal_Bool KillFile_Impl( const String& rURL )
165 : {
166 0 : sal_Bool bRet = sal_True;
167 : try
168 : {
169 0 : Content aCnt( rURL, uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >(), comphelper::getProcessComponentContext() );
170 0 : aCnt.executeCommand( OUString("delete"), makeAny( sal_Bool( sal_True ) ) );
171 : }
172 0 : catch( ::com::sun::star::ucb::CommandAbortedException& )
173 : {
174 : SAL_WARN( "cui.options", "KillFile: CommandAbortedException" );
175 0 : bRet = sal_False;
176 : }
177 0 : catch( ... )
178 : {
179 : SAL_WARN( "cui.options", "KillFile: Any other exception" );
180 0 : bRet = sal_False;
181 : }
182 :
183 0 : return bRet;
184 : }
185 :
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
191 :
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
196 :
197 0 : class ModuleUserData_Impl
198 : {
199 : sal_Bool bParent;
200 : sal_Bool bIsChecked;
201 : sal_uInt8 nType;
202 : sal_uInt8 nIndex;
203 : String sImplName;
204 :
205 : public:
206 0 : 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 0 : sImplName(sImpName)
212 : {
213 0 : }
214 0 : sal_Bool IsParent() const {return bParent;}
215 0 : sal_uInt8 GetType() const {return nType;}
216 0 : sal_Bool IsChecked() const {return bIsChecked;}
217 0 : sal_uInt8 GetIndex() const {return nIndex;}
218 : void SetIndex(sal_uInt8 nSet) {nIndex = nSet;}
219 0 : const String& GetImplName() const {return sImplName;}
220 :
221 : };
222 :
223 : //
224 : // User for user-dictionaries (XDictionary interface)
225 : //
226 : class DicUserData
227 : {
228 : sal_uLong nVal;
229 :
230 : public:
231 0 : DicUserData( sal_uLong nUserData ) : nVal( nUserData ) {}
232 : DicUserData( sal_uInt16 nEID,
233 : sal_Bool bChecked, sal_Bool bEditable, sal_Bool bDeletable );
234 :
235 0 : sal_uLong GetUserData() const { return nVal; }
236 0 : sal_uInt16 GetEntryId() const { return (sal_uInt16)(nVal >> 16); }
237 0 : sal_Bool IsChecked() const { return (sal_Bool)(nVal >> 8) & 0x01; }
238 : sal_Bool IsEditable() const { return (sal_Bool)(nVal >> 9) & 0x01; }
239 0 : sal_Bool IsDeletable() const { return (sal_Bool)(nVal >> 10) & 0x01; }
240 :
241 : void SetChecked( sal_Bool bVal );
242 : };
243 :
244 :
245 0 : DicUserData::DicUserData(
246 : sal_uInt16 nEID,
247 : sal_Bool bChecked, sal_Bool bEditable, sal_Bool bDeletable )
248 : {
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 0 : ((sal_uLong)(bDeletable ? 1 : 0) << 10);
254 0 : }
255 :
256 :
257 0 : void DicUserData::SetChecked( sal_Bool bVal )
258 : {
259 0 : nVal &= ~(1UL << 8);
260 0 : nVal |= (sal_uLong)(bVal ? 1 : 0) << 8;
261 0 : }
262 :
263 :
264 : // class BrwString_Impl -------------------------------------------------
265 :
266 0 : static void lcl_SetCheckButton( SvTreeListEntry* pEntry, sal_Bool bCheck )
267 : {
268 0 : SvLBoxButton* pItem = (SvLBoxButton*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXBUTTON));
269 :
270 : DBG_ASSERT(pItem,"SetCheckButton:Item not found");
271 0 : if (pItem->GetType() == SV_ITEM_ID_LBOXBUTTON)
272 : {
273 0 : if (bCheck)
274 0 : pItem->SetStateChecked();
275 : else
276 0 : pItem->SetStateUnchecked();
277 : }
278 0 : }
279 :
280 :
281 0 : class BrwStringDic_Impl : public SvLBoxString
282 : {
283 : public:
284 :
285 0 : BrwStringDic_Impl( SvTreeListEntry* pEntry, sal_uInt16 nFlags,
286 0 : const String& rStr ) : SvLBoxString( pEntry, nFlags, rStr ) {}
287 :
288 : virtual void Paint(
289 : const Point& rPos, SvTreeListBox& rOutDev, const SvViewDataEntry* pView, const SvTreeListEntry* pEntry);
290 : };
291 :
292 0 : void BrwStringDic_Impl::Paint(
293 : const Point& rPos, SvTreeListBox& rDev, const SvViewDataEntry* /*pView*/,
294 : const SvTreeListEntry* pEntry)
295 : {
296 0 : ModuleUserData_Impl* pData = (ModuleUserData_Impl*)pEntry->GetUserData();
297 0 : Point aPos(rPos);
298 0 : Font aOldFont( rDev.GetFont());
299 0 : if(pData->IsParent())
300 : {
301 0 : Font aFont( aOldFont );
302 0 : aFont.SetWeight( WEIGHT_BOLD );
303 0 : rDev.SetFont( aFont );
304 0 : aPos.X() = 0;
305 : }
306 : else
307 0 : aPos.X() += 5;
308 0 : rDev.DrawText( aPos, GetText() );
309 0 : rDev.SetFont( aOldFont );
310 0 : }
311 :
312 0 : class OptionsBreakSet : public ModalDialog
313 : {
314 : OKButton aOKPB;
315 : CancelButton aCancelPB;
316 : FixedLine aValFL;
317 : NumericField aValNF;
318 :
319 : public:
320 0 : OptionsBreakSet(Window* pParent, int nRID) :
321 0 : ModalDialog(pParent, CUI_RES(RID_SVXDLG_LNG_ED_NUM_PREBREAK )),
322 0 : aOKPB (this, CUI_RES(BT_OK_PREBREAK)),
323 0 : aCancelPB (this, CUI_RES(BT_CANCEL_PREBREAK)),
324 0 : aValFL (this, CUI_RES(FL_NUMVAL_PREBREAK)),
325 0 : aValNF (this, CUI_RES(ED_PREBREAK))
326 : {
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" );
330 :
331 0 : if (nRID != -1)
332 0 : aValFL.SetText( String( CUI_RES(nRID) ) );
333 0 : FreeResource();
334 0 : }
335 :
336 0 : NumericField& GetNumericFld() { return aValNF; }
337 : };
338 :
339 :
340 : /*--------------------------------------------------
341 : Entry IDs for options listbox of dialog
342 : --------------------------------------------------*/
343 :
344 : enum EID_OPTIONS
345 : {
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
356 : };
357 :
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[] =
361 : {
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
372 : };
373 :
374 :
375 0 : static inline String lcl_GetPropertyName( EID_OPTIONS eEntryId )
376 : {
377 : DBG_ASSERT( (unsigned int) eEntryId < SAL_N_ELEMENTS(aEidToPropName), "index out of range" );
378 0 : return rtl::OUString::createFromAscii( aEidToPropName[ (int) eEntryId ] );
379 : }
380 :
381 : // class OptionsUserData -------------------------------------------------
382 :
383 : class OptionsUserData
384 : {
385 : sal_uLong nVal;
386 :
387 : void SetModified();
388 :
389 : public:
390 0 : 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 );
394 :
395 0 : sal_uLong GetUserData() const { return nVal; }
396 0 : sal_uInt16 GetEntryId() const { return (sal_uInt16)(nVal >> 16); }
397 0 : sal_Bool HasNumericValue() const { return (sal_Bool)(nVal >> 10) & 0x01; }
398 0 : sal_uInt16 GetNumericValue() const { return (sal_uInt16)(nVal & 0xFF); }
399 0 : sal_Bool IsChecked() const { return (sal_Bool)(nVal >> 8) & 0x01; }
400 0 : sal_Bool IsCheckable() const { return (sal_Bool)(nVal >> 9) & 0x01; }
401 0 : sal_Bool IsModified() const { return (sal_Bool)(nVal >> 11) & 0x01; }
402 :
403 : void SetChecked( sal_Bool bVal );
404 : void SetNumericValue( sal_uInt8 nNumVal );
405 : };
406 :
407 0 : OptionsUserData::OptionsUserData( sal_uInt16 nEID,
408 : sal_Bool bHasNV, sal_uInt16 nNumVal,
409 : sal_Bool bCheckable, sal_Bool bChecked )
410 : {
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 0 : ((sal_uLong)(0xFF & nNumVal));
418 0 : }
419 :
420 0 : void OptionsUserData::SetChecked( sal_Bool bVal )
421 : {
422 0 : if (IsCheckable() && (IsChecked() != bVal))
423 : {
424 0 : nVal &= ~(1UL << 8);
425 0 : nVal |= (sal_uLong)(bVal ? 1 : 0) << 8;
426 0 : SetModified();
427 : }
428 0 : }
429 :
430 0 : void OptionsUserData::SetNumericValue( sal_uInt8 nNumVal )
431 : {
432 0 : if (HasNumericValue() && (GetNumericValue() != nNumVal))
433 : {
434 0 : nVal &= 0xffffff00;
435 0 : nVal |= (nNumVal);
436 0 : SetModified();
437 : }
438 0 : }
439 :
440 0 : void OptionsUserData::SetModified()
441 : {
442 0 : nVal |= (sal_uLong)1 << 11;
443 0 : }
444 :
445 : // class BrwString_Impl -------------------------------------------------
446 :
447 0 : class BrwString_Impl : public SvLBoxString
448 : {
449 : public:
450 :
451 0 : BrwString_Impl( SvTreeListEntry* pEntry, sal_uInt16 nFlags,
452 0 : const String& rStr ) : SvLBoxString( pEntry, nFlags, rStr ) {}
453 :
454 : virtual void Paint(
455 : const Point& rPos, SvTreeListBox& rOutDev, const SvViewDataEntry* pView, const SvTreeListEntry* pEntry);
456 : };
457 :
458 0 : void BrwString_Impl::Paint(
459 : const Point& rPos, SvTreeListBox& rDev, const SvViewDataEntry* /*pView*/,
460 : const SvTreeListEntry* pEntry)
461 : {
462 0 : Point aPos(rPos);
463 0 : aPos.X() += 20;
464 0 : rDev.DrawText( aPos, GetText() );
465 0 : if(pEntry->GetUserData())
466 : {
467 0 : Point aNewPos(aPos);
468 0 : aNewPos.X() += rDev.GetTextWidth(GetText());
469 0 : Font aOldFont( rDev.GetFont());
470 0 : Font aFont( aOldFont );
471 0 : aFont.SetWeight( WEIGHT_BOLD );
472 :
473 : //??? convert the lower byte from the user date into a string
474 0 : OptionsUserData aData( (sal_uLong) pEntry->GetUserData() );
475 0 : if(aData.HasNumericValue())
476 : {
477 0 : rtl::OUStringBuffer sTxt;
478 0 : sTxt.append(' ').append(static_cast<sal_Int32>(aData.GetNumericValue()));
479 0 : rDev.SetFont( aFont );
480 0 : rDev.DrawText( aNewPos, sTxt.makeStringAndClear() );
481 : }
482 :
483 0 : rDev.SetFont( aOldFont );
484 : }
485 0 : }
486 :
487 : // ServiceInfo_Impl ----------------------------------------------------
488 :
489 0 : struct ServiceInfo_Impl
490 : {
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;
501 :
502 0 : ServiceInfo_Impl() : bConfigured(sal_False) {}
503 : };
504 :
505 : typedef std::vector< ServiceInfo_Impl > ServiceInfoArr;
506 : typedef std::map< sal_Int16 /*LanguageType*/, Sequence< OUString > > LangImplNameTable;
507 :
508 :
509 : // SvxLinguData_Impl ----------------------------------------------------
510 :
511 : class SvxLinguData_Impl
512 : {
513 : //contains services and implementation names sorted by implementation names
514 : ServiceInfoArr aDisplayServiceArr;
515 : sal_uLong nDisplayServices;
516 :
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;
524 :
525 :
526 : sal_Bool AddRemove( Sequence< OUString > &rConfigured,
527 : const OUString &rImplName, sal_Bool bAdd );
528 :
529 : public:
530 : SvxLinguData_Impl();
531 : SvxLinguData_Impl( const SvxLinguData_Impl &rData );
532 : ~SvxLinguData_Impl();
533 :
534 : SvxLinguData_Impl & operator = (const SvxLinguData_Impl &rData);
535 :
536 0 : uno::Reference<XLinguServiceManager2> & GetManager() { return xLinguSrvcMgr; }
537 :
538 : void SetChecked( const Sequence< OUString > &rConfiguredServices );
539 : void Reconfigure( const OUString &rDisplayName, sal_Bool bEnable );
540 :
541 0 : const Sequence<Locale> & GetAllSupportedLocales() const { return aAllServiceLocales; }
542 :
543 : const LangImplNameTable & GetSpellTable() const { return aCfgSpellTable; }
544 0 : LangImplNameTable & GetSpellTable() { return aCfgSpellTable; }
545 : const LangImplNameTable & GetHyphTable() const { return aCfgHyphTable; }
546 0 : LangImplNameTable & GetHyphTable() { return aCfgHyphTable; }
547 : const LangImplNameTable & GetThesTable() const { return aCfgThesTable; }
548 0 : LangImplNameTable & GetThesTable() { return aCfgThesTable; }
549 : const LangImplNameTable & GetGrammarTable() const { return aCfgGrammarTable; }
550 0 : LangImplNameTable & GetGrammarTable() { return aCfgGrammarTable; }
551 :
552 : const ServiceInfoArr & GetDisplayServiceArray() const { return aDisplayServiceArr; }
553 0 : ServiceInfoArr & GetDisplayServiceArray() { return aDisplayServiceArr; }
554 :
555 0 : const sal_uLong & GetDisplayServiceCount() const { return nDisplayServices; }
556 0 : void SetDisplayServiceCount( sal_uLong nVal ) { nDisplayServices = nVal; }
557 :
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 );
566 :
567 : ServiceInfo_Impl * GetInfoByImplName( const OUString &rSvcImplName );
568 : };
569 :
570 :
571 0 : static sal_Int32 lcl_SeqGetIndex( const Sequence< OUString > &rSeq, const OUString &rTxt )
572 : {
573 0 : sal_Int32 nRes = -1;
574 0 : sal_Int32 nLen = rSeq.getLength();
575 0 : const OUString *pString = rSeq.getConstArray();
576 0 : for (sal_Int32 i = 0; i < nLen && nRes == -1; ++i)
577 : {
578 0 : if (pString[i] == rTxt)
579 0 : nRes = i;
580 : }
581 0 : return nRes;
582 : }
583 :
584 :
585 0 : Sequence< OUString > SvxLinguData_Impl::GetSortedImplNames( sal_Int16 nLang, sal_uInt8 nType )
586 : {
587 0 : LangImplNameTable *pTable = 0;
588 0 : switch (nType)
589 : {
590 0 : case TYPE_SPELL : pTable = &aCfgSpellTable; break;
591 0 : case TYPE_HYPH : pTable = &aCfgHyphTable; break;
592 0 : case TYPE_THES : pTable = &aCfgThesTable; break;
593 0 : case TYPE_GRAMMAR : pTable = &aCfgGrammarTable; break;
594 : }
595 0 : Sequence< OUString > aRes;
596 0 : if (pTable->count( nLang ))
597 0 : aRes = (*pTable)[ nLang ]; // add configured services
598 0 : sal_Int32 nIdx = aRes.getLength();
599 : DBG_ASSERT( (sal_Int32) nDisplayServices >= nIdx, "size mismatch" );
600 0 : aRes.realloc( nDisplayServices );
601 0 : OUString *pRes = aRes.getArray();
602 :
603 : // add not configured services
604 0 : for (sal_Int32 i = 0; i < (sal_Int32) nDisplayServices; ++i)
605 : {
606 0 : const ServiceInfo_Impl &rInfo = aDisplayServiceArr[ i ];
607 0 : OUString aImplName;
608 0 : switch (nType)
609 : {
610 0 : case TYPE_SPELL : aImplName = rInfo.sSpellImplName; break;
611 0 : case TYPE_HYPH : aImplName = rInfo.sHyphImplName; break;
612 0 : case TYPE_THES : aImplName = rInfo.sThesImplName; break;
613 0 : case TYPE_GRAMMAR : aImplName = rInfo.sGrammarImplName; break;
614 : }
615 :
616 0 : if (!aImplName.isEmpty() && (lcl_SeqGetIndex( aRes, aImplName) == -1)) // name not yet added
617 : {
618 : DBG_ASSERT( nIdx < aRes.getLength(), "index out of range" );
619 0 : if (nIdx < aRes.getLength())
620 0 : pRes[ nIdx++ ] = aImplName;
621 : }
622 0 : }
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 0 : aRes.realloc( nIdx );
627 0 : return aRes;
628 : }
629 :
630 :
631 0 : ServiceInfo_Impl * SvxLinguData_Impl::GetInfoByImplName( const OUString &rSvcImplName )
632 : {
633 0 : ServiceInfo_Impl* pInfo = 0;
634 0 : for (sal_uLong i = 0; i < nDisplayServices && !pInfo; ++i)
635 : {
636 0 : ServiceInfo_Impl &rTmp = aDisplayServiceArr[ i ];
637 0 : if (rTmp.sSpellImplName == rSvcImplName ||
638 0 : rTmp.sHyphImplName == rSvcImplName ||
639 0 : rTmp.sThesImplName == rSvcImplName ||
640 0 : rTmp.sGrammarImplName == rSvcImplName)
641 0 : pInfo = &rTmp;
642 : }
643 0 : return pInfo;
644 : }
645 :
646 :
647 : //-----------------------------------------------------------------------------
648 :
649 0 : static void lcl_MergeLocales(Sequence< Locale >& aAllLocales, const Sequence< Locale >& rAdd)
650 : {
651 0 : const Locale* pAdd = rAdd.getConstArray();
652 0 : Sequence<Locale> aLocToAdd(rAdd.getLength());
653 0 : const Locale* pAllLocales = aAllLocales.getConstArray();
654 0 : Locale* pLocToAdd = aLocToAdd.getArray();
655 0 : sal_Int32 nFound = 0;
656 : sal_Int32 i;
657 0 : for(i = 0; i < rAdd.getLength(); i++)
658 : {
659 0 : sal_Bool bFound = sal_False;
660 0 : for(sal_Int32 j = 0; j < aAllLocales.getLength() && !bFound; j++)
661 : {
662 0 : bFound = pAdd[i].Language == pAllLocales[j].Language &&
663 0 : pAdd[i].Country == pAllLocales[j].Country;
664 : }
665 0 : if(!bFound)
666 : {
667 0 : pLocToAdd[nFound++] = pAdd[i];
668 : }
669 : }
670 0 : sal_Int32 nLength = aAllLocales.getLength();
671 0 : aAllLocales.realloc( nLength + nFound);
672 0 : Locale* pAllLocales2 = aAllLocales.getArray();
673 0 : for(i = 0; i < nFound; i++)
674 0 : pAllLocales2[nLength++] = pLocToAdd[i];
675 0 : }
676 :
677 0 : static void lcl_MergeDisplayArray(
678 : SvxLinguData_Impl &rData,
679 : const ServiceInfo_Impl &rToAdd )
680 : {
681 0 : sal_uLong nCnt = 0;
682 :
683 0 : ServiceInfoArr &rSvcInfoArr = rData.GetDisplayServiceArray();
684 0 : sal_uLong nEntries = rData.GetDisplayServiceCount();
685 :
686 : ServiceInfo_Impl* pEntry;
687 0 : for (sal_uLong i = 0; i < nEntries; ++i)
688 : {
689 0 : pEntry = &rSvcInfoArr[i];
690 0 : if (pEntry && pEntry->sDisplayName == rToAdd.sDisplayName)
691 : {
692 0 : if(rToAdd.xSpell.is())
693 : {
694 : DBG_ASSERT( !pEntry->xSpell.is() &&
695 : pEntry->sSpellImplName.isEmpty(),
696 : "merge conflict" );
697 0 : pEntry->sSpellImplName = rToAdd.sSpellImplName;
698 0 : pEntry->xSpell = rToAdd.xSpell;
699 : }
700 0 : if(rToAdd.xGrammar.is())
701 : {
702 : DBG_ASSERT( !pEntry->xGrammar.is() &&
703 : pEntry->sGrammarImplName.isEmpty(),
704 : "merge conflict" );
705 0 : pEntry->sGrammarImplName = rToAdd.sGrammarImplName;
706 0 : pEntry->xGrammar = rToAdd.xGrammar;
707 : }
708 0 : if(rToAdd.xHyph.is())
709 : {
710 : DBG_ASSERT( !pEntry->xHyph.is() &&
711 : pEntry->sHyphImplName.isEmpty(),
712 : "merge conflict" );
713 0 : pEntry->sHyphImplName = rToAdd.sHyphImplName;
714 0 : pEntry->xHyph = rToAdd.xHyph;
715 : }
716 0 : if(rToAdd.xThes.is())
717 : {
718 : DBG_ASSERT( !pEntry->xThes.is() &&
719 : pEntry->sThesImplName.isEmpty(),
720 : "merge conflict" );
721 0 : pEntry->sThesImplName = rToAdd.sThesImplName;
722 0 : pEntry->xThes = rToAdd.xThes;
723 : }
724 0 : return ;
725 : }
726 0 : ++nCnt;
727 : }
728 0 : rData.GetDisplayServiceArray().push_back( rToAdd );
729 0 : rData.SetDisplayServiceCount( nCnt + 1 );
730 : }
731 :
732 0 : SvxLinguData_Impl::SvxLinguData_Impl() :
733 0 : nDisplayServices (0)
734 : {
735 0 : xMSF = ::comphelper::getProcessServiceFactory();
736 0 : xLinguSrvcMgr = LinguServiceManager::create(comphelper::getComponentContext(xMSF));
737 :
738 0 : const Locale& rCurrentLocale = Application::GetSettings().GetLanguageTag().getLocale();
739 0 : Sequence<Any> aArgs(2);//second arguments has to be empty!
740 0 : aArgs.getArray()[0] <<= SvxGetLinguPropertySet();
741 :
742 : //read spell checker
743 0 : Sequence< OUString > aSpellNames = xLinguSrvcMgr->getAvailableServices(
744 0 : cSpell, Locale() );
745 0 : const OUString* pSpellNames = aSpellNames.getConstArray();
746 :
747 : sal_Int32 nIdx;
748 0 : for(nIdx = 0; nIdx < aSpellNames.getLength(); nIdx++)
749 : {
750 0 : ServiceInfo_Impl aInfo;
751 0 : aInfo.sSpellImplName = pSpellNames[nIdx];
752 : aInfo.xSpell = uno::Reference<XSpellChecker>(
753 0 : xMSF->createInstanceWithArguments(aInfo.sSpellImplName, aArgs), UNO_QUERY);
754 :
755 0 : uno::Reference<XServiceDisplayName> xDispName(aInfo.xSpell, UNO_QUERY);
756 0 : if(xDispName.is())
757 0 : aInfo.sDisplayName = xDispName->getServiceDisplayName( rCurrentLocale );
758 :
759 0 : const Sequence< Locale > aLocales( aInfo.xSpell->getLocales() );
760 : //! suppress display of entries with no supported languages (see feature 110994)
761 0 : if (aLocales.getLength())
762 : {
763 0 : lcl_MergeLocales( aAllServiceLocales, aLocales );
764 0 : lcl_MergeDisplayArray( *this, aInfo );
765 : }
766 0 : }
767 :
768 : //read grammar checker
769 0 : Sequence< OUString > aGrammarNames = xLinguSrvcMgr->getAvailableServices(
770 0 : cGrammar, Locale() );
771 0 : const OUString* pGrammarNames = aGrammarNames.getConstArray();
772 0 : for(nIdx = 0; nIdx < aGrammarNames.getLength(); nIdx++)
773 : {
774 0 : ServiceInfo_Impl aInfo;
775 0 : aInfo.sGrammarImplName = pGrammarNames[nIdx];
776 : aInfo.xGrammar = uno::Reference<XProofreader>(
777 0 : xMSF->createInstanceWithArguments(aInfo.sGrammarImplName, aArgs), UNO_QUERY);
778 :
779 0 : uno::Reference<XServiceDisplayName> xDispName(aInfo.xGrammar, UNO_QUERY);
780 0 : if(xDispName.is())
781 0 : aInfo.sDisplayName = xDispName->getServiceDisplayName( rCurrentLocale );
782 :
783 0 : const Sequence< Locale > aLocales( aInfo.xGrammar->getLocales() );
784 : //! suppress display of entries with no supported languages (see feature 110994)
785 0 : if (aLocales.getLength())
786 : {
787 0 : lcl_MergeLocales( aAllServiceLocales, aLocales );
788 0 : lcl_MergeDisplayArray( *this, aInfo );
789 : }
790 0 : }
791 :
792 : //read hyphenator
793 0 : Sequence< OUString > aHyphNames = xLinguSrvcMgr->getAvailableServices(
794 0 : cHyph, Locale() );
795 0 : const OUString* pHyphNames = aHyphNames.getConstArray();
796 0 : for(nIdx = 0; nIdx < aHyphNames.getLength(); nIdx++)
797 : {
798 0 : ServiceInfo_Impl aInfo;
799 0 : aInfo.sHyphImplName = pHyphNames[nIdx];
800 : aInfo.xHyph = uno::Reference<XHyphenator>(
801 0 : xMSF->createInstanceWithArguments(aInfo.sHyphImplName, aArgs), UNO_QUERY);
802 :
803 0 : uno::Reference<XServiceDisplayName> xDispName(aInfo.xHyph, UNO_QUERY);
804 0 : if(xDispName.is())
805 0 : aInfo.sDisplayName = xDispName->getServiceDisplayName( rCurrentLocale );
806 :
807 0 : const Sequence< Locale > aLocales( aInfo.xHyph->getLocales() );
808 : //! suppress display of entries with no supported languages (see feature 110994)
809 0 : if (aLocales.getLength())
810 : {
811 0 : lcl_MergeLocales( aAllServiceLocales, aLocales );
812 0 : lcl_MergeDisplayArray( *this, aInfo );
813 : }
814 0 : }
815 :
816 : //read thesauri
817 0 : Sequence< OUString > aThesNames = xLinguSrvcMgr->getAvailableServices(
818 0 : cThes, Locale() );
819 0 : const OUString* pThesNames = aThesNames.getConstArray();
820 0 : for(nIdx = 0; nIdx < aThesNames.getLength(); nIdx++)
821 : {
822 0 : ServiceInfo_Impl aInfo;
823 0 : aInfo.sThesImplName = pThesNames[nIdx];
824 : aInfo.xThes = uno::Reference<XThesaurus>(
825 0 : xMSF->createInstanceWithArguments(aInfo.sThesImplName, aArgs), UNO_QUERY);
826 :
827 0 : uno::Reference<XServiceDisplayName> xDispName(aInfo.xThes, UNO_QUERY);
828 0 : if(xDispName.is())
829 0 : aInfo.sDisplayName = xDispName->getServiceDisplayName( rCurrentLocale );
830 :
831 0 : const Sequence< Locale > aLocales( aInfo.xThes->getLocales() );
832 : //! suppress display of entries with no supported languages (see feature 110994)
833 0 : if (aLocales.getLength())
834 : {
835 0 : lcl_MergeLocales( aAllServiceLocales, aLocales );
836 0 : lcl_MergeDisplayArray( *this, aInfo );
837 : }
838 0 : }
839 :
840 0 : Sequence< OUString > aCfgSvcs;
841 0 : const Locale* pAllLocales = aAllServiceLocales.getConstArray();
842 0 : for(sal_Int32 nLocale = 0; nLocale < aAllServiceLocales.getLength(); nLocale++)
843 : {
844 0 : sal_Int16 nLang = LanguageTag( pAllLocales[nLocale] ).getLanguageType();
845 :
846 0 : aCfgSvcs = xLinguSrvcMgr->getConfiguredServices(cSpell, pAllLocales[nLocale]);
847 0 : SetChecked( aCfgSvcs );
848 0 : if (aCfgSvcs.getLength())
849 0 : aCfgSpellTable[ nLang ] = aCfgSvcs;
850 :
851 0 : aCfgSvcs = xLinguSrvcMgr->getConfiguredServices(cGrammar, pAllLocales[nLocale]);
852 0 : SetChecked( aCfgSvcs );
853 0 : if (aCfgSvcs.getLength())
854 0 : aCfgGrammarTable[ nLang ] = aCfgSvcs;
855 :
856 0 : aCfgSvcs = xLinguSrvcMgr->getConfiguredServices(cHyph, pAllLocales[nLocale]);
857 0 : SetChecked( aCfgSvcs );
858 0 : if (aCfgSvcs.getLength())
859 0 : aCfgHyphTable[ nLang ] = aCfgSvcs;
860 :
861 0 : aCfgSvcs = xLinguSrvcMgr->getConfiguredServices(cThes, pAllLocales[nLocale]);
862 0 : SetChecked( aCfgSvcs );
863 0 : if (aCfgSvcs.getLength())
864 0 : aCfgThesTable[ nLang ] = aCfgSvcs;
865 0 : }
866 0 : }
867 :
868 0 : 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 0 : xLinguSrvcMgr (rData.xLinguSrvcMgr)
878 : {
879 0 : }
880 :
881 0 : SvxLinguData_Impl & SvxLinguData_Impl::operator = (const SvxLinguData_Impl &rData)
882 : {
883 0 : xMSF = rData.xMSF;
884 0 : xLinguSrvcMgr = rData.xLinguSrvcMgr;
885 0 : aAllServiceLocales = rData.aAllServiceLocales;
886 0 : aCfgSpellTable = rData.aCfgSpellTable;
887 0 : aCfgHyphTable = rData.aCfgHyphTable;
888 0 : aCfgThesTable = rData.aCfgThesTable;
889 0 : aCfgGrammarTable = rData.aCfgGrammarTable;
890 0 : aDisplayServiceArr = rData.aDisplayServiceArr;
891 0 : nDisplayServices = rData.nDisplayServices;
892 0 : return *this;
893 : }
894 :
895 0 : SvxLinguData_Impl::~SvxLinguData_Impl()
896 : {
897 0 : }
898 :
899 0 : void SvxLinguData_Impl::SetChecked(const Sequence<OUString>& rConfiguredServices)
900 : {
901 0 : const OUString* pConfiguredServices = rConfiguredServices.getConstArray();
902 0 : for(sal_Int32 n = 0; n < rConfiguredServices.getLength(); n++)
903 : {
904 : ServiceInfo_Impl* pEntry;
905 0 : for (sal_uLong i = 0; i < nDisplayServices; ++i)
906 : {
907 0 : pEntry = &aDisplayServiceArr[i];
908 0 : if (pEntry && !pEntry->bConfigured)
909 : {
910 0 : const OUString &rSrvcImplName = pConfiguredServices[n];
911 0 : if (!rSrvcImplName.isEmpty() &&
912 0 : (pEntry->sSpellImplName == rSrvcImplName ||
913 0 : pEntry->sGrammarImplName == rSrvcImplName ||
914 0 : pEntry->sHyphImplName == rSrvcImplName ||
915 0 : pEntry->sThesImplName == rSrvcImplName))
916 : {
917 0 : pEntry->bConfigured = sal_True;
918 0 : break;
919 : }
920 : }
921 : }
922 : }
923 0 : }
924 :
925 0 : sal_Bool SvxLinguData_Impl::AddRemove(
926 : Sequence< OUString > &rConfigured,
927 : const OUString &rImplName, sal_Bool bAdd )
928 : {
929 0 : sal_Bool bRet = sal_False; // modified?
930 :
931 0 : sal_Int32 nEntries = rConfigured.getLength();
932 0 : sal_Int32 nPos = lcl_SeqGetEntryPos(rConfigured, rImplName);
933 0 : if (bAdd && nPos < 0) // add new entry
934 : {
935 0 : rConfigured.realloc( ++nEntries );
936 0 : OUString *pConfigured = rConfigured.getArray();
937 0 : pConfigured = rConfigured.getArray();
938 0 : pConfigured[nEntries - 1] = rImplName;
939 0 : bRet = sal_True;
940 : }
941 0 : else if (!bAdd && nPos >= 0) // remove existing entry
942 : {
943 0 : OUString *pConfigured = rConfigured.getArray();
944 0 : for (sal_Int32 i = nPos; i < nEntries - 1; ++i)
945 0 : pConfigured[i] = pConfigured[i + 1];
946 0 : rConfigured.realloc(--nEntries);
947 0 : bRet = sal_True;
948 : }
949 :
950 0 : return bRet;
951 : }
952 :
953 :
954 0 : void SvxLinguData_Impl::Reconfigure( const OUString &rDisplayName, sal_Bool bEnable )
955 : {
956 : DBG_ASSERT( !rDisplayName.isEmpty(), "empty DisplayName" );
957 :
958 0 : ServiceInfo_Impl *pInfo = 0;
959 0 : ServiceInfo_Impl *pTmp = 0;
960 0 : for (sal_uLong i = 0; i < nDisplayServices; ++i)
961 : {
962 0 : pTmp = &aDisplayServiceArr[i];
963 0 : if (pTmp && pTmp->sDisplayName == rDisplayName)
964 : {
965 0 : pInfo = pTmp;
966 0 : break;
967 : }
968 : }
969 : DBG_ASSERT( pInfo, "DisplayName entry not found" );
970 0 : if (pInfo)
971 : {
972 0 : pInfo->bConfigured = bEnable;
973 :
974 0 : Sequence< Locale > aLocales;
975 0 : const Locale *pLocale = 0;
976 0 : sal_Int32 nLocales = 0;
977 : sal_Int32 i;
978 :
979 : // update configured spellchecker entries
980 0 : if (pInfo->xSpell.is())
981 : {
982 0 : aLocales = pInfo->xSpell->getLocales();
983 0 : pLocale = aLocales.getConstArray();
984 0 : nLocales = aLocales.getLength();
985 0 : for (i = 0; i < nLocales; ++i)
986 : {
987 0 : sal_Int16 nLang = LanguageTag( pLocale[i] ).getLanguageType();
988 0 : if (!aCfgSpellTable.count( nLang ) && bEnable)
989 0 : aCfgSpellTable[ nLang ] = Sequence< OUString >();
990 0 : if (aCfgSpellTable.count( nLang ))
991 0 : AddRemove( aCfgSpellTable[ nLang ], pInfo->sSpellImplName, bEnable );
992 : }
993 : }
994 :
995 : // update configured grammar checker entries
996 0 : if (pInfo->xGrammar.is())
997 : {
998 0 : aLocales = pInfo->xGrammar->getLocales();
999 0 : pLocale = aLocales.getConstArray();
1000 0 : nLocales = aLocales.getLength();
1001 0 : for (i = 0; i < nLocales; ++i)
1002 : {
1003 0 : sal_Int16 nLang = LanguageTag( pLocale[i] ).getLanguageType();
1004 0 : if (!aCfgGrammarTable.count( nLang ) && bEnable)
1005 0 : aCfgGrammarTable[ nLang ] = Sequence< OUString >();
1006 0 : if (aCfgGrammarTable.count( nLang ))
1007 0 : AddRemove( aCfgGrammarTable[ nLang ], pInfo->sGrammarImplName, bEnable );
1008 : }
1009 : }
1010 :
1011 : // update configured hyphenator entries
1012 0 : if (pInfo->xHyph.is())
1013 : {
1014 0 : aLocales = pInfo->xHyph->getLocales();
1015 0 : pLocale = aLocales.getConstArray();
1016 0 : nLocales = aLocales.getLength();
1017 0 : for (i = 0; i < nLocales; ++i)
1018 : {
1019 0 : sal_Int16 nLang = LanguageTag( pLocale[i] ).getLanguageType();
1020 0 : if (!aCfgHyphTable.count( nLang ) && bEnable)
1021 0 : aCfgHyphTable[ nLang ] = Sequence< OUString >();
1022 0 : if (aCfgHyphTable.count( nLang ))
1023 0 : AddRemove( aCfgHyphTable[ nLang ], pInfo->sHyphImplName, bEnable );
1024 : }
1025 : }
1026 :
1027 : // update configured spellchecker entries
1028 0 : if (pInfo->xThes.is())
1029 : {
1030 0 : aLocales = pInfo->xThes->getLocales();
1031 0 : pLocale = aLocales.getConstArray();
1032 0 : nLocales = aLocales.getLength();
1033 0 : for (i = 0; i < nLocales; ++i)
1034 : {
1035 0 : sal_Int16 nLang = LanguageTag( pLocale[i] ).getLanguageType();
1036 0 : if (!aCfgThesTable.count( nLang ) && bEnable)
1037 0 : aCfgThesTable[ nLang ] = Sequence< OUString >();
1038 0 : if (aCfgThesTable.count( nLang ))
1039 0 : AddRemove( aCfgThesTable[ nLang ], pInfo->sThesImplName, bEnable );
1040 : }
1041 0 : }
1042 : }
1043 0 : }
1044 :
1045 :
1046 : // class SvxLinguTabPage -------------------------------------------------
1047 :
1048 0 : SvxLinguTabPage::SvxLinguTabPage( Window* pParent,
1049 : const SfxItemSet& rSet ):
1050 :
1051 0 : SfxTabPage( pParent, CUI_RES( RID_SFXPAGE_LINGU ), rSet ),
1052 :
1053 0 : aLinguisticFL ( this, CUI_RES( FL_LINGUISTIC ) ),
1054 0 : aLinguModulesFT ( this, CUI_RES( FT_LINGU_MODULES ) ),
1055 0 : aLinguModulesCLB ( this, CUI_RES( CLB_LINGU_MODULES ) ),
1056 0 : aLinguModulesEditPB ( this, CUI_RES( PB_LINGU_MODULES_EDIT ) ),
1057 0 : aLinguDicsFT ( this, CUI_RES( FT_LINGU_DICS ) ),
1058 0 : aLinguDicsCLB ( this, CUI_RES( CLB_LINGU_DICS ) ),
1059 0 : aLinguDicsNewPB ( this, CUI_RES( PB_LINGU_DICS_NEW_DIC ) ),
1060 0 : aLinguDicsEditPB ( this, CUI_RES( PB_LINGU_DICS_EDIT_DIC ) ),
1061 0 : aLinguDicsDelPB ( this, CUI_RES( PB_LINGU_DICS_DEL_DIC ) ),
1062 0 : aLinguOptionsFT ( this, CUI_RES( FT_LINGU_OPTIONS ) ),
1063 0 : aLinguOptionsCLB ( this, CUI_RES( CLB_LINGU_OPTIONS ) ),
1064 0 : aLinguOptionsEditPB ( this, CUI_RES( PB_LINGU_OPTIONS_EDIT ) ),
1065 0 : aMoreDictsLink ( this, CUI_RES( FT_LINGU_OPTIONS_MOREDICTS ) ),
1066 0 : sCapitalWords ( CUI_RES( STR_CAPITAL_WORDS ) ),
1067 0 : sWordsWithDigits ( CUI_RES( STR_WORDS_WITH_DIGITS ) ),
1068 0 : sSpellSpecial ( CUI_RES( STR_SPELL_SPECIAL ) ),
1069 0 : sSpellAuto ( CUI_RES( STR_SPELL_AUTO ) ),
1070 0 : sGrammarAuto ( CUI_RES( STR_GRAMMAR_AUTO ) ),
1071 0 : sNumMinWordlen ( CUI_RES( STR_NUM_MIN_WORDLEN ) ),
1072 0 : sNumPreBreak ( CUI_RES( STR_NUM_PRE_BREAK ) ),
1073 0 : sNumPostBreak ( CUI_RES( STR_NUM_POST_BREAK ) ),
1074 0 : sHyphAuto ( CUI_RES( STR_HYPH_AUTO ) ),
1075 0 : sHyphSpecial ( CUI_RES( STR_HYPH_SPECIAL ) ),
1076 :
1077 0 : pLinguData ( NULL )
1078 : {
1079 0 : pCheckButtonData = NULL;
1080 :
1081 0 : aLinguModulesCLB.SetStyle( aLinguModulesCLB.GetStyle()|WB_CLIPCHILDREN|WB_HSCROLL|WB_FORCE_MAKEVISIBLE );
1082 0 : aLinguModulesCLB.SetHelpId(HID_CLB_LINGU_MODULES );
1083 0 : aLinguModulesCLB.SetHighlightRange();
1084 0 : aLinguModulesCLB.SetSelectHdl( LINK( this, SvxLinguTabPage, SelectHdl_Impl ));
1085 0 : aLinguModulesCLB.SetDoubleClickHdl(LINK(this, SvxLinguTabPage, BoxDoubleClickHdl_Impl));
1086 0 : aLinguModulesCLB.SetCheckButtonHdl(LINK(this, SvxLinguTabPage, BoxCheckButtonHdl_Impl));
1087 :
1088 0 : aLinguModulesEditPB.SetClickHdl( LINK( this, SvxLinguTabPage, ClickHdl_Impl ));
1089 0 : aLinguOptionsEditPB.SetClickHdl( LINK( this, SvxLinguTabPage, ClickHdl_Impl ));
1090 :
1091 0 : aLinguDicsCLB.SetStyle( aLinguDicsCLB.GetStyle()|WB_CLIPCHILDREN|WB_HSCROLL|WB_FORCE_MAKEVISIBLE );
1092 0 : aLinguDicsCLB.SetHelpId(HID_CLB_EDIT_MODULES_DICS );
1093 0 : aLinguDicsCLB.SetHighlightRange();
1094 0 : aLinguDicsCLB.SetSelectHdl( LINK( this, SvxLinguTabPage, SelectHdl_Impl ));
1095 0 : aLinguDicsCLB.SetCheckButtonHdl(LINK(this, SvxLinguTabPage, BoxCheckButtonHdl_Impl));
1096 :
1097 0 : aLinguDicsNewPB.SetClickHdl( LINK( this, SvxLinguTabPage, ClickHdl_Impl ));
1098 0 : aLinguDicsEditPB.SetClickHdl( LINK( this, SvxLinguTabPage, ClickHdl_Impl ));
1099 0 : aLinguDicsDelPB.SetClickHdl( LINK( this, SvxLinguTabPage, ClickHdl_Impl ));
1100 :
1101 0 : aLinguOptionsCLB.SetStyle( aLinguOptionsCLB.GetStyle()|WB_CLIPCHILDREN|WB_HSCROLL|WB_FORCE_MAKEVISIBLE );
1102 0 : aLinguOptionsCLB.SetHelpId(HID_CLB_LINGU_OPTIONS );
1103 0 : aLinguOptionsCLB.SetHighlightRange();
1104 0 : aLinguOptionsCLB.SetSelectHdl( LINK( this, SvxLinguTabPage, SelectHdl_Impl ));
1105 0 : aLinguOptionsCLB.SetDoubleClickHdl(LINK(this, SvxLinguTabPage, BoxDoubleClickHdl_Impl));
1106 :
1107 0 : if ( SvtExtendedSecurityOptions().GetOpenHyperlinkMode()
1108 : != SvtExtendedSecurityOptions::OPEN_NEVER )
1109 : {
1110 : aMoreDictsLink.SetURL( String(
1111 0 : RTL_CONSTASCII_USTRINGPARAM( "http://extensions.libreoffice.org/dictionaries/" ) ) );
1112 0 : aMoreDictsLink.SetClickHdl( LINK( this, SvxLinguTabPage, OpenURLHdl_Impl ) );
1113 : }
1114 : else
1115 0 : aMoreDictsLink.Hide();
1116 :
1117 0 : String sAccessibleNameModuleEdit( CUI_RES( STR_LINGU_MODULES_EDIT ) );
1118 0 : String sAccessibleNameDicsEdit ( CUI_RES( STR_LINGU_DICS_EDIT_DIC ) );
1119 0 : String sAccessibleNameOptionEdit( CUI_RES( STR_LINGU_OPTIONS_EDIT ) );
1120 :
1121 0 : aLinguModulesEditPB.SetAccessibleName(sAccessibleNameModuleEdit);
1122 0 : aLinguDicsEditPB.SetAccessibleName(sAccessibleNameDicsEdit);
1123 0 : aLinguOptionsEditPB.SetAccessibleName(sAccessibleNameOptionEdit);
1124 :
1125 0 : xProp = uno::Reference< XPropertySet >( SvxGetLinguPropertySet(), UNO_QUERY );
1126 0 : xDicList = uno::Reference< XDictionaryList >( SvxGetDictionaryList(), UNO_QUERY );
1127 0 : if (xDicList.is())
1128 : {
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 0 : aDics = xDicList->getDictionaries();
1138 :
1139 0 : UpdateDicBox_Impl();
1140 : }
1141 : else
1142 : {
1143 0 : aLinguDicsFT.Disable();
1144 0 : aLinguDicsCLB.Disable();
1145 0 : aLinguDicsNewPB.Disable();
1146 0 : aLinguDicsEditPB.Disable();
1147 0 : aLinguDicsDelPB.Disable();
1148 : }
1149 :
1150 0 : const SfxSpellCheckItem* pItem = 0;
1151 0 : SfxItemState eItemState = SFX_ITEM_UNKNOWN;
1152 :
1153 0 : eItemState = rSet.GetItemState( GetWhich( SID_ATTR_SPELL ),
1154 0 : sal_False, (const SfxPoolItem**)&pItem );
1155 :
1156 : // is it about a default-item?
1157 0 : if ( eItemState == SFX_ITEM_DEFAULT )
1158 0 : pItem = (const SfxSpellCheckItem*)&(rSet.Get( GetWhich( SID_ATTR_SPELL ) ) );
1159 0 : else if ( eItemState == SFX_ITEM_DONTCARE )
1160 0 : pItem = NULL;
1161 :
1162 0 : FreeResource();
1163 0 : }
1164 :
1165 : // -----------------------------------------------------------------------
1166 :
1167 0 : SvxLinguTabPage::~SvxLinguTabPage()
1168 : {
1169 0 : if (pLinguData)
1170 0 : delete pLinguData;
1171 0 : }
1172 :
1173 : //------------------------------------------------------------------------
1174 :
1175 : // don't throw away overloaded
1176 0 : sal_uInt16* SvxLinguTabPage::GetRanges()
1177 : {
1178 : //TL???
1179 0 : return pRanges;
1180 : }
1181 :
1182 : //------------------------------------------------------------------------
1183 :
1184 0 : SfxTabPage* SvxLinguTabPage::Create( Window* pParent,
1185 : const SfxItemSet& rAttrSet )
1186 : {
1187 0 : return ( new SvxLinguTabPage( pParent, rAttrSet ) );
1188 : }
1189 :
1190 : //------------------------------------------------------------------------
1191 :
1192 0 : sal_Bool SvxLinguTabPage::FillItemSet( SfxItemSet& rCoreSet )
1193 : {
1194 0 : sal_Bool bModified = sal_True; // !!!!
1195 :
1196 : // if not HideGroups was called with GROUP_MODULES...
1197 0 : if (aLinguModulesCLB.IsVisible())
1198 : {
1199 : DBG_ASSERT( pLinguData, "pLinguData not yet initialized" );
1200 0 : if (!pLinguData)
1201 0 : pLinguData = new SvxLinguData_Impl;
1202 :
1203 0 : LangImplNameTable::const_iterator aIt;
1204 :
1205 : // update spellchecker configuration entries
1206 0 : const LangImplNameTable *pTable = &pLinguData->GetSpellTable();
1207 0 : for (aIt = pTable->begin(); aIt != pTable->end(); ++aIt)
1208 : {
1209 0 : sal_Int16 nLang = aIt->first;
1210 0 : const Sequence< OUString > aImplNames( aIt->second );
1211 0 : uno::Reference< XLinguServiceManager2 > xMgr( pLinguData->GetManager() );
1212 0 : Locale aLocale( LanguageTag(nLang).getLocale() );
1213 0 : if (xMgr.is())
1214 0 : xMgr->setConfiguredServices( cSpell, aLocale, aImplNames );
1215 0 : }
1216 :
1217 : // update grammar checker configuration entries
1218 0 : pTable = &pLinguData->GetGrammarTable();
1219 0 : for (aIt = pTable->begin(); aIt != pTable->end(); ++aIt)
1220 : {
1221 0 : sal_Int16 nLang = aIt->first;
1222 0 : const Sequence< OUString > aImplNames( aIt->second );
1223 0 : uno::Reference< XLinguServiceManager2 > xMgr( pLinguData->GetManager() );
1224 0 : Locale aLocale( LanguageTag(nLang).getLocale() );
1225 0 : if (xMgr.is())
1226 0 : xMgr->setConfiguredServices( cGrammar, aLocale, aImplNames );
1227 0 : }
1228 :
1229 : // update hyphenator configuration entries
1230 0 : pTable = &pLinguData->GetHyphTable();
1231 0 : for (aIt = pTable->begin(); aIt != pTable->end(); ++aIt)
1232 : {
1233 0 : sal_Int16 nLang = aIt->first;
1234 0 : const Sequence< OUString > aImplNames( aIt->second );
1235 0 : uno::Reference< XLinguServiceManager2 > xMgr( pLinguData->GetManager() );
1236 0 : Locale aLocale( LanguageTag(nLang).getLocale() );
1237 0 : if (xMgr.is())
1238 0 : xMgr->setConfiguredServices( cHyph, aLocale, aImplNames );
1239 0 : }
1240 :
1241 : // update thesaurus configuration entries
1242 0 : pTable = &pLinguData->GetThesTable();
1243 0 : for (aIt = pTable->begin(); aIt != pTable->end(); ++aIt)
1244 : {
1245 0 : sal_Int16 nLang = aIt->first;
1246 0 : const Sequence< OUString > aImplNames( aIt->second );
1247 0 : uno::Reference< XLinguServiceManager2 > xMgr( pLinguData->GetManager() );
1248 0 : Locale aLocale( LanguageTag(nLang).getLocale() );
1249 0 : if (xMgr.is())
1250 0 : xMgr->setConfiguredServices( cThes, aLocale, aImplNames );
1251 0 : }
1252 : }
1253 :
1254 :
1255 : //
1256 : // activate dictionaries according to checkbox state
1257 : //
1258 0 : Sequence< OUString > aActiveDics;
1259 0 : sal_Int32 nActiveDics = 0;
1260 0 : sal_uLong nEntries = aLinguDicsCLB.GetEntryCount();
1261 0 : for (sal_uLong i = 0; i < nEntries; ++i)
1262 : {
1263 0 : sal_Int32 nDics = aDics.getLength();
1264 :
1265 0 : aActiveDics.realloc( nDics );
1266 0 : OUString *pActiveDic = aActiveDics.getArray();
1267 :
1268 0 : SvTreeListEntry *pEntry = aLinguDicsCLB.GetEntry( i );
1269 0 : if (pEntry)
1270 : {
1271 0 : DicUserData aData( (sal_uLong)pEntry->GetUserData() );
1272 0 : if (aData.GetEntryId() < nDics)
1273 : {
1274 0 : sal_Bool bChecked = aLinguDicsCLB.IsChecked( (sal_uInt16) i );
1275 0 : uno::Reference< XDictionary > xDic( aDics.getConstArray()[ i ] );
1276 0 : if (xDic.is())
1277 : {
1278 0 : if (SvxGetIgnoreAllList() == xDic)
1279 0 : bChecked = sal_True;
1280 0 : xDic->setActive( bChecked );
1281 :
1282 0 : if (bChecked)
1283 : {
1284 0 : String aDicName( xDic->getName() );
1285 0 : pActiveDic[ nActiveDics++ ] = aDicName;
1286 : }
1287 0 : }
1288 : }
1289 : }
1290 : }
1291 :
1292 0 : aActiveDics.realloc( nActiveDics );
1293 0 : Any aTmp;
1294 0 : aTmp <<= aActiveDics;
1295 0 : SvtLinguConfig aLngCfg;
1296 0 : aLngCfg.SetProperty( UPH_ACTIVE_DICTIONARIES, aTmp );
1297 :
1298 :
1299 0 : nEntries = aLinguOptionsCLB.GetEntryCount();
1300 0 : for (sal_uInt16 j = 0; j < nEntries; ++j)
1301 : {
1302 0 : SvTreeListEntry *pEntry = aLinguOptionsCLB.GetEntry( j );
1303 :
1304 0 : OptionsUserData aData( (sal_uLong)pEntry->GetUserData() );
1305 0 : String aPropName( lcl_GetPropertyName( (EID_OPTIONS) aData.GetEntryId() ) );
1306 :
1307 0 : Any aAny;
1308 0 : if (aData.IsCheckable())
1309 : {
1310 0 : sal_Bool bChecked = aLinguOptionsCLB.IsChecked( j );
1311 0 : aAny <<= bChecked;
1312 : }
1313 0 : else if (aData.HasNumericValue())
1314 : {
1315 0 : sal_Int16 nVal = aData.GetNumericValue();
1316 0 : aAny <<= nVal;
1317 : }
1318 :
1319 0 : if (xProp.is())
1320 0 : xProp->setPropertyValue( aPropName, aAny );
1321 0 : aLngCfg.SetProperty( aPropName, aAny );
1322 0 : }
1323 :
1324 0 : SvTreeListEntry *pPreBreakEntry = aLinguOptionsCLB.GetEntry( (sal_uInt16) EID_NUM_PRE_BREAK );
1325 0 : SvTreeListEntry *pPostBreakEntry = aLinguOptionsCLB.GetEntry( (sal_uInt16) EID_NUM_POST_BREAK );
1326 : DBG_ASSERT( pPreBreakEntry, "NULL Pointer" );
1327 : DBG_ASSERT( pPostBreakEntry, "NULL Pointer" );
1328 0 : if (pPreBreakEntry && pPostBreakEntry)
1329 : {
1330 0 : OptionsUserData aPreBreakData( (sal_uLong)pPreBreakEntry->GetUserData() );
1331 0 : OptionsUserData aPostBreakData( (sal_uLong)pPostBreakEntry->GetUserData() );
1332 0 : if ( aPreBreakData.IsModified() || aPostBreakData.IsModified() )
1333 : {
1334 0 : SfxHyphenRegionItem aHyp( GetWhich( SID_ATTR_HYPHENREGION ) );
1335 0 : aHyp.GetMinLead() = (sal_uInt8) aPreBreakData.GetNumericValue();
1336 0 : aHyp.GetMinTrail() = (sal_uInt8) aPostBreakData.GetNumericValue();
1337 0 : rCoreSet.Put( aHyp );
1338 : }
1339 : }
1340 :
1341 :
1342 : // automatic spell checking
1343 0 : sal_Bool bNewAutoCheck = aLinguOptionsCLB.IsChecked( (sal_uInt16) EID_SPELL_AUTO );
1344 0 : const SfxPoolItem* pOld = GetOldItem( rCoreSet, SID_AUTOSPELL_CHECK );
1345 0 : if ( !pOld || ( (SfxBoolItem*)pOld )->GetValue() != bNewAutoCheck )
1346 : {
1347 0 : rCoreSet.Put( SfxBoolItem( GetWhich( SID_AUTOSPELL_CHECK ),
1348 0 : bNewAutoCheck ) );
1349 0 : bModified |= sal_True;
1350 : }
1351 :
1352 0 : return bModified;
1353 : }
1354 :
1355 : // ----------------------------------------------------------------------
1356 :
1357 0 : sal_uLong SvxLinguTabPage::GetDicUserData( const uno::Reference< XDictionary > &rxDic, sal_uInt16 nIdx )
1358 : {
1359 0 : sal_uLong nRes = 0;
1360 : DBG_ASSERT( rxDic.is(), "dictionary not supplied" );
1361 0 : if (rxDic.is())
1362 : {
1363 0 : uno::Reference< frame::XStorable > xStor( rxDic, UNO_QUERY );
1364 :
1365 0 : sal_Bool bChecked = rxDic->isActive();
1366 0 : sal_Bool bEditable = !xStor.is() || !xStor->isReadonly();
1367 0 : sal_Bool bDeletable = bEditable;
1368 :
1369 : nRes = DicUserData( nIdx,
1370 0 : bChecked, bEditable, bDeletable ).GetUserData();
1371 : }
1372 0 : return nRes;
1373 : }
1374 :
1375 :
1376 0 : void SvxLinguTabPage::AddDicBoxEntry(
1377 : const uno::Reference< XDictionary > &rxDic,
1378 : sal_uInt16 nIdx )
1379 : {
1380 0 : aLinguDicsCLB.SetUpdateMode(sal_False);
1381 :
1382 0 : String aTxt( ::GetDicInfoStr( rxDic->getName(),
1383 0 : LanguageTag( rxDic->getLocale() ).getLanguageType(),
1384 0 : DictionaryType_NEGATIVE == rxDic->getDictionaryType() ) );
1385 0 : aLinguDicsCLB.InsertEntry( aTxt, (sal_uInt16)LISTBOX_APPEND ); // append at end
1386 0 : SvTreeListEntry* pEntry = aLinguDicsCLB.GetEntry( aLinguDicsCLB.GetEntryCount() - 1 );
1387 : DBG_ASSERT( pEntry, "failed to add entry" );
1388 0 : if (pEntry)
1389 : {
1390 0 : DicUserData aData( GetDicUserData( rxDic, nIdx ) );
1391 0 : pEntry->SetUserData( (void *) aData.GetUserData() );
1392 0 : lcl_SetCheckButton( pEntry, aData.IsChecked() );
1393 : }
1394 :
1395 0 : aLinguDicsCLB.SetUpdateMode(sal_True);
1396 0 : }
1397 :
1398 : // ----------------------------------------------------------------------
1399 :
1400 0 : void SvxLinguTabPage::UpdateDicBox_Impl()
1401 : {
1402 0 : aLinguDicsCLB.SetUpdateMode(sal_False);
1403 0 : aLinguDicsCLB.Clear();
1404 :
1405 0 : sal_Int32 nDics = aDics.getLength();
1406 0 : const uno::Reference< XDictionary > *pDic = aDics.getConstArray();
1407 0 : for (sal_Int32 i = 0; i < nDics; ++i)
1408 : {
1409 0 : const uno::Reference< XDictionary > &rDic = pDic[i];
1410 0 : if (rDic.is())
1411 0 : AddDicBoxEntry( rDic, (sal_uInt16)i );
1412 : }
1413 :
1414 0 : aLinguDicsCLB.SetUpdateMode(sal_True);
1415 0 : }
1416 :
1417 : // ----------------------------------------------------------------------
1418 :
1419 0 : void SvxLinguTabPage::UpdateModulesBox_Impl()
1420 : {
1421 0 : if (pLinguData)
1422 : {
1423 0 : const ServiceInfoArr &rAllDispSrvcArr = pLinguData->GetDisplayServiceArray();
1424 0 : const sal_uLong nDispSrvcCount = pLinguData->GetDisplayServiceCount();
1425 :
1426 0 : aLinguModulesCLB.Clear();
1427 :
1428 0 : for (sal_uInt16 i = 0; i < nDispSrvcCount; ++i)
1429 : {
1430 0 : const ServiceInfo_Impl &rInfo = rAllDispSrvcArr[i];
1431 0 : aLinguModulesCLB.InsertEntry( rInfo.sDisplayName, (sal_uInt16)LISTBOX_APPEND );
1432 0 : SvTreeListEntry* pEntry = aLinguModulesCLB.GetEntry(i);
1433 0 : pEntry->SetUserData( (void *) &rInfo );
1434 0 : aLinguModulesCLB.CheckEntryPos( i, rInfo.bConfigured );
1435 : }
1436 0 : aLinguModulesEditPB.Enable( nDispSrvcCount > 0 );
1437 : }
1438 0 : }
1439 :
1440 : //------------------------------------------------------------------------
1441 :
1442 0 : void SvxLinguTabPage::Reset( const SfxItemSet& rSet )
1443 : {
1444 : // if not HideGroups was called with GROUP_MODULES...
1445 0 : if (aLinguModulesCLB.IsVisible())
1446 : {
1447 0 : if (!pLinguData)
1448 0 : pLinguData = new SvxLinguData_Impl;
1449 0 : UpdateModulesBox_Impl();
1450 : }
1451 :
1452 :
1453 : //
1454 : // get data from configuration
1455 : //
1456 :
1457 0 : SvtLinguConfig aLngCfg;
1458 :
1459 0 : aLinguOptionsCLB.SetUpdateMode(sal_False);
1460 0 : aLinguOptionsCLB.Clear();
1461 :
1462 0 : SvTreeList *pModel = aLinguOptionsCLB.GetModel();
1463 0 : SvTreeListEntry* pEntry = NULL;
1464 :
1465 0 : sal_Int16 nVal = 0;
1466 0 : sal_Bool bVal = sal_False;
1467 0 : sal_uLong nUserData = 0;
1468 :
1469 0 : pEntry = CreateEntry( sSpellAuto, CBCOL_FIRST );
1470 0 : aLngCfg.GetProperty( UPN_IS_SPELL_AUTO ) >>= bVal;
1471 0 : const SfxPoolItem* pItem = GetItem( rSet, SID_AUTOSPELL_CHECK );
1472 0 : if (pItem)
1473 0 : bVal = ((SfxBoolItem *) pItem)->GetValue();
1474 0 : nUserData = OptionsUserData( EID_SPELL_AUTO, sal_False, 0, sal_True, bVal).GetUserData();
1475 0 : pEntry->SetUserData( (void *)nUserData );
1476 0 : pModel->Insert( pEntry );
1477 0 : lcl_SetCheckButton( pEntry, bVal );
1478 :
1479 0 : pEntry = CreateEntry( sGrammarAuto, CBCOL_FIRST );
1480 0 : aLngCfg.GetProperty( UPN_IS_GRAMMAR_AUTO ) >>= bVal;
1481 0 : nUserData = OptionsUserData( EID_GRAMMAR_AUTO, sal_False, 0, sal_True, bVal).GetUserData();
1482 0 : pEntry->SetUserData( (void *)nUserData );
1483 0 : pModel->Insert( pEntry );
1484 0 : lcl_SetCheckButton( pEntry, bVal );
1485 :
1486 0 : pEntry = CreateEntry( sCapitalWords, CBCOL_FIRST );
1487 0 : aLngCfg.GetProperty( UPN_IS_SPELL_UPPER_CASE ) >>= bVal;
1488 0 : nUserData = OptionsUserData( EID_CAPITAL_WORDS, sal_False, 0, sal_True, bVal).GetUserData();
1489 0 : pEntry->SetUserData( (void *)nUserData );
1490 0 : pModel->Insert( pEntry );
1491 0 : lcl_SetCheckButton( pEntry, bVal );
1492 :
1493 0 : pEntry = CreateEntry( sWordsWithDigits, CBCOL_FIRST );
1494 0 : aLngCfg.GetProperty( UPN_IS_SPELL_WITH_DIGITS ) >>= bVal;
1495 0 : nUserData = OptionsUserData( EID_WORDS_WITH_DIGITS, sal_False, 0, sal_True, bVal).GetUserData();
1496 0 : pEntry->SetUserData( (void *)nUserData );
1497 0 : pModel->Insert( pEntry );
1498 0 : lcl_SetCheckButton( pEntry, bVal );
1499 :
1500 0 : pEntry = CreateEntry( sSpellSpecial, CBCOL_FIRST );
1501 0 : aLngCfg.GetProperty( UPN_IS_SPELL_SPECIAL ) >>= bVal;
1502 0 : nUserData = OptionsUserData( EID_SPELL_SPECIAL, sal_False, 0, sal_True, bVal).GetUserData();
1503 0 : pEntry->SetUserData( (void *)nUserData );
1504 0 : pModel->Insert( pEntry );
1505 0 : lcl_SetCheckButton( pEntry, bVal );
1506 :
1507 0 : pEntry = CreateEntry( sNumMinWordlen, CBCOL_SECOND );
1508 0 : aLngCfg.GetProperty( UPN_HYPH_MIN_WORD_LENGTH ) >>= nVal;
1509 0 : nUserData = OptionsUserData( EID_NUM_MIN_WORDLEN, sal_True, (sal_uInt16)nVal, sal_False, sal_False).GetUserData();
1510 0 : pEntry->SetUserData( (void *)nUserData );
1511 0 : pModel->Insert( pEntry );
1512 :
1513 0 : const SfxHyphenRegionItem *pHyp = NULL;
1514 0 : sal_uInt16 nWhich = GetWhich( SID_ATTR_HYPHENREGION );
1515 0 : if ( rSet.GetItemState( nWhich, sal_False ) == SFX_ITEM_SET )
1516 0 : pHyp = &( (const SfxHyphenRegionItem &) rSet.Get( nWhich ) );
1517 :
1518 0 : pEntry = CreateEntry( sNumPreBreak, CBCOL_SECOND );
1519 0 : aLngCfg.GetProperty( UPN_HYPH_MIN_LEADING ) >>= nVal;
1520 0 : if (pHyp)
1521 0 : nVal = (sal_Int16) pHyp->GetMinLead();
1522 0 : nUserData = OptionsUserData( EID_NUM_PRE_BREAK, sal_True, (sal_uInt16)nVal, sal_False, sal_False).GetUserData();
1523 0 : pEntry->SetUserData( (void *)nUserData );
1524 0 : pModel->Insert( pEntry );
1525 :
1526 0 : pEntry = CreateEntry( sNumPostBreak, CBCOL_SECOND );
1527 0 : aLngCfg.GetProperty( UPN_HYPH_MIN_TRAILING ) >>= nVal;
1528 0 : if (pHyp)
1529 0 : nVal = (sal_Int16) pHyp->GetMinTrail();
1530 0 : nUserData = OptionsUserData( EID_NUM_POST_BREAK, sal_True, (sal_uInt16)nVal, sal_False, sal_False).GetUserData();
1531 0 : pEntry->SetUserData( (void *)nUserData );
1532 0 : pModel->Insert( pEntry );
1533 :
1534 0 : pEntry = CreateEntry( sHyphAuto, CBCOL_FIRST );
1535 0 : aLngCfg.GetProperty( UPN_IS_HYPH_AUTO ) >>= bVal;
1536 0 : nUserData = OptionsUserData( EID_HYPH_AUTO, sal_False, 0, sal_True, bVal).GetUserData();
1537 0 : pEntry->SetUserData( (void *)nUserData );
1538 0 : pModel->Insert( pEntry );
1539 0 : lcl_SetCheckButton( pEntry, bVal );
1540 :
1541 0 : pEntry = CreateEntry( sHyphSpecial, CBCOL_FIRST );
1542 0 : aLngCfg.GetProperty( UPN_IS_HYPH_SPECIAL ) >>= bVal;
1543 0 : nUserData = OptionsUserData( EID_HYPH_SPECIAL, sal_False, 0, sal_True, bVal).GetUserData();
1544 0 : pEntry->SetUserData( (void *)nUserData );
1545 0 : pModel->Insert( pEntry );
1546 0 : lcl_SetCheckButton( pEntry, bVal );
1547 :
1548 0 : aLinguOptionsCLB.SetUpdateMode(sal_True);
1549 0 : }
1550 :
1551 : // -----------------------------------------------------------------------
1552 :
1553 0 : IMPL_LINK( SvxLinguTabPage, BoxDoubleClickHdl_Impl, SvTreeListBox *, pBox )
1554 : {
1555 0 : if (pBox == &aLinguModulesCLB)
1556 : {
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 0 : this, SvxLinguTabPage, PostDblClickHdl_Impl ) );
1562 : }
1563 0 : else if (pBox == &aLinguOptionsCLB)
1564 : {
1565 0 : ClickHdl_Impl(&aLinguOptionsEditPB);
1566 : }
1567 0 : return 0;
1568 : }
1569 :
1570 : // -----------------------------------------------------------------------
1571 :
1572 0 : IMPL_LINK_NOARG(SvxLinguTabPage, PostDblClickHdl_Impl)
1573 : {
1574 0 : ClickHdl_Impl(&aLinguModulesEditPB);
1575 0 : return 0;
1576 : }
1577 :
1578 : // -----------------------------------------------------------------------
1579 :
1580 0 : IMPL_LINK_NOARG(SvxLinguTabPage, OpenURLHdl_Impl)
1581 : {
1582 0 : ::rtl::OUString sURL( aMoreDictsLink.GetURL() );
1583 0 : lcl_OpenURL( sURL );
1584 0 : return 0;
1585 : }
1586 :
1587 : // -----------------------------------------------------------------------
1588 :
1589 0 : IMPL_LINK( SvxLinguTabPage, BoxCheckButtonHdl_Impl, SvTreeListBox *, pBox )
1590 : {
1591 0 : if (pBox == &aLinguModulesCLB)
1592 : {
1593 : DBG_ASSERT( pLinguData, "NULL pointer, LinguData missing" );
1594 0 : sal_uInt16 nPos = aLinguModulesCLB.GetSelectEntryPos();
1595 0 : if (nPos != LISTBOX_ENTRY_NOTFOUND && pLinguData)
1596 : {
1597 : pLinguData->Reconfigure( aLinguModulesCLB.GetText( nPos ),
1598 0 : aLinguModulesCLB.IsChecked( nPos ) );
1599 : }
1600 : }
1601 0 : else if (pBox == &aLinguDicsCLB)
1602 : {
1603 0 : sal_uInt16 nPos = aLinguDicsCLB.GetSelectEntryPos();
1604 0 : if (nPos != LISTBOX_ENTRY_NOTFOUND)
1605 : {
1606 0 : const uno::Reference< XDictionary > &rDic = aDics.getConstArray()[ nPos ];
1607 0 : if (SvxGetIgnoreAllList() == rDic)
1608 : {
1609 0 : SvTreeListEntry* pEntry = aLinguDicsCLB.GetEntry( nPos );
1610 0 : if (pEntry)
1611 0 : lcl_SetCheckButton( pEntry, sal_True );
1612 : }
1613 : }
1614 : }
1615 0 : return 0;
1616 : }
1617 :
1618 : // -----------------------------------------------------------------------
1619 :
1620 0 : IMPL_LINK( SvxLinguTabPage, ClickHdl_Impl, PushButton *, pBtn )
1621 : {
1622 0 : if (&aLinguModulesEditPB == pBtn)
1623 : {
1624 0 : if (!pLinguData)
1625 0 : pLinguData = new SvxLinguData_Impl;
1626 :
1627 0 : SvxLinguData_Impl aOldLinguData( *pLinguData );
1628 0 : SvxEditModulesDlg aDlg( this, *pLinguData );
1629 0 : if (aDlg.Execute() != RET_OK)
1630 0 : *pLinguData = aOldLinguData;
1631 :
1632 : // evaluate new status of 'bConfigured' flag
1633 0 : sal_uLong nLen = pLinguData->GetDisplayServiceCount();
1634 0 : for (sal_uLong i = 0; i < nLen; ++i)
1635 0 : pLinguData->GetDisplayServiceArray()[i].bConfigured = sal_False;
1636 0 : const Locale* pAllLocales = pLinguData->GetAllSupportedLocales().getConstArray();
1637 0 : sal_Int32 nLocales = pLinguData->GetAllSupportedLocales().getLength();
1638 0 : for (sal_Int32 k = 0; k < nLocales; ++k)
1639 : {
1640 0 : sal_Int16 nLang = LanguageTag( pAllLocales[k] ).getLanguageType();
1641 0 : if (pLinguData->GetSpellTable().count( nLang ))
1642 0 : pLinguData->SetChecked( pLinguData->GetSpellTable()[ nLang ] );
1643 0 : if (pLinguData->GetGrammarTable().count( nLang ))
1644 0 : pLinguData->SetChecked( pLinguData->GetGrammarTable()[ nLang ] );
1645 0 : if (pLinguData->GetHyphTable().count( nLang ))
1646 0 : pLinguData->SetChecked( pLinguData->GetHyphTable()[ nLang ] );
1647 0 : if (pLinguData->GetThesTable().count( nLang ))
1648 0 : pLinguData->SetChecked( pLinguData->GetThesTable()[ nLang ] );
1649 : }
1650 :
1651 : // show new status of modules
1652 0 : UpdateModulesBox_Impl();
1653 : }
1654 0 : else if (&aLinguDicsNewPB == pBtn)
1655 : {
1656 0 : uno::Reference< XSpellChecker1 > xSpellChecker1;
1657 0 : SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
1658 0 : if(pFact)
1659 : {
1660 0 : AbstractSvxNewDictionaryDialog* aDlg = pFact->CreateSvxNewDictionaryDialog( this, xSpellChecker1, RID_SFXDLG_NEWDICT );
1661 : DBG_ASSERT(aDlg, "Dialogdiet fail!");
1662 0 : uno::Reference< XDictionary > xNewDic;
1663 0 : if ( aDlg->Execute() == RET_OK )
1664 0 : xNewDic = uno::Reference< XDictionary >( aDlg->GetNewDictionary(), UNO_QUERY );
1665 0 : if ( xNewDic.is() )
1666 : {
1667 : // add new dics to the end
1668 0 : sal_Int32 nLen = aDics.getLength();
1669 0 : aDics.realloc( nLen + 1 );
1670 :
1671 0 : aDics.getArray()[ nLen ] = xNewDic;
1672 :
1673 0 : AddDicBoxEntry( xNewDic, (sal_uInt16) nLen );
1674 : }
1675 0 : delete aDlg;
1676 0 : }
1677 : }
1678 0 : else if (&aLinguDicsEditPB == pBtn)
1679 : {
1680 0 : SvTreeListEntry *pEntry = aLinguDicsCLB.GetCurEntry();
1681 0 : if (pEntry)
1682 : {
1683 0 : DicUserData aData( (sal_uLong) pEntry->GetUserData() );
1684 0 : sal_uInt16 nDicPos = aData.GetEntryId();
1685 0 : sal_Int32 nDics = aDics.getLength();
1686 0 : if (nDicPos < nDics)
1687 : {
1688 0 : uno::Reference< XDictionary > xDic;
1689 0 : xDic = aDics.getConstArray()[ nDicPos ];
1690 0 : if (xDic.is())
1691 : {
1692 0 : uno::Reference< XSpellChecker1 > xSpellChecker1;
1693 0 : SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
1694 0 : if(pFact)
1695 : {
1696 0 : VclAbstractDialog* aDlg = pFact->CreateSvxEditDictionaryDialog( this, xDic->getName(), xSpellChecker1, RID_SFXDLG_EDITDICT );
1697 : DBG_ASSERT(aDlg, "Dialogdiet fail!");
1698 0 : aDlg->Execute();
1699 0 : delete aDlg;
1700 0 : }
1701 0 : }
1702 : }
1703 : }
1704 : }
1705 0 : else if (&aLinguDicsDelPB == pBtn)
1706 : {
1707 0 : if ( RET_NO ==
1708 0 : QueryBox( this, CUI_RES( RID_SFXQB_DELDICT ) ).Execute() )
1709 0 : return 0;
1710 :
1711 0 : SvTreeListEntry *pEntry = aLinguDicsCLB.GetCurEntry();
1712 0 : if (pEntry)
1713 : {
1714 0 : DicUserData aData( (sal_uLong) pEntry->GetUserData() );
1715 0 : sal_uInt16 nDicPos = aData.GetEntryId();
1716 0 : sal_Int32 nDics = aDics.getLength();
1717 0 : if (nDicPos < nDics)
1718 : {
1719 0 : uno::Reference< XDictionary > xDic;
1720 0 : xDic = aDics.getConstArray()[ nDicPos ];
1721 0 : if (xDic.is())
1722 : {
1723 0 : if (SvxGetIgnoreAllList() == xDic)
1724 0 : xDic->clear();
1725 : else
1726 : {
1727 0 : if (xDicList.is())
1728 0 : xDicList->removeDictionary( xDic );
1729 :
1730 0 : uno::Reference< frame::XStorable > xStor( xDic, UNO_QUERY );
1731 0 : if ( xStor->hasLocation() && !xStor->isReadonly() )
1732 : {
1733 0 : String sURL = xStor->getLocation();
1734 0 : INetURLObject aObj(sURL);
1735 : DBG_ASSERT( aObj.GetProtocol() == INET_PROT_FILE,
1736 : "non-file URLs cannot be deleted" );
1737 0 : if ( aObj.GetProtocol() == INET_PROT_FILE )
1738 : {
1739 0 : KillFile_Impl( aObj.GetMainURL( INetURLObject::NO_DECODE ) );
1740 0 : }
1741 : }
1742 :
1743 0 : aDics.getArray()[ nDicPos ] = 0;
1744 :
1745 : // remove entry from checklistbox
1746 0 : sal_uLong nCnt = aLinguDicsCLB.GetEntryCount();
1747 0 : for (sal_uLong i = 0; i < nCnt; ++i)
1748 : {
1749 0 : SvTreeListEntry *pDicEntry = aLinguDicsCLB.GetEntry( i );
1750 : DBG_ASSERT( pDicEntry, "missing entry" );
1751 0 : if (pDicEntry)
1752 : {
1753 0 : DicUserData aDicData( (sal_uLong) pDicEntry->GetUserData() );
1754 0 : if (aDicData.GetEntryId() == nDicPos )
1755 : {
1756 0 : aLinguDicsCLB.RemoveEntry( (sal_uInt16) i );
1757 : break;
1758 : }
1759 : }
1760 : }
1761 : DBG_ASSERT( nCnt > aLinguDicsCLB.GetEntryCount(),
1762 0 : "remove failed ?");
1763 : }
1764 0 : }
1765 : }
1766 : }
1767 : }
1768 0 : else if (&aLinguOptionsEditPB == pBtn)
1769 : {
1770 0 : SvTreeListEntry *pEntry = aLinguOptionsCLB.GetCurEntry();
1771 : DBG_ASSERT( pEntry, "no entry selected" );
1772 0 : if (pEntry)
1773 : {
1774 0 : OptionsUserData aData( (sal_uLong)pEntry->GetUserData() );
1775 0 : if(aData.HasNumericValue())
1776 : {
1777 0 : int nRID = -1;
1778 0 : switch (aData.GetEntryId())
1779 : {
1780 0 : case EID_NUM_PRE_BREAK : nRID = STR_NUM_PRE_BREAK_DLG; break;
1781 0 : case EID_NUM_POST_BREAK : nRID = STR_NUM_POST_BREAK_DLG; break;
1782 0 : case EID_NUM_MIN_WORDLEN: nRID = STR_NUM_MIN_WORDLEN_DLG; break;
1783 : default:
1784 : OSL_FAIL( "unexpected case" );
1785 : }
1786 :
1787 0 : OptionsBreakSet aDlg( this, nRID );
1788 0 : aDlg.GetNumericFld().SetValue( aData.GetNumericValue() );
1789 0 : if (RET_OK == aDlg.Execute() )
1790 : {
1791 0 : long nVal = static_cast<long>(aDlg.GetNumericFld().GetValue());
1792 0 : if (-1 != nVal && aData.GetNumericValue() != nVal)
1793 : {
1794 0 : aData.SetNumericValue( (sal_uInt8)nVal ); //! sets IsModified !
1795 0 : pEntry->SetUserData( (void *) aData.GetUserData() );
1796 0 : aLinguOptionsCLB.Invalidate();
1797 : }
1798 0 : }
1799 : }
1800 : }
1801 : }
1802 : else
1803 : {
1804 : OSL_FAIL( "pBtn unexpected value" );
1805 : }
1806 :
1807 0 : return 0;
1808 : }
1809 :
1810 : // -----------------------------------------------------------------------
1811 :
1812 0 : IMPL_LINK( SvxLinguTabPage, SelectHdl_Impl, SvxCheckListBox *, pBox )
1813 : {
1814 0 : if (&aLinguModulesCLB == pBox)
1815 : {
1816 : }
1817 0 : else if (&aLinguDicsCLB == pBox)
1818 : {
1819 0 : SvTreeListEntry *pEntry = pBox->GetCurEntry();
1820 0 : if (pEntry)
1821 : {
1822 0 : DicUserData aData( (sal_uLong) pEntry->GetUserData() );
1823 :
1824 : // always allow to edit (i.e. at least view the content of the dictionary)
1825 0 : aLinguDicsEditPB.Enable( true/*aData.IsEditable()*/ );
1826 0 : aLinguDicsDelPB .Enable( aData.IsDeletable() );
1827 : }
1828 : }
1829 0 : else if (&aLinguOptionsCLB == pBox)
1830 : {
1831 0 : SvTreeListEntry *pEntry = pBox->GetCurEntry();
1832 0 : if (pEntry)
1833 : {
1834 0 : OptionsUserData aData( (sal_uLong) pEntry->GetUserData() );
1835 0 : aLinguOptionsEditPB.Enable( aData.HasNumericValue() );
1836 : }
1837 : }
1838 : else
1839 : {
1840 : OSL_FAIL( "pBox unexpected value" );
1841 : }
1842 :
1843 0 : return 0;
1844 : }
1845 :
1846 : // -----------------------------------------------------------------------
1847 :
1848 0 : SvTreeListEntry* SvxLinguTabPage::CreateEntry( String& rTxt, sal_uInt16 nCol )
1849 : {
1850 0 : SvTreeListEntry* pEntry = new SvTreeListEntry;
1851 :
1852 0 : if( !pCheckButtonData )
1853 0 : pCheckButtonData = new SvLBoxButtonData( &aLinguOptionsCLB );
1854 :
1855 0 : String sEmpty;
1856 0 : if (CBCOL_FIRST == nCol)
1857 0 : pEntry->AddItem( new SvLBoxButton( pEntry, SvLBoxButtonKind_enabledCheckbox, 0, pCheckButtonData ) );
1858 0 : if (CBCOL_SECOND == nCol)
1859 0 : pEntry->AddItem( new SvLBoxString( pEntry, 0, sEmpty) ); // empty column
1860 0 : pEntry->AddItem( new SvLBoxContextBmp( pEntry, 0, Image(), Image(), 0));
1861 0 : pEntry->AddItem( new BrwString_Impl( pEntry, 0, rTxt ) );
1862 :
1863 0 : return pEntry;
1864 : }
1865 :
1866 : // -----------------------------------------------------------------------
1867 :
1868 0 : void SvxLinguTabPage::HideGroups( sal_uInt16 nGrp )
1869 : {
1870 0 : if ( 0 != ( GROUP_MODULES & nGrp ) )
1871 : {
1872 0 : aLinguModulesFT.Hide();
1873 0 : aLinguModulesCLB.Hide();
1874 0 : aLinguModulesEditPB.Hide();
1875 :
1876 : // reposition / resize remaining controls
1877 0 : long nDeltaY = aLinguDicsFT.GetPosPixel().Y() -
1878 0 : aLinguModulesFT.GetPosPixel().Y();
1879 : DBG_ASSERT( nDeltaY >= 0, "move/resize value is negative" );
1880 0 : Point aPos;
1881 :
1882 0 : aPos = aLinguDicsFT.GetPosPixel();
1883 0 : aPos.Y() -= nDeltaY;
1884 0 : aLinguDicsFT.SetPosPixel( aPos );
1885 0 : aPos = aLinguDicsCLB.GetPosPixel();
1886 0 : aPos.Y() -= nDeltaY;
1887 0 : aLinguDicsCLB.SetPosPixel( aPos );
1888 0 : aPos = aLinguDicsNewPB.GetPosPixel();
1889 0 : aPos.Y() -= nDeltaY;
1890 0 : aLinguDicsNewPB.SetPosPixel( aPos );
1891 0 : aPos = aLinguDicsEditPB.GetPosPixel();
1892 0 : aPos.Y() -= nDeltaY;
1893 0 : aLinguDicsEditPB.SetPosPixel( aPos );
1894 0 : aPos = aLinguDicsDelPB.GetPosPixel();
1895 0 : aPos.Y() -= nDeltaY;
1896 0 : aLinguDicsDelPB.SetPosPixel( aPos );
1897 :
1898 0 : aPos = aLinguOptionsFT.GetPosPixel();
1899 0 : aPos.Y() -= nDeltaY;
1900 0 : aLinguOptionsFT.SetPosPixel( aPos );
1901 0 : aPos = aLinguOptionsCLB.GetPosPixel();
1902 0 : aPos.Y() -= nDeltaY;
1903 0 : aLinguOptionsCLB.SetPosPixel( aPos );
1904 0 : aPos = aLinguOptionsEditPB.GetPosPixel();
1905 0 : aPos.Y() -= nDeltaY;
1906 0 : aLinguOptionsEditPB.SetPosPixel( aPos );
1907 :
1908 0 : Size aSize( aLinguOptionsCLB.GetSizePixel() );
1909 0 : aSize.Height() += nDeltaY;
1910 0 : aLinguOptionsCLB.SetSizePixel( aSize );
1911 :
1912 0 : if ( SvtExtendedSecurityOptions().GetOpenHyperlinkMode()
1913 : != SvtExtendedSecurityOptions::OPEN_NEVER )
1914 : {
1915 0 : aSize = GetOutputSizePixel();
1916 0 : aSize.Height() += ( aMoreDictsLink.GetSizePixel().Height() * 11 / 8 );
1917 0 : SetSizePixel( aSize );
1918 0 : aMoreDictsLink.Show();
1919 : }
1920 : }
1921 0 : }
1922 :
1923 0 : SvxEditModulesDlg::SvxEditModulesDlg(Window* pParent, SvxLinguData_Impl& rData) :
1924 0 : ModalDialog( pParent, CUI_RES(RID_SVXDLG_EDIT_MODULES ) ),
1925 0 : aModulesFL ( this, CUI_RES( FL_EDIT_MODULES_OPTIONS ) ),
1926 0 : aLanguageFT ( this, CUI_RES( FT_EDIT_MODULES_LANGUAGE ) ),
1927 0 : aLanguageLB ( this, CUI_RES( LB_EDIT_MODULES_LANGUAGE ), sal_False ),
1928 0 : aModulesCLB ( this, CUI_RES( CLB_EDIT_MODULES_MODULES ) ),
1929 0 : aPrioUpPB ( this, CUI_RES( PB_EDIT_MODULES_PRIO_UP ) ),
1930 0 : aPrioDownPB ( this, CUI_RES( PB_EDIT_MODULES_PRIO_DOWN ) ),
1931 0 : aBackPB ( this, CUI_RES( PB_EDIT_MODULES_PRIO_BACK ) ),
1932 0 : aMoreDictsLink ( this, CUI_RES( FT_EDIT_MODULES_NEWDICTSLINK ) ),
1933 0 : aButtonsFL ( this, CUI_RES( FL_EDIT_MODULES_BUTTONS ) ),
1934 0 : aHelpPB ( this, CUI_RES( PB_HELP ) ),
1935 0 : aClosePB ( this, CUI_RES( PB_OK ) ),
1936 0 : sSpell ( CUI_RES( ST_SPELL ) ),
1937 0 : sHyph ( CUI_RES( ST_HYPH ) ),
1938 0 : sThes ( CUI_RES( ST_THES ) ),
1939 0 : sGrammar ( CUI_RES( ST_GRAMMAR ) ),
1940 0 : rLinguData ( rData )
1941 : {
1942 0 : pCheckButtonData = NULL;
1943 0 : FreeResource();
1944 :
1945 0 : pDefaultLinguData = new SvxLinguData_Impl( rLinguData );
1946 :
1947 0 : aModulesCLB.SetStyle( aModulesCLB.GetStyle()|WB_CLIPCHILDREN|WB_HSCROLL|WB_FORCE_MAKEVISIBLE );
1948 0 : aModulesCLB.SetHighlightRange();
1949 0 : aModulesCLB.SetHelpId(HID_CLB_EDIT_MODULES_MODULES );
1950 0 : aModulesCLB.SetSelectHdl( LINK( this, SvxEditModulesDlg, SelectHdl_Impl ));
1951 0 : aModulesCLB.SetCheckButtonHdl( LINK( this, SvxEditModulesDlg, BoxCheckButtonHdl_Impl) );
1952 :
1953 0 : aClosePB .SetClickHdl( LINK( this, SvxEditModulesDlg, ClickHdl_Impl ));
1954 0 : aPrioUpPB .SetClickHdl( LINK( this, SvxEditModulesDlg, UpDownHdl_Impl ));
1955 0 : aPrioDownPB.SetClickHdl( LINK( this, SvxEditModulesDlg, UpDownHdl_Impl ));
1956 0 : aBackPB .SetClickHdl( LINK( this, SvxEditModulesDlg, BackHdl_Impl ));
1957 : // in case of not installed language modules
1958 0 : aPrioUpPB .Enable( sal_False );
1959 0 : aPrioDownPB.Enable( sal_False );
1960 :
1961 0 : if ( SvtExtendedSecurityOptions().GetOpenHyperlinkMode()
1962 : != SvtExtendedSecurityOptions::OPEN_NEVER )
1963 : {
1964 : aMoreDictsLink.SetURL( String(
1965 0 : RTL_CONSTASCII_USTRINGPARAM( "http://extensions.libreoffice.org/dictionaries/" ) ) );
1966 0 : aMoreDictsLink.SetClickHdl( LINK( this, SvxEditModulesDlg, OpenURLHdl_Impl ) );
1967 : }
1968 : else
1969 : {
1970 0 : aMoreDictsLink.Hide();
1971 0 : long nPos = aMoreDictsLink.GetPosPixel().Y() + aMoreDictsLink.GetSizePixel().Height();
1972 0 : Size aSize = aModulesCLB.GetSizePixel();
1973 0 : aSize.Height() += ( nPos - ( aModulesCLB.GetPosPixel().Y() + aSize.Height() ) );
1974 0 : aModulesCLB.SetSizePixel( aSize );
1975 : }
1976 :
1977 : //
1978 : //fill language box
1979 : //
1980 0 : Sequence< sal_Int16 > aAvailLang;
1981 0 : uno::Reference< XAvailableLocales > xAvail( rLinguData.GetManager(), UNO_QUERY );
1982 0 : if (xAvail.is())
1983 : {
1984 : aAvailLang = lcl_LocaleSeqToLangSeq(
1985 0 : xAvail->getAvailableLocales( cSpell ) );
1986 : }
1987 0 : const Sequence< Locale >& rLoc = rLinguData.GetAllSupportedLocales();
1988 0 : const Locale* pLocales = rLoc.getConstArray();
1989 0 : aLanguageLB.Clear();
1990 0 : for(long i = 0; i < rLoc.getLength(); i++)
1991 : {
1992 0 : sal_Int16 nLang = LanguageTag( pLocales[i] ).getLanguageType();
1993 0 : aLanguageLB.InsertLanguage( nLang, lcl_SeqHasLang( aAvailLang, nLang ) );
1994 : }
1995 0 : LanguageType eSysLang = MsLangId::getSystemLanguage();
1996 0 : aLanguageLB.SelectLanguage( eSysLang );
1997 0 : if(!aLanguageLB.IsLanguageSelected( eSysLang ) )
1998 0 : aLanguageLB.SelectEntryPos(0);
1999 :
2000 0 : aLanguageLB.SetSelectHdl( LINK( this, SvxEditModulesDlg, LangSelectHdl_Impl ));
2001 0 : LangSelectHdl_Impl(&aLanguageLB);
2002 0 : }
2003 :
2004 :
2005 0 : SvxEditModulesDlg::~SvxEditModulesDlg()
2006 : {
2007 0 : delete pDefaultLinguData;
2008 0 : }
2009 :
2010 :
2011 0 : SvTreeListEntry* SvxEditModulesDlg::CreateEntry( String& rTxt, sal_uInt16 nCol )
2012 : {
2013 0 : SvTreeListEntry* pEntry = new SvTreeListEntry;
2014 0 : if( !pCheckButtonData )
2015 : {
2016 0 : pCheckButtonData = new SvLBoxButtonData( &aModulesCLB );
2017 0 : pCheckButtonData->SetLink( aModulesCLB.GetCheckButtonHdl() );
2018 : }
2019 :
2020 0 : String sEmpty;
2021 0 : if (CBCOL_FIRST == nCol)
2022 0 : pEntry->AddItem( new SvLBoxButton( pEntry, SvLBoxButtonKind_enabledCheckbox, 0, pCheckButtonData ) );
2023 0 : if (CBCOL_SECOND == nCol)
2024 0 : pEntry->AddItem( new SvLBoxString( pEntry, 0, sEmpty) ); // empty column
2025 0 : pEntry->AddItem( new SvLBoxContextBmp( pEntry, 0, Image(), Image(), 0));
2026 0 : pEntry->AddItem( new BrwStringDic_Impl( pEntry, 0, rTxt ) );
2027 :
2028 0 : return pEntry;
2029 : }
2030 :
2031 0 : IMPL_LINK( SvxEditModulesDlg, SelectHdl_Impl, SvxCheckListBox *, pBox )
2032 : {
2033 0 : if (&aModulesCLB == pBox)
2034 : {
2035 0 : sal_Bool bDisableUp = sal_True;
2036 0 : sal_Bool bDisableDown = sal_True;
2037 0 : SvTreeListEntry *pEntry = pBox->GetCurEntry();
2038 0 : if (pEntry)
2039 : {
2040 0 : ModuleUserData_Impl* pData = (ModuleUserData_Impl*)pEntry->GetUserData();
2041 0 : if(!pData->IsParent() && pData->GetType() != TYPE_HYPH)
2042 : {
2043 0 : sal_uInt16 nCurPos = pBox->GetSelectEntryPos();
2044 0 : if(nCurPos < pBox->GetEntryCount() - 1)
2045 : {
2046 : bDisableDown = ((ModuleUserData_Impl*)pBox->
2047 0 : GetEntry(nCurPos + 1)->GetUserData())->IsParent();
2048 : }
2049 0 : if(nCurPos > 1)
2050 : {
2051 : bDisableUp = ((ModuleUserData_Impl*)pBox->
2052 0 : GetEntry(nCurPos - 1)->GetUserData())->IsParent();
2053 : }
2054 : }
2055 0 : aPrioUpPB.Enable(!bDisableUp);
2056 0 : aPrioDownPB.Enable(!bDisableDown);
2057 : }
2058 : }
2059 : else
2060 : {
2061 : OSL_FAIL( "pBox unexpected value" );
2062 : }
2063 :
2064 0 : return 0;
2065 : }
2066 :
2067 0 : IMPL_LINK( SvxEditModulesDlg, BoxCheckButtonHdl_Impl, SvTreeListBox *, pBox )
2068 : {
2069 0 : pBox = &aModulesCLB;
2070 0 : SvTreeListEntry *pCurEntry = pBox->GetCurEntry();
2071 0 : if (pCurEntry)
2072 : {
2073 : ModuleUserData_Impl* pData = (ModuleUserData_Impl *)
2074 0 : pCurEntry->GetUserData();
2075 0 : if (!pData->IsParent() && pData->GetType() == TYPE_HYPH)
2076 : {
2077 : // make hyphenator checkboxes function as radio-buttons
2078 : // (at most one box may be checked)
2079 0 : SvTreeListEntry *pEntry = pBox->First();
2080 0 : while (pEntry)
2081 : {
2082 0 : pData = (ModuleUserData_Impl *) pEntry->GetUserData();
2083 0 : if (!pData->IsParent() &&
2084 0 : pData->GetType() == TYPE_HYPH &&
2085 : pEntry != pCurEntry)
2086 : {
2087 0 : lcl_SetCheckButton( pEntry, sal_False );
2088 0 : pBox->InvalidateEntry( pEntry );
2089 : }
2090 0 : pEntry = pBox->Next( pEntry );
2091 : }
2092 : }
2093 : }
2094 0 : return 0;
2095 : }
2096 :
2097 0 : IMPL_LINK( SvxEditModulesDlg, LangSelectHdl_Impl, ListBox *, pBox )
2098 : {
2099 0 : LanguageType eCurLanguage = aLanguageLB.GetSelectLanguage();
2100 0 : static Locale aLastLocale;
2101 0 : Locale aCurLocale( LanguageTag( eCurLanguage).getLocale());
2102 0 : SvTreeList *pModel = aModulesCLB.GetModel();
2103 :
2104 0 : if (pBox)
2105 : {
2106 : // save old probably changed settings
2107 : // before switching to new language entries
2108 :
2109 0 : sal_Int16 nLang = LanguageTag( aLastLocale ).getLanguageType();
2110 :
2111 0 : sal_Int32 nStart = 0, nLocalIndex = 0;
2112 0 : Sequence< OUString > aChange;
2113 0 : sal_Bool bChanged = sal_False;
2114 0 : for(sal_uInt16 i = 0; i < aModulesCLB.GetEntryCount(); i++)
2115 : {
2116 0 : SvTreeListEntry *pEntry = aModulesCLB.GetEntry(i);
2117 0 : ModuleUserData_Impl* pData = (ModuleUserData_Impl*)pEntry->GetUserData();
2118 0 : if(pData->IsParent())
2119 : {
2120 0 : if(bChanged)
2121 : {
2122 0 : LangImplNameTable *pTable = 0;
2123 0 : sal_uInt8 nType = pData->GetType();
2124 0 : switch (nType - 1)
2125 : {
2126 0 : case TYPE_SPELL : pTable = &rLinguData.GetSpellTable(); break;
2127 0 : case TYPE_GRAMMAR : pTable = &rLinguData.GetGrammarTable(); break;
2128 0 : case TYPE_HYPH : pTable = &rLinguData.GetHyphTable(); break;
2129 0 : case TYPE_THES : pTable = &rLinguData.GetThesTable(); break;
2130 : }
2131 0 : if (pTable)
2132 : {
2133 0 : aChange.realloc(nStart);
2134 0 : (*pTable)[ nLang ] = aChange;
2135 : }
2136 : }
2137 0 : nLocalIndex = nStart = 0;
2138 0 : aChange.realloc(aModulesCLB.GetEntryCount());
2139 0 : bChanged = sal_False;
2140 : }
2141 : else
2142 : {
2143 0 : OUString* pChange = aChange.getArray();
2144 0 : pChange[nStart] = pData->GetImplName();
2145 0 : bChanged |= pData->GetIndex() != nLocalIndex ||
2146 0 : pData->IsChecked() != aModulesCLB.IsChecked(i);
2147 0 : if(aModulesCLB.IsChecked(i))
2148 0 : nStart++;
2149 0 : ++nLocalIndex;
2150 : }
2151 : }
2152 0 : if(bChanged)
2153 : {
2154 0 : aChange.realloc(nStart);
2155 0 : rLinguData.GetThesTable()[ nLang ] = aChange;
2156 0 : }
2157 : }
2158 :
2159 0 : for(sal_uLong i = 0; i < aModulesCLB.GetEntryCount(); i++)
2160 0 : delete (ModuleUserData_Impl*)aModulesCLB.GetEntry(i)->GetUserData();
2161 :
2162 : //
2163 : // display entries for new selected language
2164 : //
2165 0 : aModulesCLB.Clear();
2166 0 : if(LANGUAGE_DONTKNOW != eCurLanguage)
2167 : {
2168 : sal_uLong n;
2169 : ServiceInfo_Impl* pInfo;
2170 :
2171 : //
2172 : // spellchecker entries
2173 : //
2174 0 : SvTreeListEntry* pEntry = CreateEntry( sSpell, CBCOL_SECOND );
2175 : ModuleUserData_Impl* pUserData = new ModuleUserData_Impl(
2176 0 : String(), sal_True, sal_False, TYPE_SPELL, 0 );
2177 0 : pEntry->SetUserData( (void *)pUserData );
2178 0 : pModel->Insert( pEntry );
2179 :
2180 0 : Sequence< OUString > aNames( rLinguData.GetSortedImplNames( eCurLanguage, TYPE_SPELL ) );
2181 0 : const OUString *pName = aNames.getConstArray();
2182 0 : sal_uLong nNames = (sal_uLong) aNames.getLength();
2183 0 : sal_Int32 nLocalIndex = 0; // index relative to parent
2184 0 : for (n = 0; n < nNames; ++n)
2185 : {
2186 0 : OUString aImplName;
2187 0 : sal_Bool bIsSuppLang = sal_False;
2188 :
2189 0 : pInfo = rLinguData.GetInfoByImplName( pName[n] );
2190 0 : if (pInfo)
2191 : {
2192 0 : bIsSuppLang = pInfo->xSpell.is() &&
2193 0 : pInfo->xSpell->hasLocale( aCurLocale );
2194 0 : aImplName = pInfo->sSpellImplName;
2195 : }
2196 0 : if (!aImplName.isEmpty() && bIsSuppLang)
2197 : {
2198 0 : String aTxt( pInfo->sDisplayName );
2199 0 : SvTreeListEntry* pNewEntry = CreateEntry( aTxt, CBCOL_FIRST );
2200 :
2201 0 : LangImplNameTable &rTable = rLinguData.GetSpellTable();
2202 0 : const bool bHasLang = rTable.count( eCurLanguage );
2203 0 : if (!bHasLang)
2204 : {
2205 : DBG_WARNING( "language entry missing" ); // only relevant if all languages found should be supported
2206 : }
2207 0 : const bool bCheck = bHasLang && lcl_SeqGetEntryPos( rTable[ eCurLanguage ], aImplName ) >= 0;
2208 0 : lcl_SetCheckButton( pNewEntry, bCheck );
2209 : pUserData = new ModuleUserData_Impl( aImplName, sal_False,
2210 0 : bCheck, TYPE_SPELL, (sal_uInt8)nLocalIndex++ );
2211 0 : pNewEntry->SetUserData( (void *)pUserData );
2212 0 : pModel->Insert( pNewEntry );
2213 : }
2214 0 : }
2215 :
2216 : //
2217 : // grammar checker entries
2218 : //
2219 0 : pEntry = CreateEntry( sGrammar, CBCOL_SECOND );
2220 0 : pUserData = new ModuleUserData_Impl( String(), sal_True, sal_False, TYPE_GRAMMAR, 0 );
2221 0 : pEntry->SetUserData( (void *)pUserData );
2222 0 : pModel->Insert( pEntry );
2223 :
2224 0 : aNames = rLinguData.GetSortedImplNames( eCurLanguage, TYPE_GRAMMAR );
2225 0 : pName = aNames.getConstArray();
2226 0 : nNames = (sal_uLong) aNames.getLength();
2227 0 : nLocalIndex = 0;
2228 0 : for (n = 0; n < nNames; ++n)
2229 : {
2230 0 : OUString aImplName;
2231 0 : sal_Bool bIsSuppLang = sal_False;
2232 :
2233 0 : pInfo = rLinguData.GetInfoByImplName( pName[n] );
2234 0 : if (pInfo)
2235 : {
2236 0 : bIsSuppLang = pInfo->xGrammar.is() &&
2237 0 : pInfo->xGrammar->hasLocale( aCurLocale );
2238 0 : aImplName = pInfo->sGrammarImplName;
2239 : }
2240 0 : if (!aImplName.isEmpty() && bIsSuppLang)
2241 : {
2242 0 : String aTxt( pInfo->sDisplayName );
2243 0 : SvTreeListEntry* pNewEntry = CreateEntry( aTxt, CBCOL_FIRST );
2244 :
2245 0 : LangImplNameTable &rTable = rLinguData.GetGrammarTable();
2246 0 : const bool bHasLang = rTable.count( eCurLanguage );
2247 0 : if (!bHasLang)
2248 : {
2249 : DBG_WARNING( "language entry missing" ); // only relevant if all languages found should be supported
2250 : }
2251 0 : const bool bCheck = bHasLang && lcl_SeqGetEntryPos( rTable[ eCurLanguage ], aImplName ) >= 0;
2252 0 : lcl_SetCheckButton( pNewEntry, bCheck );
2253 : pUserData = new ModuleUserData_Impl( aImplName, sal_False,
2254 0 : bCheck, TYPE_GRAMMAR, (sal_uInt8)nLocalIndex++ );
2255 0 : pNewEntry->SetUserData( (void *)pUserData );
2256 0 : pModel->Insert( pNewEntry );
2257 : }
2258 0 : }
2259 :
2260 : //
2261 : // hyphenator entries
2262 : //
2263 0 : pEntry = CreateEntry( sHyph, CBCOL_SECOND );
2264 0 : pUserData = new ModuleUserData_Impl( String(), sal_True, sal_False, TYPE_HYPH, 0 );
2265 0 : pEntry->SetUserData( (void *)pUserData );
2266 0 : pModel->Insert( pEntry );
2267 :
2268 0 : aNames = rLinguData.GetSortedImplNames( eCurLanguage, TYPE_HYPH );
2269 0 : pName = aNames.getConstArray();
2270 0 : nNames = (sal_uLong) aNames.getLength();
2271 0 : nLocalIndex = 0;
2272 0 : for (n = 0; n < nNames; ++n)
2273 : {
2274 0 : OUString aImplName;
2275 0 : sal_Bool bIsSuppLang = sal_False;
2276 :
2277 0 : pInfo = rLinguData.GetInfoByImplName( pName[n] );
2278 0 : if (pInfo)
2279 : {
2280 0 : bIsSuppLang = pInfo->xHyph.is() &&
2281 0 : pInfo->xHyph->hasLocale( aCurLocale );
2282 0 : aImplName = pInfo->sHyphImplName;
2283 : }
2284 0 : if (!aImplName.isEmpty() && bIsSuppLang)
2285 : {
2286 0 : String aTxt( pInfo->sDisplayName );
2287 0 : SvTreeListEntry* pNewEntry = CreateEntry( aTxt, CBCOL_FIRST );
2288 :
2289 0 : LangImplNameTable &rTable = rLinguData.GetHyphTable();
2290 0 : const bool bHasLang = rTable.count( eCurLanguage );
2291 0 : if (!bHasLang)
2292 : {
2293 : DBG_WARNING( "language entry missing" ); // only relevant if all languages found should be supported
2294 : }
2295 0 : const bool bCheck = bHasLang && lcl_SeqGetEntryPos( rTable[ eCurLanguage ], aImplName ) >= 0;
2296 0 : lcl_SetCheckButton( pNewEntry, bCheck );
2297 : pUserData = new ModuleUserData_Impl( aImplName, sal_False,
2298 0 : bCheck, TYPE_HYPH, (sal_uInt8)nLocalIndex++ );
2299 0 : pNewEntry->SetUserData( (void *)pUserData );
2300 0 : pModel->Insert( pNewEntry );
2301 : }
2302 0 : }
2303 :
2304 : //
2305 : // thesaurus entries
2306 : //
2307 0 : pEntry = CreateEntry( sThes, CBCOL_SECOND );
2308 0 : pUserData = new ModuleUserData_Impl( String(), sal_True, sal_False, TYPE_THES, 0 );
2309 0 : pEntry->SetUserData( (void *)pUserData );
2310 0 : pModel->Insert( pEntry );
2311 :
2312 0 : aNames = rLinguData.GetSortedImplNames( eCurLanguage, TYPE_THES );
2313 0 : pName = aNames.getConstArray();
2314 0 : nNames = (sal_uLong) aNames.getLength();
2315 0 : nLocalIndex = 0;
2316 0 : for (n = 0; n < nNames; ++n)
2317 : {
2318 0 : OUString aImplName;
2319 0 : sal_Bool bIsSuppLang = sal_False;
2320 :
2321 0 : pInfo = rLinguData.GetInfoByImplName( pName[n] );
2322 0 : if (pInfo)
2323 : {
2324 0 : bIsSuppLang = pInfo->xThes.is() &&
2325 0 : pInfo->xThes->hasLocale( aCurLocale );
2326 0 : aImplName = pInfo->sThesImplName;
2327 : }
2328 0 : if (!aImplName.isEmpty() && bIsSuppLang)
2329 : {
2330 0 : String aTxt( pInfo->sDisplayName );
2331 0 : SvTreeListEntry* pNewEntry = CreateEntry( aTxt, CBCOL_FIRST );
2332 :
2333 0 : LangImplNameTable &rTable = rLinguData.GetThesTable();
2334 0 : const bool bHasLang = rTable.count( eCurLanguage );
2335 0 : if (!bHasLang)
2336 : {
2337 : DBG_WARNING( "language entry missing" ); // only relevant if all languages found should be supported
2338 : }
2339 0 : const bool bCheck = bHasLang && lcl_SeqGetEntryPos( rTable[ eCurLanguage ], aImplName ) >= 0;
2340 0 : lcl_SetCheckButton( pNewEntry, bCheck );
2341 : pUserData = new ModuleUserData_Impl( aImplName, sal_False,
2342 0 : bCheck, TYPE_THES, (sal_uInt8)nLocalIndex++ );
2343 0 : pNewEntry->SetUserData( (void *)pUserData );
2344 0 : pModel->Insert( pNewEntry );
2345 : }
2346 0 : }
2347 : }
2348 0 : aLastLocale = aCurLocale;
2349 0 : return 0;
2350 : }
2351 :
2352 0 : IMPL_LINK( SvxEditModulesDlg, UpDownHdl_Impl, PushButton *, pBtn )
2353 : {
2354 0 : sal_Bool bUp = &aPrioUpPB == pBtn;
2355 0 : sal_uInt16 nCurPos = aModulesCLB.GetSelectEntryPos();
2356 : SvTreeListEntry* pEntry;
2357 0 : if (nCurPos != LISTBOX_ENTRY_NOTFOUND &&
2358 0 : 0 != (pEntry = aModulesCLB.GetEntry(nCurPos)))
2359 : {
2360 0 : aModulesCLB.SetUpdateMode(sal_False);
2361 0 : SvTreeList *pModel = aModulesCLB.GetModel();
2362 :
2363 0 : ModuleUserData_Impl* pData = (ModuleUserData_Impl*)pEntry->GetUserData();
2364 0 : String aStr(aModulesCLB.GetEntryText(pEntry));
2365 0 : SvTreeListEntry* pToInsert = CreateEntry( aStr, CBCOL_FIRST );
2366 0 : pToInsert->SetUserData( (void *)pData);
2367 0 : sal_Bool bIsChecked = aModulesCLB.IsChecked(nCurPos);
2368 :
2369 0 : pModel->Remove(pEntry);
2370 :
2371 0 : sal_uInt16 nDestPos = bUp ? nCurPos - 1 : nCurPos + 1;
2372 0 : pModel->Insert(pToInsert, nDestPos);
2373 0 : aModulesCLB.CheckEntryPos(nDestPos, bIsChecked );
2374 0 : aModulesCLB.SelectEntryPos(nDestPos );
2375 0 : SelectHdl_Impl(&aModulesCLB);
2376 0 : aModulesCLB.SetUpdateMode(sal_True);
2377 : }
2378 0 : return 0;
2379 : }
2380 :
2381 0 : IMPL_LINK( SvxEditModulesDlg, ClickHdl_Impl, PushButton *, pBtn )
2382 : {
2383 0 : if (&aClosePB == pBtn)
2384 : {
2385 : // store language config
2386 0 : LangSelectHdl_Impl(&aLanguageLB);
2387 0 : EndDialog( RET_OK );
2388 : }
2389 : else
2390 : {
2391 : OSL_FAIL( "pBtn unexpected value" );
2392 : }
2393 :
2394 0 : return 0;
2395 : }
2396 :
2397 0 : IMPL_LINK_NOARG(SvxEditModulesDlg, BackHdl_Impl)
2398 : {
2399 0 : rLinguData = *pDefaultLinguData;
2400 0 : LangSelectHdl_Impl(0);
2401 0 : return 0;
2402 : }
2403 :
2404 : // -----------------------------------------------------------------------
2405 :
2406 0 : IMPL_LINK_NOARG(SvxEditModulesDlg, OpenURLHdl_Impl)
2407 : {
2408 0 : ::rtl::OUString sURL( aMoreDictsLink.GetURL() );
2409 0 : lcl_OpenURL( sURL );
2410 0 : return 0;
2411 3 : }
2412 :
2413 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|