nss: upgrade to release 3.73
[LibreOffice.git] / unotools / source / config / compatibility.cxx
blob5556a0a231d455bfc428452b3db1459aad170ed0
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
20 #include <unotools/compatibility.hxx>
21 #include <unotools/configitem.hxx>
22 #include <unotools/syslocale.hxx>
23 #include <tools/debug.hxx>
24 #include <sal/log.hxx>
25 #include <com/sun/star/uno/Any.hxx>
26 #include <com/sun/star/uno/Sequence.hxx>
27 #include <com/sun/star/beans/PropertyValue.hpp>
28 #include <com/sun/star/lang/Locale.hpp>
29 #include <i18nlangtag/languagetag.hxx>
31 #include "itemholder1.hxx"
33 #include <algorithm>
34 #include <vector>
36 using namespace ::std;
37 using namespace ::utl;
38 using namespace ::osl;
39 using namespace ::com::sun::star::uno;
40 using namespace ::com::sun::star::beans;
42 #define ROOTNODE_OPTIONS "Office.Compatibility"
43 #define PATHDELIMITER "/"
44 #define SETNODE_ALLFILEFORMATS "AllFileFormats"
46 SvtCompatibilityEntry::SvtCompatibilityEntry()
47 : m_aPropertyValue( SvtCompatibilityEntry::getElementCount() )
49 /* Should be in the start. Do not remove it. */
50 setValue<OUString>( Index::Name, OUString() );
51 setValue<OUString>( Index::Module, OUString() );
53 /* Editable list of default values. Sync it with the SvtCompatibilityEntry::Index enum class. */
54 setValue<bool>( Index::UsePrtMetrics, false );
55 setValue<bool>( Index::AddSpacing, false );
56 setValue<bool>( Index::AddSpacingAtPages, false );
57 setValue<bool>( Index::UseOurTabStops, false );
58 setValue<bool>( Index::NoExtLeading, false );
59 setValue<bool>( Index::UseLineSpacing, false );
60 setValue<bool>( Index::AddTableSpacing, false );
61 setValue<bool>( Index::UseObjectPositioning, false );
62 setValue<bool>( Index::UseOurTextWrapping, false );
63 setValue<bool>( Index::ConsiderWrappingStyle, false );
64 setValue<bool>( Index::ExpandWordSpace, true );
65 setValue<bool>( Index::ProtectForm, false );
66 setValue<bool>( Index::MsWordTrailingBlanks, false );
67 setValue<bool>( Index::SubtractFlysAnchoredAtFlys, false );
68 setValue<bool>( Index::EmptyDbFieldHidesPara, true );
69 setValue<bool>( Index::AddTableLineSpacing, false );
71 setDefaultEntry( false );
74 OUString SvtCompatibilityEntry::getName( const Index rIdx )
76 static const char* sPropertyName[] =
78 /* Should be in the start. Do not remove it. */
79 "Name",
80 "Module",
82 /* Editable list of compatibility option names. Sync it with the SvtCompatibilityEntry::Index enum class. */
83 "UsePrinterMetrics",
84 "AddSpacing",
85 "AddSpacingAtPages",
86 "UseOurTabStopFormat",
87 "NoExternalLeading",
88 "UseLineSpacing",
89 "AddTableSpacing",
90 "UseObjectPositioning",
91 "UseOurTextWrapping",
92 "ConsiderWrappingStyle",
93 "ExpandWordSpace",
94 "ProtectForm",
95 "MsWordCompTrailingBlanks",
96 "SubtractFlysAnchoredAtFlys",
97 "EmptyDbFieldHidesPara",
98 "AddTableLineSpacing",
101 /* Size of sPropertyName array not equal size of the SvtCompatibilityEntry::Index enum class */
102 assert( SAL_N_ELEMENTS(sPropertyName) == static_cast<int>( SvtCompatibilityEntry::getElementCount() ) );
104 return OUString::createFromAscii( sPropertyName[ static_cast<int>(rIdx) ] );
107 /*-****************************************************************************************************************
108 @descr support simple menu structures and operations on it
109 ****************************************************************************************************************-*/
111 /*-****************************************************************************************************
112 @short base implementation of public interface for "SvtCompatibilityOptions"!
113 @descr These class is used as static member of "SvtCompatibilityOptions" ...
114 => The code exist only for one time and isn't duplicated for every instance!
115 *//*-*****************************************************************************************************/
116 class SvtCompatibilityOptions_Impl : public ConfigItem
118 public:
119 SvtCompatibilityOptions_Impl();
120 virtual ~SvtCompatibilityOptions_Impl() override;
122 void AppendItem( const SvtCompatibilityEntry& aItem );
123 void Clear();
125 void SetDefault( SvtCompatibilityEntry::Index rIdx, bool rValue );
126 bool GetDefault( SvtCompatibilityEntry::Index rIdx ) const;
128 Sequence< Sequence< PropertyValue > > GetList() const;
130 /*-****************************************************************************************************
131 @short called for notify of configmanager
132 @descr This method is called from the ConfigManager before the application ends or from the
133 PropertyChangeListener if the sub tree broadcasts changes. You must update your
134 internal values.
136 @seealso baseclass ConfigItem
138 @param "lPropertyNames" is the list of properties which should be updated.
139 *//*-*****************************************************************************************************/
140 virtual void Notify( const Sequence< OUString >& lPropertyNames ) override;
142 private:
143 virtual void ImplCommit() override;
145 /*-****************************************************************************************************
146 @short return list of key names of our configuration management which represent one module tree
147 @descr These methods return the current list of key names! We need it to get needed values from our
148 configuration management and support dynamical menu item lists!
149 @return A list of configuration key names is returned.
150 *//*-*****************************************************************************************************/
151 Sequence< OUString > impl_GetPropertyNames( Sequence< OUString >& rItems );
153 private:
154 std::vector< SvtCompatibilityEntry > m_aOptions;
155 SvtCompatibilityEntry m_aDefOptions;
158 SvtCompatibilityOptions_Impl::SvtCompatibilityOptions_Impl() : ConfigItem( ROOTNODE_OPTIONS )
160 // Get names and values of all accessible menu entries and fill internal structures.
161 // See impl_GetPropertyNames() for further information.
162 Sequence< OUString > lNodes;
163 Sequence< OUString > lNames = impl_GetPropertyNames( lNodes );
164 Sequence< Any > lValues = GetProperties( lNames );
166 // Safe impossible cases.
167 // We need values from ALL configuration keys.
168 // Follow assignment use order of values in relation to our list of key names!
169 DBG_ASSERT( !( lNames.getLength()!=lValues.getLength() ), "SvtCompatibilityOptions_Impl::SvtCompatibilityOptions_Impl()\nI miss some values of configuration keys!\n" );
171 // Get names/values for new menu.
172 // 4 subkeys for every item!
173 bool bDefaultFound = false;
174 sal_Int32 nDestStep = 0;
175 for ( const auto& rNode : std::as_const(lNodes) )
177 SvtCompatibilityEntry aItem;
179 aItem.setValue<OUString>( SvtCompatibilityEntry::Index::Name, rNode );
181 for ( int i = static_cast<int>(SvtCompatibilityEntry::Index::Module); i < static_cast<int>(SvtCompatibilityEntry::Index::INVALID); ++i )
183 aItem.setValue( SvtCompatibilityEntry::Index(i), lValues[ nDestStep ] );
184 nDestStep++;
187 m_aOptions.push_back( aItem );
189 if ( !bDefaultFound && aItem.getValue<OUString>( SvtCompatibilityEntry::Index::Name ) == SvtCompatibilityEntry::getDefaultEntryName() )
191 SvtSysLocale aSysLocale;
192 css::lang::Locale aLocale = aSysLocale.GetLanguageTag().getLocale();
193 if ( aLocale.Language == "zh" || aLocale.Language == "ja" || aLocale.Language == "ko" )
194 aItem.setValue<bool>( SvtCompatibilityEntry::Index::ExpandWordSpace, false );
196 m_aDefOptions = aItem;
197 bDefaultFound = true;
202 SvtCompatibilityOptions_Impl::~SvtCompatibilityOptions_Impl()
204 assert( !IsModified() ); // should have been committed
207 void SvtCompatibilityOptions_Impl::AppendItem( const SvtCompatibilityEntry& aItem )
209 m_aOptions.push_back( aItem );
211 // default item reset?
212 if ( aItem.getValue<OUString>( SvtCompatibilityEntry::Index::Name ) == SvtCompatibilityEntry::getDefaultEntryName() )
213 m_aDefOptions = aItem;
215 SetModified();
218 void SvtCompatibilityOptions_Impl::Clear()
220 m_aOptions.clear();
222 SetModified();
225 void SvtCompatibilityOptions_Impl::SetDefault( SvtCompatibilityEntry::Index rIdx, bool rValue )
227 /* Are not set Name and Module */
228 assert( rIdx != SvtCompatibilityEntry::Index::Name && rIdx != SvtCompatibilityEntry::Index::Module );
230 m_aDefOptions.setValue<bool>( rIdx, rValue );
233 bool SvtCompatibilityOptions_Impl::GetDefault( SvtCompatibilityEntry::Index rIdx ) const
235 /* Are not set Name and Module */
236 assert( rIdx != SvtCompatibilityEntry::Index::Name && rIdx != SvtCompatibilityEntry::Index::Module );
238 return m_aDefOptions.getValue<bool>( rIdx );
241 Sequence< Sequence< PropertyValue > > SvtCompatibilityOptions_Impl::GetList() const
243 Sequence< PropertyValue > lProperties( SvtCompatibilityEntry::getElementCount() );
244 Sequence< Sequence< PropertyValue > > lResult( m_aOptions.size() );
246 for ( int i = static_cast<int>(SvtCompatibilityEntry::Index::Name); i < static_cast<int>(SvtCompatibilityEntry::Index::INVALID); ++i )
247 lProperties[i].Name = SvtCompatibilityEntry::getName( SvtCompatibilityEntry::Index(i) );
249 sal_Int32 j = 0;
250 for ( const auto& rItem : m_aOptions )
252 for ( int i = static_cast<int>(SvtCompatibilityEntry::Index::Name); i < static_cast<int>(SvtCompatibilityEntry::Index::INVALID); ++i )
253 lProperties[i].Value = rItem.getValue( SvtCompatibilityEntry::Index(i) );
254 lResult[ j++ ] = lProperties;
257 return lResult;
260 void SvtCompatibilityOptions_Impl::Notify( const Sequence< OUString >& )
262 SAL_WARN( "unotools.config", "SvtCompatibilityOptions_Impl::Notify() Not implemented yet! I don't know how I can handle a dynamical list of unknown properties ..." );
265 void SvtCompatibilityOptions_Impl::ImplCommit()
267 // Write all properties!
268 // Delete complete set first.
269 ClearNodeSet( SETNODE_ALLFILEFORMATS );
271 Sequence< PropertyValue > lPropertyValues( SvtCompatibilityEntry::getElementCount() - 1 );
272 sal_uInt32 nNewCount = m_aOptions.size();
273 for ( sal_uInt32 nItem = 0; nItem < nNewCount; ++nItem )
275 SvtCompatibilityEntry aItem = m_aOptions[ nItem ];
276 OUString sNode = SETNODE_ALLFILEFORMATS PATHDELIMITER + aItem.getValue<OUString>( SvtCompatibilityEntry::Index::Name ) + PATHDELIMITER;
278 for ( int i = static_cast<int>(SvtCompatibilityEntry::Index::Module); i < static_cast<int>(SvtCompatibilityEntry::Index::INVALID); ++i )
280 lPropertyValues[ i - 1 ].Name = sNode + SvtCompatibilityEntry::getName( SvtCompatibilityEntry::Index(i) );
281 lPropertyValues[ i - 1 ].Value = aItem.getValue( SvtCompatibilityEntry::Index(i) );
284 SetSetProperties( SETNODE_ALLFILEFORMATS, lPropertyValues );
288 Sequence< OUString > SvtCompatibilityOptions_Impl::impl_GetPropertyNames( Sequence< OUString >& rItems )
290 // First get ALL names of current existing list items in configuration!
291 rItems = GetNodeNames( SETNODE_ALLFILEFORMATS );
293 // expand list to result list ...
294 Sequence< OUString > lProperties( rItems.getLength() * ( SvtCompatibilityEntry::getElementCount() - 1 ) );
296 sal_Int32 nDestStep = 0;
297 // Copy entries to destination and expand every item with 2 supported sub properties.
298 for ( const auto& rItem : std::as_const(rItems) )
300 OUString sFixPath = SETNODE_ALLFILEFORMATS PATHDELIMITER + rItem + PATHDELIMITER;
301 for ( int i = static_cast<int>(SvtCompatibilityEntry::Index::Module); i < static_cast<int>(SvtCompatibilityEntry::Index::INVALID); ++i )
303 lProperties[ nDestStep ] = sFixPath + SvtCompatibilityEntry::getName( SvtCompatibilityEntry::Index(i) );
304 nDestStep++;
308 // Return result.
309 return lProperties;
312 namespace
314 std::weak_ptr<SvtCompatibilityOptions_Impl> theOptions;
317 SvtCompatibilityOptions::SvtCompatibilityOptions()
319 // Global access, must be guarded (multithreading!).
320 MutexGuard aGuard( GetOwnStaticMutex() );
322 m_pImpl = theOptions.lock();
323 if ( !m_pImpl )
325 m_pImpl = std::make_shared<SvtCompatibilityOptions_Impl>();
326 theOptions = m_pImpl;
327 ItemHolder1::holdConfigItem( EItem::Compatibility );
331 SvtCompatibilityOptions::~SvtCompatibilityOptions()
333 // Global access, must be guarded (multithreading!)
334 MutexGuard aGuard( GetOwnStaticMutex() );
335 m_pImpl.reset();
338 void SvtCompatibilityOptions::AppendItem( const SvtCompatibilityEntry& aItem )
340 MutexGuard aGuard( GetOwnStaticMutex() );
341 m_pImpl->AppendItem( aItem );
344 void SvtCompatibilityOptions::Clear()
346 MutexGuard aGuard( GetOwnStaticMutex() );
347 m_pImpl->Clear();
350 void SvtCompatibilityOptions::SetDefault( SvtCompatibilityEntry::Index rIdx, bool rValue )
352 MutexGuard aGuard( GetOwnStaticMutex() );
353 m_pImpl->SetDefault( rIdx, rValue );
356 bool SvtCompatibilityOptions::GetDefault( SvtCompatibilityEntry::Index rIdx ) const
358 MutexGuard aGuard( GetOwnStaticMutex() );
359 return m_pImpl->GetDefault( rIdx );
362 Sequence< Sequence< PropertyValue > > SvtCompatibilityOptions::GetList() const
364 MutexGuard aGuard( GetOwnStaticMutex() );
365 return m_pImpl->GetList();
368 namespace
370 class theCompatibilityOptionsMutex : public rtl::Static<osl::Mutex, theCompatibilityOptionsMutex>{};
373 Mutex& SvtCompatibilityOptions::GetOwnStaticMutex()
375 return theCompatibilityOptionsMutex::get();
378 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */