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