/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * 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 .
*/
#ifdefined(_WIN32) // Store-packaged apps (located under the protected Program Files\WindowsApps) can't use normal // shell shortcuts to their exe. TODO: show a button to open "Startup Apps" system applet? if (!sal::systools::IsStorePackagedApp())
m_xQuickStarterFrame->show();
// For now Skia is used mainly on Windows, enable the controls there. if (Application::GetToolkitName() == "win")
skiaHidden = false; // It can also be used on Linux, but only with the rarely used 'gen' backend. if (Application::GetToolkitName() == "x11")
skiaHidden = false; // OSX backend has Skia support too. if (Application::GetToolkitName() == "osx")
skiaHidden = false;
if (skiaHidden)
{
HideSkiaWidgets(); return;
}
// Easier than a custom translation string. bool bEnabled = SkiaHelper::isVCLSkiaEnabled();
m_xSkiaStatusEnabled->set_visible(bEnabled);
m_xSkiaStatusDisabled->set_visible(!bEnabled);
// Technically the 'use hardware acceleration' option could be used to mean !forceSkiaRaster, but the implementation // of the option is so tied to the implementation of the canvas module that it's simpler to ignore it.
UpdateHardwareAccelStatus(); #else
HideSkiaWidgets(); #endif
}
if (m_xFontShowCB->get_state_changed_from_saved())
{
officecfg::Office::Common::Font::View::ShowFontBoxWYSIWYG::set(m_xFontShowCB->get_active(), xChanges);
bModified = true;
}
// #i95644# if disabled, do not use value, see in ::Reset() if (m_xUseHardwareAccell->get_sensitive())
{ if(m_xUseHardwareAccell->get_state_changed_from_saved())
{
officecfg::Office::Canvas::ForceSafeServiceImpl::set(m_xUseHardwareAccell->get_active(), xChanges);
bModified = true;
}
}
// #i95644# if disabled, do not use value, see in ::Reset() if (m_xUseAntiAliase->get_sensitive())
{ if (m_xUseAntiAliase->get_active() != SvtOptionsDrawinglayer::IsAntiAliasing())
{
SvtOptionsDrawinglayer::SetAntiAliasing(m_xUseAntiAliase->get_active(), /*bTemporary*/false);
bModified = true;
bRepaintWindows = true;
}
}
static OUString lcl_getDatePatternsConfigString( const LocaleDataWrapper& rLocaleWrapper )
{ const Sequence< OUString >& aDateAcceptancePatterns = rLocaleWrapper.getDateAcceptancePatterns();
sal_Int32 nPatterns = aDateAcceptancePatterns.getLength();
OUStringBuffer aBuf( nPatterns * 6 ); // 6 := length of Y-M-D;
SAL_WARN_IF( !nPatterns, "cui.options", "No date acceptance pattern"); if (nPatterns)
{
aBuf.append(aDateAcceptancePatterns[0]); for (sal_Int32 i=1; i < nPatterns; ++i)
aBuf.append(";" + aDateAcceptancePatterns[i]);
} return aBuf.makeStringAndClear();
}
namespace
{ //what ui language will be selected by default if the user override of General::UILocale is unset ?
LanguageTag GetInstalledLocaleForSystemUILanguage()
{
css::uno::Sequence<OUString> inst(officecfg::Setup::Office::InstalledLocales::get()->getElementNames()); return LanguageTag(getInstalledLocaleForSystemUILanguage(inst, false)).makeFallback();
}
}
// tdf#114694: append the sorted list after the default entry and separator. for (constauto & [ nGroupID, sGroupName ] : aUILanguages)
{
m_xUserInterfaceLB->append(OUString::number(nGroupID), sGroupName);
}
m_xUserInterfaceLB->set_active(0);
// find out whether the user has a specific locale specified
Sequence< Any > theArgs2{ Any(NamedValue(u"nodepath"_ustr, Any(sUserLocalePath))) };
theNameAccess.set(
theConfigProvider->createInstanceWithArguments(sAccessSrvc, theArgs2 ), UNO_QUERY_THROW ); if (theNameAccess->hasByName(sUserLocaleKey))
theNameAccess->getByName(sUserLocaleKey) >>= m_sUserLocaleValue; // select the user specified locale in the listbox if (!m_sUserLocaleValue.isEmpty())
{ for (sal_Int32 i = 0, nEntryCount = m_xUserInterfaceLB->get_count(); i < nEntryCount; ++i)
{
sal_Int32 d = m_xUserInterfaceLB->get_id(i).toInt32(); if ( d > 0 && seqInstalledLanguages.getLength() > d-1 && seqInstalledLanguages[d-1] == m_sUserLocaleValue)
m_xUserInterfaceLB->set_active(i);
}
}
} catch (const Exception &)
{ // we'll just leave the box in its default setting and won't // even give it event handler...
TOOLS_WARN_EXCEPTION("cui.options", "ignoring" );
}
for (constauto& check : checkButton)
{ if (constauto pString = m_xBuilder->weld_check_button(check))
sAllStrings += pString->get_label() + " ";
}
return sAllStrings.replaceAll("_", "");
}
bool OfaLanguagesTabPage::FillItemSet( SfxItemSet* rSet )
{ // lock configuration broadcasters so that we can coordinate the notifications
pLangConfig->aSysLocaleOptions.BlockBroadcasts( true );
pLangConfig->aCTLLanguageOptions.BlockBroadcasts( true );
pLangConfig->aLinguConfig.BlockBroadcasts( true );
/* * Sequence checking only matters when CTL support is enabled. * * So we only need to check for sequence checking if * a) previously it was unchecked and is now checked or * b) it was already checked but the CTL language has changed
*/ if (
m_xCTLSupportCB->get_active() &&
(m_xCTLSupportCB->get_saved_state() != TRISTATE_TRUE ||
m_xComplexLanguageLB->get_active_id_changed_from_saved())
)
{ //sequence checking has to be switched on depending on the selected CTL language
LanguageType eCTLLang = m_xComplexLanguageLB->get_active_id(); bool bOn = MsLangId::needsSequenceChecking( eCTLLang);
pLangConfig->aCTLLanguageOptions.SetCTLSequenceCheckingRestricted(bOn);
pLangConfig->aCTLLanguageOptions.SetCTLSequenceChecking(bOn);
pLangConfig->aCTLLanguageOptions.SetCTLSequenceCheckingTypeAndReplace(bOn);
} try
{ // handle settings for UI Language // a change of setting needs to bring up a warning message
OUString aLangString;
sal_Int32 d = m_xUserInterfaceLB->get_active_id().toInt32(); if( d > 0 && seqInstalledLanguages.getLength() > d-1)
aLangString = seqInstalledLanguages[d-1];
/* if( m_xUserInterfaceLB->GetSelectedEntryPos() > 0) aLangString = ConvertLanguageToIsoString(m_xUserInterfaceLB->get_active_id());
*/
Reference< XMultiServiceFactory > theConfigProvider(
css::configuration::theDefaultProvider::get(
comphelper::getProcessComponentContext()));
Sequence< Any > theArgs{ Any(NamedValue(u"nodepath"_ustr, Any(sUserLocalePath))) };
Reference< XPropertySet >xProp(
theConfigProvider->createInstanceWithArguments(sAccessUpdSrvc, theArgs ), UNO_QUERY_THROW ); if ( m_sUserLocaleValue != aLangString)
{ // OSL_FAIL("UserInterface language was changed, restart."); // write new value
xProp->setPropertyValue(sUserLocaleKey, Any(aLangString));
Reference< XChangesBatch >(xProp, UNO_QUERY_THROW)->commitChanges(); // display info
SolarMutexGuard aGuard; if (svtools::executeRestartDialog(
comphelper::getProcessComponentContext(), GetFrameWeld(),
svtools::RESTART_REASON_LANGUAGE_CHANGE))
GetDialogController()->response(RET_OK);
// tell quickstarter to stop being a veto listener
const Reference< XComponentContext >& xContext(
comphelper::getProcessComponentContext());
css::office::Quickstart::createAndSetVeto(xContext, false, false, false/*DisableVeto*/);
}
} catch (const Exception&)
{ // we'll just leave the box in its default setting and won't // even give it event handler...
TOOLS_WARN_EXCEPTION("cui.options", "ignoring");
}
// If the "Default ..." entry was selected that means SYSTEM, the actual // eNewLocale value is temporary for the dialog only, do not resolve to // what system currently is. if (eNewLocale == LANGUAGE_USER_SYSTEM_CONFIG)
eNewLocale = LANGUAGE_SYSTEM;
if ( eOldLocale != eNewLocale )
{ // an empty string denotes SYSTEM locale
OUString sNewLang; if ( eNewLocale != LANGUAGE_SYSTEM )
sNewLang = LanguageTag::convertToBcp47( eNewLocale);
// locale nowadays get to AppSettings via notification // this will happen after releasing the lock on the ConfigurationBroadcaster at // the end of this method
pLangConfig->aSysLocaleOptions.SetLocaleConfigString( sNewLang );
rSet->Put( SfxBoolItem( SID_OPT_LOCALE_CHANGED, true ) );
// Configured currency, for example, USD-en-US or EUR-de-DE, or empty for locale default.
OUString sOldCurr = pLangConfig->aSysLocaleOptions.GetCurrencyConfigString();
OUString sId = m_xCurrencyLB->get_active_id(); const NfCurrencyEntry* pCurr = sId == "default" ? nullptr : weld::fromId<const NfCurrencyEntry*>(sId);
OUString sNewCurr; if ( pCurr )
sNewCurr = SvtSysLocaleOptions::CreateCurrencyConfigString(
pCurr->GetBankSymbol(), pCurr->GetLanguage() ); if ( sOldCurr != sNewCurr )
pLangConfig->aSysLocaleOptions.SetCurrencyConfigString( sNewCurr );
// Configured date acceptance patterns, for example Y-M-D;M-D or empty for // locale default. if (m_bDatePatternsValid && m_xDatePatternsED->get_value_changed_from_saved())
pLangConfig->aSysLocaleOptions.SetDatePatternsConfigString( m_xDatePatternsED->get_text());
if ( pLangConfig->aSysLocaleOptions.IsModified() )
pLangConfig->aSysLocaleOptions.Commit();
// first release the lock on the ConfigurationBroadcaster for Locale changes // it seems that our code relies on the fact that before other changes like e.g. currency // are broadcasted locale changes have been done
pLangConfig->aSysLocaleOptions.BlockBroadcasts( false );
pLangConfig->aCTLLanguageOptions.BlockBroadcasts( false );
pLangConfig->aLinguConfig.BlockBroadcasts( false );
// let LocaleSettingHdl enable/disable checkboxes for CJK/CTL support // #i15812# must be done *before* the configured currency is set // and update the decimal separator used for the given locale
LocaleSettingHdl(*m_xLocaleSettingLB->get_widget());
// configured currency, for example, USD-en-US or EUR-de-DE, or empty for locale default const NfCurrencyEntry* pCurr = nullptr;
OUString sCurrency = pLangConfig->aSysLocaleOptions.GetCurrencyConfigString(); if ( !sCurrency.isEmpty() )
{
LanguageType eLang;
OUString aAbbrev;
SvtSysLocaleOptions::GetCurrencyAbbrevAndLanguage( aAbbrev, eLang, sCurrency );
pCurr = SvNumberFormatter::GetCurrencyEntry( aAbbrev, eLang );
} // if pCurr==nullptr the SYSTEM entry is selected
OUString sId = !pCurr ? u"default"_ustr : weld::toId(pCurr);
m_xCurrencyLB->set_active_id(sId);
bReadonly = pLangConfig->aSysLocaleOptions.IsReadOnly(SvtSysLocaleOptions::EOption::Currency);
m_xCurrencyLB->set_sensitive(!bReadonly);
m_xCurrencyFT->set_sensitive(!bReadonly);
m_xCurrencyImg->set_visible(bReadonly);
// check the box "For the current document only" // set the focus to the Western Language box const SfxBoolItem* pLang = rSet->GetItemIfSet(SID_SET_DOCUMENT_LANGUAGE, false ); if ( pLang && pLang->GetValue() )
{
m_xWesternLanguageLB->grab_focus();
m_xCurrentDocCB->set_sensitive(true);
m_xCurrentDocCB->set_active(true);
}
}
namespace
{ void lcl_checkLanguageCheckBox(weld::CheckButton& _rCB, bool _bNewValue, bool _bOldValue)
{ if ( _bNewValue )
_rCB.set_active(true); else
_rCB.set_active( _bOldValue ); // #i15082# do not call save_state() in running dialog... // _rCB.save_state();
_rCB.set_sensitive( !_bNewValue );
}
}
IMPL_LINK_NOARG(OfaLanguagesTabPage, LocaleSettingHdl, weld::ComboBox&, void)
{
LanguageType eLang = m_xLocaleSettingLB->get_active_id();
SvtScriptType nType = SvtLanguageOptions::GetScriptTypeOfLanguage(eLang); // first check if CTL must be enabled // #103299# - if CTL font setting is not readonly if(!pLangConfig->aCTLLanguageOptions.IsReadOnly(SvtCTLOptions::E_CTLFONT))
{ bool bIsCTLFixed = bool(nType & SvtScriptType::COMPLEX);
lcl_checkLanguageCheckBox(*m_xCTLSupportCB, bIsCTLFixed, m_bOldCtl);
SupportHdl(*m_xCTLSupportCB);
} // second check if CJK must be enabled // #103299# - if CJK support is not readonly if(!SvtCJKOptions::IsAnyReadOnly())
{ bool bIsCJKFixed = bool(nType & SvtScriptType::ASIAN);
lcl_checkLanguageCheckBox(*m_xAsianSupportCB, bIsCJKFixed, m_bOldAsian);
SupportHdl(*m_xAsianSupportCB);
}
// obtain corresponding locale data
LocaleDataWrapper aLocaleWrapper(( LanguageTag(eLang) ));
// update the decimal separator key of the related CheckBox
OUString sTempLabel(m_sDecimalSeparatorLabel);
sTempLabel = sTempLabel.replaceFirst("%1", aLocaleWrapper.getNumDecimalSep() );
m_xDecimalSeparatorCB->set_label(sTempLabel);
// update the date acceptance patterns
OUString aDatePatternsString = lcl_getDatePatternsConfigString( aLocaleWrapper);
m_bDatePatternsValid = true;
m_xDatePatternsED->set_text( aDatePatternsString);
m_xDatePatternsED->set_message_type(weld::EntryMessageType::Normal);
}
IMPL_LINK( OfaLanguagesTabPage, DatePatternsHdl, weld::Entry&, rEd, void )
{
OUString aPatterns(rEd.get_text()); bool bModified = false; constbool bValid = validateDatePatterns( bModified, aPatterns); if (bModified)
{ // gtk3 keeps the cursor position on equal length set_text() but at // least the 'gen' backend does not and resets to 0. constint nCursorPos = rEd.get_position();
rEd.set_text(aPatterns);
rEd.set_position(nCursorPos);
} if (bValid)
rEd.set_message_type(weld::EntryMessageType::Normal); else
rEd.set_message_type(weld::EntryMessageType::Error);
m_bDatePatternsValid = bValid;
}
bool OfaLanguagesTabPage::validateDatePatterns( bool& rbModified, OUString& rPatterns )
{ bool bValid = true; if (!rPatterns.isEmpty())
{
OUStringBuffer aBuf( rPatterns);
sal_Int32 nChar = 0; for (sal_Int32 nIndex=0; nIndex >= 0 && bValid; ++nChar)
{ const OUString aPat( rPatterns.getToken( 0, ';', nIndex)); if (aPat.isEmpty() && nIndex < 0)
{ // Indicating failure when about to append a pattern is too // confusing. Empty patterns are ignored anyway when sequencing // to SvtSysLocale. continue; // for
} elseif (aPat.getLength() < 2)
bValid = false; else
{ bool bY, bM, bD;
bY = bM = bD = false; bool bSep = true; if (aPat.getLength() == 3)
{ // Disallow a pattern that would match a numeric input with // decimal separator, like M.D const LanguageType eLang = m_xLocaleSettingLB->get_active_id(); const LocaleDataWrapper aLocaleWrapper(( LanguageTag(eLang))); if ( aPat[1] == aLocaleWrapper.getNumDecimalSep().toChar()
|| aPat[1] == aLocaleWrapper.getNumDecimalSepAlt().toChar())
{
bValid = false;
}
} for (sal_Int32 i = 0; i < aPat.getLength() && bValid; /*nop*/)
{ const sal_Int32 j = i; const sal_uInt32 c = aPat.iterateCodePoints( &i); // Only one Y,M,D per pattern, separated by any character(s). switch (c)
{ case'y': case'Y': if (bY || !bSep)
bValid = false; elseif (c == 'y')
{
aBuf[nChar] = 'Y';
rbModified = true;
}
bY = true;
bSep = false; break; case'm': case'M': if (bM || !bSep)
bValid = false; elseif (c == 'm')
{
aBuf[nChar] = 'M';
rbModified = true;
}
bM = true;
bSep = false; break; case'd': case'D': if (bD || !bSep)
bValid = false; elseif (c == 'd')
{
aBuf[nChar] = 'D';
rbModified = true;
}
bD = true;
bSep = false; break; default: // A pattern must not start with a separator (but // may end with). if (!(bY || bM || bD))
bValid = false;
bSep = true;
}
nChar += i-j;
} // At least one of Y,M,D
bValid &= (bY || bM || bD);
}
} if (rbModified)
rPatterns = aBuf.makeStringAndClear();
} return bValid;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.