/* -*- 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 .
*/
#include <config_features.h>
#include <svl/numformat.hxx>
#include <svl/zforlist.hxx>
#include <svl/currencytable.hxx>
#include <svtools/langhelp.hxx>
#include <unotools/lingucfg.hxx>
#if defined (_WIN32)
#include <unotools/resmgr.hxx>
#endif
#include <sfx2/bindings.hxx>
#include <sfx2/viewfrm.hxx>
#include <i18nlangtag/mslangid.hxx>
#include <i18nlangtag/languagetag.hxx>
#include <unotools/compatibility.hxx>
#include <svl/languageoptions.hxx>
#include <svl/cjkoptions.hxx>
#include <svl/ctloptions.hxx>
#include <unotools/syslocaleoptions.hxx>
#include <sfx2/objsh.hxx>
#include <comphelper/propertysequence.hxx>
#include <comphelper/propertyvalue.hxx>
#include <svtools/langtab.hxx>
#include <editeng/unolingu.hxx>
#include <editeng/langitem.hxx>
#include <comphelper/processfactory.hxx>
#include <comphelper/string.hxx>
#include <rtl/ustrbuf.hxx>
#include <editeng/editids.hrc>
#include <svx/svxids.hrc>
#include <svl/intitem.hxx>
#include <svl/voiditem.hxx>
#include <GraphicsTestsDialog.hxx>
#include <unotools/searchopt.hxx>
#include <sal/log.hxx>
#include <officecfg/Office/Canvas.hxx>
#include <officecfg/Office/Common.hxx>
#include <officecfg/Setup.hxx>
#include <comphelper/configuration.hxx>
#include <comphelper/diagnose_ex.hxx>
#if HAVE_FEATURE_BREAKPAD
#include <desktop/crashreport.hxx>
#endif
#include <com/sun/star/configuration/theDefaultProvider.hpp>
#include <com/sun/star/container/XNameAccess.hpp>
#include <com/sun/star/container/XNameReplace.hpp>
#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
#include <com/sun/star/beans/NamedValue.hpp>
#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/util/XChangesBatch.hpp>
#include <com/sun/star/uno/Any.hxx>
#include <com/sun/star/container/XContentEnumerationAccess.hpp>
#include <com/sun/star/container/XSet.hpp>
#include <com/sun/star/i18n/ScriptType.hpp>
#include <com/sun/star/office/Quickstart.hpp>
#include <com/sun/star/linguistic2/XLinguProperties.hpp>
#include <comphelper/dispatchcommand.hxx>
#include <vcl/vclenum.hxx>
#include <vcl/svapp.hxx>
#include <vcl/settings.hxx>
#include <vcl/window.hxx>
#include <vcl/IconThemeInfo.hxx>
#include <vcl/skia/SkiaHelper.hxx>
#include <bitmaps.hlst>
#include "optgdlg.hxx"
#include <svtools/apearcfg.hxx>
#include <svtools/optionsdrawinglayer.hxx>
#include <svtools/restartdialog.hxx>
#include <svtools/imgdef.hxx>
#include <com/sun/star/datatransfer/clipboard/SystemClipboard.hpp>
#include <vcl/unohelp2.hxx>
#if defined (_WIN32)
#include <systools/win32/winstoreutil.hxx>
#include <vcl/fileregistration.hxx>
#endif
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::util;
using namespace ::utl;
// class OfaMiscTabPage --------------------------------------------------
DeactivateRC OfaMiscTabPage::DeactivatePage( SfxItemSet* pSet_ )
{
if ( pSet_ )
FillItemSet( pSet_ );
return DeactivateRC::LeavePage;
}
namespace
{
const OUString & impl_SystemFileOpenServiceName()
{
#if defined (_WIN32)
static constexpr OUString gPicker = u
"com.sun.star.ui.dialogs.SystemFilePicker" _ustr;
return gPicker;
#elif defined MACOSX
static constexpr OUString gPicker = u
"com.sun.star.ui.dialogs.AquaFilePicker" _ustr;
return gPicker;
#else
return EMPTY_OUSTRING;
#endif
}
bool lcl_HasSystemFilePicker()
{
if ( Application::hasNativeFileSelection() )
return true ;
// Otherwise fall-back on querying services
bool bRet =
false ;
Reference< XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory();
Reference< XContentEnumerationAccess > xEnumAccess( xFactory, UNO_QUERY );
Reference< XSet > xSet( xFactory, UNO_QUERY );
if ( ! xEnumAccess.is() || ! xSet.is() )
return bRet;
try
{
const OUString& aFileService = impl_SystemFileOpenServiceName();
Reference< XEnumeration > xEnum = xEnumAccess->createContentEnumeration( aFileService );
if ( xEnum.is() && xEnum->hasMoreElements() )
bRet =
true ;
}
catch (
const IllegalArgumentException&)
{
}
catch (
const ElementExistException&)
{
}
return bRet;
}
}
OfaMiscTabPage::OfaMiscTabPage(weld::Container* pPage, weld::DialogController* pCon
troller, const SfxItemSet& rSet)
: SfxTabPage(pPage, pController, u"cui/ui/optgeneralpage.ui" _ustr, u"OptGeneralPage" _ustr, &rSet)
, m_xExtHelpCB(m_xBuilder->weld_check_button(u"exthelp" _ustr))
, m_xExtHelpImg(m_xBuilder->weld_widget(u"lockexthelp" _ustr))
, m_xPopUpNoHelpCB(m_xBuilder->weld_check_button(u"popupnohelp" _ustr))
, m_xPopUpNoHelpImg(m_xBuilder->weld_widget(u"lockpopupnohelp" _ustr))
, m_xShowTipOfTheDay(m_xBuilder->weld_check_button(u"cbShowTipOfTheDay" _ustr))
, m_xShowTipOfTheDayImg(m_xBuilder->weld_widget(u"lockcbShowTipOfTheDay" _ustr))
, m_xFileDlgFrame(m_xBuilder->weld_widget(u"filedlgframe" _ustr))
, m_xFileDlgROImage(m_xBuilder->weld_widget(u"lockimage" _ustr))
, m_xFileDlgCB(m_xBuilder->weld_check_button(u"filedlg" _ustr))
, m_xDocStatusCB(m_xBuilder->weld_check_button(u"docstatus" _ustr))
, m_xDocStatusImg(m_xBuilder->weld_widget(u"lockdocstatus" _ustr))
, m_xYearFrame(m_xBuilder->weld_widget(u"yearframe" _ustr))
, m_xYearLabel(m_xBuilder->weld_label(u"yearslabel" _ustr))
, m_xYearValueField(m_xBuilder->weld_spin_button(u"year" _ustr))
, m_xToYearFT(m_xBuilder->weld_label(u"toyear" _ustr))
, m_xYearFrameImg(m_xBuilder->weld_widget(u"lockyears" _ustr))
#if HAVE_FEATURE_BREAKPAD
, m_xPrivacyFrame(m_xBuilder->weld_widget("privacyframe" ))
, m_xCrashReport(m_xBuilder->weld_check_button("crashreport" ))
, m_xCrashReportImg(m_xBuilder->weld_widget("lockcrashreport" ))
#endif
#if defined (_WIN32)
, m_xQuickStarterFrame(m_xBuilder->weld_widget("quickstarter" ))
, m_xQuickLaunchCB(m_xBuilder->weld_check_button("quicklaunch" ))
, m_xQuickLaunchImg(m_xBuilder->weld_widget("lockquicklaunch" ))
, m_xFileAssocFrame(m_xBuilder->weld_widget("fileassoc" ))
, m_xFileAssocBtn(m_xBuilder->weld_button("assocfiles" ))
, m_xPerformFileExtCheck(m_xBuilder->weld_check_button("cbPerformFileExtCheck" ))
, m_xPerformFileExtImg(m_xBuilder->weld_widget("lockcbPerformFileExtCheck" ))
#endif
{
#if HAVE_FEATURE_BREAKPAD
m_xPrivacyFrame->show();
#endif
#if defined (_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();
m_xFileAssocFrame->show();
m_xFileAssocBtn->connect_clicked(LINK(this , OfaMiscTabPage, FileAssocClick));
#endif
m_aStrDateInfo = m_xToYearFT->get_label();
m_xYearValueField->connect_value_changed( LINK( this , OfaMiscTabPage, TwoFigureHdl ) );
SetExchangeSupport();
}
OfaMiscTabPage::~OfaMiscTabPage()
{
}
std::unique_ptr<SfxTabPage> OfaMiscTabPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet )
{
return std::make_unique<OfaMiscTabPage>( pPage, pController, *rAttrSet );
}
OUString OfaMiscTabPage::GetAllStrings()
{
OUString sAllStrings;
OUString labels[] = { u"label1" _ustr, u"label2" _ustr, u"label4" _ustr, u"label5" _ustr, u"yearslabel" _ustr,
u"toyear" _ustr, u"label8" _ustr, u"label9" _ustr };
for (const auto & label : labels)
{
if (const auto pString = m_xBuilder->weld_label(label))
sAllStrings += pString->get_label() + " " ;
}
OUString checkButton[]
= { u"exthelp" _ustr, u"popupnohelp" _ustr, u"cbShowTipOfTheDay" _ustr, u"filedlg" _ustr,
u"docstatus" _ustr, u"crashreport" _ustr, u"quicklaunch" _ustr, u"cbPerformFileExtCheck" _ustr };
for (const auto & check : checkButton)
{
if (const auto pString = m_xBuilder->weld_check_button(check))
sAllStrings += pString->get_label() + " " ;
}
if (const auto pString = m_xBuilder->weld_button(u"assocfiles" _ustr))
sAllStrings += pString->get_label() + " " ;
return sAllStrings.replaceAll("_" , "" );
}
bool OfaMiscTabPage::FillItemSet( SfxItemSet* rSet )
{
bool bModified = false ;
std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
if ( m_xPopUpNoHelpCB->get_state_changed_from_saved() )
officecfg::Office::Common::Help::BuiltInHelpNotInstalledPopUp::set(m_xPopUpNoHelpCB->get_active(), batch);
if ( m_xExtHelpCB->get_state_changed_from_saved() )
officecfg::Office::Common::Help::ExtendedTip::set(m_xExtHelpCB->get_active(), batch);
if ( m_xShowTipOfTheDay->get_state_changed_from_saved() )
{
officecfg::Office::Common::Misc::ShowTipOfTheDay::set(m_xShowTipOfTheDay->get_active(), batch);
bModified = true ;
}
if ( m_xFileDlgCB->get_state_changed_from_saved() )
{
officecfg::Office::Common::Misc::UseSystemFileDialog::set( !m_xFileDlgCB->get_active(), batch );
bModified = true ;
}
if (m_xDocStatusCB->get_state_changed_from_saved())
{
officecfg::Office::Common::Print::PrintingModifiesDocument::set(m_xDocStatusCB->get_active(), batch);
bModified = true ;
}
const SfxUInt16Item* pUInt16Item = GetOldItem( *rSet, SID_ATTR_YEAR2000 );
sal_uInt16 nNum = static_cast <sal_uInt16>(m_xYearValueField->get_text().toInt32());
if ( pUInt16Item && pUInt16Item->GetValue() != nNum )
{
bModified = true ;
rSet->Put( SfxUInt16Item( SID_ATTR_YEAR2000, nNum ) );
}
#if HAVE_FEATURE_BREAKPAD
if (m_xCrashReport->get_state_changed_from_saved())
{
officecfg::Office::Common::Misc::CrashReport::set(m_xCrashReport->get_active(), batch);
bModified = true ;
}
#endif
#if defined (_WIN32)
if (m_xPerformFileExtCheck->get_state_changed_from_saved())
{
officecfg::Office::Common::Misc::PerformFileExtCheck::set(
m_xPerformFileExtCheck->get_active(), batch);
bModified = true ;
}
if ( m_xQuickLaunchCB->get_state_changed_from_saved())
{
rSet->Put(SfxBoolItem(SID_ATTR_QUICKLAUNCHER, m_xQuickLaunchCB->get_active()));
bModified = true ;
}
#endif
batch->commit();
return bModified;
}
void OfaMiscTabPage::Reset( const SfxItemSet* rSet )
{
bool bEnable = !officecfg::Office::Common::Help::ExtendedTip::isReadOnly();
m_xExtHelpCB->set_active( officecfg::Office::Common::Help::Tip::get() &&
officecfg::Office::Common::Help::ExtendedTip::get() );
m_xExtHelpCB->set_sensitive(bEnable);
m_xExtHelpImg->set_visible(!bEnable);
m_xExtHelpCB->save_state();
bEnable = !officecfg::Office::Common::Help::BuiltInHelpNotInstalledPopUp::isReadOnly();
m_xPopUpNoHelpCB->set_active( officecfg::Office::Common::Help::BuiltInHelpNotInstalledPopUp::get() );
m_xPopUpNoHelpCB->set_sensitive(bEnable);
m_xPopUpNoHelpImg->set_visible(!bEnable);
m_xPopUpNoHelpCB->save_state();
bEnable = !officecfg::Office::Common::Misc::ShowTipOfTheDay::isReadOnly();
m_xShowTipOfTheDay->set_active( officecfg::Office::Common::Misc::ShowTipOfTheDay::get() );
m_xShowTipOfTheDay->set_sensitive(bEnable);
m_xShowTipOfTheDayImg->set_visible(!bEnable);
m_xShowTipOfTheDay->save_state();
if (!lcl_HasSystemFilePicker())
m_xFileDlgFrame->hide();
else
{
bEnable = !officecfg::Office::Common::Misc::UseSystemFileDialog::isReadOnly();
m_xFileDlgCB->set_sensitive(bEnable);
m_xFileDlgROImage->set_visible(!bEnable);
}
m_xFileDlgCB->set_active(!officecfg::Office::Common::Misc::UseSystemFileDialog::get());
m_xFileDlgCB->save_state();
bEnable = !officecfg::Office::Common::Print::PrintingModifiesDocument::isReadOnly();
m_xDocStatusCB->set_active(officecfg::Office::Common::Print::PrintingModifiesDocument::get());
m_xDocStatusCB->set_sensitive(bEnable);
m_xDocStatusImg->set_visible(!bEnable);
m_xDocStatusCB->save_state();
bEnable = !officecfg::Office::Common::DateFormat::TwoDigitYear::isReadOnly();
m_xYearLabel->set_sensitive(bEnable);
m_xYearValueField->set_sensitive(bEnable);
m_xToYearFT->set_sensitive(bEnable);
m_xYearFrameImg->set_visible(!bEnable);
if ( const SfxUInt16Item* pYearItem = rSet->GetItemIfSet( SID_ATTR_YEAR2000, false ) )
{
m_xYearValueField->set_value( pYearItem->GetValue() );
TwoFigureHdl(*m_xYearValueField);
}
else
m_xYearFrame->set_sensitive(false );
#if HAVE_FEATURE_BREAKPAD
m_xCrashReport->set_active(officecfg::Office::Common::Misc::CrashReport::get() && CrashReporter::IsDumpEnable());
m_xCrashReport->set_sensitive(!officecfg::Office::Common::Misc::CrashReport::isReadOnly() && CrashReporter::IsDumpEnable());
m_xCrashReportImg->set_visible(officecfg::Office::Common::Misc::CrashReport::isReadOnly() && CrashReporter::IsDumpEnable());
m_xCrashReport->save_state();
#endif
#if defined (_WIN32)
if (const SfxBoolItem* pItem = rSet->GetItemIfSet( SID_ATTR_QUICKLAUNCHER, false ))
{
m_xQuickLaunchCB->set_active( pItem->GetValue() );
}
else
{
// quickstart not installed
m_xQuickStarterFrame->hide();
}
m_xQuickLaunchCB->save_state();
m_xPerformFileExtCheck->set_active(
officecfg::Office::Common::Misc::PerformFileExtCheck::get());
m_xPerformFileExtCheck->save_state();
m_xPerformFileExtCheck->set_sensitive(!officecfg::Office::Common::Misc::PerformFileExtCheck::isReadOnly());
m_xPerformFileExtImg->set_visible(officecfg::Office::Common::Misc::PerformFileExtCheck::isReadOnly());
#endif
}
IMPL_LINK_NOARG( OfaMiscTabPage, TwoFigureHdl, weld::SpinButton&, void )
{
OUString aOutput( m_aStrDateInfo );
OUString aStr( m_xYearValueField->get_text() );
sal_Int32 nNum = aStr.toInt32();
if ( aStr.getLength() != 4 || nNum < m_xYearValueField->get_min() || nNum > m_xYearValueField->get_max() )
aOutput += "????" ;
else
{
nNum += 99;
aOutput += OUString::number( nNum );
}
m_xToYearFT->set_label( aOutput );
}
#if defined (_WIN32)
IMPL_STATIC_LINK_NOARG(OfaMiscTabPage, FileAssocClick, weld::Button&, void )
{
vcl::fileregistration::LaunchRegistrationUI();
}
#endif
class CanvasSettings
{
public :
CanvasSettings();
bool IsHardwareAccelerationAvailable() const ;
private :
typedef std::vector< std::pair<OUString,Sequence<OUString> > > ServiceVector;
Reference<XNameAccess> mxForceFlagNameAccess;
ServiceVector maAvailableImplementations;
mutable bool mbHWAccelAvailable;
mutable bool mbHWAccelChecked;
};
CanvasSettings::CanvasSettings() :
mbHWAccelAvailable(false ),
mbHWAccelChecked(false )
{
try
{
Reference<XMultiServiceFactory> xConfigProvider(
css::configuration::theDefaultProvider::get(
comphelper::getProcessComponentContext()));
Sequence<Any> aArgs1(comphelper::InitAnyPropertySequence(
{
{"nodepath" , Any(u"/org.openoffice.Office.Canvas" _ustr)}
}));
mxForceFlagNameAccess.set(
xConfigProvider->createInstanceWithArguments(
u"com.sun.star.configuration.ConfigurationUpdateAccess" _ustr,
aArgs1 ),
UNO_QUERY_THROW );
Sequence<Any> aArgs2(comphelper::InitAnyPropertySequence(
{
{"nodepath" , Any(u"/org.openoffice.Office.Canvas/CanvasServiceList" _ustr)}
}));
Reference<XNameAccess> xNameAccess(
xConfigProvider->createInstanceWithArguments(
u"com.sun.star.configuration.ConfigurationAccess" _ustr,
aArgs2 ), UNO_QUERY_THROW );
Reference<XHierarchicalNameAccess> xHierarchicalNameAccess(
xNameAccess, UNO_QUERY_THROW);
for (auto & serviceName : xNameAccess->getElementNames())
{
Reference<XNameAccess> xEntryNameAccess(
xHierarchicalNameAccess->getByHierarchicalName(serviceName),
UNO_QUERY );
if ( xEntryNameAccess.is() )
{
Sequence<OUString> preferredImplementations;
if ( xEntryNameAccess->getByName(u"PreferredImplementations" _ustr) >>= preferredImplementations )
maAvailableImplementations.emplace_back(serviceName, preferredImplementations);
}
}
}
catch (const Exception&)
{
}
}
bool CanvasSettings::IsHardwareAccelerationAvailable() const
{
if ( !mbHWAccelChecked )
{
mbHWAccelChecked = true ;
Reference< XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory();
// check whether any of the service lists has an
// implementation that presents the "HardwareAcceleration" property
for (auto const & availableImpl : maAvailableImplementations)
{
for (auto & currImpl : availableImpl.second)
{
try
{
Reference<XPropertySet> xPropSet( xFactory->createInstance(
currImpl.trim() ),
UNO_QUERY_THROW );
bool bHasAccel(false );
if ( xPropSet->getPropertyValue(u"HardwareAcceleration" _ustr) >>= bHasAccel )
if ( bHasAccel )
{
mbHWAccelAvailable = true ;
return mbHWAccelAvailable;
}
}
catch (const Exception&)
{
}
}
}
}
return mbHWAccelAvailable;
}
// class OfaViewTabPage --------------------------------------------------
OfaViewTabPage::OfaViewTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
: SfxTabPage(pPage, pController, u"cui/ui/optviewpage.ui" _ustr, u"OptViewPage" _ustr, &rSet)
, pCanvasSettings(new CanvasSettings)
, m_xFontAntiAliasing(m_xBuilder->weld_check_button(u"aafont" _ustr))
, m_xFontAntiAliasingImg(m_xBuilder->weld_widget(u"lockaafont" _ustr))
, m_xAAPointLimitLabel(m_xBuilder->weld_label(u"aafrom" _ustr))
, m_xAAPointLimitLabelImg(m_xBuilder->weld_widget(u"lockaafrom" _ustr))
, m_xAAPointLimit(m_xBuilder->weld_metric_spin_button(u"aanf" _ustr, FieldUnit::PIXEL))
, m_xFontShowCB(m_xBuilder->weld_check_button(u"showfontpreview" _ustr))
, m_xFontShowImg(m_xBuilder->weld_widget(u"lockshowfontpreview" _ustr))
, m_xUseHardwareAccell(m_xBuilder->weld_check_button(u"useaccel" _ustr))
, m_xUseHardwareAccellImg(m_xBuilder->weld_widget(u"lockuseaccel" _ustr))
, m_xUseAntiAliase(m_xBuilder->weld_check_button(u"useaa" _ustr))
, m_xUseAntiAliaseImg(m_xBuilder->weld_widget(u"lockuseaa" _ustr))
, m_xUseSkia(m_xBuilder->weld_check_button(u"useskia" _ustr))
, m_xUseSkiaImg(m_xBuilder->weld_widget(u"lockuseskia" _ustr))
, m_xForceSkiaRaster(m_xBuilder->weld_check_button(u"forceskiaraster" _ustr))
, m_xForceSkiaRasterImg(m_xBuilder->weld_widget(u"lockforceskiaraster" _ustr))
, m_xSkiaStatusEnabled(m_xBuilder->weld_label(u"skiaenabled" _ustr))
, m_xSkiaStatusDisabled(m_xBuilder->weld_label(u"skiadisabled" _ustr))
, m_xSkiaLog(m_xBuilder->weld_button(u"btnSkialog" _ustr))
, m_xMouseMiddleLabel(m_xBuilder->weld_label(u"label12" _ustr))
, m_xMouseMiddleLB(m_xBuilder->weld_combo_box(u"mousemiddle" _ustr))
, m_xMouseMiddleImg(m_xBuilder->weld_widget(u"lockmousemiddle" _ustr))
, m_xRunGPTests(m_xBuilder->weld_button(u"btn_rungptest" _ustr))
{
m_xFontAntiAliasing->connect_toggled( LINK( this , OfaViewTabPage, OnAntialiasingToggled ) );
m_xUseSkia->connect_toggled(LINK(this , OfaViewTabPage, OnUseSkiaToggled));
m_xSkiaLog->connect_clicked(LINK(this , OfaViewTabPage, OnCopySkiaLog));
m_xRunGPTests->connect_clicked(LINK(this , OfaViewTabPage, OnRunGPTestClick));
// Hide "Run Graphics Test" button if Experimental Mode is off
if (!officecfg::Office::Common::Misc::ExperimentalMode::get())
m_xRunGPTests->hide();
}
OfaViewTabPage::~OfaViewTabPage()
{
}
IMPL_LINK_NOARG(OfaViewTabPage, OnRunGPTestClick, weld::Button&, void )
{
GraphicsTestsDialog m_xGraphicsTestDialog(m_xContainer.get());
m_xGraphicsTestDialog.run();
}
IMPL_LINK_NOARG( OfaViewTabPage, OnAntialiasingToggled, weld::Toggleable&, void )
{
bool bAAEnabled = m_xFontAntiAliasing->get_active() && !officecfg::Office::Common::View::FontAntiAliasing::MinPixelHeight::isReadOnly();
m_xAAPointLimitLabel->set_sensitive(bAAEnabled);
m_xAAPointLimit->set_sensitive(bAAEnabled);
}
IMPL_LINK_NOARG(OfaViewTabPage, OnUseSkiaToggled, weld::Toggleable&, void )
{
UpdateSkiaStatus();
}
IMPL_LINK_NOARG(OfaViewTabPage, OnCopySkiaLog, weld::Button&, void )
{
#if HAVE_FEATURE_SKIA
css::uno::Reference<css::datatransfer::clipboard::XClipboard> xClipboard =
css::datatransfer::clipboard::SystemClipboard::create(
comphelper::getProcessComponentContext());
OUString sInfo = SkiaHelper::readLog();
vcl::unohelper::TextDataObject::CopyStringTo(sInfo, xClipboard);
m_xSkiaLog->set_from_icon_name(RID_SVXBMP_COPY);
#endif
}
void OfaViewTabPage::HideSkiaWidgets()
{
m_xUseSkia->hide();
m_xForceSkiaRaster->hide();
m_xSkiaStatusEnabled->hide();
m_xSkiaStatusDisabled->hide();
m_xSkiaLog->hide();
}
void OfaViewTabPage::UpdateSkiaStatus()
{
#if HAVE_FEATURE_SKIA
bool skiaHidden = true ;
// 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);
m_xUseSkia->set_sensitive(!officecfg::Office::Common::VCL::UseSkia::isReadOnly());
m_xUseSkiaImg->set_visible(officecfg::Office::Common::VCL::UseSkia::isReadOnly());
m_xForceSkiaRaster->set_sensitive(m_xUseSkia->get_active() && !officecfg::Office::Common::VCL::ForceSkiaRaster::isReadOnly());
m_xForceSkiaRasterImg->set_visible(officecfg::Office::Common::VCL::ForceSkiaRaster::isReadOnly());
m_xSkiaLog->set_sensitive(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
}
std::unique_ptr<SfxTabPage> OfaViewTabPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet )
{
return std::make_unique<OfaViewTabPage>(pPage, pController, *rAttrSet);
}
OUString OfaViewTabPage::GetAllStrings()
{
OUString sAllStrings;
OUString labels[] = { u"label16" _ustr, u"label1" _ustr, u"label6" _ustr, u"label15" _ustr,
u"label14" _ustr, u"label8" _ustr, u"label9" _ustr, u"label4" _ustr, u"label12" _ustr,
u"label2" _ustr, u"skiaenabled" _ustr, u"skiadisabled" _ustr, u"label5" _ustr, u"aafrom" _ustr };
for (const auto & label : labels)
{
if (const auto pString = m_xBuilder->weld_label(label))
sAllStrings += pString->get_label() + " " ;
}
OUString checkButton[]
= { u"useaccel" _ustr, u"useaa" _ustr, u"useskia" _ustr, u"forceskiaraster" _ustr, u"showfontpreview" _ustr, u"aafont" _ustr };
for (const auto & check : checkButton)
{
if (const auto pString = m_xBuilder->weld_check_button(check))
sAllStrings += pString->get_label() + " " ;
}
sAllStrings += m_xSkiaLog->get_label() + " " + m_xRunGPTests->get_label() + " " ;
return sAllStrings.replaceAll("_" , "" );
}
bool OfaViewTabPage::FillItemSet( SfxItemSet* )
{
bool bModified = false ;
bool bRepaintWindows(false );
bool bAppearanceChanged = false ;
std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
// Middle Mouse Button
MouseMiddleButtonAction eOldMiddleMouse = static_cast <MouseMiddleButtonAction>(officecfg::Office::Common::View::Dialog::MiddleMouseButton::get());
short eNewMiddleMouse = m_xMouseMiddleLB->get_active();
if (eNewMiddleMouse > 2)
eNewMiddleMouse = 2;
if ( eNewMiddleMouse != static_cast <short >(eOldMiddleMouse) )
{
officecfg::Office::Common::View::Dialog::MiddleMouseButton::set(eNewMiddleMouse, batch);
bAppearanceChanged = true ;
}
if (m_xFontAntiAliasing->get_state_changed_from_saved())
{
bool b = m_xFontAntiAliasing->get_active();
officecfg::Office::Common::View::FontAntiAliasing::Enabled::set(b, batch);
bAppearanceChanged = true ;
}
if (m_xAAPointLimit->get_value_changed_from_saved())
{
sal_Int64 i = m_xAAPointLimit->get_value(FieldUnit::PIXEL);
officecfg::Office::Common::View::FontAntiAliasing::MinPixelHeight::set(i, batch);
bAppearanceChanged = true ;
}
std::shared_ptr<comphelper::ConfigurationChanges> xChanges(comphelper::ConfigurationChanges::create());
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 ;
}
}
if (m_xUseSkia->get_state_changed_from_saved() ||
m_xForceSkiaRaster->get_state_changed_from_saved())
{
officecfg::Office::Common::VCL::UseSkia::set(m_xUseSkia->get_active(), xChanges);
officecfg::Office::Common::VCL::ForceSkiaRaster::set(m_xForceSkiaRaster->get_active(), xChanges);
bModified = true ;
}
xChanges->commit();
if ( bAppearanceChanged )
{
batch->commit();
SvtTabAppearanceCfg::SetApplicationDefaults ( GetpApp() );
}
if (bRepaintWindows)
{
vcl::Window* pAppWindow = Application::GetFirstTopLevelWindow();
while (pAppWindow)
{
pAppWindow->Invalidate();
pAppWindow = Application::GetNextTopLevelWindow(pAppWindow);
}
}
if (m_xUseSkia->get_state_changed_from_saved() ||
m_xForceSkiaRaster->get_state_changed_from_saved())
{
SolarMutexGuard aGuard;
if ( svtools::executeRestartDialog(
comphelper::getProcessComponentContext(), nullptr,
svtools::RESTART_REASON_SKIA))
GetDialogController()->response(RET_OK);
}
return bModified;
}
void OfaViewTabPage::Reset( const SfxItemSet* )
{
bool bEnable = true ;
// Middle Mouse Button
bEnable = !officecfg::Office::Common::View::Dialog::MiddleMouseButton::isReadOnly();
sal_Int16 nMiddleMouseButton = officecfg::Office::Common::View::Dialog::MiddleMouseButton::get();
m_xMouseMiddleLB->set_active(static_cast <short >(nMiddleMouseButton));
m_xMouseMiddleLabel->set_sensitive(bEnable);
m_xMouseMiddleLB->set_sensitive(bEnable);
m_xMouseMiddleImg->set_visible(!bEnable);
m_xMouseMiddleLB->save_value();
bEnable = !officecfg::Office::Common::View::FontAntiAliasing::Enabled::isReadOnly();
bool bFontAntiAliasing = officecfg::Office::Common::View::FontAntiAliasing::Enabled::get();
m_xFontAntiAliasing->set_active( bFontAntiAliasing );
m_xFontAntiAliasing->set_sensitive(bEnable);
m_xFontAntiAliasingImg->set_visible(!bEnable);
bEnable = !officecfg::Office::Common::View::FontAntiAliasing::MinPixelHeight::isReadOnly();
sal_Int16 nFontAntiAliasingMinPixelHeight = officecfg::Office::Common::View::FontAntiAliasing::MinPixelHeight::get();
m_xAAPointLimit->set_value(nFontAntiAliasingMinPixelHeight, FieldUnit::PIXEL);
m_xAAPointLimit->set_sensitive(bEnable);
m_xAAPointLimitLabelImg->set_visible(!bEnable);
// WorkingSet
bEnable = !officecfg::Office::Common::Font::View::ShowFontBoxWYSIWYG::isReadOnly();
m_xFontShowCB->set_active(officecfg::Office::Common::Font::View::ShowFontBoxWYSIWYG::get());
m_xFontShowCB->set_sensitive(bEnable);
m_xFontShowImg->set_visible(!bEnable);
UpdateHardwareAccelStatus();
m_xUseHardwareAccell->save_state();
{ // #i95644# AntiAliasing
m_xUseAntiAliase->set_active(SvtOptionsDrawinglayer::IsAntiAliasing());
bEnable = !officecfg::Office::Common::Drawinglayer::AntiAliasing::isReadOnly();
m_xUseAntiAliase->set_sensitive(bEnable);
m_xUseAntiAliaseImg->set_visible(!bEnable);
m_xUseAntiAliase->save_state();
}
m_xUseSkia->set_active(officecfg::Office::Common::VCL::UseSkia::get());
m_xForceSkiaRaster->set_active(officecfg::Office::Common::VCL::ForceSkiaRaster::get());
m_xUseSkia->save_state();
m_xForceSkiaRaster->save_state();
m_xFontAntiAliasing->save_state();
m_xAAPointLimit->save_value();
m_xFontShowCB->save_state();
OnAntialiasingToggled(*m_xFontAntiAliasing);
UpdateSkiaStatus();
}
void OfaViewTabPage::UpdateHardwareAccelStatus()
{
// #i95644# HW accel (unified to disable mechanism)
bool bHardwareAccRO = officecfg::Office::Canvas::ForceSafeServiceImpl::isReadOnly();
if (pCanvasSettings->IsHardwareAccelerationAvailable())
{
m_xUseHardwareAccell->set_active(officecfg::Office::Canvas::ForceSafeServiceImpl::get());
m_xUseHardwareAccell->set_sensitive(!bHardwareAccRO);
m_xUseHardwareAccellImg->set_visible(bHardwareAccRO);
}
else
{
m_xUseHardwareAccell->set_active(false );
m_xUseHardwareAccell->set_sensitive(false );
m_xUseHardwareAccellImg->set_visible(true );
}
#if HAVE_FEATURE_SKIA
m_xUseHardwareAccell->set_sensitive(!bHardwareAccRO && !m_xUseSkia->get_active());
#endif
}
struct LanguageConfig_Impl
{
SvtCTLOptions aCTLLanguageOptions;
SvtSysLocaleOptions aSysLocaleOptions;
SvtLinguConfig aLinguConfig;
};
static bool bLanguageCurrentDoc_Impl = false ;
// some things we'll need...
constexpr OUString sAccessSrvc = u"com.sun.star.configuration.ConfigurationAccess" _ustr;
constexpr OUStringLiteral sAccessUpdSrvc = u"com.sun.star.configuration.ConfigurationUpdateAccess" ;
constexpr OUString sInstalledLocalesPath = u"org.openoffice.Setup/Office/InstalledLocales" _ustr;
constexpr OUString sUserLocalePath = u"org.openoffice.Office.Linguistic/General" _ustr;
constexpr OUString sUserLocaleKey = u"UILocale" _ustr;
static Sequence< OUString > seqInstalledLanguages;
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();
}
}
OfaLanguagesTabPage::OfaLanguagesTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
: SfxTabPage(pPage, pController, u"cui/ui/optlanguagespage.ui" _ustr, u"OptLanguagesPage" _ustr, &rSet)
, pLangConfig(new LanguageConfig_Impl)
, m_bDatePatternsValid(false )
, m_xUserInterfaceLB(m_xBuilder->weld_combo_box(u"userinterface" _ustr))
, m_xLocaleSettingFT(m_xBuilder->weld_label(u"localesettingFT" _ustr))
, m_xLocaleSettingLB(new SvxLanguageBox(m_xBuilder->weld_combo_box(u"localesetting" _ustr)))
, m_xLocaleSettingImg(m_xBuilder->weld_widget(u"locklocalesetting" _ustr))
, m_xDecimalSeparatorFT(m_xBuilder->weld_label(u"label6" _ustr))
, m_xDecimalSeparatorCB(m_xBuilder->weld_check_button(u"decimalseparator" _ustr))
, m_xDecimalSeparatorImg(m_xBuilder->weld_widget(u"lockdecimalseparator" _ustr))
, m_xCurrencyFT(m_xBuilder->weld_label(u"defaultcurrency" _ustr))
, m_xCurrencyLB(m_xBuilder->weld_combo_box(u"currencylb" _ustr))
, m_xCurrencyImg(m_xBuilder->weld_widget(u"lockcurrencylb" _ustr))
, m_xDatePatternsFT(m_xBuilder->weld_label(u"dataaccpatterns" _ustr))
, m_xDatePatternsED(m_xBuilder->weld_entry(u"datepatterns" _ustr))
, m_xDatePatternsImg(m_xBuilder->weld_widget(u"lockdatepatterns" _ustr))
, m_xWesternLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box(u"westernlanguage" _ustr)))
, m_xWesternLanguageFT(m_xBuilder->weld_label(u"western" _ustr))
, m_xWesternLanguageImg(m_xBuilder->weld_widget(u"lockwesternlanguage" _ustr))
, m_xAsianLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box(u"asianlanguage" _ustr)))
, m_xComplexLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box(u"complexlanguage" _ustr)))
, m_xCurrentDocCB(m_xBuilder->weld_check_button(u"currentdoc" _ustr))
, m_xAsianSupportCB(m_xBuilder->weld_check_button(u"asiansupport" _ustr))
, m_xAsianSupportImg(m_xBuilder->weld_widget(u"lockasiansupport" _ustr))
, m_xCTLSupportCB(m_xBuilder->weld_check_button(u"ctlsupport" _ustr))
, m_xCTLSupportImg(m_xBuilder->weld_widget(u"lockctlsupport" _ustr))
, m_xIgnoreLanguageChangeCB(m_xBuilder->weld_check_button(u"ignorelanguagechange" _ustr))
, m_xIgnoreLanguageChangeImg(m_xBuilder->weld_widget(u"lockignorelanguagechange" _ustr))
{
// tdf#125483 save original default label
m_sDecimalSeparatorLabel = m_xDecimalSeparatorCB->get_label();
// initialize user interface language selection
m_sSystemDefaultString = SvtLanguageTable::GetLanguageString( LANGUAGE_SYSTEM );
OUString aUILang = m_sSystemDefaultString +
" - " +
SvtLanguageTable::GetLanguageString(GetInstalledLocaleForSystemUILanguage().getLanguageType());
m_xUserInterfaceLB->append(u"0" _ustr, aUILang);
m_xUserInterfaceLB->append_separator(u"" _ustr);
try
{
Reference< XMultiServiceFactory > theConfigProvider(
css::configuration::theDefaultProvider::get(
comphelper::getProcessComponentContext()));
// find out which locales are currently installed and add them to the listbox
Sequence< Any > theArgs{ Any(NamedValue(u"nodepath" _ustr, Any(sInstalledLocalesPath))) };
Reference< XNameAccess > theNameAccess(
theConfigProvider->createInstanceWithArguments(sAccessSrvc, theArgs ), UNO_QUERY_THROW );
seqInstalledLanguages = theNameAccess->getElementNames();
LanguageType aLang = LANGUAGE_DONTKNOW;
std::vector< std::pair<sal_Int32, OUString> > aUILanguages;
for (sal_Int32 i=0; i<seqInstalledLanguages.getLength(); i++)
{
aLang = LanguageTag::convertToLanguageTypeWithFallback(seqInstalledLanguages[i]);
if (aLang != LANGUAGE_DONTKNOW)
{
OUString aLangStr( SvtLanguageTable::GetLanguageString( aLang ) );
aUILanguages.emplace_back(i+1, aLangStr);
}
}
std::sort(aUILanguages.begin(), aUILanguages.end(), [](const auto & l1, const auto & l2) {
static const auto aSorter = comphelper::string::NaturalStringSorter(
comphelper::getProcessComponentContext(),
Application::GetSettings().GetUILanguageTag().getLocale());
return aSorter.compare(l1.second, l2.second) < 0;
});
// tdf#114694: append the sorted list after the default entry and separator.
for (const auto & [ 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" );
}
m_xWesternLanguageLB->SetLanguageList(
SvxLanguageListFlags::WESTERN | SvxLanguageListFlags::ONLY_KNOWN, true , false , true , true ,
LANGUAGE_SYSTEM, css::i18n::ScriptType::LATIN);
m_xAsianLanguageLB->SetLanguageList(
SvxLanguageListFlags::CJK | SvxLanguageListFlags::ONLY_KNOWN, true , false , true , true ,
LANGUAGE_SYSTEM, css::i18n::ScriptType::ASIAN);
m_xComplexLanguageLB->SetLanguageList(
SvxLanguageListFlags::CTL | SvxLanguageListFlags::ONLY_KNOWN, true , false , true , true ,
LANGUAGE_SYSTEM, css::i18n::ScriptType::COMPLEX);
m_xLocaleSettingLB->SetLanguageList(
SvxLanguageListFlags::ALL | SvxLanguageListFlags::ONLY_KNOWN, false , false , false , true ,
LANGUAGE_USER_SYSTEM_CONFIG, css::i18n::ScriptType::WEAK);
const NfCurrencyTable& rCurrTab = SvNumberFormatter::GetTheCurrencyTable();
const NfCurrencyEntry& rCurr = SvNumberFormatter::GetCurrencyEntry( LANGUAGE_SYSTEM );
// insert SYSTEM entry
OUString aDefaultCurr = m_sSystemDefaultString + " - " + rCurr.GetBankSymbol();
m_xCurrencyLB->append(u"default" _ustr, aDefaultCurr);
m_xCurrencyLB->append_separator(u"" _ustr);
assert(m_xCurrencyLB->find_id(u"default" _ustr) != -1);
// all currencies
OUString aTwoSpace( u" " _ustr );
sal_uInt16 nCurrCount = rCurrTab.size();
std::vector< const NfCurrencyEntry* > aCurrencies;
// first entry is SYSTEM, skip it
for ( sal_uInt16 j=1; j < nCurrCount; ++j )
{
aCurrencies.push_back(&rCurrTab[j]);
}
std::sort(aCurrencies.begin(), aCurrencies.end(),
[](const NfCurrencyEntry* c1, const NfCurrencyEntry* c2) {
return c1->GetBankSymbol().compareTo(c2->GetBankSymbol()) < 0;
});
for (auto &v : aCurrencies)
{
OUString aStr_ = v->GetBankSymbol() +
aTwoSpace +
v->GetSymbol();
aStr_ = ApplyLreOrRleEmbedding( aStr_ ) +
aTwoSpace +
ApplyLreOrRleEmbedding( SvtLanguageTable::GetLanguageString( v->GetLanguage() ) );
m_xCurrencyLB->append(weld::toId(v), aStr_);
}
m_xCurrencyLB->set_active(0);
m_xLocaleSettingLB->connect_changed( LINK( this , OfaLanguagesTabPage, LocaleSettingHdl ) );
m_xDatePatternsED->connect_changed( LINK( this , OfaLanguagesTabPage, DatePatternsHdl ) );
Link<weld::Toggleable&,void > aLink( LINK( this , OfaLanguagesTabPage, SupportHdl ) );
m_xAsianSupportCB->connect_toggled( aLink );
m_xCTLSupportCB->connect_toggled( aLink );
m_bOldAsian = SvtCJKOptions::IsAnyEnabled();
m_xAsianSupportCB->set_active(m_bOldAsian);
m_xAsianSupportCB->save_state();
bool bReadonly = SvtCJKOptions::IsAnyReadOnly();
m_xAsianSupportCB->set_sensitive(!bReadonly);
m_xAsianSupportImg->set_visible(bReadonly);
SupportHdl(*m_xAsianSupportCB);
m_bOldCtl = SvtCTLOptions::IsCTLFontEnabled();
m_xCTLSupportCB->set_active(m_bOldCtl);
m_xCTLSupportCB->save_state();
bReadonly = pLangConfig->aCTLLanguageOptions.IsReadOnly(SvtCTLOptions::E_CTLFONT);
m_xCTLSupportCB->set_sensitive(!bReadonly);
m_xCTLSupportImg->set_visible(bReadonly);
SupportHdl(*m_xCTLSupportCB);
m_xIgnoreLanguageChangeCB->set_active( pLangConfig->aSysLocaleOptions.IsIgnoreLanguageChange() );
}
OfaLanguagesTabPage::~OfaLanguagesTabPage()
{
}
std::unique_ptr<SfxTabPage> OfaLanguagesTabPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet )
{
return std::make_unique<OfaLanguagesTabPage>(pPage, pController, *rAttrSet);
}
static void lcl_Update(std::unique_ptr<SfxVoidItem> pInvalidItems[], std::unique_ptr<SfxBoolItem> pBoolItems[], sal_uInt16 nCount)
{
SfxViewFrame* pCurrentFrm = SfxViewFrame::Current();
SfxViewFrame* pViewFrm = SfxViewFrame::GetFirst();
while (pViewFrm)
{
SfxBindings& rBind = pViewFrm->GetBindings();
for (sal_uInt16 i = 0; i < nCount; i++)
{
if (pCurrentFrm == pViewFrm)
rBind.InvalidateAll(false );
rBind.SetState( *pInvalidItems[i] );
rBind.SetState( *pBoolItems[i] );
}
pViewFrm = SfxViewFrame::GetNext(*pViewFrm);
}
}
OUString OfaLanguagesTabPage::GetAllStrings()
{
OUString sAllStrings;
OUString labels[]
= { u"label1" _ustr, u"label4" _ustr, u"label7" _ustr, u"localesettingFT" _ustr, u"defaultcurrency" _ustr,
u"label6" _ustr, u"dataaccpatterns" _ustr, u"label2" _ustr, u"western" _ustr, u"label3" _ustr };
for (const auto & label : labels)
{
if (const auto pString = m_xBuilder->weld_label(label))
sAllStrings += pString->get_label() + " " ;
}
OUString checkButton[] = { u"decimalseparator" _ustr, u"asiansupport" _ustr, u"ctlsupport" _ustr, u"currentdoc" _ustr,
u"ignorelanguagechange" _ustr };
for (const auto & check : checkButton)
{
if (const auto 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" );
}
LanguageTag aLanguageTag( pLangConfig->aSysLocaleOptions.GetLanguageTag());
LanguageType eOldLocale = (aLanguageTag.isSystemLocale() ? LANGUAGE_SYSTEM :
aLanguageTag.makeFallback().getLanguageType());
LanguageType eNewLocale = m_xLocaleSettingLB->get_active_id();
// 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 ) );
SvtScriptType nNewType = SvtLanguageOptions::GetScriptTypeOfLanguage( eNewLocale );
bool bNewCJK = bool ( nNewType & SvtScriptType::ASIAN );
auto batch = comphelper::ConfigurationChanges::create();
SvtCompatibilityDefault aCompatOpts(batch);
aCompatOpts.set(u"ExpandWordSpace" _ustr, !bNewCJK);
batch->commit();
}
if (m_xDecimalSeparatorCB->get_state_changed_from_saved())
pLangConfig->aSysLocaleOptions.SetDecimalSeparatorAsLocale(m_xDecimalSeparatorCB->get_active());
if (m_xIgnoreLanguageChangeCB->get_state_changed_from_saved())
pLangConfig->aSysLocaleOptions.SetIgnoreLanguageChange(m_xIgnoreLanguageChangeCB->get_active());
// 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());
SfxObjectShell* pCurrentDocShell = SfxObjectShell::Current();
Reference< css::linguistic2::XLinguProperties > xLinguProp = LinguMgr::GetLinguPropertySet();
bool bCurrentDocCBChecked = m_xCurrentDocCB->get_active();
if (m_xCurrentDocCB->get_sensitive())
bLanguageCurrentDoc_Impl = bCurrentDocCBChecked;
bool bCurrentDocCBChanged = m_xCurrentDocCB->get_state_changed_from_saved();
bool bValChanged = m_xWesternLanguageLB->get_active_id_changed_from_saved();
if ( (bCurrentDocCBChanged && !bCurrentDocCBChecked) || bValChanged)
{
LanguageType eSelectLang = m_xWesternLanguageLB->get_active_id();
if (!bCurrentDocCBChecked)
{
Any aValue;
Locale aLocale = LanguageTag::convertToLocale( eSelectLang, false );
aValue <<= aLocale;
pLangConfig->aLinguConfig.SetProperty( u"DefaultLocale" , aValue );
if (xLinguProp.is())
xLinguProp->setDefaultLocale( aLocale );
}
if (pCurrentDocShell)
{
rSet->Put(SvxLanguageItem(MsLangId::resolveSystemLanguageByScriptType(eSelectLang, css::i18n::ScriptType::LATIN),
SID_ATTR_LANGUAGE));
}
}
bValChanged = m_xAsianLanguageLB->get_active_id_changed_from_saved();
if ( (bCurrentDocCBChanged && !bCurrentDocCBChecked) || bValChanged)
{
LanguageType eSelectLang = m_xAsianLanguageLB->get_active_id();
if (!bCurrentDocCBChecked)
{
Any aValue;
Locale aLocale = LanguageTag::convertToLocale( eSelectLang, false );
aValue <<= aLocale;
pLangConfig->aLinguConfig.SetProperty( u"DefaultLocale_CJK" , aValue );
if (xLinguProp.is())
xLinguProp->setDefaultLocale_CJK( aLocale );
}
if (pCurrentDocShell)
{
rSet->Put(SvxLanguageItem(MsLangId::resolveSystemLanguageByScriptType(eSelectLang, css::i18n::ScriptType::ASIAN),
SID_ATTR_CHAR_CJK_LANGUAGE));
}
}
bValChanged = m_xComplexLanguageLB->get_active_id_changed_from_saved();
if ( (bCurrentDocCBChanged && !bCurrentDocCBChecked) || bValChanged)
{
LanguageType eSelectLang = m_xComplexLanguageLB->get_active_id();
if (!bCurrentDocCBChecked)
{
Any aValue;
Locale aLocale = LanguageTag::convertToLocale( eSelectLang, false );
aValue <<= aLocale;
pLangConfig->aLinguConfig.SetProperty( u"DefaultLocale_CTL" , aValue );
if (xLinguProp.is())
xLinguProp->setDefaultLocale_CTL( aLocale );
}
if (pCurrentDocShell)
{
rSet->Put(SvxLanguageItem(MsLangId::resolveSystemLanguageByScriptType(eSelectLang, css::i18n::ScriptType::COMPLEX),
SID_ATTR_CHAR_CTL_LANGUAGE));
}
// tdf#163228: Mongolian script supports vertical text
pLangConfig->aCTLLanguageOptions.SetCTLVerticalText(
MsLangId::getPrimaryLanguage(eSelectLang)
== MsLangId::getPrimaryLanguage(LANGUAGE_MONGOLIAN_MONGOLIAN_MONGOLIA));
}
if (m_xAsianSupportCB->get_state_changed_from_saved() )
{
bool bChecked = m_xAsianSupportCB->get_active();
SvtCJKOptions::SetAll(bChecked);
//iterate over all bindings to invalidate vertical text direction
const sal_uInt16 STATE_COUNT = 2;
std::unique_ptr<SfxBoolItem> pBoolItems[STATE_COUNT];
pBoolItems[0].reset(new SfxBoolItem(SID_VERTICALTEXT_STATE, false ));
pBoolItems[1].reset(new SfxBoolItem(SID_TEXT_FITTOSIZE_VERTICAL, false ));
std::unique_ptr<SfxVoidItem> pInvalidItems[STATE_COUNT];
pInvalidItems[0].reset(new SfxVoidItem(SID_VERTICALTEXT_STATE));
pInvalidItems[1].reset(new SfxVoidItem(SID_TEXT_FITTOSIZE_VERTICAL));
lcl_Update(pInvalidItems, pBoolItems, STATE_COUNT);
}
if ( m_xCTLSupportCB->get_state_changed_from_saved() )
{
SvtSearchOptions aOpt;
aOpt.SetIgnoreDiacritics_CTL(true );
aOpt.SetIgnoreKashida_CTL(true );
aOpt.Commit();
pLangConfig->aCTLLanguageOptions.SetCTLFontEnabled( m_xCTLSupportCB->get_active() );
const sal_uInt16 STATE_COUNT = 1;
std::unique_ptr<SfxBoolItem> pBoolItems[STATE_COUNT];
pBoolItems[0].reset(new SfxBoolItem(SID_CTLFONT_STATE, false ));
std::unique_ptr<SfxVoidItem> pInvalidItems[STATE_COUNT];
pInvalidItems[0].reset(new SfxVoidItem(SID_CTLFONT_STATE));
lcl_Update(pInvalidItems, pBoolItems, STATE_COUNT);
}
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 );
return false ;
}
void OfaLanguagesTabPage::Reset( const SfxItemSet* rSet )
{
LanguageTag aLanguageTag( pLangConfig->aSysLocaleOptions.GetLanguageTag());
if ( aLanguageTag.isSystemLocale() )
m_xLocaleSettingLB->set_active_id( LANGUAGE_USER_SYSTEM_CONFIG );
else
m_xLocaleSettingLB->set_active_id( aLanguageTag.makeFallback().getLanguageType());
bool bReadonly = pLangConfig->aSysLocaleOptions.IsReadOnly(SvtSysLocaleOptions::EOption::Locale);
m_xLocaleSettingLB->set_sensitive(!bReadonly);
m_xLocaleSettingFT->set_sensitive(!bReadonly);
m_xLocaleSettingImg->set_visible(bReadonly);
m_xDecimalSeparatorCB->set_active( pLangConfig->aSysLocaleOptions.IsDecimalSeparatorAsLocale());
bReadonly = pLangConfig->aSysLocaleOptions.IsReadOnly(SvtSysLocaleOptions::EOption::DecimalSeparator);
m_xDecimalSeparatorCB->set_sensitive(!bReadonly);
m_xDecimalSeparatorFT->set_sensitive(!bReadonly);
m_xDecimalSeparatorImg->set_visible(bReadonly);
m_xDecimalSeparatorCB->save_state();
m_xIgnoreLanguageChangeCB->set_active( pLangConfig->aSysLocaleOptions.IsIgnoreLanguageChange());
bReadonly = pLangConfig->aSysLocaleOptions.IsReadOnly(SvtSysLocaleOptions::EOption::IgnoreLanguageChange);
m_xIgnoreLanguageChangeCB->set_sensitive(!bReadonly);
m_xIgnoreLanguageChangeImg->set_visible(bReadonly);
m_xIgnoreLanguageChangeCB->save_state();
// 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);
// date acceptance patterns
OUString aDatePatternsString = pLangConfig->aSysLocaleOptions.GetDatePatternsConfigString();
if (aDatePatternsString.isEmpty())
{
const LocaleDataWrapper& rLocaleWrapper( Application::GetSettings().GetLocaleDataWrapper() );
aDatePatternsString = lcl_getDatePatternsConfigString( rLocaleWrapper);
// Let's assume patterns are valid at this point.
m_bDatePatternsValid = true ;
}
else
{
bool bModified = false ;
m_bDatePatternsValid = validateDatePatterns( bModified, aDatePatternsString);
}
m_xDatePatternsED->set_text(aDatePatternsString);
m_xDatePatternsED->set_message_type( m_bDatePatternsValid ?
weld::EntryMessageType::Normal : weld::EntryMessageType::Error);
bReadonly = pLangConfig->aSysLocaleOptions.IsReadOnly(SvtSysLocaleOptions::EOption::DatePatterns);
m_xDatePatternsED->set_sensitive(!bReadonly);
m_xDatePatternsFT->set_sensitive(!bReadonly);
m_xDatePatternsImg->set_visible(bReadonly);
m_xDatePatternsED->save_value();
//western/CJK/CLK language
LanguageType eCurLang = LANGUAGE_NONE;
LanguageType eCurLangCJK = LANGUAGE_NONE;
LanguageType eCurLangCTL = LANGUAGE_NONE;
SfxObjectShell* pCurrentDocShell = SfxObjectShell::Current();
//collect the configuration values first
m_xCurrentDocCB->set_sensitive(false );
Any aWestLang;
Any aCJKLang;
Any aCTLLang;
try
{
aWestLang = pLangConfig->aLinguConfig.GetProperty(u"DefaultLocale" );
Locale aLocale;
aWestLang >>= aLocale;
eCurLang = LanguageTag::convertToLanguageType( aLocale, false );
aCJKLang = pLangConfig->aLinguConfig.GetProperty(u"DefaultLocale_CJK" );
aLocale = Locale();
aCJKLang >>= aLocale;
eCurLangCJK = LanguageTag::convertToLanguageType( aLocale, false );
aCTLLang = pLangConfig->aLinguConfig.GetProperty(u"DefaultLocale_CTL" );
aLocale = Locale();
aCTLLang >>= aLocale;
eCurLangCTL = LanguageTag::convertToLanguageType( aLocale, false );
}
catch (const Exception&)
{
}
//overwrite them by the values provided by the DocShell
if (pCurrentDocShell)
{
m_xCurrentDocCB->set_sensitive(true );
m_xCurrentDocCB->set_active(bLanguageCurrentDoc_Impl);
if ( const SvxLanguageItem* pLangItem = rSet->GetItemIfSet(SID_ATTR_LANGUAGE, false ))
{
LanguageType eTempCurLang = pLangItem->GetValue();
if (MsLangId::resolveSystemLanguageByScriptType(eCurLang, css::i18n::ScriptType::LATIN) != eTempCurLang)
eCurLang = eTempCurLang;
}
if ( const SvxLanguageItem* pLang = rSet->GetItemIfSet(SID_ATTR_CHAR_CJK_LANGUAGE, false ))
{
LanguageType eTempCurLang = pLang->GetValue();
if (MsLangId::resolveSystemLanguageByScriptType(eCurLangCJK, css::i18n::ScriptType::ASIAN) != eTempCurLang)
eCurLangCJK = eTempCurLang;
}
if ( const SvxLanguageItem* pLang = rSet->GetItemIfSet(SID_ATTR_CHAR_CTL_LANGUAGE, false ))
{
LanguageType eTempCurLang = pLang->GetValue();
if (MsLangId::resolveSystemLanguageByScriptType(eCurLangCTL, css::i18n::ScriptType::COMPLEX) != eTempCurLang)
eCurLangCTL = eTempCurLang;
}
}
if (LANGUAGE_NONE == eCurLang || LANGUAGE_DONTKNOW == eCurLang)
m_xWesternLanguageLB->set_active_id(LANGUAGE_NONE);
else
m_xWesternLanguageLB->set_active_id(eCurLang);
if (LANGUAGE_NONE == eCurLangCJK || LANGUAGE_DONTKNOW == eCurLangCJK)
m_xAsianLanguageLB->set_active_id(LANGUAGE_NONE);
else
m_xAsianLanguageLB->set_active_id(eCurLangCJK);
if (LANGUAGE_NONE == eCurLangCTL || LANGUAGE_DONTKNOW == eCurLangCTL)
m_xComplexLanguageLB->set_active_id(LANGUAGE_NONE);
else
m_xComplexLanguageLB->set_active_id(eCurLangCTL);
m_xWesternLanguageLB->save_active_id();
m_xAsianLanguageLB->save_active_id();
m_xComplexLanguageLB->save_active_id();
m_xIgnoreLanguageChangeCB->save_state();
m_xCurrentDocCB->save_state();
bool bEnable = !pLangConfig->aLinguConfig.IsReadOnly( u"DefaultLocale" );
m_xWesternLanguageFT->set_sensitive( bEnable );
m_xWesternLanguageLB->set_sensitive( bEnable );
m_xWesternLanguageImg->set_visible( !bEnable );
// 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 );
}
}
IMPL_LINK(OfaLanguagesTabPage, SupportHdl, weld::Toggleable&, rBox, void )
{
bool bCheck = rBox.get_active();
if ( m_xAsianSupportCB.get() == &rBox )
{
bool bReadonly = pLangConfig->aLinguConfig.IsReadOnly(u"DefaultLocale_CJK" );
bCheck = ( bCheck && !bReadonly );
m_xAsianLanguageLB->set_sensitive( bCheck );
if (rBox.get_sensitive())
m_bOldAsian = bCheck;
}
else if ( m_xCTLSupportCB.get() == &rBox )
{
bool bReadonly = pLangConfig->aLinguConfig.IsReadOnly(u"DefaultLocale_CTL" );
bCheck = ( bCheck && !bReadonly );
m_xComplexLanguageLB->set_sensitive( bCheck );
if (rBox.get_sensitive())
m_bOldCtl = bCheck;
}
else
SAL_WARN( "cui.options" , "OfaLanguagesTabPage::SupportHdl(): wrong rBox" );
}
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);
}
--> --------------------
--> maximum size reached
--> --------------------
Messung V0.5 C=92 H=97 G=94
¤ Dauer der Verarbeitung: 0.18 Sekunden
¤
*© Formatika GbR, Deutschland