Files
libreoffice/svx/source/dialog/langbox.cxx

840 lines
25 KiB
C++
Raw Normal View History

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
re-base on ALv2 code. Includes: Patch contributed by Christian Lippka impress212: #i113063# patch: dubios self assign in svx/source/dialog/framelink.cxx http://svn.apache.org/viewvc?view=revision&revision=1167619 Patches contributed by Mathias Bauer gnumake4 work variously http://svn.apache.org/viewvc?view=revision&revision=1394707 http://svn.apache.org/viewvc?view=revision&revision=1394326 cws mba34issues01: #i117712#: fix several resource errors introduced by IAccessible2 implementation http://svn.apache.org/viewvc?view=revision&revision=1172343 cws mba34issues01: #i117719#: use correct resource ID http://svn.apache.org/viewvc?view=revision&revision=1172351 Patch contributed by Andre Fischer Do not add targets for junit tests when junit is disabled. http://svn.apache.org/viewvc?view=revision&revision=1241508 Patches contributed by Armin Le-Grand #118804# corrected GraphicExporter behaviour on shortcut when pixel graphic is requested http://svn.apache.org/viewvc?view=revision&revision=1240195 fix for #118525#: Using primitives for chart sub-geometry visualisation http://svn.apache.org/viewvc?view=revision&revision=1226879 #118485# - Styles for OLEs are not saved. http://svn.apache.org/viewvc?view=revision&revision=1182166 #118524: apply patch, followup fixes to 118485 http://svn.apache.org/viewvc?view=revision&revision=1186077 13f79535-47bb-0310-9956-ffa450edef68 Patch contributed by Regina Henschel linecap: Reintegrating finished LineCap feature http://svn.apache.org/viewvc?view=revision&revision=1232507 Patch contributed by Wang Lei (leiw) #i118760# split the first table cell vertically, then undo&redo, the Presentation app will crash http://svn.apache.org/viewvc?view=revision&revision=1301361 cleanup globlmn hacks, undo dependent fixmes.
2012-11-21 22:06:52 +00:00
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
2000-09-18 16:07:07 +00:00
#include <com/sun/star/linguistic2/XAvailableLocales.hpp>
#include <com/sun/star/i18n/ScriptType.hpp>
#include <linguistic/misc.hxx>
#include <rtl/ustring.hxx>
#include <unotools/localedatawrapper.hxx>
2009-12-11 11:15:06 +01:00
#include <tools/urlobj.hxx>
#include <svtools/langtab.hxx>
#include <i18nlangtag/mslangid.hxx>
#include <i18nlangtag/lang.h>
#include <editeng/scripttypeitem.hxx>
#include <editeng/unolingu.hxx>
#include <svx/langbox.hxx>
#include <svx/dialmgr.hxx>
migrate to boost::gettext * all .ui files go from <interface> to <interface domain="MODULE"> e.g. vcl * all .src files go away and the english source strings folded into the .hrc as NC_("context", "source string") * ResMgr is dropped in favour of std::locale imbued by boost::locale::generator pointed at matching MODULE .mo files * UIConfig translations are folded into the module .mo, so e.g. UIConfig_cui goes from l10n target to normal one, so the res/lang.zips of UI files go away * translation via Translation::get(hrc-define-key, imbued-std::locale) * python can now be translated with its inbuilt gettext support (we keep the name strings.hrc there to keep finding the .hrc file uniform) so magic numbers can go away there * java and starbasic components can be translated via the pre-existing css.resource.StringResourceWithLocation mechanism * en-US res files go away, their strings are now the .hrc keys in the source code * remaining .res files are replaced by .mo files * in .res/.ui-lang-zip files, the old scheme missing translations of strings results in inserting the english original so something can be found, now the standard fallback of using the english original from the source key is used, so partial translations shrink dramatically in size * extract .hrc strings with hrcex which backs onto xgettext -C --add-comments --keyword=NC_:1c,2 --from-code=UTF-8 --no-wrap * extract .ui strings with uiex which backs onto xgettext --add-comments --no-wrap * qtz for gettext translations is generated at runtime as ascii-ified crc32 of content + "|" + msgid * [API CHANGE] remove deprecated binary .res resouce loader related uno apis com::sun::star::resource::OfficeResourceLoader com::sun::star::resource::XResourceBundleLoader com::sun::star::resource::XResourceBundle when translating strings via uno apis com.sun.star.resource.StringResourceWithLocation can continue to be used Change-Id: Ia2594a2672b7301d9c3421fdf31b6cfe7f3f8d0a
2017-06-11 20:56:30 +01:00
#include <svx/strings.hrc>
#include <bitmaps.hlst>
#include <vcl/builderfactory.hxx>
#include <vcl/i18nhelp.hxx>
using namespace ::com::sun::star::util;
using namespace ::com::sun::star::linguistic2;
using namespace ::com::sun::star::uno;
static_assert((LISTBOX_APPEND == COMBOBOX_APPEND) && (LISTBOX_ENTRY_NOTFOUND == COMBOBOX_ENTRY_NOTFOUND), "If these ever dispersed we'd need a solution");
2009-12-11 11:15:06 +01:00
OUString GetDicInfoStr( const OUString& rName, const LanguageType nLang, bool bNeg )
2009-12-11 11:15:06 +01:00
{
INetURLObject aURLObj;
aURLObj.SetSmartProtocol( INetProtocol::File );
aURLObj.SetSmartURL( rName, INetURLObject::EncodeMechanism::All );
OUString aTmp( aURLObj.GetBase() );
aTmp += " ";
2009-12-11 11:15:06 +01:00
if ( bNeg )
{
aTmp += " (-) ";
2009-12-11 11:15:06 +01:00
}
if ( LANGUAGE_NONE == nLang )
aTmp += SvxResId(RID_SVXSTR_LANGUAGE_ALL);
2009-12-11 11:15:06 +01:00
else
{
aTmp += "[";
aTmp += SvtLanguageTable::GetLanguageString( nLang );
aTmp += "]";
2009-12-11 11:15:06 +01:00
}
return aTmp;
}
// misc local helper functions
static std::vector< LanguageType > lcl_LocaleSeqToLangSeq( Sequence< css::lang::Locale > const &rSeq )
{
const css::lang::Locale *pLocale = rSeq.getConstArray();
sal_Int32 nCount = rSeq.getLength();
std::vector< LanguageType > aLangs;
for (sal_Int32 i = 0; i < nCount; ++i)
{
aLangs.push_back( LanguageTag::convertToLanguageType( pLocale[i] ) );
}
return aLangs;
}
static bool lcl_SeqHasLang( const std::vector< LanguageType > & rLangSeq, LanguageType nLang )
{
for (auto const & i : rLangSeq)
if (i == nLang)
return true;
return false;
}
static bool lcl_SeqHasLang( const Sequence< sal_Int16 > & rLangSeq, sal_Int16 nLang )
{
sal_Int32 i = -1;
sal_Int32 nLen = rLangSeq.getLength();
if (nLen)
{
const sal_Int16 *pLang = rLangSeq.getConstArray();
for (i = 0; i < nLen; ++i)
{
if (nLang == pLang[i])
break;
}
}
return i >= 0 && i < nLen;
}
2000-09-18 16:07:07 +00:00
extern "C" SAL_DLLPUBLIC_EXPORT void SAL_CALL makeSvxLanguageBox(VclPtr<vcl::Window> & rRet, VclPtr<vcl::Window> & pParent, VclBuilder::stringmap & rMap)
{
WinBits nBits = WB_LEFT|WB_VCENTER|WB_3DLOOK|WB_TABSTOP;
bool bDropdown = BuilderUtils::extractDropdown(rMap);
if (bDropdown)
nBits |= WB_DROPDOWN;
else
nBits |= WB_BORDER;
VclPtrInstance<SvxLanguageBox> pLanguageBox(pParent, nBits);
pLanguageBox->EnableAutoSize(true);
rRet = pLanguageBox;
}
extern "C" SAL_DLLPUBLIC_EXPORT void SAL_CALL makeSvxLanguageComboBox(VclPtr<vcl::Window> & rRet, VclPtr<vcl::Window> & pParent, VclBuilder::stringmap & rMap)
{
WinBits nBits = WB_LEFT|WB_VCENTER|WB_3DLOOK|WB_TABSTOP;
bool bDropdown = BuilderUtils::extractDropdown(rMap);
if (bDropdown)
nBits |= WB_DROPDOWN;
else
nBits |= WB_BORDER;
VclPtrInstance<SvxLanguageComboBox> pLanguageBox(pParent, nBits);
pLanguageBox->EnableAutoSize(true);
rRet = pLanguageBox;
}
SvxLanguageBoxBase::SvxLanguageBoxBase()
: m_pSpellUsedLang(nullptr)
, m_bHasLangNone(false)
, m_bLangNoneIsLangAll(false)
, m_bWithCheckmark(false)
{
}
void SvxLanguageBoxBase::ImplLanguageBoxBaseInit()
2000-09-18 16:07:07 +00:00
{
m_aNotCheckedImage = Image(BitmapEx(RID_SVXBMP_NOTCHECKED));
m_aCheckedImage = Image(BitmapEx(RID_SVXBMP_CHECKED));
m_aAllString = SvxResId( RID_SVXSTR_LANGUAGE_ALL );
m_bHasLangNone = false;
m_bLangNoneIsLangAll = false;
if ( m_bWithCheckmark )
{
sal_uInt32 nCount = SvtLanguageTable::GetLanguageEntryCount();
for ( sal_uInt32 i = 0; i < nCount; i++ )
{
LanguageType nLangType = SvtLanguageTable::GetLanguageTypeAtIndex( i );
bool bInsert = true;
if ((LANGUAGE_DONTKNOW == nLangType) ||
(LANGUAGE_SYSTEM == nLangType))
{
bInsert = false;
}
if ( bInsert )
InsertLanguage( nLangType );
}
}
2000-09-18 16:07:07 +00:00
}
SvxLanguageBoxBase::~SvxLanguageBoxBase()
2000-09-18 16:07:07 +00:00
{
}
namespace {
bool lcl_isPrerequisite( LanguageType nLangType, SvxLanguageListFlags nLangList )
{
return
nLangType != LANGUAGE_DONTKNOW &&
nLangType != LANGUAGE_SYSTEM &&
nLangType != LANGUAGE_NONE &&
!MsLangId::isLegacy( nLangType) &&
(MsLangId::getSubLanguage( nLangType) ||
bool(nLangList & SvxLanguageListFlags::ALSO_PRIMARY_ONLY));
}
bool lcl_isScriptTypeRequested( LanguageType nLangType, SvxLanguageListFlags nLangList )
{
return
bool(nLangList & SvxLanguageListFlags::ALL) ||
(bool(nLangList & SvxLanguageListFlags::WESTERN) &&
(SvtLanguageOptions::GetScriptTypeOfLanguage(nLangType) == SvtScriptType::LATIN)) ||
(bool(nLangList & SvxLanguageListFlags::CTL) &&
(SvtLanguageOptions::GetScriptTypeOfLanguage(nLangType) == SvtScriptType::COMPLEX)) ||
(bool(nLangList & SvxLanguageListFlags::CJK) &&
(SvtLanguageOptions::GetScriptTypeOfLanguage(nLangType) == SvtScriptType::ASIAN));
}
}
void SvxLanguageBoxBase::AddLanguages( const std::vector< LanguageType >& rLanguageTypes,
SvxLanguageListFlags nLangList )
{
for ( auto const & nLangType : rLanguageTypes )
{
if (lcl_isPrerequisite( nLangType, nLangList))
{
LanguageType nLang = MsLangId::getReplacementForObsoleteLanguage( nLangType );
if (lcl_isScriptTypeRequested( nLang, nLangList))
{
sal_Int32 nAt = ImplTypeToPos( nLang );
if (nAt == LISTBOX_ENTRY_NOTFOUND)
InsertLanguage( nLang );
}
}
}
}
void SvxLanguageBoxBase::SetLanguageList( SvxLanguageListFlags nLangList,
bool bHasLangNone, bool bLangNoneIsLangAll, bool bCheckSpellAvail )
{
ImplClear();
m_bHasLangNone = bHasLangNone;
m_bLangNoneIsLangAll = bLangNoneIsLangAll;
m_bWithCheckmark = bCheckSpellAvail;
if ( SvxLanguageListFlags::EMPTY != nLangList )
{
bool bAddAvailable = (!(nLangList & SvxLanguageListFlags::ONLY_KNOWN) &&
((nLangList & SvxLanguageListFlags::ALL) ||
(nLangList & SvxLanguageListFlags::WESTERN) ||
(nLangList & SvxLanguageListFlags::CTL) ||
(nLangList & SvxLanguageListFlags::CJK)));
std::vector< LanguageType > aSpellAvailLang;
std::vector< LanguageType > aHyphAvailLang;
std::vector< LanguageType > aThesAvailLang;
Sequence< sal_Int16 > aSpellUsedLang;
std::vector< LanguageType > aHyphUsedLang;
std::vector< LanguageType > aThesUsedLang;
Reference< XAvailableLocales > xAvail( LinguMgr::GetLngSvcMgr(), UNO_QUERY );
if (xAvail.is())
{
Sequence< css::lang::Locale > aTmp;
if (bAddAvailable || (SvxLanguageListFlags::SPELL_AVAIL & nLangList))
{
aTmp = xAvail->getAvailableLocales( SN_SPELLCHECKER );
aSpellAvailLang = lcl_LocaleSeqToLangSeq( aTmp );
}
if (bAddAvailable || (SvxLanguageListFlags::HYPH_AVAIL & nLangList))
{
aTmp = xAvail->getAvailableLocales( SN_HYPHENATOR );
aHyphAvailLang = lcl_LocaleSeqToLangSeq( aTmp );
}
if (bAddAvailable || (SvxLanguageListFlags::THES_AVAIL & nLangList))
{
aTmp = xAvail->getAvailableLocales( SN_THESAURUS );
aThesAvailLang = lcl_LocaleSeqToLangSeq( aTmp );
}
}
if (SvxLanguageListFlags::SPELL_USED & nLangList)
{
Reference< XSpellChecker1 > xTmp1( LinguMgr::GetSpellChecker(), UNO_QUERY );
if (xTmp1.is())
aSpellUsedLang = xTmp1->getLanguages();
}
if (SvxLanguageListFlags::HYPH_USED & nLangList)
{
Reference< XHyphenator > xTmp( LinguMgr::GetHyphenator() );
2001-10-12 12:00:07 +00:00
if (xTmp.is()) {
Sequence < css::lang::Locale > aLocaleSequence( xTmp->getLocales() );
2001-10-12 12:00:07 +00:00
aHyphUsedLang = lcl_LocaleSeqToLangSeq( aLocaleSequence );
}
}
if (SvxLanguageListFlags::THES_USED & nLangList)
{
Reference< XThesaurus > xTmp( LinguMgr::GetThesaurus() );
2001-10-12 12:00:07 +00:00
if (xTmp.is()) {
Sequence < css::lang::Locale > aLocaleSequence( xTmp->getLocales() );
2001-10-12 12:00:07 +00:00
aThesUsedLang = lcl_LocaleSeqToLangSeq( aLocaleSequence );
}
}
std::vector<LanguageType> aKnown;
sal_uInt32 nCount;
if ( nLangList & SvxLanguageListFlags::ONLY_KNOWN )
{
aKnown = LocaleDataWrapper::getInstalledLanguageTypes();
nCount = aKnown.size();
}
else
{
nCount = SvtLanguageTable::GetLanguageEntryCount();
}
for ( sal_uInt32 i = 0; i < nCount; i++ )
{
LanguageType nLangType;
if ( nLangList & SvxLanguageListFlags::ONLY_KNOWN )
nLangType = aKnown[i];
else
nLangType = SvtLanguageTable::GetLanguageTypeAtIndex( i );
if ( lcl_isPrerequisite( nLangType, nLangList) &&
(lcl_isScriptTypeRequested( nLangType, nLangList) ||
(bool(nLangList & SvxLanguageListFlags::FBD_CHARS) &&
MsLangId::hasForbiddenCharacters(nLangType)) ||
(bool(nLangList & SvxLanguageListFlags::SPELL_AVAIL) &&
lcl_SeqHasLang(aSpellAvailLang, nLangType)) ||
(bool(nLangList & SvxLanguageListFlags::HYPH_AVAIL) &&
lcl_SeqHasLang(aHyphAvailLang, nLangType)) ||
(bool(nLangList & SvxLanguageListFlags::THES_AVAIL) &&
lcl_SeqHasLang(aThesAvailLang, nLangType)) ||
(bool(nLangList & SvxLanguageListFlags::SPELL_USED) &&
lcl_SeqHasLang(aSpellUsedLang, (sal_uInt16)nLangType)) ||
(bool(nLangList & SvxLanguageListFlags::HYPH_USED) &&
lcl_SeqHasLang(aHyphUsedLang, nLangType)) ||
(bool(nLangList & SvxLanguageListFlags::THES_USED) &&
lcl_SeqHasLang(aThesUsedLang, nLangType))) )
InsertLanguage( nLangType );
}
if (bAddAvailable)
{
// Spell checkers, hyphenators and thesauri may add language tags
// unknown so far.
AddLanguages( aSpellAvailLang, nLangList);
AddLanguages( aHyphAvailLang, nLangList);
AddLanguages( aThesAvailLang, nLangList);
}
if (bHasLangNone)
InsertLanguage( LANGUAGE_NONE );
}
}
sal_Int32 SvxLanguageBoxBase::InsertLanguage( const LanguageType nLangType )
{
return ImplInsertLanguage( nLangType, LISTBOX_APPEND, css::i18n::ScriptType::WEAK );
}
sal_Int32 SvxLanguageBoxBase::ImplInsertLanguage( const LanguageType nLangType, sal_Int32 nPos, sal_Int16 nType )
2000-09-18 16:07:07 +00:00
{
LanguageType nLang = MsLangId::getReplacementForObsoleteLanguage( nLangType);
// For obsolete and to be replaced languages check whether an entry of the
// replacement already exists and if so don't add an entry with identical
// string as would be returned by SvtLanguageTable::GetString().
if (nLang != nLangType)
{
sal_Int32 nAt = ImplTypeToPos( nLang );
if ( nAt != LISTBOX_ENTRY_NOTFOUND )
return nAt;
}
OUString aStrEntry = SvtLanguageTable::GetLanguageString( nLang );
if (LANGUAGE_NONE == nLang && m_bHasLangNone && m_bLangNoneIsLangAll)
aStrEntry = m_aAllString;
LanguageType nRealLang = nLang;
if (nRealLang == LANGUAGE_SYSTEM)
{
nRealLang = MsLangId::resolveSystemLanguageByScriptType(nRealLang, nType);
aStrEntry += " - ";
aStrEntry += SvtLanguageTable::GetLanguageString( nRealLang );
} else if (nRealLang == LANGUAGE_USER_SYSTEM_CONFIG) {
nRealLang = MsLangId::getSystemLanguage();
aStrEntry += " - ";
aStrEntry += SvtLanguageTable::GetLanguageString( nRealLang );
}
CWS-TOOLING: integrate CWS vcl99 2009-01-29 15:34:04 +0100 hdu r267149 : #i77520# fix AquaSalGraphics::GetGlyphBoundRect() result y-sign 2009-01-29 10:14:23 +0100 hdu r267099 : #i77520# implement AquaSalGraphics::GetGlyphBoundRect() 2009-01-28 17:31:17 +0100 hdu r267071 : #i79046# restore MultiSalLayout components after drawing them 2009-01-28 12:02:19 +0100 tl r267050 : #78466# default curreny listbox for Arabic builds fixed 2009-01-28 11:54:21 +0100 tl r267049 : #78466# default curreny listbox for Arabic builds fixed 2009-01-28 11:43:44 +0100 tl r267047 : #78466# default curreny listbox for Arabic builds fixed 2009-01-28 11:17:42 +0100 tl r267041 : #78466# default curreny listbox for Arabic builds fixed 2009-01-28 11:14:30 +0100 tl r267038 : #78466# default curreny listbox for Arabic builds fixed 2009-01-28 10:33:03 +0100 tl r267032 : #i72073# auto spellcheck markups in RTL context fixed 2009-01-28 09:26:00 +0100 tl r267027 : #78466# default curreny listbox for Arabic builds fixed 2009-01-28 09:25:31 +0100 tl r267026 : #78466# default curreny listbox for Arabic builds fixed 2009-01-27 16:55:14 +0100 tl r267009 : #78466# default curreny listbox for Arabic builds fixed 2009-01-27 16:54:46 +0100 tl r267008 : #78466# default curreny listbox for Arabic builds fixed 2009-01-27 16:52:23 +0100 tl r267007 : #78466# default curreny listbox for Arabic builds fixed 2009-01-27 16:46:52 +0100 tl r267006 : #i72073# auto spellcheck markups in RTL context fixed 2009-01-27 11:53:53 +0100 pl r266975 : #i98515# fix a buffer overflow 2009-01-26 19:13:28 +0100 pl r266946 : #i98119# add static vcl object helper 2009-01-26 18:11:06 +0100 pl r266940 : #i94040# catch a corner case (thanks af) 2009-01-23 10:54:42 +0100 pl r266793 : #i92102# fix some RTL UI issues 2009-01-23 10:53:35 +0100 pl r266790 : #i98169# one more case of DrawWaveLine 2009-01-23 08:38:32 +0100 hdu r266768 : #i98139# prefer Tools->Options->FontSubstitution over PreMatchHook 2009-01-21 17:30:57 +0100 pl r266694 : #i92102# adjust spin buttons 2009-01-21 13:54:16 +0100 pl r266667 : #i97130# add Click handler 2009-01-21 13:32:47 +0100 os r266662 : #158646# set SwWrtShell in C'tor of SwIndexMarkDlg 2009-01-21 12:14:03 +0100 pl r266649 : #i98196# fix autospellchecking in writer 2009-01-19 14:25:28 +0100 pl r266497 : #i97130# implement functionality of ExplainButton
2009-02-17 10:33:03 +00:00
aStrEntry = ApplyLreOrRleEmbedding( aStrEntry );
sal_Int32 nAt = 0;
if ( m_bWithCheckmark )
{
bool bFound = false;
if (!m_pSpellUsedLang)
{
Reference< XSpellChecker1 > xSpell( LinguMgr::GetSpellChecker(), UNO_QUERY );
if ( xSpell.is() )
m_pSpellUsedLang.reset( new Sequence< sal_Int16 >( xSpell->getLanguages() ) );
}
bFound = m_pSpellUsedLang &&
lcl_SeqHasLang( *m_pSpellUsedLang, (sal_uInt16)nRealLang );
2002-07-19 09:07:02 +00:00
nAt = ImplInsertImgEntry( aStrEntry, nPos, bFound );
}
else
nAt = ImplInsertEntry( aStrEntry, nPos );
2000-09-18 16:07:07 +00:00
ImplSetEntryData( nAt, reinterpret_cast<void*>((sal_uInt16)nLangType) );
return nAt;
2000-09-18 16:07:07 +00:00
}
void SvxLanguageBoxBase::InsertDefaultLanguage( sal_Int16 nType )
{
ImplInsertLanguage( LANGUAGE_SYSTEM, LISTBOX_APPEND, nType );
}
void SvxLanguageBoxBase::InsertSystemLanguage()
{
ImplInsertLanguage( LANGUAGE_USER_SYSTEM_CONFIG, LISTBOX_APPEND, css::i18n::ScriptType::WEAK );
}
void SvxLanguageBoxBase::InsertLanguage( const LanguageType nLangType,
bool bCheckEntry )
{
LanguageType nLang = MsLangId::getReplacementForObsoleteLanguage( nLangType);
// For obsolete and to be replaced languages check whether an entry of the
// replacement already exists and if so don't add an entry with identical
// string as would be returned by SvtLanguageTable::GetString().
if (nLang != nLangType)
{
sal_Int32 nAt = ImplTypeToPos( nLang );
if ( nAt != LISTBOX_ENTRY_NOTFOUND )
return;
}
OUString aStrEntry = SvtLanguageTable::GetLanguageString( nLang );
if (LANGUAGE_NONE == nLang && m_bHasLangNone && m_bLangNoneIsLangAll)
aStrEntry = m_aAllString;
sal_Int32 nAt = ImplInsertImgEntry( aStrEntry, LISTBOX_APPEND, bCheckEntry );
ImplSetEntryData( nAt, reinterpret_cast<void*>((sal_uInt16)nLang) );
}
void SvxLanguageBoxBase::RemoveLanguage( const LanguageType eLangType )
2000-09-18 16:07:07 +00:00
{
sal_Int32 nAt = ImplTypeToPos( eLangType );
2000-09-18 16:07:07 +00:00
if ( nAt != LISTBOX_ENTRY_NOTFOUND )
ImplRemoveEntryAt( nAt );
2000-09-18 16:07:07 +00:00
}
LanguageType SvxLanguageBoxBase::GetSelectLanguage() const
2000-09-18 16:07:07 +00:00
{
sal_Int32 nPos = ImplGetSelectEntryPos();
2000-09-18 16:07:07 +00:00
if ( nPos != LISTBOX_ENTRY_NOTFOUND )
return LanguageType( reinterpret_cast<sal_uIntPtr>(ImplGetEntryData(nPos)) );
2000-09-18 16:07:07 +00:00
else
return LANGUAGE_DONTKNOW;
2000-09-18 16:07:07 +00:00
}
void SvxLanguageBoxBase::SelectLanguage( const LanguageType eLangType )
2000-09-18 16:07:07 +00:00
{
// If the core uses a LangID of an imported MS document and wants to select
// a language that is replaced, we need to select the replacement instead.
LanguageType nLang = MsLangId::getReplacementForObsoleteLanguage( eLangType);
sal_Int32 nAt = ImplTypeToPos( nLang );
2000-09-18 16:07:07 +00:00
if ( nAt == LISTBOX_ENTRY_NOTFOUND )
nAt = InsertLanguage( nLang ); // on-the-fly-ID
2000-09-18 16:07:07 +00:00
if ( nAt != LISTBOX_ENTRY_NOTFOUND )
ImplSelectEntryPos( nAt, true/*bSelect*/ );
2000-09-18 16:07:07 +00:00
}
bool SvxLanguageBoxBase::IsLanguageSelected( const LanguageType eLangType ) const
2000-09-18 16:07:07 +00:00
{
// Same here, work on the replacement if applicable.
LanguageType nLang = MsLangId::getReplacementForObsoleteLanguage( eLangType);
sal_Int32 nAt = ImplTypeToPos( nLang );
2000-09-18 16:07:07 +00:00
if ( nAt != LISTBOX_ENTRY_NOTFOUND )
return ImplIsEntryPosSelected( nAt );
2000-09-18 16:07:07 +00:00
else
return false;
2000-09-18 16:07:07 +00:00
}
sal_Int32 SvxLanguageBoxBase::ImplTypeToPos( LanguageType eType ) const
{
return ImplGetEntryPos( reinterpret_cast<void*>((sal_uInt16)eType) );
}
void SvxLanguageBoxBase::SetNoSelectionLBB()
{
ImplSetNoSelection();
}
void SvxLanguageBoxBase::HideLBB()
{
ImplHide();
}
void SvxLanguageBoxBase::DisableLBB()
{
ImplDisable();
}
void SvxLanguageBoxBase::SaveValueLBB()
{
ImplSaveValue();
}
sal_Int32 SvxLanguageBoxBase::GetSelectEntryPosLBB() const
{
return ImplGetSelectEntryPos();
}
void* SvxLanguageBoxBase::GetEntryDataLBB( sal_Int32 nPos ) const
{
return ImplGetEntryData( nPos);
}
sal_Int32 SvxLanguageBoxBase::GetSavedValueLBB() const
{
return ImplGetSavedValue();
}
SvxLanguageBox::SvxLanguageBox( vcl::Window* pParent, WinBits nBits )
: ListBox( pParent, nBits )
, SvxLanguageBoxBase()
{
// display entries sorted
SetStyle( GetStyle() | WB_SORT );
ImplLanguageBoxBaseInit();
}
SvxLanguageComboBox::SvxLanguageComboBox( vcl::Window* pParent, WinBits nBits )
: ComboBox( pParent, nBits )
, SvxLanguageBoxBase()
, mnSavedValuePos( COMBOBOX_ENTRY_NOTFOUND )
, meEditedAndValid( EditedAndValid::No )
{
// display entries sorted
SetStyle( GetStyle() | WB_SORT );
EnableMultiSelection( false );
ImplLanguageBoxBaseInit();
SetModifyHdl( LINK( this, SvxLanguageComboBox, EditModifyHdl ) );
}
sal_Int32 SvxLanguageBox::ImplInsertImgEntry( const OUString& rEntry, sal_Int32 nPos, bool bChecked )
{
return InsertEntry( rEntry, (bChecked ? m_aCheckedImage : m_aNotCheckedImage), nPos );
}
sal_Int32 SvxLanguageComboBox::ImplInsertImgEntry( const OUString& rEntry, sal_Int32 nPos, bool bChecked )
{
return InsertEntryWithImage( rEntry, (bChecked ? m_aCheckedImage : m_aNotCheckedImage), nPos );
}
void SvxLanguageBox::ImplRemoveEntryAt( sal_Int32 nPos )
{
RemoveEntry( nPos);
}
void SvxLanguageComboBox::ImplRemoveEntryAt( sal_Int32 nPos )
{
RemoveEntryAt( nPos);
}
void SvxLanguageBox::ImplClear()
{
Clear();
}
void SvxLanguageComboBox::ImplClear()
{
Clear();
}
sal_Int32 SvxLanguageBox::ImplInsertEntry( const OUString& rEntry, sal_Int32 nPos )
{
return InsertEntry( rEntry, nPos);
}
sal_Int32 SvxLanguageComboBox::ImplInsertEntry( const OUString& rEntry, sal_Int32 nPos )
{
return InsertEntry( rEntry, nPos);
}
void SvxLanguageBox::ImplSetEntryData( sal_Int32 nPos, void* pData )
{
SetEntryData( nPos, pData);
}
void SvxLanguageComboBox::ImplSetEntryData( sal_Int32 nPos, void* pData )
{
SetEntryData( nPos, pData);
}
sal_Int32 SvxLanguageBox::ImplGetSelectEntryPos() const
{
return GetSelectedEntryPos();
}
sal_Int32 SvxLanguageComboBox::ImplGetSelectEntryPos() const
{
return GetSelectedEntryPos();
}
void* SvxLanguageBox::ImplGetEntryData( sal_Int32 nPos ) const
{
return GetEntryData( nPos);
}
void* SvxLanguageComboBox::ImplGetEntryData( sal_Int32 nPos ) const
{
return GetEntryData( nPos);
}
void SvxLanguageBox::ImplSelectEntryPos( sal_Int32 nPos, bool bSelect )
{
SelectEntryPos( nPos, bSelect);
}
void SvxLanguageComboBox::ImplSelectEntryPos( sal_Int32 nPos, bool bSelect )
{
SelectEntryPos( nPos, bSelect);
}
bool SvxLanguageBox::ImplIsEntryPosSelected( sal_Int32 nPos ) const
{
return IsEntryPosSelected( nPos);
}
bool SvxLanguageComboBox::ImplIsEntryPosSelected( sal_Int32 nPos ) const
{
return IsEntryPosSelected( nPos);
}
sal_Int32 SvxLanguageBox::ImplGetEntryPos( const void* pData ) const
{
return GetEntryPos( pData);
}
sal_Int32 SvxLanguageComboBox::ImplGetEntryPos( const void* pData ) const
{
return GetEntryPos( pData);
}
void SvxLanguageBox::ImplSetNoSelection()
{
SetNoSelection();
}
void SvxLanguageComboBox::ImplSetNoSelection()
{
SetNoSelection();
}
void SvxLanguageBox::ImplHide()
{
Hide();
}
void SvxLanguageComboBox::ImplHide()
{
Hide();
}
void SvxLanguageBox::ImplDisable()
{
Disable();
}
void SvxLanguageComboBox::ImplDisable()
{
Disable();
}
void SvxLanguageBox::ImplSaveValue()
{
SaveValue();
}
void SvxLanguageComboBox::ImplSaveValue()
{
// Emulate the ListBox behavior.
mnSavedValuePos = GetSelectedEntryPos();
}
sal_Int32 SvxLanguageBox::ImplGetSavedValue() const
{
return GetSavedValue();
}
sal_Int32 SvxLanguageComboBox::ImplGetSavedValue() const
{
return mnSavedValuePos;
}
IMPL_LINK_NOARG( SvxLanguageComboBox, EditModifyHdl, Edit&, void )
{
EditedAndValid eOldState = meEditedAndValid;
OUString aStr( vcl::I18nHelper::filterFormattingChars( GetText()));
if (aStr.isEmpty())
meEditedAndValid = EditedAndValid::Invalid;
else
{
const sal_Int32 nPos = GetEntryPos( aStr);
if (nPos != COMBOBOX_ENTRY_NOTFOUND)
{
Selection aSel( GetSelection());
// Select the corresponding listbox entry if not current. This
// invalidates the Edit Selection thus has to happen between
// obtaining the Selection and setting the new Selection.
sal_Int32 nSelPos = ImplGetSelectEntryPos();
bool bSetEditSelection;
if (nSelPos == nPos)
bSetEditSelection = false;
else
{
ImplSelectEntryPos( nPos, true);
bSetEditSelection = true;
}
// If typing into the Edit control led us here, advance start of a
// full selection by one so the next character will already
// continue the string instead of having to type the same character
// again to start a new string. The selection includes formatting
// characters and is reverse when obtained from the Edit control.
if (aSel.Max() == 1)
{
OUString aText( GetText());
if (aSel.Min() == aText.getLength())
{
++aSel.Max();
bSetEditSelection = true;
}
}
if (bSetEditSelection)
SetSelection( aSel);
meEditedAndValid = EditedAndValid::No;
}
else
{
OUString aCanonicalized;
bool bValid = LanguageTag::isValidBcp47( aStr, &aCanonicalized, true);
meEditedAndValid = (bValid ? EditedAndValid::Valid : EditedAndValid::Invalid);
if (bValid && aCanonicalized != aStr)
{
SetText( aCanonicalized);
SetSelection( Selection( aCanonicalized.getLength()));
}
}
}
if (eOldState != meEditedAndValid)
{
if (meEditedAndValid == EditedAndValid::Invalid)
{
#if 0
//! Gives white on white!?! instead of white on reddish.
SetControlBackground( ::Color( RGB_COLORDATA( 0xff, 0x65, 0x63)));
SetControlForeground( ::Color( COL_WHITE));
#else
SetControlForeground( ::Color( RGB_COLORDATA( 0xf0, 0, 0)));
#endif
}
else
{
SetControlForeground();
SetControlBackground();
}
}
}
sal_Int32 SvxLanguageComboBox::SaveEditedAsEntry()
{
if (meEditedAndValid != EditedAndValid::Valid)
return COMBOBOX_ENTRY_NOTFOUND;
LanguageTag aLanguageTag( vcl::I18nHelper::filterFormattingChars( GetText()));
LanguageType nLang = aLanguageTag.getLanguageType();
if (nLang == LANGUAGE_DONTKNOW)
{
SAL_WARN( "svx.dialog", "SvxLanguageComboBox::SaveEditedAsEntry: unknown tag");
return COMBOBOX_ENTRY_NOTFOUND;
}
sal_Int32 nPos = ImplTypeToPos( nLang);
if (nPos != COMBOBOX_ENTRY_NOTFOUND)
return nPos; // Already present but with a different string.
if (SvtLanguageTable::HasLanguageType( nLang))
{
// In SvtLanguageTable but not in SvxLanguageComboBox. On purpose? This
// may be an entry with different settings or CTL instead of Western or
// ... all things we don't handle yet.
SAL_WARN( "svx.dialog", "SvxLanguageComboBox::SaveEditedAsEntry: already in SvtLanguageTable: " <<
SvtLanguageTable::GetLanguageString( nLang) << ", " << nLang);
}
else
{
// Add to both, SvtLanguageTable and SvxLanguageComboBox.
/* TODO: a descriptive user comment would be a nice to have here. */
SvtLanguageTable::AddLanguageTag( aLanguageTag, OUString());
}
nPos = InsertLanguage( nLang);
return nPos;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */