Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <com/sun/star/linguistic2/XAvailableLocales.hpp>
21 : #include <com/sun/star/i18n/ScriptType.hpp>
22 : #include <linguistic/misc.hxx>
23 : #include <rtl/ustring.hxx>
24 : #include <unotools/localedatawrapper.hxx>
25 : #include <tools/urlobj.hxx>
26 : #include <svtools/langtab.hxx>
27 : #include <i18nlangtag/mslangid.hxx>
28 : #include <i18nlangtag/lang.h>
29 : #include <editeng/scripttypeitem.hxx>
30 : #include <editeng/unolingu.hxx>
31 : #include <svx/langbox.hxx>
32 : #include <svx/dialmgr.hxx>
33 : #include <svx/dialogs.hrc>
34 : #include <vcl/builder.hxx>
35 : #include <vcl/i18nhelp.hxx>
36 :
37 : using namespace ::com::sun::star::util;
38 : using namespace ::com::sun::star::lang;
39 : using namespace ::com::sun::star::linguistic2;
40 : using namespace ::com::sun::star::uno;
41 :
42 :
43 : // If these ever dispersed we'd need a solution.
44 : BOOST_STATIC_ASSERT((LISTBOX_APPEND == COMBOBOX_APPEND) && (LISTBOX_ENTRY_NOTFOUND == COMBOBOX_ENTRY_NOTFOUND));
45 :
46 :
47 0 : OUString GetDicInfoStr( const OUString& rName, const sal_uInt16 nLang, bool bNeg )
48 : {
49 0 : INetURLObject aURLObj;
50 0 : aURLObj.SetSmartProtocol( INET_PROT_FILE );
51 0 : aURLObj.SetSmartURL( rName, INetURLObject::ENCODE_ALL );
52 0 : OUString aTmp( aURLObj.GetBase() );
53 0 : aTmp += " ";
54 :
55 0 : if ( bNeg )
56 : {
57 0 : aTmp += " (-) ";
58 : }
59 :
60 0 : if ( LANGUAGE_NONE == nLang )
61 0 : aTmp += SVX_RESSTR(RID_SVXSTR_LANGUAGE_ALL);
62 : else
63 : {
64 0 : aTmp += "[";
65 0 : aTmp += SvtLanguageTable::GetLanguageString( (LanguageType)nLang );
66 0 : aTmp += "]";
67 : }
68 :
69 0 : return aTmp;
70 : }
71 :
72 :
73 : // misc local helper functions
74 :
75 :
76 0 : static Sequence< sal_Int16 > lcl_LocaleSeqToLangSeq( Sequence< Locale > &rSeq )
77 : {
78 0 : const Locale *pLocale = rSeq.getConstArray();
79 0 : sal_Int32 nCount = rSeq.getLength();
80 :
81 0 : Sequence< sal_Int16 > aLangs( nCount );
82 0 : sal_Int16 *pLang = aLangs.getArray();
83 0 : for (sal_Int32 i = 0; i < nCount; ++i)
84 : {
85 0 : pLang[i] = LanguageTag::convertToLanguageType( pLocale[i] );
86 :
87 : }
88 :
89 0 : return aLangs;
90 : }
91 :
92 :
93 0 : static bool lcl_SeqHasLang( const Sequence< sal_Int16 > & rLangSeq, sal_Int16 nLang )
94 : {
95 0 : sal_Int32 i = -1;
96 0 : sal_Int32 nLen = rLangSeq.getLength();
97 0 : if (nLen)
98 : {
99 0 : const sal_Int16 *pLang = rLangSeq.getConstArray();
100 0 : for (i = 0; i < nLen; ++i)
101 : {
102 0 : if (nLang == pLang[i])
103 0 : break;
104 : }
105 : }
106 0 : return i >= 0 && i < nLen;
107 : }
108 :
109 :
110 0 : extern "C" SAL_DLLPUBLIC_EXPORT vcl::Window* SAL_CALL makeSvxLanguageBox(vcl::Window *pParent, VclBuilder::stringmap &rMap)
111 : {
112 0 : WinBits nBits = WB_LEFT|WB_VCENTER|WB_3DLOOK|WB_TABSTOP;
113 0 : bool bDropdown = VclBuilder::extractDropdown(rMap);
114 0 : if (bDropdown)
115 0 : nBits |= WB_DROPDOWN;
116 : else
117 0 : nBits |= WB_BORDER;
118 0 : SvxLanguageBox *pLanguageBox = new SvxLanguageBox(pParent, nBits);
119 0 : pLanguageBox->EnableAutoSize(true);
120 0 : return pLanguageBox;
121 : }
122 :
123 0 : extern "C" SAL_DLLPUBLIC_EXPORT vcl::Window* SAL_CALL makeSvxLanguageComboBox(vcl::Window *pParent, VclBuilder::stringmap &rMap)
124 : {
125 0 : WinBits nBits = WB_LEFT|WB_VCENTER|WB_3DLOOK|WB_TABSTOP;
126 0 : bool bDropdown = VclBuilder::extractDropdown(rMap);
127 0 : if (bDropdown)
128 0 : nBits |= WB_DROPDOWN;
129 : else
130 0 : nBits |= WB_BORDER;
131 0 : SvxLanguageComboBox *pLanguageBox = new SvxLanguageComboBox(pParent, nBits);
132 0 : pLanguageBox->EnableAutoSize(true);
133 0 : return pLanguageBox;
134 : }
135 :
136 :
137 0 : SvxLanguageBoxBase::SvxLanguageBoxBase( bool bCheck )
138 : : m_pSpellUsedLang(NULL)
139 : , m_nLangList(LANG_LIST_EMPTY)
140 : , m_bHasLangNone(false)
141 : , m_bLangNoneIsLangAll(false)
142 0 : , m_bWithCheckmark(bCheck)
143 : {
144 0 : }
145 :
146 0 : void SvxLanguageBoxBase::ImplLanguageBoxBaseInit()
147 : {
148 0 : m_aNotCheckedImage = Image( SVX_RES( RID_SVXIMG_NOTCHECKED ) );
149 0 : m_aCheckedImage = Image( SVX_RES( RID_SVXIMG_CHECKED ) );
150 0 : m_aAllString = SVX_RESSTR( RID_SVXSTR_LANGUAGE_ALL );
151 0 : m_nLangList = LANG_LIST_EMPTY;
152 0 : m_bHasLangNone = false;
153 0 : m_bLangNoneIsLangAll = false;
154 :
155 0 : if ( m_bWithCheckmark )
156 : {
157 0 : sal_uInt32 nCount = SvtLanguageTable::GetLanguageEntryCount();
158 0 : for ( sal_uInt32 i = 0; i < nCount; i++ )
159 : {
160 0 : LanguageType nLangType = SvtLanguageTable::GetLanguageTypeAtIndex( i );
161 :
162 0 : bool bInsert = true;
163 0 : if ((LANGUAGE_DONTKNOW == nLangType) ||
164 : (LANGUAGE_SYSTEM == nLangType))
165 : {
166 0 : bInsert = false;
167 : }
168 :
169 0 : if ( bInsert )
170 0 : InsertLanguage( nLangType );
171 : }
172 0 : m_nLangList = LANG_LIST_ALL;
173 : }
174 0 : }
175 :
176 :
177 0 : SvxLanguageBoxBase::~SvxLanguageBoxBase()
178 : {
179 0 : delete m_pSpellUsedLang;
180 0 : }
181 :
182 :
183 0 : void SvxLanguageBoxBase::SetLanguageList( sal_Int16 nLangList,
184 : bool bHasLangNone, bool bLangNoneIsLangAll, bool bCheckSpellAvail )
185 : {
186 0 : ImplClear();
187 :
188 0 : m_nLangList = nLangList;
189 0 : m_bHasLangNone = bHasLangNone;
190 0 : m_bLangNoneIsLangAll = bLangNoneIsLangAll;
191 0 : m_bWithCheckmark = bCheckSpellAvail;
192 :
193 0 : if ( LANG_LIST_EMPTY != nLangList )
194 : {
195 0 : Sequence< sal_Int16 > aSpellAvailLang;
196 0 : Sequence< sal_Int16 > aHyphAvailLang;
197 0 : Sequence< sal_Int16 > aThesAvailLang;
198 0 : Sequence< sal_Int16 > aSpellUsedLang;
199 0 : Sequence< sal_Int16 > aHyphUsedLang;
200 0 : Sequence< sal_Int16 > aThesUsedLang;
201 0 : Reference< XAvailableLocales > xAvail( LinguMgr::GetLngSvcMgr(), UNO_QUERY );
202 0 : if (xAvail.is())
203 : {
204 0 : Sequence< Locale > aTmp;
205 :
206 0 : if (LANG_LIST_SPELL_AVAIL & nLangList)
207 : {
208 0 : aTmp = xAvail->getAvailableLocales( SN_SPELLCHECKER );
209 0 : aSpellAvailLang = lcl_LocaleSeqToLangSeq( aTmp );
210 : }
211 0 : if (LANG_LIST_HYPH_AVAIL & nLangList)
212 : {
213 0 : aTmp = xAvail->getAvailableLocales( SN_HYPHENATOR );
214 0 : aHyphAvailLang = lcl_LocaleSeqToLangSeq( aTmp );
215 : }
216 0 : if (LANG_LIST_THES_AVAIL & nLangList)
217 : {
218 0 : aTmp = xAvail->getAvailableLocales( SN_THESAURUS );
219 0 : aThesAvailLang = lcl_LocaleSeqToLangSeq( aTmp );
220 0 : }
221 : }
222 0 : if (LANG_LIST_SPELL_USED & nLangList)
223 : {
224 0 : Reference< XSpellChecker1 > xTmp1( SvxGetSpellChecker(), UNO_QUERY );
225 0 : if (xTmp1.is())
226 0 : aSpellUsedLang = xTmp1->getLanguages();
227 : }
228 0 : if (LANG_LIST_HYPH_USED & nLangList)
229 : {
230 0 : Reference< XHyphenator > xTmp( SvxGetHyphenator() );
231 0 : if (xTmp.is()) {
232 0 : Sequence < Locale > aLocaleSequence( xTmp->getLocales() );
233 0 : aHyphUsedLang = lcl_LocaleSeqToLangSeq( aLocaleSequence );
234 0 : }
235 : }
236 0 : if (LANG_LIST_THES_USED & nLangList)
237 : {
238 0 : Reference< XThesaurus > xTmp( SvxGetThesaurus() );
239 0 : if (xTmp.is()) {
240 0 : Sequence < Locale > aLocaleSequence( xTmp->getLocales() );
241 0 : aThesUsedLang = lcl_LocaleSeqToLangSeq( aLocaleSequence );
242 0 : }
243 : }
244 :
245 0 : ::com::sun::star::uno::Sequence< sal_uInt16 > xKnown;
246 : const sal_uInt16* pKnown;
247 : sal_uInt32 nCount;
248 0 : if ( nLangList & LANG_LIST_ONLY_KNOWN )
249 : {
250 0 : xKnown = LocaleDataWrapper::getInstalledLanguageTypes();
251 0 : pKnown = xKnown.getConstArray();
252 0 : nCount = xKnown.getLength();
253 : }
254 : else
255 : {
256 0 : nCount = SvtLanguageTable::GetLanguageEntryCount();
257 0 : pKnown = NULL;
258 : }
259 0 : for ( sal_uInt32 i = 0; i < nCount; i++ )
260 : {
261 : LanguageType nLangType;
262 0 : if ( nLangList & LANG_LIST_ONLY_KNOWN )
263 0 : nLangType = pKnown[i];
264 : else
265 0 : nLangType = SvtLanguageTable::GetLanguageTypeAtIndex( i );
266 0 : if ( nLangType != LANGUAGE_DONTKNOW &&
267 0 : nLangType != LANGUAGE_SYSTEM &&
268 0 : nLangType != LANGUAGE_NONE &&
269 0 : !MsLangId::isLegacy( nLangType) &&
270 0 : (MsLangId::getSubLanguage( nLangType) != 0 ||
271 0 : (nLangList & LANG_LIST_ALSO_PRIMARY_ONLY)) &&
272 0 : ((nLangList & LANG_LIST_ALL) != 0 ||
273 0 : ((nLangList & LANG_LIST_WESTERN) != 0 &&
274 0 : (SvtLanguageOptions::GetScriptTypeOfLanguage(nLangType) ==
275 0 : SCRIPTTYPE_LATIN)) ||
276 0 : ((nLangList & LANG_LIST_CTL) != 0 &&
277 0 : (SvtLanguageOptions::GetScriptTypeOfLanguage(nLangType) ==
278 0 : SCRIPTTYPE_COMPLEX)) ||
279 0 : ((nLangList & LANG_LIST_CJK) != 0 &&
280 0 : (SvtLanguageOptions::GetScriptTypeOfLanguage(nLangType) ==
281 0 : SCRIPTTYPE_ASIAN)) ||
282 0 : ((nLangList & LANG_LIST_FBD_CHARS) != 0 &&
283 0 : MsLangId::hasForbiddenCharacters(nLangType)) ||
284 0 : ((nLangList & LANG_LIST_SPELL_AVAIL) != 0 &&
285 0 : lcl_SeqHasLang(aSpellAvailLang, nLangType)) ||
286 0 : ((nLangList & LANG_LIST_HYPH_AVAIL) != 0 &&
287 0 : lcl_SeqHasLang(aHyphAvailLang, nLangType)) ||
288 0 : ((nLangList & LANG_LIST_THES_AVAIL) != 0 &&
289 0 : lcl_SeqHasLang(aThesAvailLang, nLangType)) ||
290 0 : ((nLangList & LANG_LIST_SPELL_USED) != 0 &&
291 0 : lcl_SeqHasLang(aSpellUsedLang, nLangType)) ||
292 0 : ((nLangList & LANG_LIST_HYPH_USED) != 0 &&
293 0 : lcl_SeqHasLang(aHyphUsedLang, nLangType)) ||
294 0 : ((nLangList & LANG_LIST_THES_USED) != 0 &&
295 0 : lcl_SeqHasLang(aThesUsedLang, nLangType))) )
296 0 : InsertLanguage( nLangType );
297 : }
298 :
299 0 : if (bHasLangNone)
300 0 : InsertLanguage( LANGUAGE_NONE );
301 : }
302 0 : }
303 :
304 :
305 0 : sal_Int32 SvxLanguageBoxBase::InsertLanguage( const LanguageType nLangType, sal_Int32 nPos )
306 : {
307 0 : return ImplInsertLanguage( nLangType, nPos, ::com::sun::star::i18n::ScriptType::WEAK );
308 : }
309 :
310 :
311 0 : sal_Int32 SvxLanguageBoxBase::ImplInsertLanguage( const LanguageType nLangType, sal_Int32 nPos, sal_Int16 nType )
312 : {
313 0 : LanguageType nLang = MsLangId::getReplacementForObsoleteLanguage( nLangType);
314 : // For obsolete and to be replaced languages check whether an entry of the
315 : // replacement already exists and if so don't add an entry with identical
316 : // string as would be returned by SvtLanguageTable::GetString().
317 0 : if (nLang != nLangType)
318 : {
319 0 : sal_Int32 nAt = ImplTypeToPos( nLang );
320 0 : if ( nAt != LISTBOX_ENTRY_NOTFOUND )
321 0 : return nAt;
322 : }
323 :
324 0 : OUString aStrEntry = SvtLanguageTable::GetLanguageString( nLang );
325 0 : if (LANGUAGE_NONE == nLang && m_bHasLangNone && m_bLangNoneIsLangAll)
326 0 : aStrEntry = m_aAllString;
327 :
328 0 : LanguageType nRealLang = nLang;
329 0 : if (nRealLang == LANGUAGE_SYSTEM)
330 : {
331 0 : nRealLang = MsLangId::resolveSystemLanguageByScriptType(nRealLang, nType);
332 0 : aStrEntry += " - ";
333 0 : aStrEntry += SvtLanguageTable::GetLanguageString( nRealLang );
334 0 : } else if (nRealLang == LANGUAGE_USER_SYSTEM_CONFIG) {
335 0 : nRealLang = MsLangId::getSystemLanguage();
336 0 : aStrEntry += " - ";
337 0 : aStrEntry += SvtLanguageTable::GetLanguageString( nRealLang );
338 : }
339 :
340 0 : aStrEntry = ApplyLreOrRleEmbedding( aStrEntry );
341 :
342 0 : sal_Int32 nAt = 0;
343 0 : if ( m_bWithCheckmark )
344 : {
345 0 : bool bFound = false;
346 :
347 0 : if (!m_pSpellUsedLang)
348 : {
349 0 : Reference< XSpellChecker1 > xSpell( SvxGetSpellChecker(), UNO_QUERY );
350 0 : if ( xSpell.is() )
351 0 : m_pSpellUsedLang = new Sequence< sal_Int16 >( xSpell->getLanguages() );
352 : }
353 : bFound = m_pSpellUsedLang ?
354 0 : lcl_SeqHasLang( *m_pSpellUsedLang, nRealLang ) : false;
355 :
356 0 : nAt = ImplInsertImgEntry( aStrEntry, nPos, bFound );
357 : }
358 : else
359 0 : nAt = ImplInsertEntry( aStrEntry, nPos );
360 :
361 0 : ImplSetEntryData( nAt, reinterpret_cast<void*>(nLangType) );
362 0 : return nAt;
363 : }
364 :
365 :
366 0 : sal_Int32 SvxLanguageBoxBase::InsertDefaultLanguage( sal_Int16 nType, sal_Int32 nPos )
367 : {
368 0 : return ImplInsertLanguage( LANGUAGE_SYSTEM, nPos, nType );
369 : }
370 :
371 :
372 0 : sal_Int32 SvxLanguageBoxBase::InsertSystemLanguage( sal_Int32 nPos )
373 : {
374 0 : return ImplInsertLanguage( LANGUAGE_USER_SYSTEM_CONFIG, nPos, ::com::sun::star::i18n::ScriptType::WEAK );
375 : }
376 :
377 :
378 0 : sal_Int32 SvxLanguageBoxBase::InsertLanguage( const LanguageType nLangType,
379 : bool bCheckEntry, sal_Int32 nPos )
380 : {
381 0 : LanguageType nLang = MsLangId::getReplacementForObsoleteLanguage( nLangType);
382 : // For obsolete and to be replaced languages check whether an entry of the
383 : // replacement already exists and if so don't add an entry with identical
384 : // string as would be returned by SvtLanguageTable::GetString().
385 0 : if (nLang != nLangType)
386 : {
387 0 : sal_Int32 nAt = ImplTypeToPos( nLang );
388 0 : if ( nAt != LISTBOX_ENTRY_NOTFOUND )
389 0 : return nAt;
390 : }
391 :
392 0 : OUString aStrEntry = SvtLanguageTable::GetLanguageString( nLang );
393 0 : if (LANGUAGE_NONE == nLang && m_bHasLangNone && m_bLangNoneIsLangAll)
394 0 : aStrEntry = m_aAllString;
395 :
396 0 : sal_Int32 nAt = ImplInsertImgEntry( aStrEntry, nPos, bCheckEntry );
397 0 : ImplSetEntryData( nAt, reinterpret_cast<void*>(nLang) );
398 :
399 0 : return nAt;
400 : }
401 :
402 :
403 0 : void SvxLanguageBoxBase::RemoveLanguage( const LanguageType eLangType )
404 : {
405 0 : sal_Int32 nAt = ImplTypeToPos( eLangType );
406 :
407 0 : if ( nAt != LISTBOX_ENTRY_NOTFOUND )
408 0 : ImplRemoveEntryAt( nAt );
409 0 : }
410 :
411 :
412 0 : LanguageType SvxLanguageBoxBase::GetSelectLanguage() const
413 : {
414 0 : sal_Int32 nPos = ImplGetSelectEntryPos();
415 :
416 0 : if ( nPos != LISTBOX_ENTRY_NOTFOUND )
417 0 : return LanguageType( reinterpret_cast<sal_uIntPtr>(ImplGetEntryData(nPos)) );
418 : else
419 0 : return LanguageType( LANGUAGE_DONTKNOW );
420 : }
421 :
422 :
423 0 : void SvxLanguageBoxBase::SelectLanguage( const LanguageType eLangType, bool bSelect )
424 : {
425 : // If the core uses a LangID of an imported MS document and wants to select
426 : // a language that is replaced, we need to select the replacement instead.
427 0 : LanguageType nLang = MsLangId::getReplacementForObsoleteLanguage( eLangType);
428 :
429 0 : sal_Int32 nAt = ImplTypeToPos( nLang );
430 :
431 0 : if ( nAt == LISTBOX_ENTRY_NOTFOUND )
432 0 : nAt = InsertLanguage( nLang ); // on-the-fly-ID
433 :
434 0 : if ( nAt != LISTBOX_ENTRY_NOTFOUND )
435 0 : ImplSelectEntryPos( nAt, bSelect );
436 0 : }
437 :
438 :
439 0 : bool SvxLanguageBoxBase::IsLanguageSelected( const LanguageType eLangType ) const
440 : {
441 : // Same here, work on the replacement if applicable.
442 0 : LanguageType nLang = MsLangId::getReplacementForObsoleteLanguage( eLangType);
443 :
444 0 : sal_Int32 nAt = ImplTypeToPos( nLang );
445 :
446 0 : if ( nAt != LISTBOX_ENTRY_NOTFOUND )
447 0 : return ImplIsEntryPosSelected( nAt );
448 : else
449 0 : return false;
450 : }
451 :
452 :
453 0 : sal_Int32 SvxLanguageBoxBase::ImplTypeToPos( LanguageType eType ) const
454 : {
455 0 : return ImplGetEntryPos( reinterpret_cast<void*>(eType) );
456 : }
457 :
458 :
459 0 : void SvxLanguageBoxBase::SetNoSelectionLBB()
460 : {
461 0 : ImplSetNoSelection();
462 0 : }
463 :
464 0 : void SvxLanguageBoxBase::HideLBB()
465 : {
466 0 : ImplHide();
467 0 : }
468 :
469 0 : void SvxLanguageBoxBase::DisableLBB()
470 : {
471 0 : ImplDisable();
472 0 : }
473 :
474 0 : void SvxLanguageBoxBase::SaveValueLBB()
475 : {
476 0 : ImplSaveValue();
477 0 : }
478 :
479 0 : sal_Int32 SvxLanguageBoxBase::GetSelectEntryPosLBB( sal_Int32 nSelIndex ) const
480 : {
481 0 : return ImplGetSelectEntryPos( nSelIndex);
482 : }
483 :
484 0 : void* SvxLanguageBoxBase::GetEntryDataLBB( sal_Int32 nPos ) const
485 : {
486 0 : return ImplGetEntryData( nPos);
487 : }
488 :
489 0 : sal_Int32 SvxLanguageBoxBase::GetSavedValueLBB() const
490 : {
491 0 : return ImplGetSavedValue();
492 : }
493 :
494 :
495 0 : SvxLanguageBox::SvxLanguageBox( vcl::Window* pParent, WinBits nBits, bool bCheck )
496 : : ListBox( pParent, nBits )
497 0 : , SvxLanguageBoxBase( bCheck )
498 : {
499 : // display entries sorted
500 0 : SetStyle( GetStyle() | WB_SORT );
501 :
502 0 : ImplLanguageBoxBaseInit();
503 0 : }
504 :
505 0 : SvxLanguageBox::~SvxLanguageBox()
506 : {
507 0 : }
508 :
509 :
510 0 : SvxLanguageComboBox::SvxLanguageComboBox( vcl::Window* pParent, WinBits nBits, bool bCheck )
511 : : ComboBox( pParent, nBits )
512 : , SvxLanguageBoxBase( bCheck )
513 : , mnSavedValuePos( COMBOBOX_ENTRY_NOTFOUND )
514 0 : , meEditedAndValid( EDITED_NO )
515 : {
516 : // display entries sorted
517 0 : SetStyle( GetStyle() | WB_SORT );
518 :
519 0 : EnableMultiSelection( false );
520 :
521 0 : ImplLanguageBoxBaseInit();
522 :
523 0 : SetModifyHdl( LINK( this, SvxLanguageComboBox, EditModifyHdl ) );
524 0 : }
525 :
526 0 : SvxLanguageComboBox::~SvxLanguageComboBox()
527 : {
528 0 : }
529 :
530 :
531 0 : sal_Int32 SvxLanguageBox::ImplInsertImgEntry( const OUString& rEntry, sal_Int32 nPos, bool bChecked )
532 : {
533 0 : return InsertEntry( rEntry, (bChecked ? m_aCheckedImage : m_aNotCheckedImage), nPos );
534 : }
535 :
536 0 : sal_Int32 SvxLanguageComboBox::ImplInsertImgEntry( const OUString& rEntry, sal_Int32 nPos, bool bChecked )
537 : {
538 0 : return InsertEntryWithImage( rEntry, (bChecked ? m_aCheckedImage : m_aNotCheckedImage), nPos );
539 : }
540 :
541 :
542 0 : void SvxLanguageBox::ImplRemoveEntryAt( sal_Int32 nPos )
543 : {
544 0 : RemoveEntry( nPos);
545 0 : }
546 :
547 0 : void SvxLanguageComboBox::ImplRemoveEntryAt( sal_Int32 nPos )
548 : {
549 0 : RemoveEntryAt( nPos);
550 0 : }
551 :
552 :
553 0 : void SvxLanguageBox::ImplClear()
554 : {
555 0 : Clear();
556 0 : }
557 :
558 0 : void SvxLanguageComboBox::ImplClear()
559 : {
560 0 : Clear();
561 0 : }
562 :
563 :
564 0 : sal_Int32 SvxLanguageBox::ImplInsertEntry( const OUString& rEntry, sal_Int32 nPos )
565 : {
566 0 : return InsertEntry( rEntry, nPos);
567 : }
568 :
569 0 : sal_Int32 SvxLanguageComboBox::ImplInsertEntry( const OUString& rEntry, sal_Int32 nPos )
570 : {
571 0 : return InsertEntry( rEntry, nPos);
572 : }
573 :
574 :
575 0 : void SvxLanguageBox::ImplSetEntryData( sal_Int32 nPos, void* pData )
576 : {
577 0 : SetEntryData( nPos, pData);
578 0 : }
579 :
580 0 : void SvxLanguageComboBox::ImplSetEntryData( sal_Int32 nPos, void* pData )
581 : {
582 0 : SetEntryData( nPos, pData);
583 0 : }
584 :
585 :
586 0 : sal_Int32 SvxLanguageBox::ImplGetSelectEntryPos( sal_Int32 nSelIndex ) const
587 : {
588 0 : return GetSelectEntryPos( nSelIndex);
589 : }
590 :
591 0 : sal_Int32 SvxLanguageComboBox::ImplGetSelectEntryPos( sal_Int32 nSelIndex ) const
592 : {
593 0 : return GetSelectEntryPos( nSelIndex);
594 : }
595 :
596 :
597 0 : void* SvxLanguageBox::ImplGetEntryData( sal_Int32 nPos ) const
598 : {
599 0 : return GetEntryData( nPos);
600 : }
601 :
602 0 : void* SvxLanguageComboBox::ImplGetEntryData( sal_Int32 nPos ) const
603 : {
604 0 : return GetEntryData( nPos);
605 : }
606 :
607 :
608 0 : void SvxLanguageBox::ImplSelectEntryPos( sal_Int32 nPos, bool bSelect )
609 : {
610 0 : SelectEntryPos( nPos, bSelect);
611 0 : }
612 :
613 0 : void SvxLanguageComboBox::ImplSelectEntryPos( sal_Int32 nPos, bool bSelect )
614 : {
615 0 : SelectEntryPos( nPos, bSelect);
616 0 : }
617 :
618 :
619 0 : bool SvxLanguageBox::ImplIsEntryPosSelected( sal_Int32 nPos ) const
620 : {
621 0 : return IsEntryPosSelected( nPos);
622 : }
623 :
624 0 : bool SvxLanguageComboBox::ImplIsEntryPosSelected( sal_Int32 nPos ) const
625 : {
626 0 : return IsEntryPosSelected( nPos);
627 : }
628 :
629 :
630 0 : sal_Int32 SvxLanguageBox::ImplGetEntryPos( const void* pData ) const
631 : {
632 0 : return GetEntryPos( pData);
633 : }
634 :
635 0 : sal_Int32 SvxLanguageComboBox::ImplGetEntryPos( const void* pData ) const
636 : {
637 0 : return GetEntryPos( pData);
638 : }
639 :
640 :
641 0 : sal_Int32 SvxLanguageBox::ImplGetEntryCount() const
642 : {
643 0 : return GetEntryCount();
644 : }
645 :
646 0 : sal_Int32 SvxLanguageComboBox::ImplGetEntryCount() const
647 : {
648 0 : return GetEntryCount();
649 : }
650 :
651 :
652 0 : void SvxLanguageBox::ImplSetNoSelection()
653 : {
654 0 : SetNoSelection();
655 0 : }
656 :
657 0 : void SvxLanguageComboBox::ImplSetNoSelection()
658 : {
659 0 : SetNoSelection();
660 0 : }
661 :
662 :
663 0 : void SvxLanguageBox::ImplHide()
664 : {
665 0 : Hide();
666 0 : }
667 :
668 0 : void SvxLanguageComboBox::ImplHide()
669 : {
670 0 : Hide();
671 0 : }
672 :
673 :
674 0 : void SvxLanguageBox::ImplDisable()
675 : {
676 0 : Disable();
677 0 : }
678 :
679 0 : void SvxLanguageComboBox::ImplDisable()
680 : {
681 0 : Disable();
682 0 : }
683 :
684 :
685 0 : void SvxLanguageBox::ImplSaveValue()
686 : {
687 0 : SaveValue();
688 0 : }
689 :
690 0 : void SvxLanguageComboBox::ImplSaveValue()
691 : {
692 : // Emulate the ListBox behavior.
693 0 : mnSavedValuePos = GetSelectEntryPos();
694 0 : }
695 :
696 :
697 0 : sal_Int32 SvxLanguageBox::ImplGetSavedValue() const
698 : {
699 0 : return GetSavedValue();
700 : }
701 :
702 0 : sal_Int32 SvxLanguageComboBox::ImplGetSavedValue() const
703 : {
704 0 : return mnSavedValuePos;
705 : }
706 :
707 :
708 0 : IMPL_LINK( SvxLanguageComboBox, EditModifyHdl, SvxLanguageComboBox*, /*pEd*/ )
709 : {
710 0 : EditedAndValid eOldState = meEditedAndValid;
711 0 : OUString aStr( vcl::I18nHelper::filterFormattingChars( GetText()));
712 0 : if (aStr.isEmpty())
713 0 : meEditedAndValid = EDITED_INVALID;
714 : else
715 : {
716 0 : const sal_Int32 nPos = GetEntryPos( aStr);
717 0 : if (nPos != COMBOBOX_ENTRY_NOTFOUND)
718 : {
719 : // Advance start of full selection by one so the next character
720 : // will already continue the string instead of having to type the
721 : // same character again to start a new string. The selection
722 : // includes formatting characters and is reverse when obtained from
723 : // the Edit control.
724 0 : Selection aSel( GetSelection());
725 0 : if (aSel.Max() == 1)
726 : {
727 0 : OUString aText( GetText());
728 0 : if (aSel.Min() == aText.getLength())
729 : {
730 0 : ++aSel.Max();
731 0 : SetSelection( aSel);
732 0 : }
733 : }
734 0 : meEditedAndValid = EDITED_NO;
735 : }
736 : else
737 : {
738 0 : OUString aCanonicalized;
739 0 : bool bValid = LanguageTag::isValidBcp47( aStr, &aCanonicalized, true);
740 0 : meEditedAndValid = (bValid ? EDITED_VALID : EDITED_INVALID);
741 0 : if (bValid && aCanonicalized != aStr)
742 : {
743 0 : SetText( aCanonicalized);
744 0 : SetSelection( Selection( aCanonicalized.getLength()));
745 0 : }
746 : }
747 : }
748 0 : if (eOldState != meEditedAndValid)
749 : {
750 0 : if (meEditedAndValid == EDITED_INVALID)
751 : {
752 : #if 0
753 : //! Gives white on white!?! instead of white on reddish.
754 : SetControlBackground( ::Color( RGB_COLORDATA( 0xff, 0x65, 0x63)));
755 : SetControlForeground( ::Color( COL_WHITE));
756 : #else
757 0 : SetControlForeground( ::Color( RGB_COLORDATA( 0xf0, 0, 0)));
758 : #endif
759 : }
760 : else
761 : {
762 0 : SetControlForeground();
763 0 : SetControlBackground();
764 : }
765 : }
766 0 : return 0;
767 : }
768 :
769 :
770 :
771 :
772 0 : sal_Int32 SvxLanguageComboBox::SaveEditedAsEntry()
773 : {
774 0 : if (meEditedAndValid != EDITED_VALID)
775 0 : return COMBOBOX_ENTRY_NOTFOUND;
776 :
777 0 : LanguageTag aLanguageTag( vcl::I18nHelper::filterFormattingChars( GetText()));
778 0 : LanguageType nLang = aLanguageTag.getLanguageType();
779 0 : if (nLang == LANGUAGE_DONTKNOW)
780 : {
781 : SAL_WARN( "svx.dialog", "SvxLanguageComboBox::SaveEditedAsEntry: unknown tag");
782 0 : return COMBOBOX_ENTRY_NOTFOUND;
783 : }
784 :
785 0 : sal_Int32 nPos = ImplTypeToPos( nLang);
786 0 : if (nPos != COMBOBOX_ENTRY_NOTFOUND)
787 0 : return nPos; // Already present but with a different string.
788 :
789 0 : if (SvtLanguageTable::HasLanguageType( nLang))
790 : {
791 : // In SvtLanguageTable but not in SvxLanguageComboBox. On purpose? This
792 : // may be an entry with different settings or CTL instead of Western or
793 : // ... all things we don't handle yet.
794 : SAL_WARN( "svx.dialog", "SvxLanguageComboBox::SaveEditedAsEntry: already in SvtLanguageTable: " <<
795 : SvtLanguageTable::GetLanguageString( nLang) << ", " << nLang);
796 : }
797 : else
798 : {
799 : // Add to both, SvtLanguageTable and SvxLanguageComboBox.
800 : /* TODO: a descriptive user comment would be a nice to have here. */
801 0 : SvtLanguageTable::AddLanguageTag( aLanguageTag, OUString());
802 : }
803 :
804 0 : nPos = InsertLanguage( nLang);
805 :
806 0 : return nPos;
807 651 : }
808 :
809 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|