update emoji autocorrect entries from po-files
[LibreOffice.git] / unotools / source / config / dynamicmenuoptions.cxx
blobcf706c4b42e06e5152b91ee04730b427c21b18f4
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/dynamicmenuoptions.hxx>
24 #include <unotools/moduleoptions.hxx>
25 #include <unotools/configmgr.hxx>
26 #include <unotools/configitem.hxx>
27 #include <tools/debug.hxx>
28 #include <com/sun/star/uno/Any.hxx>
29 #include <com/sun/star/uno/Sequence.hxx>
31 #include <vector>
33 #include "itemholder1.hxx"
35 #include <algorithm>
37 using namespace ::std;
38 using namespace ::utl;
39 using namespace ::osl;
40 using namespace ::com::sun::star::uno;
41 using namespace ::com::sun::star::beans;
43 #define ROOTNODE_MENUS OUString("Office.Common/Menus/")
44 #define PATHDELIMITER OUString("/")
46 #define SETNODE_NEWMENU OUString("New")
47 #define SETNODE_WIZARDMENU OUString("Wizard")
48 #define SETNODE_HELPBOOKMARKS OUString("HelpBookmarks")
50 #define PROPERTYNAME_URL DYNAMICMENU_PROPERTYNAME_URL
51 #define PROPERTYNAME_TITLE DYNAMICMENU_PROPERTYNAME_TITLE
52 #define PROPERTYNAME_IMAGEIDENTIFIER DYNAMICMENU_PROPERTYNAME_IMAGEIDENTIFIER
53 #define PROPERTYNAME_TARGETNAME DYNAMICMENU_PROPERTYNAME_TARGETNAME
55 #define PROPERTYCOUNT 4
57 #define OFFSET_URL 0
58 #define OFFSET_TITLE 1
59 #define OFFSET_IMAGEIDENTIFIER 2
60 #define OFFSET_TARGETNAME 3
62 #define PATHPREFIX_SETUP OUString("m")
64 /*-****************************************************************************************************************
65 @descr struct to hold information about one menu entry.
66 ****************************************************************************************************************-*/
67 struct SvtDynMenuEntry
69 OUString sName;
70 OUString sURL;
71 OUString sTitle;
72 OUString sImageIdentifier;
73 OUString sTargetName;
76 /*-****************************************************************************************************************
77 @descr support simple menu structures and operations on it
78 ****************************************************************************************************************-*/
79 class SvtDynMenu
81 public:
82 // append setup written menu entry
83 // Don't touch name of entry. It was defined by setup and must be the same every time!
84 // Look for double menu entries here too... may be some separator items are superflous...
85 void AppendSetupEntry( const SvtDynMenuEntry& rEntry )
87 if(
88 ( lSetupEntries.size() < 1 ) ||
89 ( lSetupEntries.rbegin()->sURL != rEntry.sURL )
92 lSetupEntries.push_back( rEntry );
96 // convert internal list to external format
97 // for using it on right menus really
98 // Notice: We build a property list with 4 entries and set it on result list then.
99 // The while-loop starts with pointer on internal member list lSetupEntries, change to
100 // lUserEntries then and stop after that with NULL!
101 // Separator entries will be packed in another way then normal entries! We define
102 // special strings "sEmpty" and "sSeparator" to perform too ...
103 Sequence< Sequence< PropertyValue > > GetList() const
105 sal_Int32 nSetupCount = (sal_Int32)lSetupEntries.size();
106 sal_Int32 nUserCount = (sal_Int32)lUserEntries.size();
107 sal_Int32 nStep = 0;
108 Sequence< PropertyValue > lProperties ( PROPERTYCOUNT );
109 Sequence< Sequence< PropertyValue > > lResult ( nSetupCount+nUserCount );
110 OUString sSeparator ( "private:separator" );
111 OUString sEmpty;
112 const vector< SvtDynMenuEntry >* pList = &lSetupEntries;
114 lProperties[OFFSET_URL ].Name = PROPERTYNAME_URL;
115 lProperties[OFFSET_TITLE ].Name = PROPERTYNAME_TITLE;
116 lProperties[OFFSET_IMAGEIDENTIFIER].Name = PROPERTYNAME_IMAGEIDENTIFIER;
117 lProperties[OFFSET_TARGETNAME ].Name = PROPERTYNAME_TARGETNAME;
119 while( pList != NULL )
121 for( vector< SvtDynMenuEntry >::const_iterator pItem =pList->begin();
122 pItem!=pList->end();
123 ++pItem )
125 if( pItem->sURL == sSeparator )
127 lProperties[OFFSET_URL ].Value <<= sSeparator;
128 lProperties[OFFSET_TITLE ].Value <<= sEmpty;
129 lProperties[OFFSET_IMAGEIDENTIFIER ].Value <<= sEmpty;
130 lProperties[OFFSET_TARGETNAME ].Value <<= sEmpty;
132 else
134 lProperties[OFFSET_URL ].Value <<= pItem->sURL;
135 lProperties[OFFSET_TITLE ].Value <<= pItem->sTitle;
136 lProperties[OFFSET_IMAGEIDENTIFIER ].Value <<= pItem->sImageIdentifier;
137 lProperties[OFFSET_TARGETNAME ].Value <<= pItem->sTargetName;
139 lResult[nStep] = lProperties;
140 ++nStep;
142 if( pList == &lSetupEntries )
143 pList = &lUserEntries;
144 else
145 pList = NULL;
147 return lResult;
150 private:
151 vector< SvtDynMenuEntry > lSetupEntries;
152 vector< SvtDynMenuEntry > lUserEntries;
155 class SvtDynamicMenuOptions_Impl : public ConfigItem
157 public:
159 SvtDynamicMenuOptions_Impl();
160 virtual ~SvtDynamicMenuOptions_Impl();
162 /*-****************************************************************************************************
163 @short called for notify of configmanager
164 @descr These method is called from the ConfigManager before application ends or from the
165 PropertyChangeListener if the sub tree broadcasts changes. You must update your
166 internal values.
168 @seealso baseclass ConfigItem
170 @param "lPropertyNames" is the list of properties which should be updated.
171 *//*-*****************************************************************************************************/
173 virtual void Notify( const Sequence< OUString >& lPropertyNames ) SAL_OVERRIDE;
175 /*-****************************************************************************************************
176 @short base implementation of public interface for "SvtDynamicMenuOptions"!
177 @descr These class is used as static member of "SvtDynamicMenuOptions" ...
178 => The code exist only for one time and isn't duplicated for every instance!
179 *//*-*****************************************************************************************************/
181 Sequence< Sequence< PropertyValue > > GetMenu ( EDynamicMenuType eMenu ) const;
183 private:
185 virtual void ImplCommit() SAL_OVERRIDE;
187 /*-****************************************************************************************************
188 @short return list of key names of our configuration management which represent oue module tree
189 @descr These methods return the current list of key names! We need it to get needed values from our
190 configuration management and support dynamical menu item lists!
191 @param "nNewCount" , returns count of menu entries for "new"
192 @param "nWizardCount" , returns count of menu entries for "wizard"
193 @return A list of configuration key names is returned.
194 *//*-*****************************************************************************************************/
196 Sequence< OUString > impl_GetPropertyNames( sal_uInt32& nNewCount, sal_uInt32& nWizardCount, sal_uInt32& nHelpBookmarksCount );
198 /*-****************************************************************************************************
199 @short sort given source list and expand it for all well known properties to destination
200 @descr We must support sets of entries with count inside the name .. but some of them could be missing!
201 e.g. s1-s2-s3-s0-u1-s6-u5-u7
202 Then we must sort it by name and expand it to the follow one:
203 sSetNode/s0/URL
204 sSetNode/s0/Title
205 sSetNode/s0/...
206 sSetNode/s1/URL
207 sSetNode/s1/Title
208 sSetNode/s1/...
210 sSetNode/s6/URL
211 sSetNode/s6/Title
212 sSetNode/s6/...
213 sSetNode/u1/URL
214 sSetNode/u1/Title
215 sSetNode/u1/...
217 sSetNode/u7/URL
218 sSetNode/u7/Title
219 sSetNode/u7/...
220 Rules: We start with all setup written entries names "sx" and x=[0..n].
221 Then we handle all "ux" items. Inside these blocks we sort it ascending by number.
223 @attention We add these expanded list to the end of given "lDestination" list!
224 So we must start on "lDestination.getLength()".
225 Reallocation of memory of destination list is done by us!
227 @seealso method impl_GetPropertyNames()
229 @param "lSource" , original list (e.g. [m1-m2-m3-m6-m0] )
230 @param "lDestination" , destination of operation
231 @param "sSetNode" , name of configuration set to build complete path
232 @return A list of configuration key names is returned.
233 *//*-*****************************************************************************************************/
235 static void impl_SortAndExpandPropertyNames( const Sequence< OUString >& lSource ,
236 Sequence< OUString >& lDestination ,
237 const OUString& sSetNode );
239 // private member
241 private:
243 SvtDynMenu m_aNewMenu;
244 SvtDynMenu m_aWizardMenu;
245 SvtDynMenu m_aHelpBookmarksMenu;
248 // constructor
250 SvtDynamicMenuOptions_Impl::SvtDynamicMenuOptions_Impl()
251 // Init baseclasses first
252 : ConfigItem( ROOTNODE_MENUS )
253 // Init member then...
255 // Get names and values of all accessible menu entries and fill internal structures.
256 // See impl_GetPropertyNames() for further information.
257 sal_uInt32 nNewCount = 0;
258 sal_uInt32 nWizardCount = 0;
259 sal_uInt32 nHelpBookmarksCount = 0;
260 Sequence< OUString > lNames = impl_GetPropertyNames ( nNewCount ,
261 nWizardCount ,
262 nHelpBookmarksCount );
263 Sequence< Any > lValues = GetProperties ( lNames );
265 // Safe impossible cases.
266 // We need values from ALL configuration keys.
267 // Follow assignment use order of values in relation to our list of key names!
268 DBG_ASSERT( !(lNames.getLength()!=lValues.getLength()), "SvtDynamicMenuOptions_Impl::SvtDynamicMenuOptions_Impl()\nI miss some values of configuration keys!\n" );
270 // Copy values from list in right order to our internal member.
271 // Attention: List for names and values have an internal construction pattern!
273 // first "New" menu ...
274 // Name Value
275 // /New/1/URL "private:factory/swriter"
276 // /New/1/Title "Neues Writer Dokument"
277 // /New/1/ImageIdentifier "icon_writer"
278 // /New/1/TargetName "_blank"
280 // /New/2/URL "private:factory/scalc"
281 // /New/2/Title "Neues Calc Dokument"
282 // /New/2/ImageIdentifier "icon_calc"
283 // /New/2/TargetName "_blank"
285 // second "Wizard" menu ...
286 // /Wizard/1/URL "file://b"
287 // /Wizard/1/Title "MalWas"
288 // /Wizard/1/ImageIdentifier "icon_?"
289 // /Wizard/1/TargetName "_self"
291 // ... and so on ...
293 sal_uInt32 nItem = 0;
294 sal_uInt32 nPosition = 0;
296 // Get names/values for new menu.
297 // 4 subkeys for every item!
298 for( nItem=0; nItem<nNewCount; ++nItem )
300 SvtDynMenuEntry aItem;
301 lValues[nPosition] >>= aItem.sURL;
302 ++nPosition;
303 lValues[nPosition] >>= aItem.sTitle;
304 ++nPosition;
305 lValues[nPosition] >>= aItem.sImageIdentifier;
306 ++nPosition;
307 lValues[nPosition] >>= aItem.sTargetName;
308 ++nPosition;
309 m_aNewMenu.AppendSetupEntry( aItem );
312 // Attention: Don't reset nPosition here!
314 // Get names/values for wizard menu.
315 // 4 subkeys for every item!
316 for( nItem=0; nItem<nWizardCount; ++nItem )
318 SvtDynMenuEntry aItem;
319 lValues[nPosition] >>= aItem.sURL;
320 ++nPosition;
321 lValues[nPosition] >>= aItem.sTitle;
322 ++nPosition;
323 lValues[nPosition] >>= aItem.sImageIdentifier;
324 ++nPosition;
325 lValues[nPosition] >>= aItem.sTargetName;
326 ++nPosition;
327 m_aWizardMenu.AppendSetupEntry( aItem );
330 // Attention: Don't reset nPosition here!
332 // Get names/values for wizard menu.
333 // 4 subkeys for every item!
334 for( nItem=0; nItem<nHelpBookmarksCount; ++nItem )
336 SvtDynMenuEntry aItem;
337 lValues[nPosition] >>= aItem.sURL;
338 ++nPosition;
339 lValues[nPosition] >>= aItem.sTitle;
340 ++nPosition;
341 lValues[nPosition] >>= aItem.sImageIdentifier;
342 ++nPosition;
343 lValues[nPosition] >>= aItem.sTargetName;
344 ++nPosition;
345 m_aHelpBookmarksMenu.AppendSetupEntry( aItem );
348 /*TODO: Not used in the moment! see Notify() ...
349 // Enable notification mechanism of our baseclass.
350 // We need it to get information about changes outside these class on our used configuration keys!
351 EnableNotification( lNames );
355 // destructor
357 SvtDynamicMenuOptions_Impl::~SvtDynamicMenuOptions_Impl()
359 assert(!IsModified()); // should have been committed
362 // public method
364 void SvtDynamicMenuOptions_Impl::Notify( const Sequence< OUString >& )
366 DBG_ASSERT( false, "SvtDynamicMenuOptions_Impl::Notify()\nNot implemented yet! I don't know how I can handle a dynamical list of unknown properties ...\n" );
369 // public method
371 void SvtDynamicMenuOptions_Impl::ImplCommit()
373 SAL_WARN("unotools.config", "SvtDynamicMenuOptions_Impl::ImplCommit(): Not implemented yet!");
375 // Write all properties!
376 // Delete complete sets first.
377 ClearNodeSet( SETNODE_NEWMENU );
378 ClearNodeSet( SETNODE_WIZARDMENU );
379 ClearNodeSet( SETNODE_HELPBOOKMARKS );
381 MenuEntry aItem;
382 OUString sNode;
383 Sequence< PropertyValue > lPropertyValues( PROPERTYCOUNT );
384 sal_uInt32 nItem = 0;
386 // Copy "new" menu entries to save-list!
387 sal_uInt32 nNewCount = m_aNewMenu.size();
388 for( nItem=0; nItem<nNewCount; ++nItem )
390 aItem = m_aNewMenu[nItem];
391 // Format: "New/1/URL"
392 // "New/1/Title"
393 // ...
394 sNode = SETNODE_NEWMENU + PATHDELIMITER + PATHPREFIX + OUString::valueOf( (sal_Int32)nItem ) + PATHDELIMITER;
396 lPropertyValues[OFFSET_URL ].Name = sNode + PROPERTYNAME_URL;
397 lPropertyValues[OFFSET_TITLE ].Name = sNode + PROPERTYNAME_TITLE;
398 lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Name = sNode + PROPERTYNAME_IMAGEIDENTIFIER;
399 lPropertyValues[OFFSET_TARGETNAME ].Name = sNode + PROPERTYNAME_TARGETNAME;
401 lPropertyValues[OFFSET_URL ].Value <<= aItem.sURL;
402 lPropertyValues[OFFSET_TITLE ].Value <<= aItem.sTitle;
403 lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Value <<= aItem.sImageIdentifier;
404 lPropertyValues[OFFSET_TARGETNAME ].Value <<= aItem.sTargetName;
406 SetSetProperties( SETNODE_NEWMENU, lPropertyValues );
409 // Copy "wizard" menu entries to save-list!
410 sal_uInt32 nWizardCount = m_aWizardMenu.size();
411 for( nItem=0; nItem<nWizardCount; ++nItem )
413 aItem = m_aWizardMenu[nItem];
414 // Format: "Wizard/1/URL"
415 // "Wizard/1/Title"
416 // ...
417 sNode = SETNODE_WIZARDMENU + PATHDELIMITER + PATHPREFIX + OUString::valueOf( (sal_Int32)nItem ) + PATHDELIMITER;
419 lPropertyValues[OFFSET_URL ].Name = sNode + PROPERTYNAME_URL;
420 lPropertyValues[OFFSET_TITLE ].Name = sNode + PROPERTYNAME_TITLE;
421 lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Name = sNode + PROPERTYNAME_IMAGEIDENTIFIER;
422 lPropertyValues[OFFSET_TARGETNAME ].Name = sNode + PROPERTYNAME_TARGETNAME;
424 lPropertyValues[OFFSET_URL ].Value <<= aItem.sURL;
425 lPropertyValues[OFFSET_TITLE ].Value <<= aItem.sTitle;
426 lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Value <<= aItem.sImageIdentifier;
427 lPropertyValues[OFFSET_TARGETNAME ].Value <<= aItem.sTargetName;
429 SetSetProperties( SETNODE_WIZARDMENU, lPropertyValues );
432 // Copy help bookmarks entries to save-list!
433 sal_uInt32 nHelpBookmarksCount = m_aHelpBookmarksMenu.size();
434 for( nItem=0; nItem<nHelpBookmarksCount; ++nItem )
436 aItem = m_aHelpBookmarksMenu[nItem];
437 // Format: "HelpBookmarks/1/URL"
438 // "HelpBookmarks/1/Title"
439 // ...
440 sNode = SETNODE_HELPBOOKMARKS + PATHDELIMITER + PATHPREFIX + OUString::valueOf( (sal_Int32)nItem ) + PATHDELIMITER;
442 lPropertyValues[OFFSET_URL ].Name = sNode + PROPERTYNAME_URL;
443 lPropertyValues[OFFSET_TITLE ].Name = sNode + PROPERTYNAME_TITLE;
444 lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Name = sNode + PROPERTYNAME_IMAGEIDENTIFIER;
445 lPropertyValues[OFFSET_TARGETNAME ].Name = sNode + PROPERTYNAME_TARGETNAME;
447 lPropertyValues[OFFSET_URL ].Value <<= aItem.sURL;
448 lPropertyValues[OFFSET_TITLE ].Value <<= aItem.sTitle;
449 lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Value <<= aItem.sImageIdentifier;
450 lPropertyValues[OFFSET_TARGETNAME ].Value <<= aItem.sTargetName;
452 SetSetProperties( SETNODE_HELPBOOKMARKS, lPropertyValues );
457 // public method
459 Sequence< Sequence< PropertyValue > > SvtDynamicMenuOptions_Impl::GetMenu( EDynamicMenuType eMenu ) const
461 Sequence< Sequence< PropertyValue > > lReturn;
462 switch( eMenu )
464 case E_NEWMENU : {
465 lReturn = m_aNewMenu.GetList();
467 break;
469 case E_WIZARDMENU : {
470 lReturn = m_aWizardMenu.GetList();
472 break;
474 case E_HELPBOOKMARKS : {
475 lReturn = m_aHelpBookmarksMenu.GetList();
477 break;
479 return lReturn;
482 // private method
484 Sequence< OUString > SvtDynamicMenuOptions_Impl::impl_GetPropertyNames( sal_uInt32& nNewCount, sal_uInt32& nWizardCount, sal_uInt32& nHelpBookmarksCount )
486 // First get ALL names of current existing list items in configuration!
487 Sequence< OUString > lNewItems = GetNodeNames( SETNODE_NEWMENU );
488 Sequence< OUString > lWizardItems = GetNodeNames( SETNODE_WIZARDMENU );
489 Sequence< OUString > lHelpBookmarksItems = GetNodeNames( SETNODE_HELPBOOKMARKS );
491 // Get information about list counts ...
492 nNewCount = lNewItems.getLength ();
493 nWizardCount = lWizardItems.getLength ();
494 nHelpBookmarksCount = lHelpBookmarksItems.getLength();
496 // Sort and expand all three list to result list ...
497 Sequence< OUString > lProperties;
498 impl_SortAndExpandPropertyNames( lNewItems , lProperties, SETNODE_NEWMENU );
499 impl_SortAndExpandPropertyNames( lWizardItems , lProperties, SETNODE_WIZARDMENU );
500 impl_SortAndExpandPropertyNames( lHelpBookmarksItems, lProperties, SETNODE_HELPBOOKMARKS );
502 // Return result.
503 return lProperties;
506 // private helper
508 class CountWithPrefixSort
510 public:
511 bool operator() ( const OUString& s1 ,
512 const OUString& s2 ) const
514 // Get order numbers from entry name without prefix.
515 // e.g. "m10" => 10
516 // "m5" => 5
517 sal_Int32 n1 = s1.copy( 1, s1.getLength()-1 ).toInt32();
518 sal_Int32 n2 = s2.copy( 1, s2.getLength()-1 ).toInt32();
519 // MUST be in [0,1] ... because it's a difference between
520 // insert-positions of given entries in sorted list!
521 return( n1<n2 );
525 class SelectByPrefix
527 public:
528 bool operator() ( const OUString& s ) const
530 // Prefer setup written entries by check first letter of given string. It must be a "s".
531 return s.startsWith( PATHPREFIX_SETUP );
535 // private method
537 void SvtDynamicMenuOptions_Impl::impl_SortAndExpandPropertyNames( const Sequence< OUString >& lSource ,
538 Sequence< OUString >& lDestination ,
539 const OUString& sSetNode )
541 OUString sFixPath;
542 vector< OUString > lTemp;
543 sal_Int32 nSourceCount = lSource.getLength();
544 sal_Int32 nDestinationStep = lDestination.getLength(); // start on end of current list ...!
546 lDestination.realloc( (nSourceCount*PROPERTYCOUNT)+nDestinationStep ); // get enough memory for copy operations after nDestination ...
548 // Copy all items to temp. vector to use fast sort operations :-)
549 for( sal_Int32 nSourceStep=0; nSourceStep<nSourceCount; ++nSourceStep )
550 lTemp.push_back( lSource[nSourceStep] );
552 // Sort all entries by number ...
553 stable_sort( lTemp.begin(), lTemp.end(), CountWithPrefixSort() );
554 // and split into setup & user written entries!
555 stable_partition( lTemp.begin(), lTemp.end(), SelectByPrefix() );
557 // Copy sorted entries to destination and expand every item with
558 // 4 supported sub properties.
559 for( vector< OUString >::const_iterator pItem =lTemp.begin();
560 pItem!=lTemp.end();
561 ++pItem )
563 sFixPath = sSetNode;
564 sFixPath += PATHDELIMITER;
565 sFixPath += *pItem;
566 sFixPath += PATHDELIMITER;
568 lDestination[nDestinationStep] = sFixPath;
569 lDestination[nDestinationStep] += PROPERTYNAME_URL;
570 ++nDestinationStep;
571 lDestination[nDestinationStep] = sFixPath;
572 lDestination[nDestinationStep] += PROPERTYNAME_TITLE;
573 ++nDestinationStep;
574 lDestination[nDestinationStep] = sFixPath;
575 lDestination[nDestinationStep] += PROPERTYNAME_IMAGEIDENTIFIER;
576 ++nDestinationStep;
577 lDestination[nDestinationStep] = sFixPath;
578 lDestination[nDestinationStep] += PROPERTYNAME_TARGETNAME;
579 ++nDestinationStep;
583 // initialize static member
584 // DON'T DO IT IN YOUR HEADER!
585 // see definition for further information
587 SvtDynamicMenuOptions_Impl* SvtDynamicMenuOptions::m_pDataContainer = NULL;
588 sal_Int32 SvtDynamicMenuOptions::m_nRefCount = 0;
590 // constructor
592 SvtDynamicMenuOptions::SvtDynamicMenuOptions()
594 // Global access, must be guarded (multithreading!).
595 MutexGuard aGuard( GetOwnStaticMutex() );
596 // Increase our refcount ...
597 ++m_nRefCount;
598 // ... and initialize our data container only if it not already exist!
599 if( m_pDataContainer == NULL )
601 m_pDataContainer = new SvtDynamicMenuOptions_Impl;
602 ItemHolder1::holdConfigItem(E_DYNAMICMENUOPTIONS);
606 // destructor
608 SvtDynamicMenuOptions::~SvtDynamicMenuOptions()
610 // Global access, must be guarded (multithreading!)
611 MutexGuard aGuard( GetOwnStaticMutex() );
612 // Decrease our refcount.
613 --m_nRefCount;
614 // If last instance was deleted ...
615 // we must destroy our static data container!
616 if( m_nRefCount <= 0 )
618 delete m_pDataContainer;
619 m_pDataContainer = NULL;
623 // public method
625 Sequence< Sequence< PropertyValue > > SvtDynamicMenuOptions::GetMenu( EDynamicMenuType eMenu ) const
627 MutexGuard aGuard( GetOwnStaticMutex() );
628 return m_pDataContainer->GetMenu( eMenu );
631 namespace
633 class theDynamicMenuOptionsMutex : public rtl::Static<osl::Mutex, theDynamicMenuOptionsMutex>{};
636 // private method
638 Mutex& SvtDynamicMenuOptions::GetOwnStaticMutex()
640 return theDynamicMenuOptionsMutex::get();
643 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */