Updated core
[LibreOffice.git] / unotools / source / config / cmdoptions.cxx
blobf1cf83d0def82b1ffe32ae0ddeb9b9228f32e666
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 <unotools/cmdoptions.hxx>
21 #include <unotools/configmgr.hxx>
22 #include <unotools/configitem.hxx>
23 #include <tools/debug.hxx>
24 #include <com/sun/star/uno/Any.hxx>
25 #include <com/sun/star/uno/Sequence.hxx>
26 #include <cppuhelper/weakref.hxx>
27 #include <rtl/ustrbuf.hxx>
28 #include <rtl/instance.hxx>
30 #include <itemholder1.hxx>
32 #include <algorithm>
33 #include <boost/unordered_map.hpp>
35 using namespace ::std ;
36 using namespace ::utl ;
37 using namespace ::rtl ;
38 using namespace ::osl ;
39 using namespace ::com::sun::star::uno ;
40 using namespace ::com::sun::star::beans ;
42 #define ROOTNODE_CMDOPTIONS OUString("Office.Commands/Execute")
43 #define PATHDELIMITER OUString("/")
45 #define SETNODE_DISABLED OUString("Disabled")
47 #define PROPERTYNAME_CMD OUString("Command")
49 // Method to retrieve a hash code from a string. May be we have to change it to decrease collisions in the hash map
50 struct OUStringHashCode
52 size_t operator()( const OUString& sString ) const
54 return sString.hashCode();
58 /*-****************************************************************************************************************
59 @descr support simple command option structures and operations on it
60 ****************************************************************************************************************-*/
61 class SvtCmdOptions
63 public:
64 //---------------------------------------------------------------------------------------------------------
65 // the only way to free memory!
66 void Clear()
68 m_aCommandHashMap.clear();
71 sal_Bool HasEntries() const
73 return ( m_aCommandHashMap.size() > 0 );
76 sal_Bool Lookup( const OUString& aCmd ) const
78 CommandHashMap::const_iterator pEntry = m_aCommandHashMap.find( aCmd );
79 return ( pEntry != m_aCommandHashMap.end() );
82 void AddCommand( const OUString& aCmd )
84 m_aCommandHashMap.insert( CommandHashMap::value_type( aCmd, 0 ) );
87 //---------------------------------------------------------------------------------------------------------
88 // convert internal list to external format
89 // for using it on right menus realy
90 // Notice: We build a property list with 4 entries and set it on result list then.
91 // The while-loop starts with pointer on internal member list lSetupEntries, change to
92 // lUserEntries then and stop after that with NULL!
93 // Separator entries will be packed in another way then normal entries! We define
94 // special strings "sEmpty" and "sSeparator" to perform too ...
95 Sequence< OUString > GetList() const
97 sal_Int32 nCount = (sal_Int32)m_aCommandHashMap.size();
98 sal_Int32 nIndex = 0;
99 Sequence< OUString > aList( nCount );
101 CommandHashMap::const_iterator pEntry = m_aCommandHashMap.begin();
102 while ( pEntry != m_aCommandHashMap.end() )
103 aList[nIndex++] = pEntry->first;
105 return aList;
108 private:
109 class CommandHashMap : public ::boost::unordered_map< OUString ,
110 sal_Int32 ,
111 OUStringHashCode ,
112 ::std::equal_to< OUString > >
114 public:
115 inline void free()
117 CommandHashMap().swap( *this );
121 CommandHashMap m_aCommandHashMap;
124 typedef ::std::vector< ::com::sun::star::uno::WeakReference< ::com::sun::star::frame::XFrame > > SvtFrameVector;
126 class SvtCommandOptions_Impl : public ConfigItem
128 public:
130 SvtCommandOptions_Impl();
131 ~SvtCommandOptions_Impl();
133 /*-****************************************************************************************************//**
134 @short called for notify of configmanager
135 @descr These method is called from the ConfigManager before application ends or from the
136 PropertyChangeListener if the sub tree broadcasts changes. You must update your
137 internal values.
139 @seealso baseclass ConfigItem
141 @param "lPropertyNames" is the list of properties which should be updated.
142 @return -
144 @onerror -
145 *//*-*****************************************************************************************************/
147 virtual void Notify( const Sequence< OUString >& lPropertyNames );
149 /*-****************************************************************************************************//**
150 @short write changes to configuration
151 @descr These method writes the changed values into the sub tree
152 and should always called in our destructor to guarantee consistency of config data.
154 @seealso baseclass ConfigItem
156 @param -
157 @return -
159 @onerror -
160 *//*-*****************************************************************************************************/
162 virtual void Commit();
164 /*-****************************************************************************************************//**
165 @short base implementation of public interface for "SvtDynamicMenuOptions"!
166 @descr These class is used as static member of "SvtDynamicMenuOptions" ...
167 => The code exist only for one time and isn't duplicated for every instance!
169 @seealso -
171 @param -
172 @return -
174 @onerror -
175 *//*-*****************************************************************************************************/
177 sal_Bool HasEntries ( SvtCommandOptions::CmdOption eOption ) const;
178 sal_Bool Lookup ( SvtCommandOptions::CmdOption eCmdOption, const OUString& ) const;
179 void EstablisFrameCallback(const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& xFrame);
181 private:
183 /*-****************************************************************************************************//**
184 @short return list of key names of our configuration management which represent oue module tree
185 @descr These methods return the current list of key names! We need it to get needed values from our
186 configuration management and support dynamical menu item lists!
188 @seealso -
190 @param "nDisabledCount" , returns count of menu entries for "new"
191 @return A list of configuration key names is returned.
193 @onerror -
194 *//*-*****************************************************************************************************/
196 Sequence< OUString > impl_GetPropertyNames();
198 private:
199 SvtCmdOptions m_aDisabledCommands;
200 SvtFrameVector m_lFrames;
203 //*****************************************************************************************************************
204 // constructor
205 //*****************************************************************************************************************
206 SvtCommandOptions_Impl::SvtCommandOptions_Impl()
207 // Init baseclasses first
208 : ConfigItem( ROOTNODE_CMDOPTIONS )
209 // Init member then...
211 // Get names and values of all accessible menu entries and fill internal structures.
212 // See impl_GetPropertyNames() for further information.
213 Sequence< OUString > lNames = impl_GetPropertyNames ();
214 Sequence< Any > lValues = GetProperties ( lNames );
216 // Safe impossible cases.
217 // We need values from ALL configuration keys.
218 // Follow assignment use order of values in relation to our list of key names!
219 DBG_ASSERT( !(lNames.getLength()!=lValues.getLength()), "SvtCommandOptions_Impl::SvtCommandOptions_Impl()\nI miss some values of configuration keys!\n" );
221 // Copy values from list in right order to ouer internal member.
222 // Attention: List for names and values have an internal construction pattern!
223 sal_Int32 nItem = 0 ;
224 OUString sCmd ;
226 // Get names/values for disabled commands.
227 for( nItem=0; nItem < lNames.getLength(); ++nItem )
229 // Currently only one value
230 lValues[nItem] >>= sCmd;
231 m_aDisabledCommands.AddCommand( sCmd );
234 /*TODO: Not used in the moment! see Notify() ...
235 // Enable notification mechanism of ouer baseclass.
236 // We need it to get information about changes outside these class on ouer used configuration keys! */
237 Sequence< OUString > aNotifySeq( 1 );
238 aNotifySeq[0] = "Disabled";
239 EnableNotification( aNotifySeq, sal_True );
242 //*****************************************************************************************************************
243 // destructor
244 //*****************************************************************************************************************
245 SvtCommandOptions_Impl::~SvtCommandOptions_Impl()
247 // We must save our current values .. if user forget it!
248 if( IsModified() == sal_True )
250 Commit();
254 //*****************************************************************************************************************
255 // public method
256 //*****************************************************************************************************************
257 void SvtCommandOptions_Impl::Notify( const Sequence< OUString >& )
259 MutexGuard aGuard( SvtCommandOptions::GetOwnStaticMutex() );
261 Sequence< OUString > lNames = impl_GetPropertyNames ();
262 Sequence< Any > lValues = GetProperties ( lNames );
264 // Safe impossible cases.
265 // We need values from ALL configuration keys.
266 // Follow assignment use order of values in relation to our list of key names!
267 DBG_ASSERT( !(lNames.getLength()!=lValues.getLength()), "SvtCommandOptions_Impl::SvtCommandOptions_Impl()\nI miss some values of configuration keys!\n" );
269 // Copy values from list in right order to ouer internal member.
270 // Attention: List for names and values have an internal construction pattern!
271 sal_Int32 nItem = 0 ;
272 OUString sCmd ;
274 m_aDisabledCommands.Clear();
276 // Get names/values for disabled commands.
277 for( nItem=0; nItem < lNames.getLength(); ++nItem )
279 // Currently only one value
280 lValues[nItem] >>= sCmd;
281 m_aDisabledCommands.AddCommand( sCmd );
284 // dont forget to update all existing frames and her might cached dispatch objects!
285 // But look for already killed frames. We hold weak references instead of hard ones ...
286 for (SvtFrameVector::const_iterator pIt = m_lFrames.begin();
287 pIt != m_lFrames.end() ;
288 ++pIt )
290 ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > xFrame(pIt->get(), ::com::sun::star::uno::UNO_QUERY);
291 if (xFrame.is())
292 xFrame->contextChanged();
296 //*****************************************************************************************************************
297 // public method
298 //*****************************************************************************************************************
299 void SvtCommandOptions_Impl::Commit()
301 OSL_FAIL( "SvtCommandOptions_Impl::Commit()\nNot implemented yet!\n" );
304 //*****************************************************************************************************************
305 // public method
306 //*****************************************************************************************************************
307 sal_Bool SvtCommandOptions_Impl::HasEntries( SvtCommandOptions::CmdOption eOption ) const
309 if ( eOption == SvtCommandOptions::CMDOPTION_DISABLED )
310 return ( m_aDisabledCommands.HasEntries() > 0 );
311 else
312 return sal_False;
315 //*****************************************************************************************************************
316 // public method
317 //*****************************************************************************************************************
318 sal_Bool SvtCommandOptions_Impl::Lookup( SvtCommandOptions::CmdOption eCmdOption, const OUString& aCommand ) const
320 switch( eCmdOption )
322 case SvtCommandOptions::CMDOPTION_DISABLED:
324 return m_aDisabledCommands.Lookup( aCommand );
326 default:
327 DBG_ASSERT( sal_False, "SvtCommandOptions_Impl::GetList()\nUnknown option type given!\n" );
330 return sal_False;
333 //*****************************************************************************************************************
334 // public method
335 //*****************************************************************************************************************
336 void SvtCommandOptions_Impl::EstablisFrameCallback(const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& xFrame)
338 // check if frame already exists inside list
339 // ignore double registrations
340 // every frame must be notified one times only!
341 ::com::sun::star::uno::WeakReference< ::com::sun::star::frame::XFrame > xWeak(xFrame);
342 SvtFrameVector::const_iterator pIt = ::std::find(m_lFrames.begin(), m_lFrames.end(), xWeak);
343 if (pIt == m_lFrames.end())
344 m_lFrames.push_back(xWeak);
347 //*****************************************************************************************************************
348 // private method
349 //*****************************************************************************************************************
350 Sequence< OUString > SvtCommandOptions_Impl::impl_GetPropertyNames()
352 // First get ALL names of current existing list items in configuration!
353 Sequence< OUString > lDisabledItems = GetNodeNames( SETNODE_DISABLED, utl::CONFIG_NAME_LOCAL_PATH );
355 OUString aSetNode( SETNODE_DISABLED );
356 aSetNode += PATHDELIMITER;
358 OUString aCommandKey( PATHDELIMITER );
359 aCommandKey += PROPERTYNAME_CMD;
361 // Expand all keys
362 for (sal_Int32 i=0; i<lDisabledItems.getLength(); ++i )
364 OUStringBuffer aBuffer( 32 );
365 aBuffer.append( aSetNode );
366 aBuffer.append( lDisabledItems[i] );
367 aBuffer.append( aCommandKey );
368 lDisabledItems[i] = aBuffer.makeStringAndClear();
371 // Return result.
372 return lDisabledItems;
375 //*****************************************************************************************************************
376 // initialize static member
377 // DON'T DO IT IN YOUR HEADER!
378 // see definition for further information
379 //*****************************************************************************************************************
380 SvtCommandOptions_Impl* SvtCommandOptions::m_pDataContainer = NULL ;
381 sal_Int32 SvtCommandOptions::m_nRefCount = 0 ;
383 //*****************************************************************************************************************
384 // constructor
385 //*****************************************************************************************************************
386 SvtCommandOptions::SvtCommandOptions()
388 // Global access, must be guarded (multithreading!).
389 MutexGuard aGuard( GetOwnStaticMutex() );
390 // Increase ouer refcount ...
391 ++m_nRefCount;
392 // ... and initialize ouer data container only if it not already exist!
393 if( m_pDataContainer == NULL )
395 m_pDataContainer = new SvtCommandOptions_Impl;
396 ItemHolder1::holdConfigItem(E_CMDOPTIONS);
400 //*****************************************************************************************************************
401 // destructor
402 //*****************************************************************************************************************
403 SvtCommandOptions::~SvtCommandOptions()
405 // Global access, must be guarded (multithreading!)
406 MutexGuard aGuard( GetOwnStaticMutex() );
407 // Decrease ouer refcount.
408 --m_nRefCount;
409 // If last instance was deleted ...
410 // we must destroy ouer static data container!
411 if( m_nRefCount <= 0 )
413 delete m_pDataContainer;
414 m_pDataContainer = NULL;
418 //*****************************************************************************************************************
419 // public method
420 //*****************************************************************************************************************
421 sal_Bool SvtCommandOptions::HasEntries( CmdOption eOption ) const
423 MutexGuard aGuard( GetOwnStaticMutex() );
424 return m_pDataContainer->HasEntries( eOption );
427 //*****************************************************************************************************************
428 // public method
429 //*****************************************************************************************************************
430 sal_Bool SvtCommandOptions::Lookup( CmdOption eCmdOption, const OUString& aCommandURL ) const
432 MutexGuard aGuard( GetOwnStaticMutex() );
433 return m_pDataContainer->Lookup( eCmdOption, aCommandURL );
436 //*****************************************************************************************************************
437 // public method
438 //*****************************************************************************************************************
439 void SvtCommandOptions::EstablisFrameCallback(const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& xFrame)
441 MutexGuard aGuard( GetOwnStaticMutex() );
442 m_pDataContainer->EstablisFrameCallback(xFrame);
445 namespace
447 class theCommandOptionsMutex : public rtl::Static<osl::Mutex, theCommandOptionsMutex>{};
450 //*****************************************************************************************************************
451 // private method
452 //*****************************************************************************************************************
453 Mutex& SvtCommandOptions::GetOwnStaticMutex()
455 return theCommandOptionsMutex::get();
458 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */