Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / unotools / source / config / compatibility.cxx
blobde8aaa00c7f9673a88e64e9ea416aa2fe82606e1
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>
35 using namespace ::utl;
36 using namespace ::osl;
37 using namespace ::com::sun::star::uno;
38 using namespace ::com::sun::star::beans;
40 constexpr OUStringLiteral ROOTNODE_OPTIONS = u"Office.Compatibility";
41 #define PATHDELIMITER "/"
42 #define SETNODE_ALLFILEFORMATS "AllFileFormats"
44 SvtCompatibilityEntry::SvtCompatibilityEntry()
45 : m_aPropertyValue( SvtCompatibilityEntry::getElementCount() )
47 /* Should be in the start. Do not remove it. */
48 setValue<OUString>( Index::Name, OUString() );
49 setValue<OUString>( Index::Module, OUString() );
51 /* Editable list of default values. Sync it with the SvtCompatibilityEntry::Index enum class. */
52 setValue<bool>( Index::AddSpacing, false );
53 setValue<bool>( Index::AddSpacingAtPages, false );
54 setValue<bool>( Index::UseOurTabStops, false );
55 setValue<bool>( Index::NoExtLeading, false );
56 setValue<bool>( Index::UseLineSpacing, false );
57 setValue<bool>( Index::AddTableSpacing, false );
58 setValue<bool>( Index::UseObjectPositioning, false );
59 setValue<bool>( Index::UseOurTextWrapping, false );
60 setValue<bool>( Index::ConsiderWrappingStyle, false );
61 setValue<bool>( Index::ExpandWordSpace, true );
62 setValue<bool>( Index::ProtectForm, false );
63 setValue<bool>( Index::MsWordTrailingBlanks, false );
64 setValue<bool>( Index::SubtractFlysAnchoredAtFlys, false );
65 setValue<bool>( Index::EmptyDbFieldHidesPara, true );
66 setValue<bool>( Index::AddTableLineSpacing, false );
69 OUString SvtCompatibilityEntry::getName( const Index rIdx )
71 static const char* sPropertyName[] =
73 /* Should be in the start. Do not remove it. */
74 "Name",
75 "Module",
77 /* Editable list of compatibility option names. Sync it with the SvtCompatibilityEntry::Index enum class. */
78 "AddSpacing",
79 "AddSpacingAtPages",
80 "UseOurTabStopFormat",
81 "NoExternalLeading",
82 "UseLineSpacing",
83 "AddTableSpacing",
84 "UseObjectPositioning",
85 "UseOurTextWrapping",
86 "ConsiderWrappingStyle",
87 "ExpandWordSpace",
88 "ProtectForm",
89 "MsWordCompTrailingBlanks",
90 "SubtractFlysAnchoredAtFlys",
91 "EmptyDbFieldHidesPara",
93 "AddTableLineSpacing" // Must be the last one
96 /* Size of sPropertyName array not equal size of the SvtCompatibilityEntry::Index enum class */
97 assert( std::size(sPropertyName) == SvtCompatibilityEntry::getElementCount() );
99 return OUString::createFromAscii( sPropertyName[ static_cast<int>(rIdx) ] );
102 /*-****************************************************************************************************************
103 @descr support simple menu structures and operations on it
104 ****************************************************************************************************************-*/
106 /*-****************************************************************************************************
107 @short base implementation of public interface for "SvtCompatibilityOptions"!
108 @descr These class is used as static member of "SvtCompatibilityOptions" ...
109 => The code exist only for one time and isn't duplicated for every instance!
110 *//*-*****************************************************************************************************/
111 class SvtCompatibilityOptions_Impl : public ConfigItem
113 public:
114 SvtCompatibilityOptions_Impl();
115 virtual ~SvtCompatibilityOptions_Impl() override;
117 void AppendItem( const SvtCompatibilityEntry& aItem );
118 void Clear();
120 void SetDefault( SvtCompatibilityEntry::Index rIdx, bool rValue );
121 bool GetDefault( SvtCompatibilityEntry::Index rIdx ) const;
123 const std::vector< SvtCompatibilityEntry > & GetOptions() const { return m_aOptions; }
125 /*-****************************************************************************************************
126 @short called for notify of configmanager
127 @descr This method is called from the ConfigManager before the application ends or from the
128 PropertyChangeListener if the sub tree broadcasts changes. You must update your
129 internal values.
131 @seealso baseclass ConfigItem
133 @param "lPropertyNames" is the list of properties which should be updated.
134 *//*-*****************************************************************************************************/
135 virtual void Notify( const Sequence< OUString >& lPropertyNames ) override;
137 private:
138 virtual void ImplCommit() override;
140 /*-****************************************************************************************************
141 @short return list of key names of our configuration management which represent one module tree
142 @descr These methods return the current list of key names! We need it to get needed values from our
143 configuration management and support dynamical menu item lists!
144 @return A list of configuration key names is returned.
145 *//*-*****************************************************************************************************/
146 Sequence< OUString > impl_GetPropertyNames( Sequence< OUString >& rItems );
148 private:
149 std::vector< SvtCompatibilityEntry > m_aOptions;
150 SvtCompatibilityEntry m_aDefOptions;
153 SvtCompatibilityOptions_Impl::SvtCompatibilityOptions_Impl() : ConfigItem( ROOTNODE_OPTIONS )
155 // Get names and values of all accessible menu entries and fill internal structures.
156 // See impl_GetPropertyNames() for further information.
157 Sequence< OUString > lNodes;
158 Sequence< OUString > lNames = impl_GetPropertyNames( lNodes );
159 Sequence< Any > lValues = GetProperties( lNames );
161 // Safe impossible cases.
162 // We need values from ALL configuration keys.
163 // Follow assignment use order of values in relation to our list of key names!
164 DBG_ASSERT( !( lNames.getLength()!=lValues.getLength() ), "SvtCompatibilityOptions_Impl::SvtCompatibilityOptions_Impl()\nI miss some values of configuration keys!\n" );
166 // Get names/values for new menu.
167 // 4 subkeys for every item!
168 bool bDefaultFound = false;
169 sal_Int32 nDestStep = 0;
170 for ( const auto& rNode : std::as_const(lNodes) )
172 SvtCompatibilityEntry aItem;
174 aItem.setValue<OUString>( SvtCompatibilityEntry::Index::Name, rNode );
176 for ( int i = static_cast<int>(SvtCompatibilityEntry::Index::Module); i < static_cast<int>(SvtCompatibilityEntry::Index::INVALID); ++i )
178 aItem.setValue( SvtCompatibilityEntry::Index(i), lValues[ nDestStep ] );
179 nDestStep++;
182 m_aOptions.push_back( aItem );
184 if ( !bDefaultFound && aItem.getValue<OUString>( SvtCompatibilityEntry::Index::Name ) == SvtCompatibilityEntry::DEFAULT_ENTRY_NAME )
186 SvtSysLocale aSysLocale;
187 css::lang::Locale aLocale = aSysLocale.GetLanguageTag().getLocale();
188 if ( aLocale.Language == "zh" || aLocale.Language == "ja" || aLocale.Language == "ko" )
189 aItem.setValue<bool>( SvtCompatibilityEntry::Index::ExpandWordSpace, false );
191 m_aDefOptions = aItem;
192 bDefaultFound = true;
197 SvtCompatibilityOptions_Impl::~SvtCompatibilityOptions_Impl()
199 assert( !IsModified() ); // should have been committed
202 void SvtCompatibilityOptions_Impl::AppendItem( const SvtCompatibilityEntry& aItem )
204 m_aOptions.push_back( aItem );
206 // default item reset?
207 if ( aItem.getValue<OUString>( SvtCompatibilityEntry::Index::Name ) == SvtCompatibilityEntry::DEFAULT_ENTRY_NAME )
208 m_aDefOptions = aItem;
210 SetModified();
213 void SvtCompatibilityOptions_Impl::Clear()
215 m_aOptions.clear();
217 SetModified();
220 void SvtCompatibilityOptions_Impl::SetDefault( SvtCompatibilityEntry::Index rIdx, bool rValue )
222 /* Are not set Name and Module */
223 assert( rIdx != SvtCompatibilityEntry::Index::Name && rIdx != SvtCompatibilityEntry::Index::Module );
225 m_aDefOptions.setValue<bool>( rIdx, rValue );
228 bool SvtCompatibilityOptions_Impl::GetDefault( SvtCompatibilityEntry::Index rIdx ) const
230 /* Are not set Name and Module */
231 assert( rIdx != SvtCompatibilityEntry::Index::Name && rIdx != SvtCompatibilityEntry::Index::Module );
233 return m_aDefOptions.getValue<bool>( rIdx );
236 void SvtCompatibilityOptions_Impl::Notify( const Sequence< OUString >& )
238 SAL_WARN( "unotools.config", "SvtCompatibilityOptions_Impl::Notify() Not implemented yet! I don't know how I can handle a dynamical list of unknown properties ..." );
241 void SvtCompatibilityOptions_Impl::ImplCommit()
243 // Write all properties!
244 // Delete complete set first.
245 ClearNodeSet( SETNODE_ALLFILEFORMATS );
247 Sequence< PropertyValue > lPropertyValues( SvtCompatibilityEntry::getElementCount() - 1 );
248 auto lPropertyValuesRange = asNonConstRange(lPropertyValues);
249 sal_uInt32 nNewCount = m_aOptions.size();
250 for ( sal_uInt32 nItem = 0; nItem < nNewCount; ++nItem )
252 SvtCompatibilityEntry aItem = m_aOptions[ nItem ];
253 OUString sNode = SETNODE_ALLFILEFORMATS PATHDELIMITER + aItem.getValue<OUString>( SvtCompatibilityEntry::Index::Name ) + PATHDELIMITER;
255 for ( int i = static_cast<int>(SvtCompatibilityEntry::Index::Module); i < static_cast<int>(SvtCompatibilityEntry::Index::INVALID); ++i )
257 lPropertyValuesRange[ i - 1 ].Name = sNode + SvtCompatibilityEntry::getName( SvtCompatibilityEntry::Index(i) );
258 lPropertyValuesRange[ i - 1 ].Value = aItem.getValue( SvtCompatibilityEntry::Index(i) );
261 SetSetProperties( SETNODE_ALLFILEFORMATS, lPropertyValues );
265 Sequence< OUString > SvtCompatibilityOptions_Impl::impl_GetPropertyNames( Sequence< OUString >& rItems )
267 // First get ALL names of current existing list items in configuration!
268 rItems = GetNodeNames( SETNODE_ALLFILEFORMATS );
270 // expand list to result list ...
271 Sequence< OUString > lProperties( rItems.getLength() * ( SvtCompatibilityEntry::getElementCount() - 1 ) );
272 auto lPropertiesRange = asNonConstRange(lProperties);
274 sal_Int32 nDestStep = 0;
275 // Copy entries to destination and expand every item with 2 supported sub properties.
276 for ( const auto& rItem : std::as_const(rItems) )
278 OUString sFixPath = SETNODE_ALLFILEFORMATS PATHDELIMITER + rItem + PATHDELIMITER;
279 for ( int i = static_cast<int>(SvtCompatibilityEntry::Index::Module); i < static_cast<int>(SvtCompatibilityEntry::Index::INVALID); ++i )
281 lPropertiesRange[ nDestStep ] = sFixPath + SvtCompatibilityEntry::getName( SvtCompatibilityEntry::Index(i) );
282 nDestStep++;
286 // Return result.
287 return lProperties;
290 namespace
292 std::weak_ptr<SvtCompatibilityOptions_Impl> theOptions;
295 SvtCompatibilityOptions::SvtCompatibilityOptions()
297 // Global access, must be guarded (multithreading!).
298 MutexGuard aGuard( GetOwnStaticMutex() );
300 m_pImpl = theOptions.lock();
301 if ( !m_pImpl )
303 m_pImpl = std::make_shared<SvtCompatibilityOptions_Impl>();
304 theOptions = m_pImpl;
305 ItemHolder1::holdConfigItem( EItem::Compatibility );
309 SvtCompatibilityOptions::~SvtCompatibilityOptions()
311 // Global access, must be guarded (multithreading!)
312 MutexGuard aGuard( GetOwnStaticMutex() );
313 m_pImpl.reset();
316 void SvtCompatibilityOptions::AppendItem( const SvtCompatibilityEntry& aItem )
318 MutexGuard aGuard( GetOwnStaticMutex() );
319 m_pImpl->AppendItem( aItem );
322 void SvtCompatibilityOptions::Clear()
324 MutexGuard aGuard( GetOwnStaticMutex() );
325 m_pImpl->Clear();
328 void SvtCompatibilityOptions::SetDefault( SvtCompatibilityEntry::Index rIdx, bool rValue )
330 MutexGuard aGuard( GetOwnStaticMutex() );
331 m_pImpl->SetDefault( rIdx, rValue );
334 bool SvtCompatibilityOptions::GetDefault( SvtCompatibilityEntry::Index rIdx ) const
336 MutexGuard aGuard( GetOwnStaticMutex() );
337 return m_pImpl->GetDefault( rIdx );
340 std::vector< SvtCompatibilityEntry > SvtCompatibilityOptions::GetList() const
342 MutexGuard aGuard( GetOwnStaticMutex() );
344 return m_pImpl->GetOptions();
347 Mutex& SvtCompatibilityOptions::GetOwnStaticMutex()
349 static osl::Mutex aMutex;
350 return aMutex;
353 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */