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