1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: cmdoptions.cxx,v $
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 //_________________________________________________________________________________________________________________
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>
53 //_________________________________________________________________________________________________________________
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 //_________________________________________________________________________________________________________________
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
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 ****************************************************************************************************************-*/
98 //---------------------------------------------------------------------------------------------------------
99 // the only way to free memory!
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
;
148 class CommandHashMap
: public ::std::hash_map
< ::rtl::OUString
,
151 ::std::equal_to
< ::rtl::OUString
> >
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 //-------------------------------------------------------------------------------------------------------------
169 //-------------------------------------------------------------------------------------------------------------
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
190 @seealso baseclass ConfigItem
192 @param "lPropertyNames" is the list of properties which should be updated.
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
211 *//*-*****************************************************************************************************/
213 virtual void Commit();
215 //---------------------------------------------------------------------------------------------------------
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!
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 //-------------------------------------------------------------------------------------------------------------
242 //-------------------------------------------------------------------------------------------------------------
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!
253 @param "nDisabledCount" , returns count of menu entries for "new"
254 @return A list of configuration key names is returned.
257 *//*-*****************************************************************************************************/
259 Sequence
< OUString
> impl_GetPropertyNames();
261 //-------------------------------------------------------------------------------------------------------------
263 //-------------------------------------------------------------------------------------------------------------
266 SvtCmdOptions m_aDisabledCommands
;
267 SvtFrameVector m_lFrames
;
270 //_________________________________________________________________________________________________________________
272 //_________________________________________________________________________________________________________________
274 //*****************************************************************************************************************
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 ;
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 //*****************************************************************************************************************
318 //*****************************************************************************************************************
319 SvtCommandOptions_Impl::~SvtCommandOptions_Impl()
321 // We must save our current values .. if user forget it!
322 if( IsModified() == sal_True
)
328 //*****************************************************************************************************************
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 ;
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() ;
366 ::com::sun::star::uno::Reference
< ::com::sun::star::frame::XFrame
> xFrame(pIt
->get(), ::com::sun::star::uno::UNO_QUERY
);
368 xFrame
->contextChanged();
372 //*****************************************************************************************************************
374 //*****************************************************************************************************************
375 void SvtCommandOptions_Impl::Commit()
377 DBG_ERROR( "SvtCommandOptions_Impl::Commit()\nNot implemented yet!\n" );
380 //*****************************************************************************************************************
382 //*****************************************************************************************************************
383 void SvtCommandOptions_Impl::Clear( SvtCommandOptions::CmdOption eCmdOption
)
387 case SvtCommandOptions::CMDOPTION_DISABLED
:
389 m_aDisabledCommands
.Clear();
395 DBG_ASSERT( sal_False
, "SvtCommandOptions_Impl::Clear()\nUnknown option type given!\n" );
399 //*****************************************************************************************************************
401 //*****************************************************************************************************************
402 sal_Bool
SvtCommandOptions_Impl::HasEntries( SvtCommandOptions::CmdOption eOption
) const
404 if ( eOption
== SvtCommandOptions::CMDOPTION_DISABLED
)
405 return ( m_aDisabledCommands
.HasEntries() > 0 );
410 //*****************************************************************************************************************
412 //*****************************************************************************************************************
413 Sequence
< OUString
> SvtCommandOptions_Impl::GetList( SvtCommandOptions::CmdOption eCmdOption
) const
415 Sequence
< OUString
> lReturn
;
419 case SvtCommandOptions::CMDOPTION_DISABLED
:
421 lReturn
= m_aDisabledCommands
.GetList();
426 DBG_ASSERT( sal_False
, "SvtCommandOptions_Impl::GetList()\nUnknown option type given!\n" );
432 //*****************************************************************************************************************
434 //*****************************************************************************************************************
435 sal_Bool
SvtCommandOptions_Impl::Lookup( SvtCommandOptions::CmdOption eCmdOption
, const OUString
& aCommand
) const
439 case SvtCommandOptions::CMDOPTION_DISABLED
:
441 return m_aDisabledCommands
.Lookup( aCommand
);
444 DBG_ASSERT( sal_False
, "SvtCommandOptions_Impl::GetList()\nUnknown option type given!\n" );
450 //*****************************************************************************************************************
452 //*****************************************************************************************************************
453 void SvtCommandOptions_Impl::AddCommand( SvtCommandOptions::CmdOption eCmdOption
, const OUString
& sCmd
)
457 case SvtCommandOptions::CMDOPTION_DISABLED
:
459 m_aDisabledCommands
.AddCommand( sCmd
);
465 DBG_ASSERT( sal_False
, "SvtCommandOptions_Impl::GetList()\nUnknown option type given!\n" );
469 //*****************************************************************************************************************
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 //*****************************************************************************************************************
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
;
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();
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 //*****************************************************************************************************************
521 //*****************************************************************************************************************
522 SvtCommandOptions::SvtCommandOptions()
524 // Global access, must be guarded (multithreading!).
525 MutexGuard
aGuard( GetOwnStaticMutex() );
526 // Increase ouer refcount ...
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 //*****************************************************************************************************************
538 //*****************************************************************************************************************
539 SvtCommandOptions::~SvtCommandOptions()
541 // Global access, must be guarded (multithreading!)
542 MutexGuard
aGuard( GetOwnStaticMutex() );
543 // Decrease ouer refcount.
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 //*****************************************************************************************************************
556 //*****************************************************************************************************************
557 void SvtCommandOptions::Clear( CmdOption eCmdOption
)
559 MutexGuard
aGuard( GetOwnStaticMutex() );
560 m_pDataContainer
->Clear( eCmdOption
);
563 //*****************************************************************************************************************
565 //*****************************************************************************************************************
566 sal_Bool
SvtCommandOptions::HasEntries( CmdOption eOption
) const
568 MutexGuard
aGuard( GetOwnStaticMutex() );
569 return m_pDataContainer
->HasEntries( eOption
);
572 //*****************************************************************************************************************
574 //*****************************************************************************************************************
575 sal_Bool
SvtCommandOptions::Lookup( CmdOption eCmdOption
, const OUString
& aCommandURL
) const
577 MutexGuard
aGuard( GetOwnStaticMutex() );
578 return m_pDataContainer
->Lookup( eCmdOption
, aCommandURL
);
581 //*****************************************************************************************************************
583 //*****************************************************************************************************************
584 Sequence
< OUString
> SvtCommandOptions::GetList( CmdOption eCmdOption
) const
586 MutexGuard
aGuard( GetOwnStaticMutex() );
587 return m_pDataContainer
->GetList( eCmdOption
);
590 //*****************************************************************************************************************
592 //*****************************************************************************************************************
593 void SvtCommandOptions::AddCommand( CmdOption eCmdOption
, const OUString
& sURL
)
595 MutexGuard
aGuard( GetOwnStaticMutex() );
596 m_pDataContainer
->AddCommand( eCmdOption
, sURL
);
599 //*****************************************************************************************************************
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 //*****************************************************************************************************************
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!) ...
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!
624 // Create the new mutex and set it for return on static variable.
629 // Return new created or already existing mutex object.