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 .
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"
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. */
77 /* Editable list of compatibility option names. Sync it with the SvtCompatibilityEntry::Index enum class. */
80 "UseOurTabStopFormat",
84 "UseObjectPositioning",
86 "ConsiderWrappingStyle",
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
114 SvtCompatibilityOptions_Impl();
115 virtual ~SvtCompatibilityOptions_Impl() override
;
117 void AppendItem( const SvtCompatibilityEntry
& aItem
);
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
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
;
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
);
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
] );
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
;
213 void SvtCompatibilityOptions_Impl::Clear()
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
) );
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();
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() );
316 void SvtCompatibilityOptions::AppendItem( const SvtCompatibilityEntry
& aItem
)
318 MutexGuard
aGuard( GetOwnStaticMutex() );
319 m_pImpl
->AppendItem( aItem
);
322 void SvtCompatibilityOptions::Clear()
324 MutexGuard
aGuard( GetOwnStaticMutex() );
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
;
353 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */