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"
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. */
82 /* Editable list of compatibility option names. Sync it with the SvtCompatibilityEntry::Index enum class. */
86 "UseOurTabStopFormat",
90 "UseObjectPositioning",
92 "ConsiderWrappingStyle",
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
119 SvtCompatibilityOptions_Impl();
120 virtual ~SvtCompatibilityOptions_Impl() override
;
122 void AppendItem( const SvtCompatibilityEntry
& aItem
);
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
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
;
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
);
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
] );
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
;
218 void SvtCompatibilityOptions_Impl::Clear()
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
) );
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
;
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
) );
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();
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() );
338 void SvtCompatibilityOptions::AppendItem( const SvtCompatibilityEntry
& aItem
)
340 MutexGuard
aGuard( GetOwnStaticMutex() );
341 m_pImpl
->AppendItem( aItem
);
344 void SvtCompatibilityOptions::Clear()
346 MutexGuard
aGuard( GetOwnStaticMutex() );
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();
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: */