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 <osl/diagnose.h>
24 #include <tools/debug.hxx>
25 #include <o3tl/any.hxx>
26 #include <i18nlangtag/mslangid.hxx>
27 #include <svl/asiancfg.hxx>
28 #include <com/sun/star/lang/Locale.hpp>
29 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
30 #include <com/sun/star/i18n/XForbiddenCharacters.hpp>
31 #include <com/sun/star/beans/XPropertySet.hpp>
32 #include <sfx2/viewfrm.hxx>
33 #include <sfx2/objsh.hxx>
34 #include <vcl/svapp.hxx>
35 #include <vcl/settings.hxx>
36 #include <unotools/localedatawrapper.hxx>
38 using namespace com::sun::star::uno
;
39 using namespace com::sun::star::lang
;
40 using namespace com::sun::star::i18n
;
41 using namespace com::sun::star::frame
;
42 using namespace com::sun::star::beans
;
44 const sal_Char cIsKernAsianPunctuation
[] = "IsKernAsianPunctuation";
45 const sal_Char cCharacterCompressionType
[] = "CharacterCompressionType";
47 struct SvxForbiddenChars_Impl
50 std::unique_ptr
<ForbiddenCharacters
> pCharacters
;
53 struct SvxAsianLayoutPage_Impl
55 SvxAsianConfig aConfig
;
56 SvxAsianLayoutPage_Impl() {}
58 Reference
< XForbiddenCharacters
> xForbidden
;
59 Reference
< XPropertySet
> xPrSet
;
60 Reference
< XPropertySetInfo
> xPrSetInfo
;
61 std::map
< LanguageType
, std::unique_ptr
<SvxForbiddenChars_Impl
> >
64 bool hasForbiddenCharacters(LanguageType eLang
);
65 SvxForbiddenChars_Impl
* getForbiddenCharacters(LanguageType eLang
);
66 void addForbiddenCharacters(LanguageType eLang
, std::unique_ptr
<ForbiddenCharacters
> pForbidden
);
69 bool SvxAsianLayoutPage_Impl::hasForbiddenCharacters(LanguageType eLang
)
71 return aChangedLanguagesMap
.count( eLang
);
74 SvxForbiddenChars_Impl
* SvxAsianLayoutPage_Impl::getForbiddenCharacters(LanguageType eLang
)
76 auto it
= aChangedLanguagesMap
.find( eLang
);
77 DBG_ASSERT( ( it
!= aChangedLanguagesMap
.end() ), "language not available");
78 if( it
!= aChangedLanguagesMap
.end() )
79 return it
->second
.get();
83 void SvxAsianLayoutPage_Impl::addForbiddenCharacters(
84 LanguageType eLang
, std::unique_ptr
<ForbiddenCharacters
> pForbidden
)
86 auto itOld
= aChangedLanguagesMap
.find( eLang
);
87 if( itOld
== aChangedLanguagesMap
.end() )
89 std::unique_ptr
<SvxForbiddenChars_Impl
> pChar(new SvxForbiddenChars_Impl
);
90 pChar
->bRemoved
= nullptr == pForbidden
;
91 pChar
->pCharacters
= std::move(pForbidden
);
92 aChangedLanguagesMap
.emplace( eLang
, std::move(pChar
) );
96 itOld
->second
->bRemoved
= nullptr == pForbidden
;
97 itOld
->second
->pCharacters
= std::move(pForbidden
);
101 static LanguageType
eLastUsedLanguageTypeForForbiddenCharacters(USHRT_MAX
);
103 SvxAsianLayoutPage::SvxAsianLayoutPage(weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
& rSet
)
104 : SfxTabPage(pPage
, pController
, "cui/ui/optasianpage.ui", "OptAsianPage", &rSet
)
105 , pImpl(new SvxAsianLayoutPage_Impl
)
106 , m_xCharKerningRB(m_xBuilder
->weld_radio_button("charkerning"))
107 , m_xCharPunctKerningRB(m_xBuilder
->weld_radio_button("charpunctkerning"))
108 , m_xNoCompressionRB(m_xBuilder
->weld_radio_button("nocompression"))
109 , m_xPunctCompressionRB(m_xBuilder
->weld_radio_button("punctcompression"))
110 , m_xPunctKanaCompressionRB(m_xBuilder
->weld_radio_button("punctkanacompression"))
111 , m_xLanguageFT(m_xBuilder
->weld_label("languageft"))
112 , m_xLanguageLB(new SvxLanguageBox(m_xBuilder
->weld_combo_box("language")))
113 , m_xStandardCB(m_xBuilder
->weld_check_button("standard"))
114 , m_xStartFT(m_xBuilder
->weld_label("startft"))
115 , m_xStartED(m_xBuilder
->weld_entry("start"))
116 , m_xEndFT(m_xBuilder
->weld_label("endft"))
117 , m_xEndED(m_xBuilder
->weld_entry("end"))
118 , m_xHintFT(m_xBuilder
->weld_label("hintft"))
120 LanguageHdl(*m_xLanguageLB
->get_widget());
121 m_xLanguageLB
->connect_changed(LINK(this, SvxAsianLayoutPage
, LanguageHdl
));
122 m_xStandardCB
->connect_toggled(LINK(this, SvxAsianLayoutPage
, ChangeStandardHdl
));
123 Link
<weld::Entry
&,void> aLk(LINK(this, SvxAsianLayoutPage
, ModifyHdl
));
124 m_xStartED
->connect_changed(aLk
);
125 m_xEndED
->connect_changed(aLk
);
127 m_xLanguageLB
->SetLanguageList( SvxLanguageListFlags::FBD_CHARS
, false, false );
130 SvxAsianLayoutPage::~SvxAsianLayoutPage()
134 std::unique_ptr
<SfxTabPage
> SvxAsianLayoutPage::Create(weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
* rAttrSet
)
136 return std::make_unique
<SvxAsianLayoutPage
>(pPage
, pController
, *rAttrSet
);
139 bool SvxAsianLayoutPage::FillItemSet( SfxItemSet
* )
141 if(m_xCharKerningRB
->get_state_changed_from_saved())
143 pImpl
->aConfig
.SetKerningWesternTextOnly(m_xCharKerningRB
->get_active());
144 OUString
sPunct(cIsKernAsianPunctuation
);
145 if(pImpl
->xPrSetInfo
.is() && pImpl
->xPrSetInfo
->hasPropertyByName(sPunct
))
147 bool bVal
= !m_xCharKerningRB
->get_active();
148 pImpl
->xPrSet
->setPropertyValue(sPunct
, Any(bVal
));
152 if(m_xNoCompressionRB
->get_state_changed_from_saved() ||
153 m_xPunctCompressionRB
->get_state_changed_from_saved())
155 CharCompressType nSet
= m_xNoCompressionRB
->get_active() ? CharCompressType::NONE
:
156 m_xPunctCompressionRB
->get_active() ? CharCompressType::PunctuationOnly
:
157 CharCompressType::PunctuationAndKana
;
158 pImpl
->aConfig
.SetCharDistanceCompression(nSet
);
159 OUString
sCompress(cCharacterCompressionType
);
160 if(pImpl
->xPrSetInfo
.is() && pImpl
->xPrSetInfo
->hasPropertyByName(sCompress
))
162 pImpl
->xPrSet
->setPropertyValue(sCompress
, Any(static_cast<sal_uInt16
>(nSet
)));
165 pImpl
->aConfig
.Commit();
166 if(pImpl
->xForbidden
.is())
170 for (auto const& changedLanguage
: pImpl
->aChangedLanguagesMap
)
172 Locale
aLocale( LanguageTag::convertToLocale(changedLanguage
.first
));
173 if(changedLanguage
.second
->bRemoved
)
174 pImpl
->xForbidden
->removeForbiddenCharacters( aLocale
);
175 else if(changedLanguage
.second
->pCharacters
)
176 pImpl
->xForbidden
->setForbiddenCharacters( aLocale
, *( changedLanguage
.second
->pCharacters
) );
179 catch (const Exception
&)
181 OSL_FAIL("exception in XForbiddenCharacters");
184 eLastUsedLanguageTypeForForbiddenCharacters
= m_xLanguageLB
->get_active_id();
189 void SvxAsianLayoutPage::Reset( const SfxItemSet
* )
191 SfxViewFrame
* pCurFrm
= SfxViewFrame::Current();
192 SfxObjectShell
* pDocSh
= pCurFrm
? pCurFrm
->GetObjectShell() : nullptr;
193 Reference
< XModel
> xModel
;
195 xModel
= pDocSh
->GetModel();
196 Reference
<XMultiServiceFactory
> xFact(xModel
, UNO_QUERY
);
199 pImpl
->xPrSet
.set(xFact
->createInstance("com.sun.star.document.Settings"), UNO_QUERY
);
201 if( pImpl
->xPrSet
.is() )
202 pImpl
->xPrSetInfo
= pImpl
->xPrSet
->getPropertySetInfo();
203 OUString
sForbidden("ForbiddenCharacters");
204 bool bKernWesternText
= pImpl
->aConfig
.IsKerningWesternTextOnly();
205 CharCompressType nCompress
= pImpl
->aConfig
.GetCharDistanceCompression();
206 if(pImpl
->xPrSetInfo
.is())
208 if(pImpl
->xPrSetInfo
->hasPropertyByName(sForbidden
))
210 Any aForbidden
= pImpl
->xPrSet
->getPropertyValue(sForbidden
);
211 aForbidden
>>= pImpl
->xForbidden
;
213 OUString
sCompress(cCharacterCompressionType
);
214 if(pImpl
->xPrSetInfo
->hasPropertyByName(sCompress
))
216 Any aVal
= pImpl
->xPrSet
->getPropertyValue(sCompress
);
219 nCompress
= static_cast<CharCompressType
>(nTmp
);
221 OUString
sPunct(cIsKernAsianPunctuation
);
222 if(pImpl
->xPrSetInfo
->hasPropertyByName(sPunct
))
224 Any aVal
= pImpl
->xPrSet
->getPropertyValue(sPunct
);
225 bKernWesternText
= !*o3tl::doAccess
<bool>(aVal
);
230 m_xLanguageFT
->set_sensitive(false);
231 m_xLanguageLB
->set_sensitive(false);
232 m_xStandardCB
->set_sensitive(false);
233 m_xStartFT
->set_sensitive(false);
234 m_xStartED
->set_sensitive(false);
235 m_xEndFT
->set_sensitive(false);
236 m_xEndED
->set_sensitive(false);
237 m_xHintFT
->set_sensitive(false);
240 m_xCharKerningRB
->set_active(true);
242 m_xCharPunctKerningRB
->set_active(true);
245 case CharCompressType::NONE
: m_xNoCompressionRB
->set_active(true); break;
246 case CharCompressType::PunctuationOnly
: m_xPunctCompressionRB
->set_active(true); break;
247 default: m_xPunctKanaCompressionRB
->set_active(true);
249 m_xCharKerningRB
->save_state();
250 m_xNoCompressionRB
->save_state();
251 m_xPunctCompressionRB
->save_state();
252 m_xPunctKanaCompressionRB
->save_state();
254 m_xLanguageLB
->set_active(0);
255 //preselect the system language in the box - if available
256 if(LanguageType(USHRT_MAX
) == eLastUsedLanguageTypeForForbiddenCharacters
)
258 eLastUsedLanguageTypeForForbiddenCharacters
=
259 Application::GetSettings().GetLanguageTag().getLanguageType();
260 if (MsLangId::isSimplifiedChinese(eLastUsedLanguageTypeForForbiddenCharacters
))
261 eLastUsedLanguageTypeForForbiddenCharacters
= LANGUAGE_CHINESE_SIMPLIFIED
;
262 else if (MsLangId::isTraditionalChinese(eLastUsedLanguageTypeForForbiddenCharacters
))
263 eLastUsedLanguageTypeForForbiddenCharacters
= LANGUAGE_CHINESE_TRADITIONAL
;
265 m_xLanguageLB
->set_active_id(eLastUsedLanguageTypeForForbiddenCharacters
);
266 LanguageHdl(*m_xLanguageLB
->get_widget());
269 IMPL_LINK_NOARG(SvxAsianLayoutPage
, LanguageHdl
, weld::ComboBox
&, void)
272 LanguageType eSelectLanguage
= m_xLanguageLB
->get_active_id();
273 LanguageTag
aLanguageTag( eSelectLanguage
);
274 const Locale
& aLocale( aLanguageTag
.getLocale());
276 OUString sStart
, sEnd
;
278 if(pImpl
->xForbidden
.is())
280 bAvail
= pImpl
->hasForbiddenCharacters(eSelectLanguage
);
283 SvxForbiddenChars_Impl
* pElement
= pImpl
->getForbiddenCharacters(eSelectLanguage
);
284 if(pElement
->bRemoved
|| !pElement
->pCharacters
)
290 sStart
= pElement
->pCharacters
->beginLine
;
291 sEnd
= pElement
->pCharacters
->endLine
;
298 bAvail
= pImpl
->xForbidden
->hasForbiddenCharacters(aLocale
);
301 ForbiddenCharacters aForbidden
= pImpl
->xForbidden
->getForbiddenCharacters( aLocale
);
302 sStart
= aForbidden
.beginLine
;
303 sEnd
= aForbidden
.endLine
;
306 catch (const Exception
&)
308 OSL_FAIL("exception in XForbiddenCharacters");
314 bAvail
= pImpl
->aConfig
.GetStartEndChars( aLocale
, sStart
, sEnd
);
318 LocaleDataWrapper
aWrap( aLanguageTag
);
319 ForbiddenCharacters aForbidden
= aWrap
.getForbiddenCharacters();
320 sStart
= aForbidden
.beginLine
;
321 sEnd
= aForbidden
.endLine
;
323 m_xStandardCB
->set_active(!bAvail
);
324 m_xStartED
->set_sensitive(bAvail
);
325 m_xEndED
->set_sensitive(bAvail
);
326 m_xStartFT
->set_sensitive(bAvail
);
327 m_xEndFT
->set_sensitive(bAvail
);
328 m_xStartED
->set_text(sStart
);
329 m_xEndED
->set_text(sEnd
);
332 IMPL_LINK(SvxAsianLayoutPage
, ChangeStandardHdl
, weld::ToggleButton
&, rBox
, void)
334 bool bCheck
= rBox
.get_active();
335 m_xStartED
->set_sensitive(!bCheck
);
336 m_xEndED
->set_sensitive(!bCheck
);
337 m_xStartFT
->set_sensitive(!bCheck
);
338 m_xEndFT
->set_sensitive(!bCheck
);
340 ModifyHdl(*m_xStartED
);
343 IMPL_LINK(SvxAsianLayoutPage
, ModifyHdl
, weld::Entry
&, rEdit
, void)
345 LanguageType eSelectLanguage
= m_xLanguageLB
->get_active_id();
346 Locale
aLocale( LanguageTag::convertToLocale( eSelectLanguage
));
347 OUString sStart
= m_xStartED
->get_text();
348 OUString sEnd
= m_xEndED
->get_text();
349 bool bEnable
= rEdit
.get_sensitive();
350 if(pImpl
->xForbidden
.is())
356 std::unique_ptr
<ForbiddenCharacters
> pFCSet(new ForbiddenCharacters
);
357 pFCSet
->beginLine
= sStart
;
358 pFCSet
->endLine
= sEnd
;
359 pImpl
->addForbiddenCharacters(eSelectLanguage
, std::move(pFCSet
));
362 pImpl
->addForbiddenCharacters(eSelectLanguage
, nullptr);
364 catch (const Exception
&)
366 OSL_FAIL("exception in XForbiddenCharacters");
369 pImpl
->aConfig
.SetStartEndChars( aLocale
, bEnable
? &sStart
: nullptr, bEnable
? &sEnd
: nullptr);
372 const sal_uInt16
* SvxAsianLayoutPage::GetRanges()
375 static const sal_uInt16 pAsianLayoutRanges
[] = { 0 };
376 return pAsianLayoutRanges
;
379 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */