xref: /AOO41X/main/cui/source/options/optlingu.cxx (revision 96c859818fb8eeeaba8481e542767a5a41a12dec)
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" ) ) );
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" ) ) );
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