tdf#129905 tdf#160365 sw: don't always draw text boundary on frames
[LibreOffice.git] / unotools / source / config / cmdoptions.cxx
blob015637d644a209d9871090f06ba20df77f530b5b
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 aGuard.unlock(); // because we can call back into ourself
226 xFrame->contextChanged();
227 aGuard.lock();
228 ++pIt;
230 else
231 pIt = m_lFrames.erase(pIt);
235 // public method
237 void SvtCommandOptions_Impl::ImplCommit()
239 SAL_WARN("unotools.config","SvtCommandOptions_Impl::ImplCommit(): Not implemented yet!");
242 // public method
244 bool SvtCommandOptions_Impl::HasEntriesDisabled() const
246 return m_aDisabledCommands.HasEntries();
249 // public method
251 bool SvtCommandOptions_Impl::LookupDisabled( const OUString& aCommand ) const
253 return m_aDisabledCommands.Lookup( aCommand );
256 // public method
258 void SvtCommandOptions_Impl::EstablishFrameCallback(const css::uno::Reference< css::frame::XFrame >& xFrame)
260 // check if frame already exists inside list
261 // ignore double registrations
262 // every frame must be notified one times only!
263 css::uno::WeakReference< css::frame::XFrame > xWeak(xFrame);
264 SvtFrameVector::const_iterator pIt = ::std::find(m_lFrames.begin(), m_lFrames.end(), xWeak);
265 if (pIt == m_lFrames.end())
266 m_lFrames.push_back(xWeak);
269 // private method
271 Sequence< OUString > SvtCommandOptions_Impl::impl_GetPropertyNames()
273 // First get ALL names of current existing list items in configuration!
274 Sequence< OUString > lDisabledItems = GetNodeNames( SETNODE_DISABLED, utl::ConfigNameFormat::LocalPath );
276 // Expand all keys
277 for (OUString& rItem : asNonConstRange(lDisabledItems))
278 rItem = SETNODE_DISABLED PATHDELIMITER + rItem + PATHDELIMITER PROPERTYNAME_CMD;
280 // Return result.
281 return lDisabledItems;
284 namespace {
286 std::weak_ptr<SvtCommandOptions_Impl> g_pCommandOptions;
290 SvtCommandOptions::SvtCommandOptions()
292 // Global access, must be guarded (multithreading!).
293 std::unique_lock aGuard( GetOwnStaticMutex() );
295 m_pImpl = g_pCommandOptions.lock();
296 if( !m_pImpl )
298 m_pImpl = std::make_shared<SvtCommandOptions_Impl>();
299 g_pCommandOptions = m_pImpl;
300 aGuard.unlock(); // because holdConfigItem will call this constructor
301 ItemHolder1::holdConfigItem(EItem::CmdOptions);
305 SvtCommandOptions::~SvtCommandOptions()
307 // Global access, must be guarded (multithreading!)
308 std::unique_lock aGuard( GetOwnStaticMutex() );
310 m_pImpl.reset();
313 // public method
315 bool SvtCommandOptions::HasEntriesDisabled() const
317 std::unique_lock aGuard( GetOwnStaticMutex() );
318 return m_pImpl->HasEntriesDisabled();
321 // public method
323 bool SvtCommandOptions::LookupDisabled( const OUString& aCommandURL ) const
325 std::unique_lock aGuard( GetOwnStaticMutex() );
326 return m_pImpl->LookupDisabled( aCommandURL );
329 // public method
331 void SvtCommandOptions::EstablishFrameCallback(const css::uno::Reference< css::frame::XFrame >& xFrame)
333 std::unique_lock aGuard( GetOwnStaticMutex() );
334 m_pImpl->EstablishFrameCallback(xFrame);
337 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */