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