Version 6.4.0.3, tag libreoffice-6.4.0.3
[LibreOffice.git] / unotools / source / config / cmdoptions.cxx
blob56b61ad2704afc899777e24cd35a3a417782f160
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>
30 #include <rtl/instance.hxx>
32 #include "itemholder1.hxx"
34 #include <algorithm>
35 #include <unordered_map>
37 using namespace ::std;
38 using namespace ::utl;
39 using namespace ::osl;
40 using namespace ::com::sun::star::uno;
41 using namespace ::com::sun::star::beans;
43 #define ROOTNODE_CMDOPTIONS "Office.Commands/Execute"
44 #define PATHDELIMITER "/"
46 #define SETNODE_DISABLED "Disabled"
48 #define PROPERTYNAME_CMD "Command"
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 typedef ::std::vector< css::uno::WeakReference< css::frame::XFrame > > SvtFrameVector;
88 class SvtCommandOptions_Impl : public ConfigItem
90 public:
92 SvtCommandOptions_Impl();
93 virtual ~SvtCommandOptions_Impl() override;
95 /*-****************************************************************************************************
96 @short called for notify of configmanager
97 @descr This method is called from the ConfigManager before the application ends or from the
98 PropertyChangeListener if the sub tree broadcasts changes. You must update your
99 internal values.
101 @seealso baseclass ConfigItem
103 @param "lPropertyNames" is the list of properties which should be updated.
104 *//*-*****************************************************************************************************/
106 virtual void Notify( const Sequence< OUString >& lPropertyNames ) override;
108 /*-****************************************************************************************************
109 @short base implementation of public interface for "SvtDynamicMenuOptions"!
110 @descr These class is used as static member of "SvtDynamicMenuOptions" ...
111 => The code exist only for one time and isn't duplicated for every instance!
112 *//*-*****************************************************************************************************/
114 bool HasEntries ( SvtCommandOptions::CmdOption eOption ) const;
115 bool Lookup ( SvtCommandOptions::CmdOption eCmdOption, const OUString& ) const;
116 void EstablishFrameCallback(const css::uno::Reference< css::frame::XFrame >& xFrame);
118 private:
120 virtual void ImplCommit() override;
122 /*-****************************************************************************************************
123 @short return list of key names of our configuration management which represent our module tree
124 @descr This method returns the current list of key names! We need it to get needed values from our
125 configuration management and support dynamical menu item lists!
126 @param "nDisabledCount", returns count of menu entries for "new"
127 @return A list of configuration key names is returned.
128 *//*-*****************************************************************************************************/
130 Sequence< OUString > impl_GetPropertyNames();
132 private:
133 SvtCmdOptions m_aDisabledCommands;
134 SvtFrameVector m_lFrames;
137 // constructor
139 SvtCommandOptions_Impl::SvtCommandOptions_Impl()
140 // Init baseclasses first
141 : ConfigItem( ROOTNODE_CMDOPTIONS )
142 // Init member then...
144 // Get names and values of all accessible menu entries and fill internal structures.
145 // See impl_GetPropertyNames() for further information.
146 Sequence< OUString > lNames = impl_GetPropertyNames ();
147 Sequence< Any > lValues = GetProperties ( lNames );
149 // Safe impossible cases.
150 // We need values from ALL configuration keys.
151 // Follow assignment use order of values in relation to our list of key names!
152 DBG_ASSERT( !(lNames.getLength()!=lValues.getLength()), "SvtCommandOptions_Impl::SvtCommandOptions_Impl()\nI miss some values of configuration keys!\n" );
154 // Copy values from list in right order to our internal member.
155 // Attention: List for names and values have an internal construction pattern!
156 sal_Int32 nItem = 0;
157 OUString sCmd;
159 // Get names/values for disabled commands.
160 for( nItem=0; nItem < lNames.getLength(); ++nItem )
162 // Currently only one value
163 lValues[nItem] >>= sCmd;
164 m_aDisabledCommands.AddCommand( sCmd );
167 /*TODO: Not used in the moment! see Notify() ...
168 // Enable notification mechanism of our baseclass.
169 // We need it to get information about changes outside these class on our used configuration keys! */
170 Sequence<OUString> aNotifySeq { "Disabled" };
171 EnableNotification( aNotifySeq, true );
174 // destructor
176 SvtCommandOptions_Impl::~SvtCommandOptions_Impl()
178 assert(!IsModified()); // should have been committed
181 // public method
183 void SvtCommandOptions_Impl::Notify( const Sequence< OUString >& )
185 MutexGuard aGuard( SvtCommandOptions::GetOwnStaticMutex() );
187 Sequence< OUString > lNames = impl_GetPropertyNames ();
188 Sequence< Any > lValues = GetProperties ( lNames );
190 // Safe impossible cases.
191 // We need values from ALL configuration keys.
192 // Follow assignment use order of values in relation to our list of key names!
193 DBG_ASSERT( !(lNames.getLength()!=lValues.getLength()), "SvtCommandOptions_Impl::Notify()\nI miss some values of configuration keys!\n" );
195 // Copy values from list in right order to our internal member.
196 // Attention: List for names and values have an internal construction pattern!
197 sal_Int32 nItem = 0;
198 OUString sCmd;
200 m_aDisabledCommands.Clear();
202 // Get names/values for disabled commands.
203 for( nItem=0; nItem < lNames.getLength(); ++nItem )
205 // Currently only one value
206 lValues[nItem] >>= sCmd;
207 m_aDisabledCommands.AddCommand( sCmd );
210 // don't forget to update all existing frames and her might cached dispatch objects!
211 // But look for already killed frames. We hold weak references instead of hard ones ...
212 for (SvtFrameVector::iterator pIt = m_lFrames.begin(); pIt != m_lFrames.end(); )
214 css::uno::Reference< css::frame::XFrame > xFrame(pIt->get(), css::uno::UNO_QUERY);
215 if (xFrame.is())
217 xFrame->contextChanged();
218 ++pIt;
220 else
221 pIt = m_lFrames.erase(pIt);
225 // public method
227 void SvtCommandOptions_Impl::ImplCommit()
229 SAL_WARN("unotools.config","SvtCommandOptions_Impl::ImplCommit(): Not implemented yet!");
232 // public method
234 bool SvtCommandOptions_Impl::HasEntries( SvtCommandOptions::CmdOption eOption ) const
236 if ( eOption == SvtCommandOptions::CMDOPTION_DISABLED )
237 return m_aDisabledCommands.HasEntries();
238 else
239 return false;
242 // public method
244 bool SvtCommandOptions_Impl::Lookup( SvtCommandOptions::CmdOption eCmdOption, const OUString& aCommand ) const
246 switch( eCmdOption )
248 case SvtCommandOptions::CMDOPTION_DISABLED:
250 return m_aDisabledCommands.Lookup( aCommand );
252 default:
253 SAL_WARN( "unotools.config", "SvtCommandOptions_Impl::Lookup() Unknown option type given!" );
256 return false;
259 // public method
261 void SvtCommandOptions_Impl::EstablishFrameCallback(const css::uno::Reference< css::frame::XFrame >& xFrame)
263 // check if frame already exists inside list
264 // ignore double registrations
265 // every frame must be notified one times only!
266 css::uno::WeakReference< css::frame::XFrame > xWeak(xFrame);
267 SvtFrameVector::const_iterator pIt = ::std::find(m_lFrames.begin(), m_lFrames.end(), xWeak);
268 if (pIt == m_lFrames.end())
269 m_lFrames.push_back(xWeak);
272 // private method
274 Sequence< OUString > SvtCommandOptions_Impl::impl_GetPropertyNames()
276 // First get ALL names of current existing list items in configuration!
277 Sequence< OUString > lDisabledItems = GetNodeNames( SETNODE_DISABLED, utl::ConfigNameFormat::LocalPath );
279 // Expand all keys
280 std::transform(lDisabledItems.begin(), lDisabledItems.end(), lDisabledItems.begin(),
281 [](const OUString& rItem) -> OUString {
282 return SETNODE_DISABLED PATHDELIMITER + rItem + PATHDELIMITER PROPERTYNAME_CMD; });
284 // Return result.
285 return lDisabledItems;
288 namespace {
290 std::weak_ptr<SvtCommandOptions_Impl> g_pCommandOptions;
294 SvtCommandOptions::SvtCommandOptions()
296 // Global access, must be guarded (multithreading!).
297 MutexGuard aGuard( GetOwnStaticMutex() );
299 m_pImpl = g_pCommandOptions.lock();
300 if( !m_pImpl )
302 m_pImpl = std::make_shared<SvtCommandOptions_Impl>();
303 g_pCommandOptions = m_pImpl;
304 ItemHolder1::holdConfigItem(EItem::CmdOptions);
308 SvtCommandOptions::~SvtCommandOptions()
310 // Global access, must be guarded (multithreading!)
311 MutexGuard aGuard( GetOwnStaticMutex() );
313 m_pImpl.reset();
316 // public method
318 bool SvtCommandOptions::HasEntries( CmdOption eOption ) const
320 MutexGuard aGuard( GetOwnStaticMutex() );
321 return m_pImpl->HasEntries( eOption );
324 // public method
326 bool SvtCommandOptions::Lookup( CmdOption eCmdOption, const OUString& aCommandURL ) const
328 MutexGuard aGuard( GetOwnStaticMutex() );
329 return m_pImpl->Lookup( eCmdOption, aCommandURL );
332 // public method
334 void SvtCommandOptions::EstablishFrameCallback(const css::uno::Reference< css::frame::XFrame >& xFrame)
336 MutexGuard aGuard( GetOwnStaticMutex() );
337 m_pImpl->EstablishFrameCallback(xFrame);
340 namespace
342 class theCommandOptionsMutex : public rtl::Static<osl::Mutex, theCommandOptionsMutex>{};
345 // private method
347 Mutex& SvtCommandOptions::GetOwnStaticMutex()
349 return theCommandOptionsMutex::get();
352 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */