Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / unotools / source / config / cmdoptions.cxx
blobec4e826b8c8a622834381a6b03ac1a458bc0913c
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 <sal/config.h>
22 #include <sal/log.hxx>
23 #include <unotools/cmdoptions.hxx>
24 #include <unotools/configitem.hxx>
25 #include <tools/debug.hxx>
26 #include <com/sun/star/uno/Any.hxx>
27 #include <com/sun/star/uno/Sequence.hxx>
28 #include <com/sun/star/frame/XFrame.hpp>
29 #include <cppuhelper/weakref.hxx>
31 #include "itemholder1.hxx"
33 #include <algorithm>
34 #include <unordered_map>
36 using namespace ::utl;
37 using namespace ::osl;
38 using namespace ::com::sun::star::uno;
39 using namespace ::com::sun::star::beans;
41 constexpr OUStringLiteral ROOTNODE_CMDOPTIONS = u"Office.Commands/Execute";
42 #define PATHDELIMITER "/"
44 #define SETNODE_DISABLED "Disabled"
46 #define PROPERTYNAME_CMD "Command"
48 namespace {
50 /*-****************************************************************************************************************
51 @descr support simple command option structures and operations on it
52 ****************************************************************************************************************-*/
53 class SvtCmdOptions
55 public:
57 // the only way to free memory!
58 void Clear()
60 m_aCommandHashMap.clear();
63 bool HasEntries() const
65 return ( !m_aCommandHashMap.empty() );
68 bool Lookup( const OUString& aCmd ) const
70 CommandHashMap::const_iterator pEntry = m_aCommandHashMap.find( aCmd );
71 return ( pEntry != m_aCommandHashMap.end() );
74 void AddCommand( const OUString& aCmd )
76 m_aCommandHashMap.emplace( aCmd, 0 );
79 private:
80 typedef std::unordered_map<OUString, sal_Int32>
81 CommandHashMap;
83 CommandHashMap m_aCommandHashMap;
86 std::mutex& GetOwnStaticMutex()
88 static std::mutex theCommandOptionsMutex;
89 return theCommandOptionsMutex;
94 typedef ::std::vector< css::uno::WeakReference< css::frame::XFrame > > SvtFrameVector;
96 class SvtCommandOptions_Impl : public ConfigItem
98 public:
100 SvtCommandOptions_Impl();
101 virtual ~SvtCommandOptions_Impl() override;
103 /*-****************************************************************************************************
104 @short called for notify of configmanager
105 @descr This method is called from the ConfigManager before the application ends or from the
106 PropertyChangeListener if the sub tree broadcasts changes. You must update your
107 internal values.
109 @seealso baseclass ConfigItem
111 @param "lPropertyNames" is the list of properties which should be updated.
112 *//*-*****************************************************************************************************/
114 virtual void Notify( const Sequence< OUString >& lPropertyNames ) override;
116 /*-****************************************************************************************************
117 @short base implementation of public interface for "SvtDynamicMenuOptions"!
118 @descr These class is used as static member of "SvtDynamicMenuOptions" ...
119 => The code exist only for one time and isn't duplicated for every instance!
120 *//*-*****************************************************************************************************/
122 bool HasEntriesDisabled() const;
123 bool LookupDisabled( const OUString& ) const;
124 void EstablishFrameCallback(const css::uno::Reference< css::frame::XFrame >& xFrame);
126 private:
128 virtual void ImplCommit() override;
130 /*-****************************************************************************************************
131 @short return list of key names of our configuration management which represent our module tree
132 @descr This method returns the current list of key names! We need it to get needed values from our
133 configuration management and support dynamical menu item lists!
134 @param "nDisabledCount", returns count of menu entries for "new"
135 @return A list of configuration key names is returned.
136 *//*-*****************************************************************************************************/
138 Sequence< OUString > impl_GetPropertyNames();
140 private:
141 SvtCmdOptions m_aDisabledCommands;
142 SvtFrameVector m_lFrames;
145 // constructor
147 SvtCommandOptions_Impl::SvtCommandOptions_Impl()
148 // Init baseclasses first
149 : ConfigItem( ROOTNODE_CMDOPTIONS )
150 // Init member then...
152 // Get names and values of all accessible menu entries and fill internal structures.
153 // See impl_GetPropertyNames() for further information.
154 Sequence< OUString > lNames = impl_GetPropertyNames ();
155 Sequence< Any > lValues = GetProperties ( lNames );
157 // Safe impossible cases.
158 // We need values from ALL configuration keys.
159 // Follow assignment use order of values in relation to our list of key names!
160 DBG_ASSERT( !(lNames.getLength()!=lValues.getLength()), "SvtCommandOptions_Impl::SvtCommandOptions_Impl()\nI miss some values of configuration keys!\n" );
162 // Copy values from list in right order to our internal member.
163 // Attention: List for names and values have an internal construction pattern!
164 sal_Int32 nItem = 0;
165 OUString sCmd;
167 // Get names/values for disabled commands.
168 for( nItem=0; nItem < lNames.getLength(); ++nItem )
170 // Currently only one value
171 lValues[nItem] >>= sCmd;
172 m_aDisabledCommands.AddCommand( sCmd );
175 /*TODO: Not used in the moment! see Notify() ...
176 // Enable notification mechanism of our baseclass.
177 // We need it to get information about changes outside these class on our used configuration keys! */
178 Sequence<OUString> aNotifySeq { "Disabled" };
179 EnableNotification( aNotifySeq, true );
182 // destructor
184 SvtCommandOptions_Impl::~SvtCommandOptions_Impl()
186 assert(!IsModified()); // should have been committed
189 // public method
191 void SvtCommandOptions_Impl::Notify( const Sequence< OUString >& )
193 std::unique_lock aGuard( GetOwnStaticMutex() );
195 Sequence< OUString > lNames = impl_GetPropertyNames ();
196 Sequence< Any > lValues = GetProperties ( lNames );
198 // Safe impossible cases.
199 // We need values from ALL configuration keys.
200 // Follow assignment use order of values in relation to our list of key names!
201 DBG_ASSERT( !(lNames.getLength()!=lValues.getLength()), "SvtCommandOptions_Impl::Notify()\nI miss some values of configuration keys!\n" );
203 // Copy values from list in right order to our internal member.
204 // Attention: List for names and values have an internal construction pattern!
205 sal_Int32 nItem = 0;
206 OUString sCmd;
208 m_aDisabledCommands.Clear();
210 // Get names/values for disabled commands.
211 for( nItem=0; nItem < lNames.getLength(); ++nItem )
213 // Currently only one value
214 lValues[nItem] >>= sCmd;
215 m_aDisabledCommands.AddCommand( sCmd );
218 // don't forget to update all existing frames and her might cached dispatch objects!
219 // But look for already killed frames. We hold weak references instead of hard ones ...
220 for (SvtFrameVector::iterator pIt = m_lFrames.begin(); pIt != m_lFrames.end(); )
222 css::uno::Reference< css::frame::XFrame > xFrame(pIt->get(), css::uno::UNO_QUERY);
223 if (xFrame.is())
225 xFrame->contextChanged();
226 ++pIt;
228 else
229 pIt = m_lFrames.erase(pIt);
233 // public method
235 void SvtCommandOptions_Impl::ImplCommit()
237 SAL_WARN("unotools.config","SvtCommandOptions_Impl::ImplCommit(): Not implemented yet!");
240 // public method
242 bool SvtCommandOptions_Impl::HasEntriesDisabled() const
244 return m_aDisabledCommands.HasEntries();
247 // public method
249 bool SvtCommandOptions_Impl::LookupDisabled( const OUString& aCommand ) const
251 return m_aDisabledCommands.Lookup( aCommand );
254 // public method
256 void SvtCommandOptions_Impl::EstablishFrameCallback(const css::uno::Reference< css::frame::XFrame >& xFrame)
258 // check if frame already exists inside list
259 // ignore double registrations
260 // every frame must be notified one times only!
261 css::uno::WeakReference< css::frame::XFrame > xWeak(xFrame);
262 SvtFrameVector::const_iterator pIt = ::std::find(m_lFrames.begin(), m_lFrames.end(), xWeak);
263 if (pIt == m_lFrames.end())
264 m_lFrames.push_back(xWeak);
267 // private method
269 Sequence< OUString > SvtCommandOptions_Impl::impl_GetPropertyNames()
271 // First get ALL names of current existing list items in configuration!
272 Sequence< OUString > lDisabledItems = GetNodeNames( SETNODE_DISABLED, utl::ConfigNameFormat::LocalPath );
274 // Expand all keys
275 for (OUString& rItem : asNonConstRange(lDisabledItems))
276 rItem = SETNODE_DISABLED PATHDELIMITER + rItem + PATHDELIMITER PROPERTYNAME_CMD;
278 // Return result.
279 return lDisabledItems;
282 namespace {
284 std::weak_ptr<SvtCommandOptions_Impl> g_pCommandOptions;
288 SvtCommandOptions::SvtCommandOptions()
290 // Global access, must be guarded (multithreading!).
291 std::unique_lock aGuard( GetOwnStaticMutex() );
293 m_pImpl = g_pCommandOptions.lock();
294 if( !m_pImpl )
296 m_pImpl = std::make_shared<SvtCommandOptions_Impl>();
297 g_pCommandOptions = m_pImpl;
298 aGuard.unlock(); // because holdConfigItem will call this constructor
299 ItemHolder1::holdConfigItem(EItem::CmdOptions);
303 SvtCommandOptions::~SvtCommandOptions()
305 // Global access, must be guarded (multithreading!)
306 std::unique_lock aGuard( GetOwnStaticMutex() );
308 m_pImpl.reset();
311 // public method
313 bool SvtCommandOptions::HasEntriesDisabled() const
315 std::unique_lock aGuard( GetOwnStaticMutex() );
316 return m_pImpl->HasEntriesDisabled();
319 // public method
321 bool SvtCommandOptions::LookupDisabled( const OUString& aCommandURL ) const
323 std::unique_lock aGuard( GetOwnStaticMutex() );
324 return m_pImpl->LookupDisabled( aCommandURL );
327 // public method
329 void SvtCommandOptions::EstablishFrameCallback(const css::uno::Reference< css::frame::XFrame >& xFrame)
331 std::unique_lock aGuard( GetOwnStaticMutex() );
332 m_pImpl->EstablishFrameCallback(xFrame);
335 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */