1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
22 #include <optasian.hxx>
23 #include <tools/debug.hxx>
24 #include <comphelper/diagnose_ex.hxx>
25 #include <o3tl/any.hxx>
26 #include <i18nlangtag/mslangid.hxx>
27 #include <svl/asiancfg.hxx>
28 #include <com/sun/star/frame/XModel.hpp>
29 #include <com/sun/star/lang/Locale.hpp>
30 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
31 #include <com/sun/star/i18n/XForbiddenCharacters.hpp>
32 #include <com/sun/star/beans/XPropertySet.hpp>
33 #include <sfx2/viewfrm.hxx>
34 #include <sfx2/objsh.hxx>
35 #include <vcl/svapp.hxx>
36 #include <vcl/settings.hxx>
37 #include <unotools/localedatawrapper.hxx>
39 using namespace com::sun::star::uno
;
40 using namespace com::sun::star::lang
;
41 using namespace com::sun::star::i18n
;
42 using namespace com::sun::star::frame
;
43 using namespace com::sun::star::beans
;
45 constexpr OUStringLiteral cIsKernAsianPunctuation
= u
"IsKernAsianPunctuation";
46 constexpr OUStringLiteral cCharacterCompressionType
= u
"CharacterCompressionType";
50 struct SvxForbiddenChars_Impl
53 std::optional
<ForbiddenCharacters
> oCharacters
;
58 struct SvxAsianLayoutPage_Impl
60 SvxAsianConfig aConfig
;
61 SvxAsianLayoutPage_Impl() {}
63 Reference
< XForbiddenCharacters
> xForbidden
;
64 Reference
< XPropertySet
> xPrSet
;
65 Reference
< XPropertySetInfo
> xPrSetInfo
;
66 std::map
< LanguageType
, SvxForbiddenChars_Impl
>
69 bool hasForbiddenCharacters(LanguageType eLang
);
70 SvxForbiddenChars_Impl
* getForbiddenCharacters(LanguageType eLang
);
71 void addForbiddenCharacters(LanguageType eLang
, std::optional
<ForbiddenCharacters
> oForbidden
);
74 bool SvxAsianLayoutPage_Impl::hasForbiddenCharacters(LanguageType eLang
)
76 return aChangedLanguagesMap
.count( eLang
);
79 SvxForbiddenChars_Impl
* SvxAsianLayoutPage_Impl::getForbiddenCharacters(LanguageType eLang
)
81 auto it
= aChangedLanguagesMap
.find( eLang
);
82 DBG_ASSERT( ( it
!= aChangedLanguagesMap
.end() ), "language not available");
83 if( it
!= aChangedLanguagesMap
.end() )
88 void SvxAsianLayoutPage_Impl::addForbiddenCharacters(
89 LanguageType eLang
, std::optional
<ForbiddenCharacters
> oForbidden
)
91 auto itOld
= aChangedLanguagesMap
.find( eLang
);
92 if( itOld
== aChangedLanguagesMap
.end() )
94 SvxForbiddenChars_Impl aChar
;
95 aChar
.bRemoved
= !oForbidden
.has_value();
96 aChar
.oCharacters
= std::move(oForbidden
);
97 aChangedLanguagesMap
.emplace( eLang
, std::move(aChar
) );
101 itOld
->second
.bRemoved
= !oForbidden
.has_value();
102 itOld
->second
.oCharacters
= std::move(oForbidden
);
106 static LanguageType
eLastUsedLanguageTypeForForbiddenCharacters(USHRT_MAX
);
108 SvxAsianLayoutPage::SvxAsianLayoutPage(weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
& rSet
)
109 : SfxTabPage(pPage
, pController
, "cui/ui/optasianpage.ui", "OptAsianPage", &rSet
)
110 , pImpl(new SvxAsianLayoutPage_Impl
)
111 , m_xCharKerningRB(m_xBuilder
->weld_radio_button("charkerning"))
112 , m_xCharPunctKerningRB(m_xBuilder
->weld_radio_button("charpunctkerning"))
113 , m_xNoCompressionRB(m_xBuilder
->weld_radio_button("nocompression"))
114 , m_xPunctCompressionRB(m_xBuilder
->weld_radio_button("punctcompression"))
115 , m_xPunctKanaCompressionRB(m_xBuilder
->weld_radio_button("punctkanacompression"))
116 , m_xLanguageFT(m_xBuilder
->weld_label("languageft"))
117 , m_xLanguageLB(new SvxLanguageBox(m_xBuilder
->weld_combo_box("language")))
118 , m_xStandardCB(m_xBuilder
->weld_check_button("standard"))
119 , m_xStartFT(m_xBuilder
->weld_label("startft"))
120 , m_xStartED(m_xBuilder
->weld_entry("start"))
121 , m_xEndFT(m_xBuilder
->weld_label("endft"))
122 , m_xEndED(m_xBuilder
->weld_entry("end"))
123 , m_xHintFT(m_xBuilder
->weld_label("hintft"))
125 LanguageHdl(*m_xLanguageLB
->get_widget());
126 m_xLanguageLB
->connect_changed(LINK(this, SvxAsianLayoutPage
, LanguageHdl
));
127 m_xStandardCB
->connect_toggled(LINK(this, SvxAsianLayoutPage
, ChangeStandardHdl
));
128 Link
<weld::Entry
&,void> aLk(LINK(this, SvxAsianLayoutPage
, ModifyHdl
));
129 m_xStartED
->connect_changed(aLk
);
130 m_xEndED
->connect_changed(aLk
);
132 m_xLanguageLB
->SetLanguageList( SvxLanguageListFlags::FBD_CHARS
, false, false );
135 SvxAsianLayoutPage::~SvxAsianLayoutPage()
139 std::unique_ptr
<SfxTabPage
> SvxAsianLayoutPage::Create(weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
* rAttrSet
)
141 return std::make_unique
<SvxAsianLayoutPage
>(pPage
, pController
, *rAttrSet
);
144 bool SvxAsianLayoutPage::FillItemSet( SfxItemSet
* )
146 if(m_xCharKerningRB
->get_state_changed_from_saved())
148 pImpl
->aConfig
.SetKerningWesternTextOnly(m_xCharKerningRB
->get_active());
149 OUString
sPunct(cIsKernAsianPunctuation
);
150 if(pImpl
->xPrSetInfo
.is() && pImpl
->xPrSetInfo
->hasPropertyByName(sPunct
))
152 bool bVal
= !m_xCharKerningRB
->get_active();
153 pImpl
->xPrSet
->setPropertyValue(sPunct
, Any(bVal
));
157 if(m_xNoCompressionRB
->get_state_changed_from_saved() ||
158 m_xPunctCompressionRB
->get_state_changed_from_saved())
160 CharCompressType nSet
= m_xNoCompressionRB
->get_active() ? CharCompressType::NONE
:
161 m_xPunctCompressionRB
->get_active() ? CharCompressType::PunctuationOnly
:
162 CharCompressType::PunctuationAndKana
;
163 pImpl
->aConfig
.SetCharDistanceCompression(nSet
);
164 OUString
sCompress(cCharacterCompressionType
);
165 if(pImpl
->xPrSetInfo
.is() && pImpl
->xPrSetInfo
->hasPropertyByName(sCompress
))
167 pImpl
->xPrSet
->setPropertyValue(sCompress
, Any(static_cast<sal_uInt16
>(nSet
)));
170 pImpl
->aConfig
.Commit();
171 if(pImpl
->xForbidden
.is())
175 for (auto const& changedLanguage
: pImpl
->aChangedLanguagesMap
)
177 Locale
aLocale( LanguageTag::convertToLocale(changedLanguage
.first
));
178 if(changedLanguage
.second
.bRemoved
)
179 pImpl
->xForbidden
->removeForbiddenCharacters( aLocale
);
180 else if(changedLanguage
.second
.oCharacters
)
181 pImpl
->xForbidden
->setForbiddenCharacters( aLocale
, *( changedLanguage
.second
.oCharacters
) );
184 catch (const Exception
&)
186 TOOLS_WARN_EXCEPTION( "cui.options", "in XForbiddenCharacters");
189 eLastUsedLanguageTypeForForbiddenCharacters
= m_xLanguageLB
->get_active_id();
194 void SvxAsianLayoutPage::Reset( const SfxItemSet
* )
196 SfxViewFrame
* pCurFrm
= SfxViewFrame::Current();
197 SfxObjectShell
* pDocSh
= pCurFrm
? pCurFrm
->GetObjectShell() : nullptr;
198 Reference
< XModel
> xModel
;
200 xModel
= pDocSh
->GetModel();
201 Reference
<XMultiServiceFactory
> xFact(xModel
, UNO_QUERY
);
204 pImpl
->xPrSet
.set(xFact
->createInstance("com.sun.star.document.Settings"), UNO_QUERY
);
206 if( pImpl
->xPrSet
.is() )
207 pImpl
->xPrSetInfo
= pImpl
->xPrSet
->getPropertySetInfo();
208 bool bKernWesternText
= pImpl
->aConfig
.IsKerningWesternTextOnly();
209 CharCompressType nCompress
= pImpl
->aConfig
.GetCharDistanceCompression();
210 if(pImpl
->xPrSetInfo
.is())
212 OUString
sForbidden("ForbiddenCharacters");
213 if(pImpl
->xPrSetInfo
->hasPropertyByName(sForbidden
))
215 Any aForbidden
= pImpl
->xPrSet
->getPropertyValue(sForbidden
);
216 aForbidden
>>= pImpl
->xForbidden
;
218 OUString
sCompress(cCharacterCompressionType
);
219 if(pImpl
->xPrSetInfo
->hasPropertyByName(sCompress
))
221 Any aVal
= pImpl
->xPrSet
->getPropertyValue(sCompress
);
224 nCompress
= static_cast<CharCompressType
>(nTmp
);
226 OUString
sPunct(cIsKernAsianPunctuation
);
227 if(pImpl
->xPrSetInfo
->hasPropertyByName(sPunct
))
229 Any aVal
= pImpl
->xPrSet
->getPropertyValue(sPunct
);
230 bKernWesternText
= !*o3tl::doAccess
<bool>(aVal
);
235 m_xLanguageFT
->set_sensitive(false);
236 m_xLanguageLB
->set_sensitive(false);
237 m_xStandardCB
->set_sensitive(false);
238 m_xStartFT
->set_sensitive(false);
239 m_xStartED
->set_sensitive(false);
240 m_xEndFT
->set_sensitive(false);
241 m_xEndED
->set_sensitive(false);
242 m_xHintFT
->set_sensitive(false);
245 m_xCharKerningRB
->set_active(true);
247 m_xCharPunctKerningRB
->set_active(true);
250 case CharCompressType::NONE
: m_xNoCompressionRB
->set_active(true); break;
251 case CharCompressType::PunctuationOnly
: m_xPunctCompressionRB
->set_active(true); break;
252 default: m_xPunctKanaCompressionRB
->set_active(true);
254 m_xCharKerningRB
->save_state();
255 m_xNoCompressionRB
->save_state();
256 m_xPunctCompressionRB
->save_state();
257 m_xPunctKanaCompressionRB
->save_state();
259 m_xLanguageLB
->set_active(0);
260 //preselect the system language in the box - if available
261 if(LanguageType(USHRT_MAX
) == eLastUsedLanguageTypeForForbiddenCharacters
)
263 eLastUsedLanguageTypeForForbiddenCharacters
=
264 Application::GetSettings().GetLanguageTag().getLanguageType();
265 if (MsLangId::isSimplifiedChinese(eLastUsedLanguageTypeForForbiddenCharacters
))
266 eLastUsedLanguageTypeForForbiddenCharacters
= LANGUAGE_CHINESE_SIMPLIFIED
;
267 else if (MsLangId::isTraditionalChinese(eLastUsedLanguageTypeForForbiddenCharacters
))
268 eLastUsedLanguageTypeForForbiddenCharacters
= LANGUAGE_CHINESE_TRADITIONAL
;
270 m_xLanguageLB
->set_active_id(eLastUsedLanguageTypeForForbiddenCharacters
);
271 LanguageHdl(*m_xLanguageLB
->get_widget());
274 IMPL_LINK_NOARG(SvxAsianLayoutPage
, LanguageHdl
, weld::ComboBox
&, void)
277 LanguageType eSelectLanguage
= m_xLanguageLB
->get_active_id();
278 LanguageTag
aLanguageTag( eSelectLanguage
);
279 const Locale
& aLocale( aLanguageTag
.getLocale());
281 OUString sStart
, sEnd
;
283 if(pImpl
->xForbidden
.is())
285 bAvail
= pImpl
->hasForbiddenCharacters(eSelectLanguage
);
288 SvxForbiddenChars_Impl
* pElement
= pImpl
->getForbiddenCharacters(eSelectLanguage
);
289 if(pElement
->bRemoved
|| !pElement
->oCharacters
)
295 sStart
= pElement
->oCharacters
->beginLine
;
296 sEnd
= pElement
->oCharacters
->endLine
;
303 bAvail
= pImpl
->xForbidden
->hasForbiddenCharacters(aLocale
);
306 ForbiddenCharacters aForbidden
= pImpl
->xForbidden
->getForbiddenCharacters( aLocale
);
307 sStart
= aForbidden
.beginLine
;
308 sEnd
= aForbidden
.endLine
;
311 catch (const Exception
&)
313 TOOLS_WARN_EXCEPTION( "cui.options", "in XForbiddenCharacters");
319 bAvail
= pImpl
->aConfig
.GetStartEndChars( aLocale
, sStart
, sEnd
);
323 LocaleDataWrapper
aWrap( std::move(aLanguageTag
) );
324 ForbiddenCharacters aForbidden
= aWrap
.getForbiddenCharacters();
325 sStart
= aForbidden
.beginLine
;
326 sEnd
= aForbidden
.endLine
;
328 m_xStandardCB
->set_active(!bAvail
);
329 m_xStartED
->set_sensitive(bAvail
);
330 m_xEndED
->set_sensitive(bAvail
);
331 m_xStartFT
->set_sensitive(bAvail
);
332 m_xEndFT
->set_sensitive(bAvail
);
333 m_xStartED
->set_text(sStart
);
334 m_xEndED
->set_text(sEnd
);
337 IMPL_LINK(SvxAsianLayoutPage
, ChangeStandardHdl
, weld::Toggleable
&, rBox
, void)
339 bool bCheck
= rBox
.get_active();
340 m_xStartED
->set_sensitive(!bCheck
);
341 m_xEndED
->set_sensitive(!bCheck
);
342 m_xStartFT
->set_sensitive(!bCheck
);
343 m_xEndFT
->set_sensitive(!bCheck
);
345 ModifyHdl(*m_xStartED
);
348 IMPL_LINK(SvxAsianLayoutPage
, ModifyHdl
, weld::Entry
&, rEdit
, void)
350 LanguageType eSelectLanguage
= m_xLanguageLB
->get_active_id();
351 Locale
aLocale( LanguageTag::convertToLocale( eSelectLanguage
));
352 OUString sStart
= m_xStartED
->get_text();
353 OUString sEnd
= m_xEndED
->get_text();
354 bool bEnable
= rEdit
.get_sensitive();
355 if(pImpl
->xForbidden
.is())
361 ForbiddenCharacters aFCSet
;
362 aFCSet
.beginLine
= sStart
;
363 aFCSet
.endLine
= sEnd
;
364 pImpl
->addForbiddenCharacters(eSelectLanguage
, std::move(aFCSet
));
367 pImpl
->addForbiddenCharacters(eSelectLanguage
, std::nullopt
);
369 catch (const Exception
&)
371 TOOLS_WARN_EXCEPTION( "cui.options", "in XForbiddenCharacters");
374 pImpl
->aConfig
.SetStartEndChars( aLocale
, bEnable
? &sStart
: nullptr, bEnable
? &sEnd
: nullptr);
377 WhichRangesContainer
SvxAsianLayoutPage::GetRanges()
380 return WhichRangesContainer();
383 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */