1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
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 ****************************************************************************************************************-*/
64 //---------------------------------------------------------------------------------------------------------
65 // the only way to free memory!
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();
99 Sequence
< OUString
> aList( nCount
);
101 CommandHashMap::const_iterator pEntry
= m_aCommandHashMap
.begin();
102 while ( pEntry
!= m_aCommandHashMap
.end() )
103 aList
[nIndex
++] = pEntry
->first
;
109 class CommandHashMap
: public ::boost::unordered_map
< OUString
,
112 ::std::equal_to
< OUString
> >
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
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
139 @seealso baseclass ConfigItem
141 @param "lPropertyNames" is the list of properties which should be updated.
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
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!
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
);
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!
190 @param "nDisabledCount" , returns count of menu entries for "new"
191 @return A list of configuration key names is returned.
194 *//*-*****************************************************************************************************/
196 Sequence
< OUString
> impl_GetPropertyNames();
199 SvtCmdOptions m_aDisabledCommands
;
200 SvtFrameVector m_lFrames
;
203 //*****************************************************************************************************************
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 ;
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 //*****************************************************************************************************************
244 //*****************************************************************************************************************
245 SvtCommandOptions_Impl::~SvtCommandOptions_Impl()
247 // We must save our current values .. if user forget it!
248 if( IsModified() == sal_True
)
254 //*****************************************************************************************************************
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 ;
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() ;
290 ::com::sun::star::uno::Reference
< ::com::sun::star::frame::XFrame
> xFrame(pIt
->get(), ::com::sun::star::uno::UNO_QUERY
);
292 xFrame
->contextChanged();
296 //*****************************************************************************************************************
298 //*****************************************************************************************************************
299 void SvtCommandOptions_Impl::Commit()
301 OSL_FAIL( "SvtCommandOptions_Impl::Commit()\nNot implemented yet!\n" );
304 //*****************************************************************************************************************
306 //*****************************************************************************************************************
307 sal_Bool
SvtCommandOptions_Impl::HasEntries( SvtCommandOptions::CmdOption eOption
) const
309 if ( eOption
== SvtCommandOptions::CMDOPTION_DISABLED
)
310 return ( m_aDisabledCommands
.HasEntries() > 0 );
315 //*****************************************************************************************************************
317 //*****************************************************************************************************************
318 sal_Bool
SvtCommandOptions_Impl::Lookup( SvtCommandOptions::CmdOption eCmdOption
, const OUString
& aCommand
) const
322 case SvtCommandOptions::CMDOPTION_DISABLED
:
324 return m_aDisabledCommands
.Lookup( aCommand
);
327 DBG_ASSERT( sal_False
, "SvtCommandOptions_Impl::GetList()\nUnknown option type given!\n" );
333 //*****************************************************************************************************************
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 //*****************************************************************************************************************
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
;
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();
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 //*****************************************************************************************************************
385 //*****************************************************************************************************************
386 SvtCommandOptions::SvtCommandOptions()
388 // Global access, must be guarded (multithreading!).
389 MutexGuard
aGuard( GetOwnStaticMutex() );
390 // Increase ouer refcount ...
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 //*****************************************************************************************************************
402 //*****************************************************************************************************************
403 SvtCommandOptions::~SvtCommandOptions()
405 // Global access, must be guarded (multithreading!)
406 MutexGuard
aGuard( GetOwnStaticMutex() );
407 // Decrease ouer refcount.
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 //*****************************************************************************************************************
420 //*****************************************************************************************************************
421 sal_Bool
SvtCommandOptions::HasEntries( CmdOption eOption
) const
423 MutexGuard
aGuard( GetOwnStaticMutex() );
424 return m_pDataContainer
->HasEntries( eOption
);
427 //*****************************************************************************************************************
429 //*****************************************************************************************************************
430 sal_Bool
SvtCommandOptions::Lookup( CmdOption eCmdOption
, const OUString
& aCommandURL
) const
432 MutexGuard
aGuard( GetOwnStaticMutex() );
433 return m_pDataContainer
->Lookup( eCmdOption
, aCommandURL
);
436 //*****************************************************************************************************************
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
);
447 class theCommandOptionsMutex
: public rtl::Static
<osl::Mutex
, theCommandOptionsMutex
>{};
450 //*****************************************************************************************************************
452 //*****************************************************************************************************************
453 Mutex
& SvtCommandOptions::GetOwnStaticMutex()
455 return theCommandOptionsMutex::get();
458 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */