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 <linguistic/misc.hxx>
41 #include<rtl/ustring.hxx>
42 #include <unotools/localedatawrapper.hxx>
44 #include <svtools/langtab.hxx>
45 #include <tools/shl.hxx>
46 #include <i18npool/mslangid.hxx>
47 #include <i18npool/lang.h>
48 #include <svx/scripttypeitem.hxx>
49 #include <unolingu.hxx>
50 #include <svx/langbox.hxx>
51 #include <svx/dialmgr.hxx>
52 #include <svx/dialogs.hrc>
54 using namespace ::com::sun::star::util
;
55 using namespace ::com::sun::star::lang
;
56 using namespace ::com::sun::star::linguistic2
;
57 using namespace ::com::sun::star::uno
;
60 //========================================================================
61 // misc local helper functions
62 //========================================================================
66 static Sequence
< INT16
> lcl_LocaleSeqToLangSeq( Sequence
< Locale
> &rSeq
)
68 const Locale
*pLocale
= rSeq
.getConstArray();
69 INT32 nCount
= rSeq
.getLength();
71 Sequence
< INT16
> aLangs( nCount
);
72 INT16
*pLang
= aLangs
.getArray();
73 for (INT32 i
= 0; i
< nCount
; ++i
)
75 pLang
[i
] = SvxLocaleToLanguage( pLocale
[i
] );
83 static BOOL
lcl_SeqHasLang( const Sequence
< INT16
> & rLangSeq
, INT16 nLang
)
86 INT32 nLen
= rLangSeq
.getLength();
89 const INT16
*pLang
= rLangSeq
.getConstArray();
90 for (i
= 0; i
< nLen
; ++i
)
92 if (nLang
== pLang
[i
])
96 return i
>= 0 && i
< nLen
;
99 //========================================================================
100 // class SvxLanguageBox
101 //========================================================================
103 USHORT
TypeToPos_Impl( LanguageType eType
, const ListBox
& rLb
)
105 USHORT nPos
= LISTBOX_ENTRY_NOTFOUND
;
106 USHORT nCount
= rLb
.GetEntryCount();
108 for ( USHORT i
=0; nPos
== LISTBOX_ENTRY_NOTFOUND
&& i
<nCount
; i
++ )
109 if ( eType
== LanguageType((ULONG
)rLb
.GetEntryData(i
)) )
115 //-----------------------------------------------------------------------
116 SvxLanguageBox::SvxLanguageBox( Window
* pParent
, WinBits nWinStyle
, BOOL bCheck
) :
117 ListBox( pParent
, nWinStyle
),
118 m_pSpellUsedLang( NULL
),
119 m_bWithCheckmark( bCheck
)
123 //------------------------------------------------------------------------
124 SvxLanguageBox::SvxLanguageBox( Window
* pParent
, const ResId
& rResId
, BOOL bCheck
) :
125 ListBox( pParent
, rResId
),
126 m_pSpellUsedLang( NULL
),
127 m_bWithCheckmark( bCheck
)
131 //------------------------------------------------------------------------
132 void SvxLanguageBox::Init()
134 m_pLangTable
= new SvtLanguageTable
;
135 m_aNotCheckedImage
= Image( SVX_RES( RID_SVXIMG_NOTCHECKED
) );
136 m_aCheckedImage
= Image( SVX_RES( RID_SVXIMG_CHECKED
) );
137 m_aCheckedImageHC
= Image( SVX_RES( RID_SVXIMG_CHECKED_H
) );
138 m_aAllString
= String( SVX_RESSTR( RID_SVXSTR_LANGUAGE_ALL
) );
139 m_nLangList
= LANG_LIST_EMPTY
;
140 m_bHasLangNone
= FALSE
;
141 m_bLangNoneIsLangAll
= FALSE
;
143 // display entries sorted
144 SetStyle( GetStyle() | WB_SORT
);
146 if ( m_bWithCheckmark
)
148 SvtLanguageTable aLangTable
;
149 sal_uInt32 nCount
= aLangTable
.GetEntryCount();
150 for ( sal_uInt32 i
= 0; i
< nCount
; i
++ )
152 LanguageType nLangType
= aLangTable
.GetTypeAtIndex( i
);
155 if ((LANGUAGE_DONTKNOW
== nLangType
) ||
156 (LANGUAGE_SYSTEM
== nLangType
) ||
157 (LANGUAGE_USER1
<= nLangType
&& nLangType
<= LANGUAGE_USER9
))
163 InsertLanguage( nLangType
);
165 m_nLangList
= LANG_LIST_ALL
;
168 //------------------------------------------------------------------------
170 SvxLanguageBox::~SvxLanguageBox()
172 delete m_pSpellUsedLang
;
176 //------------------------------------------------------------------------
178 USHORT
SvxLanguageBox::ImplInsertImgEntry( const String
& rEntry
, USHORT nPos
, bool bChecked
)
182 nRet
= InsertEntry( rEntry
, m_aNotCheckedImage
, nPos
);
183 else if( GetSettings().GetStyleSettings().GetFaceColor().IsDark() )
184 nRet
= InsertEntry( rEntry
, m_aCheckedImageHC
, nPos
);
186 nRet
= InsertEntry( rEntry
, m_aCheckedImage
, nPos
);
190 //------------------------------------------------------------------------
192 void SvxLanguageBox::SetLanguageList( INT16 nLangList
,
193 BOOL bHasLangNone
, BOOL bLangNoneIsLangAll
, BOOL bCheckSpellAvail
)
197 m_nLangList
= nLangList
;
198 m_bHasLangNone
= bHasLangNone
;
199 m_bLangNoneIsLangAll
= bLangNoneIsLangAll
;
200 m_bWithCheckmark
= bCheckSpellAvail
;
202 if ( LANG_LIST_EMPTY
!= nLangList
)
204 Sequence
< INT16
> aSpellAvailLang
;
205 Sequence
< INT16
> aHyphAvailLang
;
206 Sequence
< INT16
> aThesAvailLang
;
207 Sequence
< INT16
> aSpellUsedLang
;
208 Sequence
< INT16
> aHyphUsedLang
;
209 Sequence
< INT16
> aThesUsedLang
;
210 Reference
< XAvailableLocales
> xAvail( LinguMgr::GetLngSvcMgr(), UNO_QUERY
);
213 Sequence
< Locale
> aTmp
;
215 if (LANG_LIST_SPELL_AVAIL
& nLangList
)
217 aTmp
= xAvail
->getAvailableLocales( A2OU( SN_SPELLCHECKER
) );
218 aSpellAvailLang
= lcl_LocaleSeqToLangSeq( aTmp
);
220 if (LANG_LIST_HYPH_AVAIL
& nLangList
)
222 aTmp
= xAvail
->getAvailableLocales( A2OU( SN_HYPHENATOR
) );
223 aHyphAvailLang
= lcl_LocaleSeqToLangSeq( aTmp
);
225 if (LANG_LIST_THES_AVAIL
& nLangList
)
227 aTmp
= xAvail
->getAvailableLocales( A2OU( SN_THESAURUS
) );
228 aThesAvailLang
= lcl_LocaleSeqToLangSeq( aTmp
);
231 if (LANG_LIST_SPELL_USED
& nLangList
)
233 Reference
< XSpellChecker1
> xTmp1( SvxGetSpellChecker(), UNO_QUERY
);
235 aSpellUsedLang
= xTmp1
->getLanguages();
237 if (LANG_LIST_HYPH_USED
& nLangList
)
239 Reference
< XHyphenator
> xTmp( SvxGetHyphenator() );
241 Sequence
< Locale
> aLocaleSequence( xTmp
->getLocales() );
242 aHyphUsedLang
= lcl_LocaleSeqToLangSeq( aLocaleSequence
);
245 if (LANG_LIST_THES_USED
& nLangList
)
247 Reference
< XThesaurus
> xTmp( SvxGetThesaurus() );
249 Sequence
< Locale
> aLocaleSequence( xTmp
->getLocales() );
250 aThesUsedLang
= lcl_LocaleSeqToLangSeq( aLocaleSequence
);
254 SvtLanguageTable aLangTable
;
255 ::com::sun::star::uno::Sequence
< sal_uInt16
> xKnown
;
256 const sal_uInt16
* pKnown
;
258 if ( nLangList
& LANG_LIST_ONLY_KNOWN
)
260 xKnown
= LocaleDataWrapper::getInstalledLanguageTypes();
261 pKnown
= xKnown
.getConstArray();
262 nCount
= xKnown
.getLength();
266 nCount
= aLangTable
.GetEntryCount();
269 for ( sal_uInt32 i
= 0; i
< nCount
; i
++ )
271 LanguageType nLangType
;
272 if ( nLangList
& LANG_LIST_ONLY_KNOWN
)
273 nLangType
= pKnown
[i
];
275 nLangType
= aLangTable
.GetTypeAtIndex( i
);
276 if ( nLangType
!= LANGUAGE_DONTKNOW
&&
277 nLangType
!= LANGUAGE_SYSTEM
&&
278 nLangType
!= LANGUAGE_NONE
&&
279 (nLangType
< LANGUAGE_USER1
|| nLangType
> LANGUAGE_USER9
) &&
280 (MsLangId::getSubLanguage( nLangType
) != 0 ||
281 (nLangList
& LANG_LIST_ALSO_PRIMARY_ONLY
)) &&
282 ((nLangList
& LANG_LIST_ALL
) != 0 ||
283 ((nLangList
& LANG_LIST_WESTERN
) != 0 &&
284 (SvtLanguageOptions::GetScriptTypeOfLanguage(nLangType
) ==
285 SCRIPTTYPE_LATIN
)) ||
286 ((nLangList
& LANG_LIST_CTL
) != 0 &&
287 (SvtLanguageOptions::GetScriptTypeOfLanguage(nLangType
) ==
288 SCRIPTTYPE_COMPLEX
)) ||
289 ((nLangList
& LANG_LIST_CJK
) != 0 &&
290 (SvtLanguageOptions::GetScriptTypeOfLanguage(nLangType
) ==
291 SCRIPTTYPE_ASIAN
)) ||
292 ((nLangList
& LANG_LIST_FBD_CHARS
) != 0 &&
293 MsLangId::hasForbiddenCharacters(nLangType
)) ||
294 ((nLangList
& LANG_LIST_SPELL_AVAIL
) != 0 &&
295 lcl_SeqHasLang(aSpellAvailLang
, nLangType
)) ||
296 ((nLangList
& LANG_LIST_HYPH_AVAIL
) != 0 &&
297 lcl_SeqHasLang(aHyphAvailLang
, nLangType
)) ||
298 ((nLangList
& LANG_LIST_THES_AVAIL
) != 0 &&
299 lcl_SeqHasLang(aThesAvailLang
, nLangType
)) ||
300 ((nLangList
& LANG_LIST_SPELL_USED
) != 0 &&
301 lcl_SeqHasLang(aSpellUsedLang
, nLangType
)) ||
302 ((nLangList
& LANG_LIST_HYPH_USED
) != 0 &&
303 lcl_SeqHasLang(aHyphUsedLang
, nLangType
)) ||
304 ((nLangList
& LANG_LIST_THES_USED
) != 0 &&
305 lcl_SeqHasLang(aThesUsedLang
, nLangType
))) )
306 InsertLanguage( nLangType
);
310 InsertLanguage( LANGUAGE_NONE
);
314 //------------------------------------------------------------------------
316 USHORT
SvxLanguageBox::InsertLanguage( const LanguageType nLangType
, USHORT nPos
)
318 LanguageType nLang
= MsLangId::getReplacementForObsoleteLanguage( nLangType
);
319 // For obsolete and to be replaced languages check whether an entry of the
320 // replacement already exists and if so don't add an entry with identical
321 // string as would be returned by SvtLanguageTable::GetString().
322 if (nLang
!= nLangType
)
324 USHORT nAt
= TypeToPos_Impl( nLang
, *this );
325 if ( nAt
!= LISTBOX_ENTRY_NOTFOUND
)
329 String aStrEntry
= m_pLangTable
->GetString( nLang
);
330 if (LANGUAGE_NONE
== nLang
&& m_bHasLangNone
&& m_bLangNoneIsLangAll
)
331 aStrEntry
= m_aAllString
;
332 aStrEntry
= ApplyLreOrRleEmbedding( aStrEntry
);
335 if ( m_bWithCheckmark
)
337 sal_Bool bFound
= sal_False
;
339 if (!m_pSpellUsedLang
)
341 Reference
< XSpellChecker1
> xSpell( SvxGetSpellChecker(), UNO_QUERY
);
343 m_pSpellUsedLang
= new Sequence
< INT16
>( xSpell
->getLanguages() );
345 bFound
= m_pSpellUsedLang
?
346 lcl_SeqHasLang( *m_pSpellUsedLang
, nLang
) : FALSE
;
348 nAt
= ImplInsertImgEntry( aStrEntry
, nPos
, bFound
);
351 nAt
= InsertEntry( aStrEntry
, nPos
);
353 SetEntryData( nAt
, (void*)(ULONG
)nLangType
);
357 //------------------------------------------------------------------------
359 USHORT
SvxLanguageBox::InsertLanguage( const LanguageType nLangType
,
360 BOOL bCheckEntry
, USHORT nPos
)
362 LanguageType nLang
= MsLangId::getReplacementForObsoleteLanguage( nLangType
);
363 // For obsolete and to be replaced languages check whether an entry of the
364 // replacement already exists and if so don't add an entry with identical
365 // string as would be returned by SvtLanguageTable::GetString().
366 if (nLang
!= nLangType
)
368 USHORT nAt
= TypeToPos_Impl( nLang
, *this );
369 if ( nAt
!= LISTBOX_ENTRY_NOTFOUND
)
373 String aStrEntry
= m_pLangTable
->GetString( nLang
);
374 if (LANGUAGE_NONE
== nLang
&& m_bHasLangNone
&& m_bLangNoneIsLangAll
)
375 aStrEntry
= m_aAllString
;
377 USHORT nAt
= ImplInsertImgEntry( aStrEntry
, nPos
, bCheckEntry
);
378 SetEntryData( nAt
, (void*)(ULONG
)nLang
);
383 //------------------------------------------------------------------------
385 void SvxLanguageBox::RemoveLanguage( const LanguageType eLangType
)
387 USHORT nAt
= TypeToPos_Impl( eLangType
, *this );
389 if ( nAt
!= LISTBOX_ENTRY_NOTFOUND
)
393 //------------------------------------------------------------------------
395 LanguageType
SvxLanguageBox::GetSelectLanguage() const
397 USHORT nPos
= GetSelectEntryPos();
399 if ( nPos
!= LISTBOX_ENTRY_NOTFOUND
)
400 return LanguageType( (ULONG
)GetEntryData(nPos
) );
402 return LanguageType( LANGUAGE_DONTKNOW
);
405 //------------------------------------------------------------------------
407 void SvxLanguageBox::SelectLanguage( const LanguageType eLangType
, BOOL bSelect
)
409 // If the core uses a LangID of an imported MS document and wants to select
410 // a language that is replaced, we need to select the replacement instead.
411 LanguageType nLang
= MsLangId::getReplacementForObsoleteLanguage( eLangType
);
413 USHORT nAt
= TypeToPos_Impl( nLang
, *this );
415 if ( nAt
!= LISTBOX_ENTRY_NOTFOUND
)
416 SelectEntryPos( nAt
, bSelect
);
419 //------------------------------------------------------------------------
421 BOOL
SvxLanguageBox::IsLanguageSelected( const LanguageType eLangType
) const
423 // Same here, work on the replacement if applicable.
424 LanguageType nLang
= MsLangId::getReplacementForObsoleteLanguage( eLangType
);
426 USHORT nAt
= TypeToPos_Impl( nLang
, *this );
428 if ( nAt
!= LISTBOX_ENTRY_NOTFOUND
)
429 return IsEntryPosSelected( nAt
);
439 SvxLanguageBox::~SvxLanguageBox ()
443 SvxLanguageBox::SvxLanguageBox( Context
* pParent
, const char* pFile
, BOOL bCheck
)
444 : ListBox ( pParent
, pFile
, bCheck
)
448 void SvxLanguageBox::SetLanguageList( sal_Int16
/*list*/, bool/*hasLangNone*/, bool /*langNoneIsLangAll*/, bool /*checkSpellAvail*/)
452 sal_uInt16
SvxLanguageBox::InsertLanguage( const LanguageType
/*type*/, sal_uInt16
/*pos*/)
456 sal_uInt16
SvxLanguageBox::InsertLanguage( const LanguageType
/*type*/, bool/*checkEntry*/, sal_uInt16
/*pos*/)
460 void SvxLanguageBox::RemoveLanguage( const LanguageType
/*type*/)
463 void SvxLanguageBox::SelectLanguage( const LanguageType
/*type*/, bool/*select*/)
466 LanguageType
SvxLanguageBox::GetSelectLanguage() const
470 bool SvxLanguageBox::IsLanguageSelected( const LanguageType
/*type*/) const
475 /*IMPL_IMPL (SvxLanguageBox, ListBox);
476 IMPL_CONSTRUCTORS ( SvxLanguageBox, ListBox, "svxlanguagebox" );
477 IMPL_GET_IMPL( SvxLanguageBox );
478 IMPL_GET_WINDOW (SvxLanguageBox);*/