merge the formfield patch from ooo-build
[ooovba.git] / svtools / source / config / cmdoptions.cxx
blob27fffc2af0165352b926307a395d2042b14612ea
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: cmdoptions.cxx,v $
10 * $Revision: 1.11 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svtools.hxx"
34 //_________________________________________________________________________________________________________________
35 // includes
36 //_________________________________________________________________________________________________________________
38 #include <svtools/cmdoptions.hxx>
39 #include <unotools/configmgr.hxx>
40 #include <unotools/configitem.hxx>
41 #include <tools/debug.hxx>
42 #include <com/sun/star/uno/Any.hxx>
43 #include <com/sun/star/uno/Sequence.hxx>
44 #include <cppuhelper/weakref.hxx>
45 #include <tools/urlobj.hxx>
46 #include <rtl/ustrbuf.hxx>
48 #include <itemholder1.hxx>
50 #include <algorithm>
51 #include <hash_map>
53 //_________________________________________________________________________________________________________________
54 // namespaces
55 //_________________________________________________________________________________________________________________
57 using namespace ::std ;
58 using namespace ::utl ;
59 using namespace ::rtl ;
60 using namespace ::osl ;
61 using namespace ::com::sun::star::uno ;
62 using namespace ::com::sun::star::beans ;
64 //_________________________________________________________________________________________________________________
65 // const
66 //_________________________________________________________________________________________________________________
68 #define ROOTNODE_CMDOPTIONS OUString(RTL_CONSTASCII_USTRINGPARAM("Office.Commands/Execute" ))
69 #define PATHDELIMITER OUString(RTL_CONSTASCII_USTRINGPARAM("/" ))
71 #define SETNODE_DISABLED OUString(RTL_CONSTASCII_USTRINGPARAM("Disabled" ))
73 #define PROPERTYNAME_CMD OUString(RTL_CONSTASCII_USTRINGPARAM("Command" ))
75 #define PROPERTYCOUNT 1
77 #define OFFSET_CMD 0
79 //_________________________________________________________________________________________________________________
80 // private declarations!
81 //_________________________________________________________________________________________________________________
83 // Method to retrieve a hash code from a string. May be we have to change it to decrease collisions in the hash map
84 struct OUStringHashCode
86 size_t operator()( const ::rtl::OUString& sString ) const
88 return sString.hashCode();
92 /*-****************************************************************************************************************
93 @descr support simple command option structures and operations on it
94 ****************************************************************************************************************-*/
95 class SvtCmdOptions
97 public:
98 //---------------------------------------------------------------------------------------------------------
99 // the only way to free memory!
100 void Clear()
102 m_aCommandHashMap.clear();
105 sal_Bool HasEntries() const
107 return ( m_aCommandHashMap.size() > 0 );
110 void SetContainerSize( sal_Int32 nSize )
112 m_aCommandHashMap.resize( nSize );
115 sal_Bool Lookup( const OUString& aCmd ) const
117 CommandHashMap::const_iterator pEntry = m_aCommandHashMap.find( aCmd );
118 return ( pEntry != m_aCommandHashMap.end() );
121 void AddCommand( const OUString& aCmd )
123 m_aCommandHashMap.insert( CommandHashMap::value_type( aCmd, 0 ) );
126 //---------------------------------------------------------------------------------------------------------
127 // convert internal list to external format
128 // for using it on right menus realy
129 // Notice: We build a property list with 4 entries and set it on result list then.
130 // The while-loop starts with pointer on internal member list lSetupEntries, change to
131 // lUserEntries then and stop after that with NULL!
132 // Separator entries will be packed in another way then normal entries! We define
133 // special strings "sEmpty" and "sSeperator" to perform too ...
134 Sequence< OUString > GetList() const
136 sal_Int32 nCount = (sal_Int32)m_aCommandHashMap.size();
137 sal_Int32 nIndex = 0;
138 Sequence< OUString > aList( nCount );
140 CommandHashMap::const_iterator pEntry = m_aCommandHashMap.begin();
141 while ( pEntry != m_aCommandHashMap.end() )
142 aList[nIndex++] = pEntry->first;
144 return aList;
147 private:
148 class CommandHashMap : public ::std::hash_map< ::rtl::OUString ,
149 sal_Int32 ,
150 OUStringHashCode ,
151 ::std::equal_to< ::rtl::OUString > >
153 public:
154 inline void free()
156 CommandHashMap().swap( *this );
160 CommandHashMap m_aCommandHashMap;
163 typedef ::std::vector< ::com::sun::star::uno::WeakReference< ::com::sun::star::frame::XFrame > > SvtFrameVector;
165 class SvtCommandOptions_Impl : public ConfigItem
167 //-------------------------------------------------------------------------------------------------------------
168 // public methods
169 //-------------------------------------------------------------------------------------------------------------
171 public:
173 //---------------------------------------------------------------------------------------------------------
174 // constructor / destructor
175 //---------------------------------------------------------------------------------------------------------
177 SvtCommandOptions_Impl();
178 ~SvtCommandOptions_Impl();
180 //---------------------------------------------------------------------------------------------------------
181 // overloaded methods of baseclass
182 //---------------------------------------------------------------------------------------------------------
184 /*-****************************************************************************************************//**
185 @short called for notify of configmanager
186 @descr These method is called from the ConfigManager before application ends or from the
187 PropertyChangeListener if the sub tree broadcasts changes. You must update your
188 internal values.
190 @seealso baseclass ConfigItem
192 @param "lPropertyNames" is the list of properties which should be updated.
193 @return -
195 @onerror -
196 *//*-*****************************************************************************************************/
198 virtual void Notify( const Sequence< OUString >& lPropertyNames );
200 /*-****************************************************************************************************//**
201 @short write changes to configuration
202 @descr These method writes the changed values into the sub tree
203 and should always called in our destructor to guarantee consistency of config data.
205 @seealso baseclass ConfigItem
207 @param -
208 @return -
210 @onerror -
211 *//*-*****************************************************************************************************/
213 virtual void Commit();
215 //---------------------------------------------------------------------------------------------------------
216 // public interface
217 //---------------------------------------------------------------------------------------------------------
219 /*-****************************************************************************************************//**
220 @short base implementation of public interface for "SvtDynamicMenuOptions"!
221 @descr These class is used as static member of "SvtDynamicMenuOptions" ...
222 => The code exist only for one time and isn't duplicated for every instance!
224 @seealso -
226 @param -
227 @return -
229 @onerror -
230 *//*-*****************************************************************************************************/
232 void Clear ( SvtCommandOptions::CmdOption eCmdOption );
233 sal_Bool HasEntries ( SvtCommandOptions::CmdOption eOption ) const;
234 sal_Bool Lookup ( SvtCommandOptions::CmdOption eCmdOption, const OUString& ) const;
235 Sequence< OUString > GetList ( SvtCommandOptions::CmdOption eCmdOption ) const ;
236 void AddCommand ( SvtCommandOptions::CmdOption eCmdOption,
237 const OUString& sURL );
238 void EstablisFrameCallback(const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& xFrame);
240 //-------------------------------------------------------------------------------------------------------------
241 // private methods
242 //-------------------------------------------------------------------------------------------------------------
244 private:
246 /*-****************************************************************************************************//**
247 @short return list of key names of our configuration management which represent oue module tree
248 @descr These methods return the current list of key names! We need it to get needed values from our
249 configuration management and support dynamical menu item lists!
251 @seealso -
253 @param "nDisabledCount" , returns count of menu entries for "new"
254 @return A list of configuration key names is returned.
256 @onerror -
257 *//*-*****************************************************************************************************/
259 Sequence< OUString > impl_GetPropertyNames();
261 //-------------------------------------------------------------------------------------------------------------
262 // private member
263 //-------------------------------------------------------------------------------------------------------------
265 private:
266 SvtCmdOptions m_aDisabledCommands;
267 SvtFrameVector m_lFrames;
270 //_________________________________________________________________________________________________________________
271 // definitions
272 //_________________________________________________________________________________________________________________
274 //*****************************************************************************************************************
275 // constructor
276 //*****************************************************************************************************************
277 SvtCommandOptions_Impl::SvtCommandOptions_Impl()
278 // Init baseclasses first
279 : ConfigItem( ROOTNODE_CMDOPTIONS )
280 // Init member then...
282 // Get names and values of all accessable menu entries and fill internal structures.
283 // See impl_GetPropertyNames() for further informations.
284 Sequence< OUString > lNames = impl_GetPropertyNames ();
285 Sequence< Any > lValues = GetProperties ( lNames );
287 // Safe impossible cases.
288 // We need values from ALL configuration keys.
289 // Follow assignment use order of values in relation to our list of key names!
290 DBG_ASSERT( !(lNames.getLength()!=lValues.getLength()), "SvtCommandOptions_Impl::SvtCommandOptions_Impl()\nI miss some values of configuration keys!\n" );
292 // Copy values from list in right order to ouer internal member.
293 // Attention: List for names and values have an internal construction pattern!
294 sal_Int32 nItem = 0 ;
295 OUString sCmd ;
297 // Set size of hash_map reach a used size of approx. 60%
298 m_aDisabledCommands.SetContainerSize( lNames.getLength() * 10 / 6 );
300 // Get names/values for disabled commands.
301 for( nItem=0; nItem < lNames.getLength(); ++nItem )
303 // Currently only one value
304 lValues[nItem] >>= sCmd;
305 m_aDisabledCommands.AddCommand( sCmd );
308 /*TODO: Not used in the moment! see Notify() ...
309 // Enable notification mechanism of ouer baseclass.
310 // We need it to get information about changes outside these class on ouer used configuration keys! */
311 Sequence< OUString > aNotifySeq( 1 );
312 aNotifySeq[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( "Disabled" ));
313 EnableNotification( aNotifySeq, sal_True );
316 //*****************************************************************************************************************
317 // destructor
318 //*****************************************************************************************************************
319 SvtCommandOptions_Impl::~SvtCommandOptions_Impl()
321 // We must save our current values .. if user forget it!
322 if( IsModified() == sal_True )
324 Commit();
328 //*****************************************************************************************************************
329 // public method
330 //*****************************************************************************************************************
331 void SvtCommandOptions_Impl::Notify( const Sequence< OUString >& )
333 MutexGuard aGuard( SvtCommandOptions::GetOwnStaticMutex() );
335 Sequence< OUString > lNames = impl_GetPropertyNames ();
336 Sequence< Any > lValues = GetProperties ( lNames );
338 // Safe impossible cases.
339 // We need values from ALL configuration keys.
340 // Follow assignment use order of values in relation to our list of key names!
341 DBG_ASSERT( !(lNames.getLength()!=lValues.getLength()), "SvtCommandOptions_Impl::SvtCommandOptions_Impl()\nI miss some values of configuration keys!\n" );
343 // Copy values from list in right order to ouer internal member.
344 // Attention: List for names and values have an internal construction pattern!
345 sal_Int32 nItem = 0 ;
346 OUString sCmd ;
348 // Set size of hash_map reach a used size of approx. 60%
349 m_aDisabledCommands.Clear();
350 m_aDisabledCommands.SetContainerSize( lNames.getLength() * 10 / 6 );
352 // Get names/values for disabled commands.
353 for( nItem=0; nItem < lNames.getLength(); ++nItem )
355 // Currently only one value
356 lValues[nItem] >>= sCmd;
357 m_aDisabledCommands.AddCommand( sCmd );
360 // dont forget to update all existing frames and her might cached dispatch objects!
361 // But look for already killed frames. We hold weak references instead of hard ones ...
362 for (SvtFrameVector::const_iterator pIt = m_lFrames.begin();
363 pIt != m_lFrames.end() ;
364 ++pIt )
366 ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > xFrame(pIt->get(), ::com::sun::star::uno::UNO_QUERY);
367 if (xFrame.is())
368 xFrame->contextChanged();
372 //*****************************************************************************************************************
373 // public method
374 //*****************************************************************************************************************
375 void SvtCommandOptions_Impl::Commit()
377 DBG_ERROR( "SvtCommandOptions_Impl::Commit()\nNot implemented yet!\n" );
380 //*****************************************************************************************************************
381 // public method
382 //*****************************************************************************************************************
383 void SvtCommandOptions_Impl::Clear( SvtCommandOptions::CmdOption eCmdOption )
385 switch( eCmdOption )
387 case SvtCommandOptions::CMDOPTION_DISABLED:
389 m_aDisabledCommands.Clear();
390 SetModified();
392 break;
394 default:
395 DBG_ASSERT( sal_False, "SvtCommandOptions_Impl::Clear()\nUnknown option type given!\n" );
399 //*****************************************************************************************************************
400 // public method
401 //*****************************************************************************************************************
402 sal_Bool SvtCommandOptions_Impl::HasEntries( SvtCommandOptions::CmdOption eOption ) const
404 if ( eOption == SvtCommandOptions::CMDOPTION_DISABLED )
405 return ( m_aDisabledCommands.HasEntries() > 0 );
406 else
407 return sal_False;
410 //*****************************************************************************************************************
411 // public method
412 //*****************************************************************************************************************
413 Sequence< OUString > SvtCommandOptions_Impl::GetList( SvtCommandOptions::CmdOption eCmdOption ) const
415 Sequence< OUString > lReturn;
417 switch( eCmdOption )
419 case SvtCommandOptions::CMDOPTION_DISABLED:
421 lReturn = m_aDisabledCommands.GetList();
423 break;
425 default:
426 DBG_ASSERT( sal_False, "SvtCommandOptions_Impl::GetList()\nUnknown option type given!\n" );
429 return lReturn;
432 //*****************************************************************************************************************
433 // public method
434 //*****************************************************************************************************************
435 sal_Bool SvtCommandOptions_Impl::Lookup( SvtCommandOptions::CmdOption eCmdOption, const OUString& aCommand ) const
437 switch( eCmdOption )
439 case SvtCommandOptions::CMDOPTION_DISABLED:
441 return m_aDisabledCommands.Lookup( aCommand );
443 default:
444 DBG_ASSERT( sal_False, "SvtCommandOptions_Impl::GetList()\nUnknown option type given!\n" );
447 return sal_False;
450 //*****************************************************************************************************************
451 // public method
452 //*****************************************************************************************************************
453 void SvtCommandOptions_Impl::AddCommand( SvtCommandOptions::CmdOption eCmdOption, const OUString& sCmd )
455 switch( eCmdOption )
457 case SvtCommandOptions::CMDOPTION_DISABLED:
459 m_aDisabledCommands.AddCommand( sCmd );
460 SetModified();
462 break;
464 default:
465 DBG_ASSERT( sal_False, "SvtCommandOptions_Impl::GetList()\nUnknown option type given!\n" );
469 //*****************************************************************************************************************
470 // public method
471 //*****************************************************************************************************************
472 void SvtCommandOptions_Impl::EstablisFrameCallback(const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& xFrame)
474 // check if frame already exists inside list
475 // ignore double registrations
476 // every frame must be notified one times only!
477 ::com::sun::star::uno::WeakReference< ::com::sun::star::frame::XFrame > xWeak(xFrame);
478 SvtFrameVector::const_iterator pIt = ::std::find(m_lFrames.begin(), m_lFrames.end(), xWeak);
479 if (pIt == m_lFrames.end())
480 m_lFrames.push_back(xWeak);
483 //*****************************************************************************************************************
484 // private method
485 //*****************************************************************************************************************
486 Sequence< OUString > SvtCommandOptions_Impl::impl_GetPropertyNames()
488 // First get ALL names of current existing list items in configuration!
489 Sequence< OUString > lDisabledItems = GetNodeNames( SETNODE_DISABLED, utl::CONFIG_NAME_LOCAL_PATH );
491 OUString aSetNode( SETNODE_DISABLED );
492 aSetNode += PATHDELIMITER;
494 OUString aCommandKey( PATHDELIMITER );
495 aCommandKey += PROPERTYNAME_CMD;
497 // Expand all keys
498 for (sal_Int32 i=0; i<lDisabledItems.getLength(); ++i )
500 OUStringBuffer aBuffer( 32 );
501 aBuffer.append( aSetNode );
502 aBuffer.append( lDisabledItems[i] );
503 aBuffer.append( aCommandKey );
504 lDisabledItems[i] = aBuffer.makeStringAndClear();
507 // Return result.
508 return lDisabledItems;
511 //*****************************************************************************************************************
512 // initialize static member
513 // DON'T DO IT IN YOUR HEADER!
514 // see definition for further informations
515 //*****************************************************************************************************************
516 SvtCommandOptions_Impl* SvtCommandOptions::m_pDataContainer = NULL ;
517 sal_Int32 SvtCommandOptions::m_nRefCount = 0 ;
519 //*****************************************************************************************************************
520 // constructor
521 //*****************************************************************************************************************
522 SvtCommandOptions::SvtCommandOptions()
524 // Global access, must be guarded (multithreading!).
525 MutexGuard aGuard( GetOwnStaticMutex() );
526 // Increase ouer refcount ...
527 ++m_nRefCount;
528 // ... and initialize ouer data container only if it not already exist!
529 if( m_pDataContainer == NULL )
531 m_pDataContainer = new SvtCommandOptions_Impl;
532 ItemHolder1::holdConfigItem(E_CMDOPTIONS);
536 //*****************************************************************************************************************
537 // destructor
538 //*****************************************************************************************************************
539 SvtCommandOptions::~SvtCommandOptions()
541 // Global access, must be guarded (multithreading!)
542 MutexGuard aGuard( GetOwnStaticMutex() );
543 // Decrease ouer refcount.
544 --m_nRefCount;
545 // If last instance was deleted ...
546 // we must destroy ouer static data container!
547 if( m_nRefCount <= 0 )
549 delete m_pDataContainer;
550 m_pDataContainer = NULL;
554 //*****************************************************************************************************************
555 // public method
556 //*****************************************************************************************************************
557 void SvtCommandOptions::Clear( CmdOption eCmdOption )
559 MutexGuard aGuard( GetOwnStaticMutex() );
560 m_pDataContainer->Clear( eCmdOption );
563 //*****************************************************************************************************************
564 // public method
565 //*****************************************************************************************************************
566 sal_Bool SvtCommandOptions::HasEntries( CmdOption eOption ) const
568 MutexGuard aGuard( GetOwnStaticMutex() );
569 return m_pDataContainer->HasEntries( eOption );
572 //*****************************************************************************************************************
573 // public method
574 //*****************************************************************************************************************
575 sal_Bool SvtCommandOptions::Lookup( CmdOption eCmdOption, const OUString& aCommandURL ) const
577 MutexGuard aGuard( GetOwnStaticMutex() );
578 return m_pDataContainer->Lookup( eCmdOption, aCommandURL );
581 //*****************************************************************************************************************
582 // public method
583 //*****************************************************************************************************************
584 Sequence< OUString > SvtCommandOptions::GetList( CmdOption eCmdOption ) const
586 MutexGuard aGuard( GetOwnStaticMutex() );
587 return m_pDataContainer->GetList( eCmdOption );
590 //*****************************************************************************************************************
591 // public method
592 //*****************************************************************************************************************
593 void SvtCommandOptions::AddCommand( CmdOption eCmdOption, const OUString& sURL )
595 MutexGuard aGuard( GetOwnStaticMutex() );
596 m_pDataContainer->AddCommand( eCmdOption, sURL );
599 //*****************************************************************************************************************
600 // public method
601 //*****************************************************************************************************************
602 void SvtCommandOptions::EstablisFrameCallback(const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& xFrame)
604 MutexGuard aGuard( GetOwnStaticMutex() );
605 m_pDataContainer->EstablisFrameCallback(xFrame);
608 //*****************************************************************************************************************
609 // private method
610 //*****************************************************************************************************************
611 Mutex& SvtCommandOptions::GetOwnStaticMutex()
613 // Initialize static mutex only for one time!
614 static Mutex* pMutex = NULL;
615 // If these method first called (Mutex not already exist!) ...
616 if( pMutex == NULL )
618 // ... we must create a new one. Protect follow code with the global mutex -
619 // It must be - we create a static variable!
620 MutexGuard aGuard( Mutex::getGlobalMutex() );
621 // We must check our pointer again - because it can be that another instance of ouer class will be fastr then these!
622 if( pMutex == NULL )
624 // Create the new mutex and set it for return on static variable.
625 static Mutex aMutex;
626 pMutex = &aMutex;
629 // Return new created or already existing mutex object.
630 return *pMutex;