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