Version 6.4.0.3, tag libreoffice-6.4.0.3
[LibreOffice.git] / unotools / source / config / compatibility.cxx
bloba71c8ac39c8dd3a8a33d0ed56bf2bebec7f6f543
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 );
70 setDefaultEntry( false );
73 OUString SvtCompatibilityEntry::getName( const Index rIdx )
75 static const char* sPropertyName[] =
77 /* Should be in the start. Do not remove it. */
78 "Name",
79 "Module",
81 /* Editable list of compatibility option names. Sync it with the SvtCompatibilityEntry::Index enum class. */
82 "UsePrinterMetrics",
83 "AddSpacing",
84 "AddSpacingAtPages",
85 "UseOurTabStopFormat",
86 "NoExternalLeading",
87 "UseLineSpacing",
88 "AddTableSpacing",
89 "UseObjectPositioning",
90 "UseOurTextWrapping",
91 "ConsiderWrappingStyle",
92 "ExpandWordSpace",
93 "ProtectForm",
94 "MsWordCompTrailingBlanks",
95 "SubtractFlysAnchoredAtFlys",
96 "EmptyDbFieldHidesPara",
99 /* Size of sPropertyName array not equal size of the SvtCompatibilityEntry::Index enum class */
100 assert( SAL_N_ELEMENTS(sPropertyName) == static_cast<int>( SvtCompatibilityEntry::getElementCount() ) );
102 return OUString::createFromAscii( sPropertyName[ static_cast<int>(rIdx) ] );
105 /*-****************************************************************************************************************
106 @descr support simple menu structures and operations on it
107 ****************************************************************************************************************-*/
109 /*-****************************************************************************************************
110 @short base implementation of public interface for "SvtCompatibilityOptions"!
111 @descr These class is used as static member of "SvtCompatibilityOptions" ...
112 => The code exist only for one time and isn't duplicated for every instance!
113 *//*-*****************************************************************************************************/
114 class SvtCompatibilityOptions_Impl : public ConfigItem
116 public:
117 SvtCompatibilityOptions_Impl();
118 virtual ~SvtCompatibilityOptions_Impl() override;
120 void AppendItem( const SvtCompatibilityEntry& aItem );
121 void Clear();
123 void SetDefault( SvtCompatibilityEntry::Index rIdx, bool rValue );
124 bool GetDefault( SvtCompatibilityEntry::Index rIdx ) const;
126 Sequence< Sequence< PropertyValue > > GetList() const;
128 /*-****************************************************************************************************
129 @short called for notify of configmanager
130 @descr This method is called from the ConfigManager before the application ends or from the
131 PropertyChangeListener if the sub tree broadcasts changes. You must update your
132 internal values.
134 @seealso baseclass ConfigItem
136 @param "lPropertyNames" is the list of properties which should be updated.
137 *//*-*****************************************************************************************************/
138 virtual void Notify( const Sequence< OUString >& lPropertyNames ) override;
140 private:
141 virtual void ImplCommit() override;
143 /*-****************************************************************************************************
144 @short return list of key names of our configuration management which represent one module tree
145 @descr These methods return the current list of key names! We need it to get needed values from our
146 configuration management and support dynamical menu item lists!
147 @return A list of configuration key names is returned.
148 *//*-*****************************************************************************************************/
149 Sequence< OUString > impl_GetPropertyNames( Sequence< OUString >& rItems );
151 private:
152 std::vector< SvtCompatibilityEntry > m_aOptions;
153 SvtCompatibilityEntry m_aDefOptions;
156 SvtCompatibilityOptions_Impl::SvtCompatibilityOptions_Impl() : ConfigItem( ROOTNODE_OPTIONS )
158 // Get names and values of all accessible menu entries and fill internal structures.
159 // See impl_GetPropertyNames() for further information.
160 Sequence< OUString > lNodes;
161 Sequence< OUString > lNames = impl_GetPropertyNames( lNodes );
162 Sequence< Any > lValues = GetProperties( lNames );
164 // Safe impossible cases.
165 // We need values from ALL configuration keys.
166 // Follow assignment use order of values in relation to our list of key names!
167 DBG_ASSERT( !( lNames.getLength()!=lValues.getLength() ), "SvtCompatibilityOptions_Impl::SvtCompatibilityOptions_Impl()\nI miss some values of configuration keys!\n" );
169 // Get names/values for new menu.
170 // 4 subkeys for every item!
171 bool bDefaultFound = false;
172 sal_Int32 nDestStep = 0;
173 for ( const auto& rNode : std::as_const(lNodes) )
175 SvtCompatibilityEntry aItem;
177 aItem.setValue<OUString>( SvtCompatibilityEntry::Index::Name, rNode );
179 for ( int i = static_cast<int>(SvtCompatibilityEntry::Index::Module); i < static_cast<int>(SvtCompatibilityEntry::Index::INVALID); ++i )
181 aItem.setValue( SvtCompatibilityEntry::Index(i), lValues[ nDestStep ] );
182 nDestStep++;
185 m_aOptions.push_back( aItem );
187 if ( !bDefaultFound && aItem.getValue<OUString>( SvtCompatibilityEntry::Index::Name ) == SvtCompatibilityEntry::getDefaultEntryName() )
189 SvtSysLocale aSysLocale;
190 css::lang::Locale aLocale = aSysLocale.GetLanguageTag().getLocale();
191 if ( aLocale.Language == "zh" || aLocale.Language == "ja" || aLocale.Language == "ko" )
192 aItem.setValue<bool>( SvtCompatibilityEntry::Index::ExpandWordSpace, false );
194 m_aDefOptions = aItem;
195 bDefaultFound = true;
200 SvtCompatibilityOptions_Impl::~SvtCompatibilityOptions_Impl()
202 assert( !IsModified() ); // should have been committed
205 void SvtCompatibilityOptions_Impl::AppendItem( const SvtCompatibilityEntry& aItem )
207 m_aOptions.push_back( aItem );
209 // default item reset?
210 if ( aItem.getValue<OUString>( SvtCompatibilityEntry::Index::Name ) == SvtCompatibilityEntry::getDefaultEntryName() )
211 m_aDefOptions = aItem;
213 SetModified();
216 void SvtCompatibilityOptions_Impl::Clear()
218 m_aOptions.clear();
220 SetModified();
223 void SvtCompatibilityOptions_Impl::SetDefault( SvtCompatibilityEntry::Index rIdx, bool rValue )
225 /* Are not set Name and Module */
226 assert( rIdx != SvtCompatibilityEntry::Index::Name && rIdx != SvtCompatibilityEntry::Index::Module );
228 m_aDefOptions.setValue<bool>( rIdx, rValue );
231 bool SvtCompatibilityOptions_Impl::GetDefault( SvtCompatibilityEntry::Index rIdx ) const
233 /* Are not set Name and Module */
234 assert( rIdx != SvtCompatibilityEntry::Index::Name && rIdx != SvtCompatibilityEntry::Index::Module );
236 return m_aDefOptions.getValue<bool>( rIdx );
239 Sequence< Sequence< PropertyValue > > SvtCompatibilityOptions_Impl::GetList() const
241 Sequence< PropertyValue > lProperties( SvtCompatibilityEntry::getElementCount() );
242 Sequence< Sequence< PropertyValue > > lResult( m_aOptions.size() );
244 for ( int i = static_cast<int>(SvtCompatibilityEntry::Index::Name); i < static_cast<int>(SvtCompatibilityEntry::Index::INVALID); ++i )
245 lProperties[i].Name = SvtCompatibilityEntry::getName( SvtCompatibilityEntry::Index(i) );
247 sal_Int32 j = 0;
248 for ( const auto& rItem : m_aOptions )
250 for ( int i = static_cast<int>(SvtCompatibilityEntry::Index::Name); i < static_cast<int>(SvtCompatibilityEntry::Index::INVALID); ++i )
251 lProperties[i].Value = rItem.getValue( SvtCompatibilityEntry::Index(i) );
252 lResult[ j++ ] = lProperties;
255 return lResult;
258 void SvtCompatibilityOptions_Impl::Notify( const Sequence< OUString >& )
260 SAL_WARN( "unotools.config", "SvtCompatibilityOptions_Impl::Notify() Not implemented yet! I don't know how I can handle a dynamical list of unknown properties ..." );
263 void SvtCompatibilityOptions_Impl::ImplCommit()
265 // Write all properties!
266 // Delete complete set first.
267 ClearNodeSet( SETNODE_ALLFILEFORMATS );
269 Sequence< PropertyValue > lPropertyValues( SvtCompatibilityEntry::getElementCount() - 1 );
270 sal_uInt32 nNewCount = m_aOptions.size();
271 for ( sal_uInt32 nItem = 0; nItem < nNewCount; ++nItem )
273 SvtCompatibilityEntry aItem = m_aOptions[ nItem ];
274 OUString sNode = SETNODE_ALLFILEFORMATS PATHDELIMITER + aItem.getValue<OUString>( SvtCompatibilityEntry::Index::Name ) + PATHDELIMITER;
276 for ( int i = static_cast<int>(SvtCompatibilityEntry::Index::Module); i < static_cast<int>(SvtCompatibilityEntry::Index::INVALID); ++i )
278 lPropertyValues[ i - 1 ].Name = sNode + SvtCompatibilityEntry::getName( SvtCompatibilityEntry::Index(i) );
279 lPropertyValues[ i - 1 ].Value = aItem.getValue( SvtCompatibilityEntry::Index(i) );
282 SetSetProperties( SETNODE_ALLFILEFORMATS, lPropertyValues );
286 Sequence< OUString > SvtCompatibilityOptions_Impl::impl_GetPropertyNames( Sequence< OUString >& rItems )
288 // First get ALL names of current existing list items in configuration!
289 rItems = GetNodeNames( SETNODE_ALLFILEFORMATS );
291 // expand list to result list ...
292 Sequence< OUString > lProperties( rItems.getLength() * ( SvtCompatibilityEntry::getElementCount() - 1 ) );
294 sal_Int32 nDestStep = 0;
295 // Copy entries to destination and expand every item with 2 supported sub properties.
296 for ( const auto& rItem : std::as_const(rItems) )
298 OUString sFixPath = SETNODE_ALLFILEFORMATS PATHDELIMITER + rItem + PATHDELIMITER;
299 for ( int i = static_cast<int>(SvtCompatibilityEntry::Index::Module); i < static_cast<int>(SvtCompatibilityEntry::Index::INVALID); ++i )
301 lProperties[ nDestStep ] = sFixPath + SvtCompatibilityEntry::getName( SvtCompatibilityEntry::Index(i) );
302 nDestStep++;
306 // Return result.
307 return lProperties;
310 namespace
312 std::weak_ptr<SvtCompatibilityOptions_Impl> theOptions;
315 SvtCompatibilityOptions::SvtCompatibilityOptions()
317 // Global access, must be guarded (multithreading!).
318 MutexGuard aGuard( GetOwnStaticMutex() );
320 m_pImpl = theOptions.lock();
321 if ( !m_pImpl )
323 m_pImpl = std::make_shared<SvtCompatibilityOptions_Impl>();
324 theOptions = m_pImpl;
325 ItemHolder1::holdConfigItem( EItem::Compatibility );
329 SvtCompatibilityOptions::~SvtCompatibilityOptions()
331 // Global access, must be guarded (multithreading!)
332 MutexGuard aGuard( GetOwnStaticMutex() );
333 m_pImpl.reset();
336 void SvtCompatibilityOptions::AppendItem( const SvtCompatibilityEntry& aItem )
338 MutexGuard aGuard( GetOwnStaticMutex() );
339 m_pImpl->AppendItem( aItem );
342 void SvtCompatibilityOptions::Clear()
344 MutexGuard aGuard( GetOwnStaticMutex() );
345 m_pImpl->Clear();
348 void SvtCompatibilityOptions::SetDefault( SvtCompatibilityEntry::Index rIdx, bool rValue )
350 MutexGuard aGuard( GetOwnStaticMutex() );
351 m_pImpl->SetDefault( rIdx, rValue );
354 bool SvtCompatibilityOptions::GetDefault( SvtCompatibilityEntry::Index rIdx ) const
356 MutexGuard aGuard( GetOwnStaticMutex() );
357 return m_pImpl->GetDefault( rIdx );
360 Sequence< Sequence< PropertyValue > > SvtCompatibilityOptions::GetList() const
362 MutexGuard aGuard( GetOwnStaticMutex() );
363 return m_pImpl->GetList();
366 namespace
368 class theCompatibilityOptionsMutex : public rtl::Static<osl::Mutex, theCompatibilityOptionsMutex>{};
371 Mutex& SvtCompatibilityOptions::GetOwnStaticMutex()
373 return theCompatibilityOptionsMutex::get();
376 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */