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