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 OUString cIsKernAsianPunctuation
= u
"IsKernAsianPunctuation"_ustr
;
46 constexpr OUString cCharacterCompressionType
= u
"CharacterCompressionType"_ustr
;
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
, u
"cui/ui/optasianpage.ui"_ustr
, u
"OptAsianPage"_ustr
, &rSet
)
110 , pImpl(new SvxAsianLayoutPage_Impl
)
111 , m_xCharKerningRB(m_xBuilder
->weld_radio_button(u
"charkerning"_ustr
))
112 , m_xCharPunctKerningRB(m_xBuilder
->weld_radio_button(u
"charpunctkerning"_ustr
))
113 , m_xNoCompressionRB(m_xBuilder
->weld_radio_button(u
"nocompression"_ustr
))
114 , m_xPunctCompressionRB(m_xBuilder
->weld_radio_button(u
"punctcompression"_ustr
))
115 , m_xPunctKanaCompressionRB(m_xBuilder
->weld_radio_button(u
"punctkanacompression"_ustr
))
116 , m_xLanguageFT(m_xBuilder
->weld_label(u
"languageft"_ustr
))
117 , m_xLanguageLB(new SvxLanguageBox(m_xBuilder
->weld_combo_box(u
"language"_ustr
)))
118 , m_xStandardCB(m_xBuilder
->weld_check_button(u
"standard"_ustr
))
119 , m_xStartFT(m_xBuilder
->weld_label(u
"startft"_ustr
))
120 , m_xStartED(m_xBuilder
->weld_entry(u
"start"_ustr
))
121 , m_xEndFT(m_xBuilder
->weld_label(u
"endft"_ustr
))
122 , m_xEndED(m_xBuilder
->weld_entry(u
"end"_ustr
))
123 , m_xHintFT(m_xBuilder
->weld_label(u
"hintft"_ustr
))
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 OUString
SvxAsianLayoutPage::GetAllStrings()
146 OUString sAllStrings
;
148 = { u
"label1"_ustr
, u
"label2"_ustr
, u
"label3"_ustr
, u
"languageft"_ustr
, u
"startft"_ustr
, u
"endft"_ustr
, u
"hintft"_ustr
};
150 for (const auto& label
: labels
)
152 if (const auto pString
= m_xBuilder
->weld_label(label
))
153 sAllStrings
+= pString
->get_label() + " ";
156 OUString radioButton
[] = { u
"charkerning"_ustr
, u
"charpunctkerning"_ustr
, u
"nocompression"_ustr
,
157 u
"punctcompression"_ustr
, u
"punctkanacompression"_ustr
};
159 for (const auto& radio
: radioButton
)
161 if (const auto pString
= m_xBuilder
->weld_radio_button(radio
))
162 sAllStrings
+= pString
->get_label() + " ";
165 sAllStrings
+= m_xStandardCB
->get_label() + " ";
167 return sAllStrings
.replaceAll("_", "");
170 bool SvxAsianLayoutPage::FillItemSet( SfxItemSet
* )
172 if(m_xCharKerningRB
->get_state_changed_from_saved())
174 pImpl
->aConfig
.SetKerningWesternTextOnly(m_xCharKerningRB
->get_active());
175 OUString
sPunct(cIsKernAsianPunctuation
);
176 if(pImpl
->xPrSetInfo
.is() && pImpl
->xPrSetInfo
->hasPropertyByName(sPunct
))
178 bool bVal
= !m_xCharKerningRB
->get_active();
179 pImpl
->xPrSet
->setPropertyValue(sPunct
, Any(bVal
));
183 if(m_xNoCompressionRB
->get_state_changed_from_saved() ||
184 m_xPunctCompressionRB
->get_state_changed_from_saved())
186 CharCompressType nSet
= m_xNoCompressionRB
->get_active() ? CharCompressType::NONE
:
187 m_xPunctCompressionRB
->get_active() ? CharCompressType::PunctuationOnly
:
188 CharCompressType::PunctuationAndKana
;
189 pImpl
->aConfig
.SetCharDistanceCompression(nSet
);
190 OUString
sCompress(cCharacterCompressionType
);
191 if(pImpl
->xPrSetInfo
.is() && pImpl
->xPrSetInfo
->hasPropertyByName(sCompress
))
193 pImpl
->xPrSet
->setPropertyValue(sCompress
, Any(static_cast<sal_uInt16
>(nSet
)));
196 pImpl
->aConfig
.Commit();
197 if(pImpl
->xForbidden
.is())
201 for (auto const& changedLanguage
: pImpl
->aChangedLanguagesMap
)
203 Locale
aLocale( LanguageTag::convertToLocale(changedLanguage
.first
));
204 if(changedLanguage
.second
.bRemoved
)
205 pImpl
->xForbidden
->removeForbiddenCharacters( aLocale
);
206 else if(changedLanguage
.second
.oCharacters
)
207 pImpl
->xForbidden
->setForbiddenCharacters( aLocale
, *( changedLanguage
.second
.oCharacters
) );
210 catch (const Exception
&)
212 TOOLS_WARN_EXCEPTION( "cui.options", "in XForbiddenCharacters");
215 eLastUsedLanguageTypeForForbiddenCharacters
= m_xLanguageLB
->get_active_id();
220 void SvxAsianLayoutPage::Reset( const SfxItemSet
* )
222 SfxViewFrame
* pCurFrm
= SfxViewFrame::Current();
223 SfxObjectShell
* pDocSh
= pCurFrm
? pCurFrm
->GetObjectShell() : nullptr;
224 Reference
< XModel
> xModel
;
226 xModel
= pDocSh
->GetModel();
227 Reference
<XMultiServiceFactory
> xFact(xModel
, UNO_QUERY
);
230 pImpl
->xPrSet
.set(xFact
->createInstance(u
"com.sun.star.document.Settings"_ustr
), UNO_QUERY
);
232 if( pImpl
->xPrSet
.is() )
233 pImpl
->xPrSetInfo
= pImpl
->xPrSet
->getPropertySetInfo();
234 bool bKernWesternText
= SvxAsianConfig::IsKerningWesternTextOnly();
235 CharCompressType nCompress
= SvxAsianConfig::GetCharDistanceCompression();
236 if(pImpl
->xPrSetInfo
.is())
238 OUString
sForbidden(u
"ForbiddenCharacters"_ustr
);
239 if(pImpl
->xPrSetInfo
->hasPropertyByName(sForbidden
))
241 Any aForbidden
= pImpl
->xPrSet
->getPropertyValue(sForbidden
);
242 aForbidden
>>= pImpl
->xForbidden
;
244 OUString
sCompress(cCharacterCompressionType
);
245 if(pImpl
->xPrSetInfo
->hasPropertyByName(sCompress
))
247 Any aVal
= pImpl
->xPrSet
->getPropertyValue(sCompress
);
250 nCompress
= static_cast<CharCompressType
>(nTmp
);
252 OUString
sPunct(cIsKernAsianPunctuation
);
253 if(pImpl
->xPrSetInfo
->hasPropertyByName(sPunct
))
255 Any aVal
= pImpl
->xPrSet
->getPropertyValue(sPunct
);
256 bKernWesternText
= !*o3tl::doAccess
<bool>(aVal
);
261 m_xLanguageFT
->set_sensitive(false);
262 m_xLanguageLB
->set_sensitive(false);
263 m_xStandardCB
->set_sensitive(false);
264 m_xStartFT
->set_sensitive(false);
265 m_xStartED
->set_sensitive(false);
266 m_xEndFT
->set_sensitive(false);
267 m_xEndED
->set_sensitive(false);
268 m_xHintFT
->set_sensitive(false);
271 m_xCharKerningRB
->set_active(true);
273 m_xCharPunctKerningRB
->set_active(true);
276 case CharCompressType::NONE
: m_xNoCompressionRB
->set_active(true); break;
277 case CharCompressType::PunctuationOnly
: m_xPunctCompressionRB
->set_active(true); break;
278 default: m_xPunctKanaCompressionRB
->set_active(true);
280 m_xCharKerningRB
->save_state();
281 m_xNoCompressionRB
->save_state();
282 m_xPunctCompressionRB
->save_state();
283 m_xPunctKanaCompressionRB
->save_state();
285 m_xLanguageLB
->set_active(0);
286 //preselect the system language in the box - if available
287 if(LanguageType(USHRT_MAX
) == eLastUsedLanguageTypeForForbiddenCharacters
)
289 eLastUsedLanguageTypeForForbiddenCharacters
=
290 Application::GetSettings().GetLanguageTag().getLanguageType();
291 if (MsLangId::isSimplifiedChinese(eLastUsedLanguageTypeForForbiddenCharacters
))
292 eLastUsedLanguageTypeForForbiddenCharacters
= LANGUAGE_CHINESE_SIMPLIFIED
;
293 else if (MsLangId::isTraditionalChinese(eLastUsedLanguageTypeForForbiddenCharacters
))
294 eLastUsedLanguageTypeForForbiddenCharacters
= LANGUAGE_CHINESE_TRADITIONAL
;
296 m_xLanguageLB
->set_active_id(eLastUsedLanguageTypeForForbiddenCharacters
);
297 LanguageHdl(*m_xLanguageLB
->get_widget());
300 IMPL_LINK_NOARG(SvxAsianLayoutPage
, LanguageHdl
, weld::ComboBox
&, void)
303 LanguageType eSelectLanguage
= m_xLanguageLB
->get_active_id();
304 LanguageTag
aLanguageTag( eSelectLanguage
);
305 const Locale
& aLocale( aLanguageTag
.getLocale());
307 OUString sStart
, sEnd
;
309 if(pImpl
->xForbidden
.is())
311 bAvail
= pImpl
->hasForbiddenCharacters(eSelectLanguage
);
314 SvxForbiddenChars_Impl
* pElement
= pImpl
->getForbiddenCharacters(eSelectLanguage
);
315 if(pElement
->bRemoved
|| !pElement
->oCharacters
)
321 sStart
= pElement
->oCharacters
->beginLine
;
322 sEnd
= pElement
->oCharacters
->endLine
;
329 bAvail
= pImpl
->xForbidden
->hasForbiddenCharacters(aLocale
);
332 ForbiddenCharacters aForbidden
= pImpl
->xForbidden
->getForbiddenCharacters( aLocale
);
333 sStart
= aForbidden
.beginLine
;
334 sEnd
= aForbidden
.endLine
;
337 catch (const Exception
&)
339 TOOLS_WARN_EXCEPTION( "cui.options", "in XForbiddenCharacters");
345 bAvail
= SvxAsianConfig::GetStartEndChars( aLocale
, sStart
, sEnd
);
349 LocaleDataWrapper
aWrap( std::move(aLanguageTag
) );
350 ForbiddenCharacters aForbidden
= aWrap
.getForbiddenCharacters();
351 sStart
= aForbidden
.beginLine
;
352 sEnd
= aForbidden
.endLine
;
354 m_xStandardCB
->set_active(!bAvail
);
355 m_xStartED
->set_sensitive(bAvail
);
356 m_xEndED
->set_sensitive(bAvail
);
357 m_xStartFT
->set_sensitive(bAvail
);
358 m_xEndFT
->set_sensitive(bAvail
);
359 m_xStartED
->set_text(sStart
);
360 m_xEndED
->set_text(sEnd
);
363 IMPL_LINK(SvxAsianLayoutPage
, ChangeStandardHdl
, weld::Toggleable
&, rBox
, void)
365 bool bCheck
= rBox
.get_active();
366 m_xStartED
->set_sensitive(!bCheck
);
367 m_xEndED
->set_sensitive(!bCheck
);
368 m_xStartFT
->set_sensitive(!bCheck
);
369 m_xEndFT
->set_sensitive(!bCheck
);
371 ModifyHdl(*m_xStartED
);
374 IMPL_LINK(SvxAsianLayoutPage
, ModifyHdl
, weld::Entry
&, rEdit
, void)
376 LanguageType eSelectLanguage
= m_xLanguageLB
->get_active_id();
377 Locale
aLocale( LanguageTag::convertToLocale( eSelectLanguage
));
378 OUString sStart
= m_xStartED
->get_text();
379 OUString sEnd
= m_xEndED
->get_text();
380 bool bEnable
= rEdit
.get_sensitive();
381 if(pImpl
->xForbidden
.is())
387 ForbiddenCharacters aFCSet
;
388 aFCSet
.beginLine
= sStart
;
389 aFCSet
.endLine
= sEnd
;
390 pImpl
->addForbiddenCharacters(eSelectLanguage
, std::move(aFCSet
));
393 pImpl
->addForbiddenCharacters(eSelectLanguage
, std::nullopt
);
395 catch (const Exception
&)
397 TOOLS_WARN_EXCEPTION( "cui.options", "in XForbiddenCharacters");
400 pImpl
->aConfig
.SetStartEndChars( aLocale
, bEnable
? &sStart
: nullptr, bEnable
? &sEnd
: nullptr);
403 const WhichRangesContainer
& SvxAsianLayoutPage::GetRanges()
406 static const WhichRangesContainer gEmpty
;
410 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */