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