1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: langbox.cxx,v $
10 * $Revision: 1.25.132.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
34 // include ---------------------------------------------------------------
36 #ifndef _COM_SUN_STAR_LINGUISTIC2_XLINGUSERVICEMANAGER_HDL_
37 #include <com/sun/star/linguistic2/XLinguServiceManager.hdl>
39 #include <com/sun/star/linguistic2/XAvailableLocales.hpp>
40 #include <com/sun/star/i18n/ScriptType.hpp>
41 #include <linguistic/misc.hxx>
42 #include <rtl/ustring.hxx>
43 #include <unotools/localedatawrapper.hxx>
45 #include <svtools/langtab.hxx>
46 #include <tools/shl.hxx>
47 #include <i18npool/mslangid.hxx>
48 #include <i18npool/lang.h>
49 #include <svx/scripttypeitem.hxx>
50 #include <unolingu.hxx>
51 #include <svx/langbox.hxx>
52 #include <svx/dialmgr.hxx>
53 #include <svx/dialogs.hrc>
55 using namespace ::com::sun::star::util
;
56 using namespace ::com::sun::star::lang
;
57 using namespace ::com::sun::star::linguistic2
;
58 using namespace ::com::sun::star::uno
;
61 //========================================================================
62 // misc local helper functions
63 //========================================================================
67 static Sequence
< INT16
> lcl_LocaleSeqToLangSeq( Sequence
< Locale
> &rSeq
)
69 const Locale
*pLocale
= rSeq
.getConstArray();
70 INT32 nCount
= rSeq
.getLength();
72 Sequence
< INT16
> aLangs( nCount
);
73 INT16
*pLang
= aLangs
.getArray();
74 for (INT32 i
= 0; i
< nCount
; ++i
)
76 pLang
[i
] = SvxLocaleToLanguage( pLocale
[i
] );
84 static BOOL
lcl_SeqHasLang( const Sequence
< INT16
> & rLangSeq
, INT16 nLang
)
87 INT32 nLen
= rLangSeq
.getLength();
90 const INT16
*pLang
= rLangSeq
.getConstArray();
91 for (i
= 0; i
< nLen
; ++i
)
93 if (nLang
== pLang
[i
])
97 return i
>= 0 && i
< nLen
;
100 //========================================================================
101 // class SvxLanguageBox
102 //========================================================================
104 USHORT
TypeToPos_Impl( LanguageType eType
, const ListBox
& rLb
)
106 USHORT nPos
= LISTBOX_ENTRY_NOTFOUND
;
107 USHORT nCount
= rLb
.GetEntryCount();
109 for ( USHORT i
=0; nPos
== LISTBOX_ENTRY_NOTFOUND
&& i
<nCount
; i
++ )
110 if ( eType
== LanguageType((ULONG
)rLb
.GetEntryData(i
)) )
116 //-----------------------------------------------------------------------
117 SvxLanguageBox::SvxLanguageBox( Window
* pParent
, WinBits nWinStyle
, BOOL bCheck
) :
118 ListBox( pParent
, nWinStyle
),
119 m_pSpellUsedLang( NULL
),
120 m_bWithCheckmark( bCheck
)
124 //------------------------------------------------------------------------
125 SvxLanguageBox::SvxLanguageBox( Window
* pParent
, const ResId
& rResId
, BOOL bCheck
) :
126 ListBox( pParent
, rResId
),
127 m_pSpellUsedLang( NULL
),
128 m_bWithCheckmark( bCheck
)
132 //------------------------------------------------------------------------
133 void SvxLanguageBox::Init()
135 m_pLangTable
= new SvtLanguageTable
;
136 m_aNotCheckedImage
= Image( SVX_RES( RID_SVXIMG_NOTCHECKED
) );
137 m_aCheckedImage
= Image( SVX_RES( RID_SVXIMG_CHECKED
) );
138 m_aCheckedImageHC
= Image( SVX_RES( RID_SVXIMG_CHECKED_H
) );
139 m_aAllString
= String( SVX_RESSTR( RID_SVXSTR_LANGUAGE_ALL
) );
140 m_nLangList
= LANG_LIST_EMPTY
;
141 m_bHasLangNone
= FALSE
;
142 m_bLangNoneIsLangAll
= FALSE
;
144 // display entries sorted
145 SetStyle( GetStyle() | WB_SORT
);
147 if ( m_bWithCheckmark
)
149 SvtLanguageTable aLangTable
;
150 sal_uInt32 nCount
= aLangTable
.GetEntryCount();
151 for ( sal_uInt32 i
= 0; i
< nCount
; i
++ )
153 LanguageType nLangType
= aLangTable
.GetTypeAtIndex( i
);
156 if ((LANGUAGE_DONTKNOW
== nLangType
) ||
157 (LANGUAGE_SYSTEM
== nLangType
) ||
158 (LANGUAGE_USER1
<= nLangType
&& nLangType
<= LANGUAGE_USER9
))
164 InsertLanguage( nLangType
);
166 m_nLangList
= LANG_LIST_ALL
;
169 //------------------------------------------------------------------------
171 SvxLanguageBox::~SvxLanguageBox()
173 delete m_pSpellUsedLang
;
177 //------------------------------------------------------------------------
179 USHORT
SvxLanguageBox::ImplInsertImgEntry( const String
& rEntry
, USHORT nPos
, bool bChecked
)
183 nRet
= InsertEntry( rEntry
, m_aNotCheckedImage
, nPos
);
184 else if( GetSettings().GetStyleSettings().GetFaceColor().IsDark() )
185 nRet
= InsertEntry( rEntry
, m_aCheckedImageHC
, nPos
);
187 nRet
= InsertEntry( rEntry
, m_aCheckedImage
, nPos
);
191 //------------------------------------------------------------------------
193 void SvxLanguageBox::SetLanguageList( INT16 nLangList
,
194 BOOL bHasLangNone
, BOOL bLangNoneIsLangAll
, BOOL bCheckSpellAvail
)
198 m_nLangList
= nLangList
;
199 m_bHasLangNone
= bHasLangNone
;
200 m_bLangNoneIsLangAll
= bLangNoneIsLangAll
;
201 m_bWithCheckmark
= bCheckSpellAvail
;
203 if ( LANG_LIST_EMPTY
!= nLangList
)
205 Sequence
< INT16
> aSpellAvailLang
;
206 Sequence
< INT16
> aHyphAvailLang
;
207 Sequence
< INT16
> aThesAvailLang
;
208 Sequence
< INT16
> aSpellUsedLang
;
209 Sequence
< INT16
> aHyphUsedLang
;
210 Sequence
< INT16
> aThesUsedLang
;
211 Reference
< XAvailableLocales
> xAvail( LinguMgr::GetLngSvcMgr(), UNO_QUERY
);
214 Sequence
< Locale
> aTmp
;
216 if (LANG_LIST_SPELL_AVAIL
& nLangList
)
218 aTmp
= xAvail
->getAvailableLocales( A2OU( SN_SPELLCHECKER
) );
219 aSpellAvailLang
= lcl_LocaleSeqToLangSeq( aTmp
);
221 if (LANG_LIST_HYPH_AVAIL
& nLangList
)
223 aTmp
= xAvail
->getAvailableLocales( A2OU( SN_HYPHENATOR
) );
224 aHyphAvailLang
= lcl_LocaleSeqToLangSeq( aTmp
);
226 if (LANG_LIST_THES_AVAIL
& nLangList
)
228 aTmp
= xAvail
->getAvailableLocales( A2OU( SN_THESAURUS
) );
229 aThesAvailLang
= lcl_LocaleSeqToLangSeq( aTmp
);
232 if (LANG_LIST_SPELL_USED
& nLangList
)
234 Reference
< XSpellChecker1
> xTmp1( SvxGetSpellChecker(), UNO_QUERY
);
236 aSpellUsedLang
= xTmp1
->getLanguages();
238 if (LANG_LIST_HYPH_USED
& nLangList
)
240 Reference
< XHyphenator
> xTmp( SvxGetHyphenator() );
242 Sequence
< Locale
> aLocaleSequence( xTmp
->getLocales() );
243 aHyphUsedLang
= lcl_LocaleSeqToLangSeq( aLocaleSequence
);
246 if (LANG_LIST_THES_USED
& nLangList
)
248 Reference
< XThesaurus
> xTmp( SvxGetThesaurus() );
250 Sequence
< Locale
> aLocaleSequence( xTmp
->getLocales() );
251 aThesUsedLang
= lcl_LocaleSeqToLangSeq( aLocaleSequence
);
255 SvtLanguageTable aLangTable
;
256 ::com::sun::star::uno::Sequence
< sal_uInt16
> xKnown
;
257 const sal_uInt16
* pKnown
;
259 if ( nLangList
& LANG_LIST_ONLY_KNOWN
)
261 xKnown
= LocaleDataWrapper::getInstalledLanguageTypes();
262 pKnown
= xKnown
.getConstArray();
263 nCount
= xKnown
.getLength();
267 nCount
= aLangTable
.GetEntryCount();
270 for ( sal_uInt32 i
= 0; i
< nCount
; i
++ )
272 LanguageType nLangType
;
273 if ( nLangList
& LANG_LIST_ONLY_KNOWN
)
274 nLangType
= pKnown
[i
];
276 nLangType
= aLangTable
.GetTypeAtIndex( i
);
277 if ( nLangType
!= LANGUAGE_DONTKNOW
&&
278 nLangType
!= LANGUAGE_SYSTEM
&&
279 nLangType
!= LANGUAGE_NONE
&&
280 (nLangType
< LANGUAGE_USER1
|| nLangType
> LANGUAGE_USER9
) &&
281 (MsLangId::getSubLanguage( nLangType
) != 0 ||
282 (nLangList
& LANG_LIST_ALSO_PRIMARY_ONLY
)) &&
283 ((nLangList
& LANG_LIST_ALL
) != 0 ||
284 ((nLangList
& LANG_LIST_WESTERN
) != 0 &&
285 (SvtLanguageOptions::GetScriptTypeOfLanguage(nLangType
) ==
286 SCRIPTTYPE_LATIN
)) ||
287 ((nLangList
& LANG_LIST_CTL
) != 0 &&
288 (SvtLanguageOptions::GetScriptTypeOfLanguage(nLangType
) ==
289 SCRIPTTYPE_COMPLEX
)) ||
290 ((nLangList
& LANG_LIST_CJK
) != 0 &&
291 (SvtLanguageOptions::GetScriptTypeOfLanguage(nLangType
) ==
292 SCRIPTTYPE_ASIAN
)) ||
293 ((nLangList
& LANG_LIST_FBD_CHARS
) != 0 &&
294 MsLangId::hasForbiddenCharacters(nLangType
)) ||
295 ((nLangList
& LANG_LIST_SPELL_AVAIL
) != 0 &&
296 lcl_SeqHasLang(aSpellAvailLang
, nLangType
)) ||
297 ((nLangList
& LANG_LIST_HYPH_AVAIL
) != 0 &&
298 lcl_SeqHasLang(aHyphAvailLang
, nLangType
)) ||
299 ((nLangList
& LANG_LIST_THES_AVAIL
) != 0 &&
300 lcl_SeqHasLang(aThesAvailLang
, nLangType
)) ||
301 ((nLangList
& LANG_LIST_SPELL_USED
) != 0 &&
302 lcl_SeqHasLang(aSpellUsedLang
, nLangType
)) ||
303 ((nLangList
& LANG_LIST_HYPH_USED
) != 0 &&
304 lcl_SeqHasLang(aHyphUsedLang
, nLangType
)) ||
305 ((nLangList
& LANG_LIST_THES_USED
) != 0 &&
306 lcl_SeqHasLang(aThesUsedLang
, nLangType
))) )
307 InsertLanguage( nLangType
);
311 InsertLanguage( LANGUAGE_NONE
);
315 //------------------------------------------------------------------------
317 USHORT
SvxLanguageBox::InsertLanguage( const LanguageType nLangType
, USHORT nPos
)
319 return ImplInsertLanguage( nLangType
, nPos
, ::com::sun::star::i18n::ScriptType::WEAK
);
322 //------------------------------------------------------------------------
324 USHORT
SvxLanguageBox::ImplInsertLanguage( const LanguageType nLangType
, USHORT nPos
, sal_Int16 nType
)
326 LanguageType nLang
= MsLangId::getReplacementForObsoleteLanguage( nLangType
);
327 // For obsolete and to be replaced languages check whether an entry of the
328 // replacement already exists and if so don't add an entry with identical
329 // string as would be returned by SvtLanguageTable::GetString().
330 if (nLang
!= nLangType
)
332 USHORT nAt
= TypeToPos_Impl( nLang
, *this );
333 if ( nAt
!= LISTBOX_ENTRY_NOTFOUND
)
337 String aStrEntry
= m_pLangTable
->GetString( nLang
);
338 if (LANGUAGE_NONE
== nLang
&& m_bHasLangNone
&& m_bLangNoneIsLangAll
)
339 aStrEntry
= m_aAllString
;
341 LanguageType nRealLang
= nLang
;
342 if (nRealLang
== LANGUAGE_SYSTEM
)
344 nRealLang
= MsLangId::resolveSystemLanguageByScriptType(nRealLang
, nType
);
345 aStrEntry
.AppendAscii(" - ");
346 aStrEntry
.Append(m_pLangTable
->GetString( nRealLang
));
349 aStrEntry
= ApplyLreOrRleEmbedding( aStrEntry
);
352 if ( m_bWithCheckmark
)
354 sal_Bool bFound
= sal_False
;
356 if (!m_pSpellUsedLang
)
358 Reference
< XSpellChecker1
> xSpell( SvxGetSpellChecker(), UNO_QUERY
);
360 m_pSpellUsedLang
= new Sequence
< INT16
>( xSpell
->getLanguages() );
362 bFound
= m_pSpellUsedLang
?
363 lcl_SeqHasLang( *m_pSpellUsedLang
, nRealLang
) : FALSE
;
365 nAt
= ImplInsertImgEntry( aStrEntry
, nPos
, bFound
);
368 nAt
= InsertEntry( aStrEntry
, nPos
);
370 SetEntryData( nAt
, (void*)(ULONG
)nLangType
);
374 //------------------------------------------------------------------------
376 USHORT
SvxLanguageBox::InsertDefaultLanguage( sal_Int16 nType
, USHORT nPos
)
378 return ImplInsertLanguage( LANGUAGE_SYSTEM
, nPos
, nType
);
381 //------------------------------------------------------------------------
383 USHORT
SvxLanguageBox::InsertLanguage( const LanguageType nLangType
,
384 BOOL bCheckEntry
, USHORT nPos
)
386 LanguageType nLang
= MsLangId::getReplacementForObsoleteLanguage( nLangType
);
387 // For obsolete and to be replaced languages check whether an entry of the
388 // replacement already exists and if so don't add an entry with identical
389 // string as would be returned by SvtLanguageTable::GetString().
390 if (nLang
!= nLangType
)
392 USHORT nAt
= TypeToPos_Impl( nLang
, *this );
393 if ( nAt
!= LISTBOX_ENTRY_NOTFOUND
)
397 String aStrEntry
= m_pLangTable
->GetString( nLang
);
398 if (LANGUAGE_NONE
== nLang
&& m_bHasLangNone
&& m_bLangNoneIsLangAll
)
399 aStrEntry
= m_aAllString
;
401 USHORT nAt
= ImplInsertImgEntry( aStrEntry
, nPos
, bCheckEntry
);
402 SetEntryData( nAt
, (void*)(ULONG
)nLang
);
407 //------------------------------------------------------------------------
409 void SvxLanguageBox::RemoveLanguage( const LanguageType eLangType
)
411 USHORT nAt
= TypeToPos_Impl( eLangType
, *this );
413 if ( nAt
!= LISTBOX_ENTRY_NOTFOUND
)
417 //------------------------------------------------------------------------
419 LanguageType
SvxLanguageBox::GetSelectLanguage() const
421 USHORT nPos
= GetSelectEntryPos();
423 if ( nPos
!= LISTBOX_ENTRY_NOTFOUND
)
424 return LanguageType( (ULONG
)GetEntryData(nPos
) );
426 return LanguageType( LANGUAGE_DONTKNOW
);
429 //------------------------------------------------------------------------
431 void SvxLanguageBox::SelectLanguage( const LanguageType eLangType
, BOOL bSelect
)
433 // If the core uses a LangID of an imported MS document and wants to select
434 // a language that is replaced, we need to select the replacement instead.
435 LanguageType nLang
= MsLangId::getReplacementForObsoleteLanguage( eLangType
);
437 USHORT nAt
= TypeToPos_Impl( nLang
, *this );
439 if ( nAt
!= LISTBOX_ENTRY_NOTFOUND
)
440 SelectEntryPos( nAt
, bSelect
);
443 //------------------------------------------------------------------------
445 BOOL
SvxLanguageBox::IsLanguageSelected( const LanguageType eLangType
) const
447 // Same here, work on the replacement if applicable.
448 LanguageType nLang
= MsLangId::getReplacementForObsoleteLanguage( eLangType
);
450 USHORT nAt
= TypeToPos_Impl( nLang
, *this );
452 if ( nAt
!= LISTBOX_ENTRY_NOTFOUND
)
453 return IsEntryPosSelected( nAt
);
463 SvxLanguageBox::~SvxLanguageBox ()
467 SvxLanguageBox::SvxLanguageBox( Context
* pParent
, const char* pFile
, BOOL bCheck
)
468 : ListBox ( pParent
, pFile
, bCheck
)
472 void SvxLanguageBox::SetLanguageList( sal_Int16
/*list*/, bool/*hasLangNone*/, bool /*langNoneIsLangAll*/, bool /*checkSpellAvail*/)
476 sal_uInt16
SvxLanguageBox::InsertLanguage( const LanguageType
/*type*/, sal_uInt16
/*pos*/)
480 sal_uInt16
SvxLanguageBox::InsertLanguage( const LanguageType
/*type*/, bool/*checkEntry*/, sal_uInt16
/*pos*/)
484 void SvxLanguageBox::RemoveLanguage( const LanguageType
/*type*/)
487 void SvxLanguageBox::SelectLanguage( const LanguageType
/*type*/, bool/*select*/)
490 LanguageType
SvxLanguageBox::GetSelectLanguage() const
494 bool SvxLanguageBox::IsLanguageSelected( const LanguageType
/*type*/) const
499 /*IMPL_IMPL (SvxLanguageBox, ListBox);
500 IMPL_CONSTRUCTORS ( SvxLanguageBox, ListBox, "svxlanguagebox" );
501 IMPL_GET_IMPL( SvxLanguageBox );
502 IMPL_GET_WINDOW (SvxLanguageBox);*/