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 <svtools/miscopt.hxx>
21 #include <unotools/configitem.hxx>
22 #include <tools/debug.hxx>
23 #include <com/sun/star/uno/Any.hxx>
24 #include <com/sun/star/uno/Sequence.hxx>
25 #include <comphelper/sequence.hxx>
26 #include <tools/link.hxx>
27 #include <osl/diagnose.h>
29 #include "itemholder2.hxx"
31 #include <svtools/imgdef.hxx>
32 #include <vcl/svapp.hxx>
33 #include <vcl/settings.hxx>
34 #include <officecfg/Office/Common.hxx>
39 using namespace ::utl
;
40 using namespace ::osl
;
41 using namespace ::com::sun::star::uno
;
42 using namespace ::com::sun::star
;
44 constexpr OUStringLiteral ROOTNODE_MISC
= u
"Office.Common/Misc";
46 // PROPERTYHANDLE defines must be sequential from zero for Commit/Load
47 constexpr OUStringLiteral PROPERTYNAME_SYMBOLSET
= u
"SymbolSet";
48 constexpr OUStringLiteral PROPERTYNAME_ICONTHEME
= u
"SymbolStyle";
49 #define PROPERTYHANDLE_SYMBOLSTYLE 1
50 constexpr OUStringLiteral PROPERTYNAME_SIDEBARICONSIZE
= u
"SidebarIconSize";
51 constexpr OUStringLiteral PROPERTYNAME_NOTEBOOKBARICONSIZE
= u
"NotebookbarIconSize";
53 static std::mutex
& GetInitMutex()
55 static std::mutex theSvtMiscOptionsMutex
;
56 return theSvtMiscOptionsMutex
;
60 class SvtMiscOptions_Impl
: public ConfigItem
63 ::std::vector
<Link
<LinkParamNone
*,void>> aList
;
64 bool m_bIsSymbolsStyleRO
;
65 bool m_bIconThemeWasSetAutomatically
;
67 virtual void ImplCommit() override
;
71 SvtMiscOptions_Impl();
72 virtual ~SvtMiscOptions_Impl() override
;
74 /*-****************************************************************************************************
75 @short called for notify of configmanager
76 @descr This method is called from the ConfigManager before the application ends or from the
77 PropertyChangeListener if the sub tree broadcasts changes. You must update your
80 @seealso baseclass ConfigItem
82 @param "seqPropertyNames" is the list of properties which should be updated.
83 *//*-*****************************************************************************************************/
85 virtual void Notify( const Sequence
< OUString
>& seqPropertyNames
) override
;
87 /** loads required data from the configuration. It's called in the constructor to
88 read all entries and form ::Notify to re-read changed settings
91 void Load( const Sequence
< OUString
>& rPropertyNames
);
95 static OUString
GetIconTheme();
97 enum class SetModifiedFlag
{ SET
, DONT_SET
};
99 /** Set the icon theme
102 * The name of the icon theme to use.
105 * Whether to call SetModified() and CallListeners().
108 * The @p setModified flag was introduced because the unittests fail if we call SetModified()
109 * during initialization in the constructor.
112 SetIconTheme(const OUString
&theme
, SetModifiedFlag setModified
);
114 bool IconThemeWasSetAutomatically() const
115 {return m_bIconThemeWasSetAutomatically
;}
117 void AddListenerLink( const Link
<LinkParamNone
*,void>& rLink
);
118 void RemoveListenerLink( const Link
<LinkParamNone
*,void>& rLink
);
119 void CallListeners();
127 /*-****************************************************************************************************
128 @short return list of key names of our configuration management which represent our module tree
129 @descr These methods return a static const list of key names. We need it to get needed values from our
130 configuration management.
131 @return A list of needed configuration keys is returned.
132 *//*-*****************************************************************************************************/
134 static Sequence
< OUString
> GetPropertyNames();
140 SvtMiscOptions_Impl::SvtMiscOptions_Impl()
141 // Init baseclasses first
142 : ConfigItem( ROOTNODE_MISC
)
144 , m_bIsSymbolsStyleRO( false )
145 , m_bIconThemeWasSetAutomatically( false )
147 // Use our static list of configuration keys to get his values.
148 Sequence
< OUString
> seqNames
= GetPropertyNames ( );
150 Sequence
< Any
> seqValues
= GetProperties ( seqNames
);
151 Sequence
< sal_Bool
> seqRO
= GetReadOnlyStates ( seqNames
);
153 // Safe impossible cases.
154 // We need values from ALL configuration keys.
155 // Follow assignment use order of values in relation to our list of key names!
156 DBG_ASSERT( !(seqNames
.getLength()!=seqValues
.getLength()), "SvtMiscOptions_Impl::SvtMiscOptions_Impl()\nI miss some values of configuration keys!\n" );
158 // Copy values from list in right order to our internal member.
159 sal_Int32 nPropertyCount
= seqValues
.getLength();
160 for( sal_Int32 nProperty
=0; nProperty
<nPropertyCount
; ++nProperty
)
162 if (!seqValues
[nProperty
].hasValue())
166 case PROPERTYHANDLE_SYMBOLSTYLE
:
169 if (seqValues
[nProperty
] >>= aIconTheme
)
170 SetIconTheme(aIconTheme
, SetModifiedFlag::DONT_SET
);
172 OSL_FAIL("Wrong type of \"Misc\\SymbolStyle\"!" );
174 m_bIsSymbolsStyleRO
= seqRO
[nProperty
];
181 // Enable notification mechanism of our baseclass.
182 // We need it to get information about changes outside these class on our used configuration keys!
183 EnableNotification( seqNames
);
189 SvtMiscOptions_Impl::~SvtMiscOptions_Impl()
191 assert(!IsModified()); // should have been committed
194 void SvtMiscOptions_Impl::Load( const Sequence
< OUString
>& rPropertyNames
)
196 const uno::Sequence
< OUString
> aInternalPropertyNames( GetPropertyNames());
197 Sequence
< Any
> seqValues
= GetProperties( rPropertyNames
);
199 // Safe impossible cases.
200 // We need values from ALL configuration keys.
201 // Follow assignment use order of values in relation to our list of key names!
202 DBG_ASSERT( !(rPropertyNames
.getLength()!=seqValues
.getLength()), "SvtSecurityOptions_Impl::SvtSecurityOptions_Impl()\nI miss some values of configuration keys!\n" );
204 // Copy values from list in right order to our internal member.
205 sal_Int32 nPropertyCount
= seqValues
.getLength();
206 for( sal_Int32 nProperty
=0; nProperty
<nPropertyCount
; ++nProperty
)
208 if (!seqValues
[nProperty
].hasValue())
210 switch( comphelper::findValue(aInternalPropertyNames
, rPropertyNames
[nProperty
]) )
212 case PROPERTYHANDLE_SYMBOLSTYLE
: {
214 if (seqValues
[nProperty
] >>= aIconTheme
)
215 SetIconTheme(aIconTheme
, SetModifiedFlag::DONT_SET
);
217 OSL_FAIL("Wrong type of \"Misc\\SymbolStyle\"!" );
224 void SvtMiscOptions_Impl::AddListenerLink( const Link
<LinkParamNone
*,void>& rLink
)
226 aList
.push_back( rLink
);
229 void SvtMiscOptions_Impl::RemoveListenerLink( const Link
<LinkParamNone
*,void>& rLink
)
231 aList
.erase(std::remove(aList
.begin(), aList
.end(), rLink
), aList
.end());
234 void SvtMiscOptions_Impl::CallListeners()
236 for (auto const& elem
: aList
)
237 elem
.Call( nullptr );
240 OUString
SvtMiscOptions_Impl::GetIconTheme()
242 return Application::GetSettings().GetStyleSettings().DetermineIconTheme();
246 SvtMiscOptions_Impl::SetIconTheme(const OUString
&rName
, SetModifiedFlag setModified
)
248 OUString
aTheme(rName
);
249 if (aTheme
.isEmpty() || aTheme
== "auto")
251 aTheme
= Application::GetSettings().GetStyleSettings().GetAutomaticallyChosenIconTheme();
252 m_bIconThemeWasSetAutomatically
= true;
255 m_bIconThemeWasSetAutomatically
= false;
257 AllSettings aAllSettings
= Application::GetSettings();
258 StyleSettings aStyleSettings
= aAllSettings
.GetStyleSettings();
259 aStyleSettings
.SetIconTheme(aTheme
);
261 aAllSettings
.SetStyleSettings(aStyleSettings
);
262 Application::MergeSystemSettings( aAllSettings
);
263 Application::SetSettings(aAllSettings
);
265 if (setModified
== SetModifiedFlag::SET
) {
274 void SvtMiscOptions_Impl::Notify( const Sequence
< OUString
>& rPropertyNames
)
276 Load( rPropertyNames
);
283 void SvtMiscOptions_Impl::ImplCommit()
285 if ( !m_bIsSymbolsStyleRO
)
287 // Get names of supported properties, create a list for values and copy current values to it.
288 Sequence
< OUString
> seqNames
{ PROPERTYNAME_ICONTHEME
};
289 sal_Int32 nCount
= seqNames
.getLength();
290 Sequence
< Any
> seqValues ( nCount
);
291 auto seqValuesRange
= asNonConstRange(seqValues
);
293 if (m_bIconThemeWasSetAutomatically
) {
297 value
= GetIconTheme();
299 seqValuesRange
[0] <<= value
;
300 // Set properties in configuration.
301 PutProperties( seqNames
, seqValues
);
308 Sequence
< OUString
> SvtMiscOptions_Impl::GetPropertyNames()
310 return Sequence
<OUString
>
312 PROPERTYNAME_SYMBOLSET
,
313 PROPERTYNAME_ICONTHEME
,
314 // SidebarIconSize and NotebookbarIconSize so
315 // notifications for their changes are also broadcast
316 // from SvtMiscOptions
317 PROPERTYNAME_SIDEBARICONSIZE
,
318 PROPERTYNAME_NOTEBOOKBARICONSIZE
324 std::weak_ptr
<SvtMiscOptions_Impl
> g_pMiscOptions
;
328 SvtMiscOptions::SvtMiscOptions()
330 // Global access, must be guarded (multithreading!).
331 std::unique_lock
aGuard( GetInitMutex() );
333 m_pImpl
= g_pMiscOptions
.lock();
336 m_pImpl
= std::make_shared
<SvtMiscOptions_Impl
>();
337 g_pMiscOptions
= m_pImpl
;
338 aGuard
.unlock(); // because holdConfigItem will call this constructor
339 svtools::ItemHolder2::holdConfigItem(EItem::MiscOptions
);
343 SvtMiscOptions::~SvtMiscOptions()
345 // Global access, must be guarded (multithreading!)
346 std::unique_lock
aGuard( GetInitMutex() );
352 sal_Int16
SvtMiscOptions::GetSymbolsSize()
354 return officecfg::Office::Common::Misc::SymbolSet::get();
357 void SvtMiscOptions::SetSymbolsSize( sal_Int16 nSet
)
359 if (!officecfg::Office::Common::Misc::SymbolSet::isReadOnly())
361 std::shared_ptr
<comphelper::ConfigurationChanges
> batch(comphelper::ConfigurationChanges::create());
362 officecfg::Office::Common::Misc::SymbolSet::set(nSet
, batch
);
364 m_pImpl
->CallListeners();
368 sal_Int16
SvtMiscOptions::GetCurrentSymbolsSize()
370 sal_Int16 eOptSymbolsSize
= GetSymbolsSize();
372 if ( eOptSymbolsSize
== SFX_SYMBOLS_SIZE_AUTO
)
374 // Use system settings, we have to retrieve the toolbar icon size from the
376 ToolbarIconSize nStyleIconSize
= Application::GetSettings().GetStyleSettings().GetToolbarIconSize();
377 if (nStyleIconSize
== ToolbarIconSize::Size32
)
378 eOptSymbolsSize
= SFX_SYMBOLS_SIZE_32
;
379 else if (nStyleIconSize
== ToolbarIconSize::Large
)
380 eOptSymbolsSize
= SFX_SYMBOLS_SIZE_LARGE
;
382 eOptSymbolsSize
= SFX_SYMBOLS_SIZE_SMALL
;
385 return eOptSymbolsSize
;
388 bool SvtMiscOptions::AreCurrentSymbolsLarge()
390 return ( GetCurrentSymbolsSize() == SFX_SYMBOLS_SIZE_LARGE
|| GetCurrentSymbolsSize() == SFX_SYMBOLS_SIZE_32
);
393 OUString
SvtMiscOptions::GetIconTheme()
395 return SvtMiscOptions_Impl::GetIconTheme();
398 void SvtMiscOptions::SetIconTheme(const OUString
& iconTheme
)
400 m_pImpl
->SetIconTheme(iconTheme
, SvtMiscOptions_Impl::SetModifiedFlag::SET
);
403 void SvtMiscOptions::AddListenerLink( const Link
<LinkParamNone
*,void>& rLink
)
405 m_pImpl
->AddListenerLink( rLink
);
408 void SvtMiscOptions::RemoveListenerLink( const Link
<LinkParamNone
*,void>& rLink
)
410 m_pImpl
->RemoveListenerLink( rLink
);
414 SvtMiscOptions::IconThemeWasSetAutomatically() const
416 return m_pImpl
->IconThemeWasSetAutomatically();
419 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */