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 .
21 #include <unotools/dynamicmenuoptions.hxx>
22 #include <unotools/moduleoptions.hxx>
23 #include <unotools/configmgr.hxx>
24 #include <unotools/configitem.hxx>
25 #include <tools/debug.hxx>
26 #include <com/sun/star/uno/Any.hxx>
27 #include <com/sun/star/uno/Sequence.hxx>
31 #include <itemholder1.hxx>
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_MENUS OUString("Office.Common/Menus/")
43 #define PATHDELIMITER OUString("/")
45 #define SETNODE_NEWMENU OUString("New")
46 #define SETNODE_WIZARDMENU OUString("Wizard")
47 #define SETNODE_HELPBOOKMARKS OUString("HelpBookmarks")
49 #define PROPERTYNAME_URL DYNAMICMENU_PROPERTYNAME_URL
50 #define PROPERTYNAME_TITLE DYNAMICMENU_PROPERTYNAME_TITLE
51 #define PROPERTYNAME_IMAGEIDENTIFIER DYNAMICMENU_PROPERTYNAME_IMAGEIDENTIFIER
52 #define PROPERTYNAME_TARGETNAME DYNAMICMENU_PROPERTYNAME_TARGETNAME
54 #define PROPERTYCOUNT 4
57 #define OFFSET_TITLE 1
58 #define OFFSET_IMAGEIDENTIFIER 2
59 #define OFFSET_TARGETNAME 3
61 #define PATHPREFIX_SETUP OUString("m")
62 #define PATHPREFIX_USER OUString("u")
64 /*-****************************************************************************************************************
65 @descr struct to hold information about one menu entry.
66 ****************************************************************************************************************-*/
67 struct SvtDynMenuEntry
72 SvtDynMenuEntry( const OUString
& sNewURL
,
73 const OUString
& sNewTitle
,
74 const OUString
& sNewImageIdentifier
,
75 const OUString
& sNewTargetName
)
79 sImageIdentifier
= sNewImageIdentifier
;
80 sTargetName
= sNewTargetName
;
87 OUString sImageIdentifier
;
88 OUString sTargetName
;
91 /*-****************************************************************************************************************
92 @descr support simple menu structures and operations on it
93 ****************************************************************************************************************-*/
97 // append setup written menu entry
98 // Don't touch name of entry. It was defined by setup and must be the same everytime!
99 // Look for double menu entries here too ... may be some separator items are supeflous ...
100 void AppendSetupEntry( const SvtDynMenuEntry
& rEntry
)
103 ( lSetupEntries
.size() < 1 ) ||
104 ( lSetupEntries
.rbegin()->sURL
!= rEntry
.sURL
)
107 lSetupEntries
.push_back( rEntry
);
111 // append user specific menu entry
112 // We must find unique name for it by using special prefix
113 // and next count of user setted entries!
114 // Look for double menu entries here too ... may be some separator items are supeflous ...
115 void AppendUserEntry( SvtDynMenuEntry
& rEntry
)
118 ( lUserEntries
.size() < 1 ) ||
119 ( lUserEntries
.rbegin()->sURL
!= rEntry
.sURL
)
122 rEntry
.sName
= PATHPREFIX_USER
;
123 rEntry
.sName
+= OUString::valueOf( (sal_Int32
)impl_getNextUserEntryNr() );
124 lUserEntries
.push_back( rEntry
);
128 // the only way to free memory!
131 lSetupEntries
.clear();
132 lUserEntries
.clear();
135 // convert internal list to external format
136 // for using it on right menus realy
137 // Notice: We build a property list with 4 entries and set it on result list then.
138 // The while-loop starts with pointer on internal member list lSetupEntries, change to
139 // lUserEntries then and stop after that with NULL!
140 // Separator entries will be packed in another way then normal entries! We define
141 // special strings "sEmpty" and "sSeparator" to perform too ...
142 Sequence
< Sequence
< PropertyValue
> > GetList() const
144 sal_Int32 nSetupCount
= (sal_Int32
)lSetupEntries
.size();
145 sal_Int32 nUserCount
= (sal_Int32
)lUserEntries
.size();
147 Sequence
< PropertyValue
> lProperties ( PROPERTYCOUNT
);
148 Sequence
< Sequence
< PropertyValue
> > lResult ( nSetupCount
+nUserCount
);
149 OUString
sSeparator ( "private:separator" );
151 const vector
< SvtDynMenuEntry
>* pList
= &lSetupEntries
;
153 lProperties
[OFFSET_URL
].Name
= PROPERTYNAME_URL
;
154 lProperties
[OFFSET_TITLE
].Name
= PROPERTYNAME_TITLE
;
155 lProperties
[OFFSET_IMAGEIDENTIFIER
].Name
= PROPERTYNAME_IMAGEIDENTIFIER
;
156 lProperties
[OFFSET_TARGETNAME
].Name
= PROPERTYNAME_TARGETNAME
;
158 while( pList
!= NULL
)
160 for( vector
< SvtDynMenuEntry
>::const_iterator pItem
=pList
->begin();
161 pItem
!=pList
->end() ;
164 if( pItem
->sURL
== sSeparator
)
166 lProperties
[OFFSET_URL
].Value
<<= sSeparator
;
167 lProperties
[OFFSET_TITLE
].Value
<<= sEmpty
;
168 lProperties
[OFFSET_IMAGEIDENTIFIER
].Value
<<= sEmpty
;
169 lProperties
[OFFSET_TARGETNAME
].Value
<<= sEmpty
;
173 lProperties
[OFFSET_URL
].Value
<<= pItem
->sURL
;
174 lProperties
[OFFSET_TITLE
].Value
<<= pItem
->sTitle
;
175 lProperties
[OFFSET_IMAGEIDENTIFIER
].Value
<<= pItem
->sImageIdentifier
;
176 lProperties
[OFFSET_TARGETNAME
].Value
<<= pItem
->sTargetName
;
178 lResult
[nStep
] = lProperties
;
181 if( pList
== &lSetupEntries
)
182 pList
= &lUserEntries
;
191 // search for an entry named "ux" with x=[0..i] inside our menu
192 // which has set highest number x. So we can add another user entry.
193 sal_Int32
impl_getNextUserEntryNr() const
196 for( vector
< SvtDynMenuEntry
>::const_iterator pItem
=lUserEntries
.begin();
197 pItem
!=lUserEntries
.end() ;
200 if( pItem
->sName
.startsWith( PATHPREFIX_USER
) )
202 OUString sNr
= pItem
->sName
.copy( 1, pItem
->sName
.getLength()-1 );
203 sal_Int32 nCheckNr
= sNr
.toInt32();
208 // Attention: Code isn't prepared for recyling of unused fragmented numbers!
209 // If we reach end of sal_Int32 range ... we must stop further working ...
210 // But I think nobody expand a menu to more then 1000 ... 100000 ... entries ... or?
211 DBG_ASSERT( !(nNr
>0x7fffffff), "Menu::impl_getNextUserEntryNr()\nUser count can be out of range next time ...\n" );
216 vector
< SvtDynMenuEntry
> lSetupEntries
;
217 vector
< SvtDynMenuEntry
> lUserEntries
;
220 class SvtDynamicMenuOptions_Impl
: public ConfigItem
224 SvtDynamicMenuOptions_Impl();
225 ~SvtDynamicMenuOptions_Impl();
227 /*-****************************************************************************************************//**
228 @short called for notify of configmanager
229 @descr These method is called from the ConfigManager before application ends or from the
230 PropertyChangeListener if the sub tree broadcasts changes. You must update your
233 @seealso baseclass ConfigItem
235 @param "lPropertyNames" is the list of properties which should be updated.
239 *//*-*****************************************************************************************************/
241 virtual void Notify( const Sequence
< OUString
>& lPropertyNames
);
243 /*-****************************************************************************************************//**
244 @short write changes to configuration
245 @descr These method writes the changed values into the sub tree
246 and should always called in our destructor to guarantee consistency of config data.
248 @seealso baseclass ConfigItem
254 *//*-*****************************************************************************************************/
256 virtual void Commit();
258 /*-****************************************************************************************************//**
259 @short base implementation of public interface for "SvtDynamicMenuOptions"!
260 @descr These class is used as static member of "SvtDynamicMenuOptions" ...
261 => The code exist only for one time and isn't duplicated for every instance!
269 *//*-*****************************************************************************************************/
271 Sequence
< Sequence
< PropertyValue
> > GetMenu ( EDynamicMenuType eMenu
) const ;
275 /*-****************************************************************************************************//**
276 @short return list of key names of our configuration management which represent oue module tree
277 @descr These methods return the current list of key names! We need it to get needed values from our
278 configuration management and support dynamical menu item lists!
282 @param "nNewCount" , returns count of menu entries for "new"
283 @param "nWizardCount" , returns count of menu entries for "wizard"
284 @return A list of configuration key names is returned.
287 *//*-*****************************************************************************************************/
289 Sequence
< OUString
> impl_GetPropertyNames( sal_uInt32
& nNewCount
, sal_uInt32
& nWizardCount
, sal_uInt32
& nHelpBookmarksCount
);
291 /*-****************************************************************************************************//**
292 @short sort given source list and expand it for all well known properties to destination
293 @descr We must support sets of entries with count inside the name .. but some of them could be missing!
294 e.g. s1-s2-s3-s0-u1-s6-u5-u7
295 Then we must sort it by name and expand it to the follow one:
313 Rules: We start with all setup written entries names "sx" and x=[0..n].
314 Then we handle all "ux" items. Inside these blocks we sort it ascending by number.
316 @attention We add these expanded list to the end of given "lDestination" list!
317 So we must start on "lDestination.getLength()".
318 Reallocation of memory of destination list is done by us!
320 @seealso method impl_GetPropertyNames()
322 @param "lSource" , original list (e.g. [m1-m2-m3-m6-m0] )
323 @param "lDestination" , destination of operation
324 @param "sSetNode" , name of configuration set to build complete path
325 @return A list of configuration key names is returned.
328 *//*-*****************************************************************************************************/
330 void impl_SortAndExpandPropertyNames( const Sequence
< OUString
>& lSource
,
331 Sequence
< OUString
>& lDestination
,
332 const OUString
& sSetNode
);
334 //-------------------------------------------------------------------------------------------------------------
336 //-------------------------------------------------------------------------------------------------------------
340 SvtDynMenu m_aNewMenu
;
341 SvtDynMenu m_aWizardMenu
;
342 SvtDynMenu m_aHelpBookmarksMenu
;
345 //*****************************************************************************************************************
347 //*****************************************************************************************************************
348 SvtDynamicMenuOptions_Impl::SvtDynamicMenuOptions_Impl()
349 // Init baseclasses first
350 : ConfigItem( ROOTNODE_MENUS
)
351 // Init member then...
353 // Get names and values of all accessible menu entries and fill internal structures.
354 // See impl_GetPropertyNames() for further information.
355 sal_uInt32 nNewCount
= 0;
356 sal_uInt32 nWizardCount
= 0;
357 sal_uInt32 nHelpBookmarksCount
= 0;
358 Sequence
< OUString
> lNames
= impl_GetPropertyNames ( nNewCount
,
360 nHelpBookmarksCount
);
361 Sequence
< Any
> lValues
= GetProperties ( lNames
);
363 // Safe impossible cases.
364 // We need values from ALL configuration keys.
365 // Follow assignment use order of values in relation to our list of key names!
366 DBG_ASSERT( !(lNames
.getLength()!=lValues
.getLength()), "SvtDynamicMenuOptions_Impl::SvtDynamicMenuOptions_Impl()\nI miss some values of configuration keys!\n" );
368 // Copy values from list in right order to ouer internal member.
369 // Attention: List for names and values have an internal construction pattern!
371 // first "New" menu ...
373 // /New/1/URL "private:factory/swriter"
374 // /New/1/Title "Neues Writer Dokument"
375 // /New/1/ImageIdentifier "icon_writer"
376 // /New/1/TargetName "_blank"
378 // /New/2/URL "private:factory/scalc"
379 // /New/2/Title "Neues Calc Dokument"
380 // /New/2/ImageIdentifier "icon_calc"
381 // /New/2/TargetName "_blank"
383 // second "Wizard" menu ...
384 // /Wizard/1/URL "file://b"
385 // /Wizard/1/Title "MalWas"
386 // /Wizard/1/ImageIdentifier "icon_?"
387 // /Wizard/1/TargetName "_self"
391 sal_uInt32 nItem
= 0 ;
392 sal_uInt32 nPosition
= 0 ;
394 // Get names/values for new menu.
395 // 4 subkeys for every item!
396 for( nItem
=0; nItem
<nNewCount
; ++nItem
)
398 SvtDynMenuEntry aItem
;
399 lValues
[nPosition
] >>= aItem
.sURL
;
401 lValues
[nPosition
] >>= aItem
.sTitle
;
403 lValues
[nPosition
] >>= aItem
.sImageIdentifier
;
405 lValues
[nPosition
] >>= aItem
.sTargetName
;
407 m_aNewMenu
.AppendSetupEntry( aItem
);
410 // Attention: Don't reset nPosition here!
412 // Get names/values for wizard menu.
413 // 4 subkeys for every item!
414 for( nItem
=0; nItem
<nWizardCount
; ++nItem
)
416 SvtDynMenuEntry aItem
;
417 lValues
[nPosition
] >>= aItem
.sURL
;
419 lValues
[nPosition
] >>= aItem
.sTitle
;
421 lValues
[nPosition
] >>= aItem
.sImageIdentifier
;
423 lValues
[nPosition
] >>= aItem
.sTargetName
;
425 m_aWizardMenu
.AppendSetupEntry( aItem
);
428 // Attention: Don't reset nPosition here!
430 // Get names/values for wizard menu.
431 // 4 subkeys for every item!
432 for( nItem
=0; nItem
<nHelpBookmarksCount
; ++nItem
)
434 SvtDynMenuEntry aItem
;
435 lValues
[nPosition
] >>= aItem
.sURL
;
437 lValues
[nPosition
] >>= aItem
.sTitle
;
439 lValues
[nPosition
] >>= aItem
.sImageIdentifier
;
441 lValues
[nPosition
] >>= aItem
.sTargetName
;
443 m_aHelpBookmarksMenu
.AppendSetupEntry( aItem
);
446 /*TODO: Not used in the moment! see Notify() ...
447 // Enable notification mechanism of ouer baseclass.
448 // We need it to get information about changes outside these class on ouer used configuration keys!
449 EnableNotification( lNames );
453 //*****************************************************************************************************************
455 //*****************************************************************************************************************
456 SvtDynamicMenuOptions_Impl::~SvtDynamicMenuOptions_Impl()
458 // We must save our current values .. if user forget it!
459 if( IsModified() == sal_True
)
465 //*****************************************************************************************************************
467 //*****************************************************************************************************************
468 void SvtDynamicMenuOptions_Impl::Notify( const Sequence
< OUString
>& )
470 DBG_ASSERT( sal_False
, "SvtDynamicMenuOptions_Impl::Notify()\nNot implemented yet! I don't know how I can handle a dynamical list of unknown properties ...\n" );
473 //*****************************************************************************************************************
475 //*****************************************************************************************************************
476 void SvtDynamicMenuOptions_Impl::Commit()
478 OSL_FAIL( "SvtDynamicMenuOptions_Impl::Commit()\nNot implemented yet!\n" );
480 // Write all properties!
481 // Delete complete sets first.
482 ClearNodeSet( SETNODE_NEWMENU );
483 ClearNodeSet( SETNODE_WIZARDMENU );
484 ClearNodeSet( SETNODE_HELPBOOKMARKS );
488 Sequence< PropertyValue > lPropertyValues( PROPERTYCOUNT );
489 sal_uInt32 nItem = 0 ;
491 // Copy "new" menu entries to save-list!
492 sal_uInt32 nNewCount = m_aNewMenu.size();
493 for( nItem=0; nItem<nNewCount; ++nItem )
495 aItem = m_aNewMenu[nItem];
496 // Format: "New/1/URL"
499 sNode = SETNODE_NEWMENU + PATHDELIMITER + PATHPREFIX + OUString::valueOf( (sal_Int32)nItem ) + PATHDELIMITER;
501 lPropertyValues[OFFSET_URL ].Name = sNode + PROPERTYNAME_URL ;
502 lPropertyValues[OFFSET_TITLE ].Name = sNode + PROPERTYNAME_TITLE ;
503 lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Name = sNode + PROPERTYNAME_IMAGEIDENTIFIER ;
504 lPropertyValues[OFFSET_TARGETNAME ].Name = sNode + PROPERTYNAME_TARGETNAME ;
506 lPropertyValues[OFFSET_URL ].Value <<= aItem.sURL ;
507 lPropertyValues[OFFSET_TITLE ].Value <<= aItem.sTitle ;
508 lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Value <<= aItem.sImageIdentifier ;
509 lPropertyValues[OFFSET_TARGETNAME ].Value <<= aItem.sTargetName ;
511 SetSetProperties( SETNODE_NEWMENU, lPropertyValues );
514 // Copy "wizard" menu entries to save-list!
515 sal_uInt32 nWizardCount = m_aWizardMenu.size();
516 for( nItem=0; nItem<nWizardCount; ++nItem )
518 aItem = m_aWizardMenu[nItem];
519 // Format: "Wizard/1/URL"
522 sNode = SETNODE_WIZARDMENU + PATHDELIMITER + PATHPREFIX + OUString::valueOf( (sal_Int32)nItem ) + PATHDELIMITER;
524 lPropertyValues[OFFSET_URL ].Name = sNode + PROPERTYNAME_URL ;
525 lPropertyValues[OFFSET_TITLE ].Name = sNode + PROPERTYNAME_TITLE ;
526 lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Name = sNode + PROPERTYNAME_IMAGEIDENTIFIER ;
527 lPropertyValues[OFFSET_TARGETNAME ].Name = sNode + PROPERTYNAME_TARGETNAME ;
529 lPropertyValues[OFFSET_URL ].Value <<= aItem.sURL ;
530 lPropertyValues[OFFSET_TITLE ].Value <<= aItem.sTitle ;
531 lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Value <<= aItem.sImageIdentifier ;
532 lPropertyValues[OFFSET_TARGETNAME ].Value <<= aItem.sTargetName ;
534 SetSetProperties( SETNODE_WIZARDMENU, lPropertyValues );
537 // Copy help bookmarks entries to save-list!
538 sal_uInt32 nHelpBookmarksCount = m_aHelpBookmarksMenu.size();
539 for( nItem=0; nItem<nHelpBookmarksCount; ++nItem )
541 aItem = m_aHelpBookmarksMenu[nItem];
542 // Format: "HelpBookmarks/1/URL"
543 // "HelpBookmarks/1/Title"
545 sNode = SETNODE_HELPBOOKMARKS + PATHDELIMITER + PATHPREFIX + OUString::valueOf( (sal_Int32)nItem ) + PATHDELIMITER;
547 lPropertyValues[OFFSET_URL ].Name = sNode + PROPERTYNAME_URL ;
548 lPropertyValues[OFFSET_TITLE ].Name = sNode + PROPERTYNAME_TITLE ;
549 lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Name = sNode + PROPERTYNAME_IMAGEIDENTIFIER ;
550 lPropertyValues[OFFSET_TARGETNAME ].Name = sNode + PROPERTYNAME_TARGETNAME ;
552 lPropertyValues[OFFSET_URL ].Value <<= aItem.sURL ;
553 lPropertyValues[OFFSET_TITLE ].Value <<= aItem.sTitle ;
554 lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Value <<= aItem.sImageIdentifier ;
555 lPropertyValues[OFFSET_TARGETNAME ].Value <<= aItem.sTargetName ;
557 SetSetProperties( SETNODE_HELPBOOKMARKS, lPropertyValues );
562 //*****************************************************************************************************************
564 //*****************************************************************************************************************
565 Sequence
< Sequence
< PropertyValue
> > SvtDynamicMenuOptions_Impl::GetMenu( EDynamicMenuType eMenu
) const
567 Sequence
< Sequence
< PropertyValue
> > lReturn
;
571 lReturn
= m_aNewMenu
.GetList();
575 case E_WIZARDMENU
: {
576 lReturn
= m_aWizardMenu
.GetList();
580 case E_HELPBOOKMARKS
: {
581 lReturn
= m_aHelpBookmarksMenu
.GetList();
588 //*****************************************************************************************************************
590 //*****************************************************************************************************************
591 Sequence
< OUString
> SvtDynamicMenuOptions_Impl::impl_GetPropertyNames( sal_uInt32
& nNewCount
, sal_uInt32
& nWizardCount
, sal_uInt32
& nHelpBookmarksCount
)
593 // First get ALL names of current existing list items in configuration!
594 Sequence
< OUString
> lNewItems
= GetNodeNames( SETNODE_NEWMENU
);
595 Sequence
< OUString
> lWizardItems
= GetNodeNames( SETNODE_WIZARDMENU
);
596 Sequence
< OUString
> lHelpBookmarksItems
= GetNodeNames( SETNODE_HELPBOOKMARKS
);
598 // Get information about list counts ...
599 nNewCount
= lNewItems
.getLength ();
600 nWizardCount
= lWizardItems
.getLength ();
601 nHelpBookmarksCount
= lHelpBookmarksItems
.getLength();
603 // Sort and expand all three list to result list ...
604 Sequence
< OUString
> lProperties
;
605 impl_SortAndExpandPropertyNames( lNewItems
, lProperties
, SETNODE_NEWMENU
);
606 impl_SortAndExpandPropertyNames( lWizardItems
, lProperties
, SETNODE_WIZARDMENU
);
607 impl_SortAndExpandPropertyNames( lHelpBookmarksItems
, lProperties
, SETNODE_HELPBOOKMARKS
);
613 //*****************************************************************************************************************
615 //*****************************************************************************************************************
616 class CountWithPrefixSort
619 int operator() ( const OUString
& s1
,
620 const OUString
& s2
) const
622 // Get order numbers from entry name without prefix.
625 sal_Int32 n1
= s1
.copy( 1, s1
.getLength()-1 ).toInt32();
626 sal_Int32 n2
= s2
.copy( 1, s2
.getLength()-1 ).toInt32();
627 // MUST be in [0,1] ... because it's a difference between
628 // insert-positions of given entries in sorted list!
636 bool operator() ( const OUString
& s
) const
638 // Prefer setup written entries by check first letter of given string. It must be a "s".
639 return( s
.indexOf( PATHPREFIX_SETUP
) == 0 );
643 //*****************************************************************************************************************
645 //*****************************************************************************************************************
646 void SvtDynamicMenuOptions_Impl::impl_SortAndExpandPropertyNames( const Sequence
< OUString
>& lSource
,
647 Sequence
< OUString
>& lDestination
,
648 const OUString
& sSetNode
)
651 vector
< OUString
> lTemp
;
652 sal_Int32 nSourceCount
= lSource
.getLength() ;
653 sal_Int32 nDestinationStep
= lDestination
.getLength() ; // start on end of current list ...!
655 lDestination
.realloc( (nSourceCount
*PROPERTYCOUNT
)+nDestinationStep
); // get enough memory for copy operations after nDestination ...
657 // Copy all items to temp. vector to use fast sort operations :-)
658 for( sal_Int32 nSourceStep
=0; nSourceStep
<nSourceCount
; ++nSourceStep
)
659 lTemp
.push_back( lSource
[nSourceStep
] );
661 // Sort all entries by number ...
662 stable_sort( lTemp
.begin(), lTemp
.end(), CountWithPrefixSort() );
663 // and split into setup & user written entries!
664 stable_partition( lTemp
.begin(), lTemp
.end(), SelectByPrefix() );
666 // Copy sorted entries to destination and expand every item with
667 // 4 supported sub properties.
668 for( vector
< OUString
>::const_iterator pItem
=lTemp
.begin() ;
672 sFixPath
= sSetNode
;
673 sFixPath
+= PATHDELIMITER
;
675 sFixPath
+= PATHDELIMITER
;
677 lDestination
[nDestinationStep
] = sFixPath
;
678 lDestination
[nDestinationStep
] += PROPERTYNAME_URL
;
680 lDestination
[nDestinationStep
] = sFixPath
;
681 lDestination
[nDestinationStep
] += PROPERTYNAME_TITLE
;
683 lDestination
[nDestinationStep
] = sFixPath
;
684 lDestination
[nDestinationStep
] += PROPERTYNAME_IMAGEIDENTIFIER
;
686 lDestination
[nDestinationStep
] = sFixPath
;
687 lDestination
[nDestinationStep
] += PROPERTYNAME_TARGETNAME
;
692 //*****************************************************************************************************************
693 // initialize static member
694 // DON'T DO IT IN YOUR HEADER!
695 // see definition for further information
696 //*****************************************************************************************************************
697 SvtDynamicMenuOptions_Impl
* SvtDynamicMenuOptions::m_pDataContainer
= NULL
;
698 sal_Int32
SvtDynamicMenuOptions::m_nRefCount
= 0 ;
700 //*****************************************************************************************************************
702 //*****************************************************************************************************************
703 SvtDynamicMenuOptions::SvtDynamicMenuOptions()
705 // Global access, must be guarded (multithreading!).
706 MutexGuard
aGuard( GetOwnStaticMutex() );
707 // Increase ouer refcount ...
709 // ... and initialize ouer data container only if it not already exist!
710 if( m_pDataContainer
== NULL
)
712 m_pDataContainer
= new SvtDynamicMenuOptions_Impl
;
713 ItemHolder1::holdConfigItem(E_DYNAMICMENUOPTIONS
);
717 //*****************************************************************************************************************
719 //*****************************************************************************************************************
720 SvtDynamicMenuOptions::~SvtDynamicMenuOptions()
722 // Global access, must be guarded (multithreading!)
723 MutexGuard
aGuard( GetOwnStaticMutex() );
724 // Decrease ouer refcount.
726 // If last instance was deleted ...
727 // we must destroy ouer static data container!
728 if( m_nRefCount
<= 0 )
730 delete m_pDataContainer
;
731 m_pDataContainer
= NULL
;
735 //*****************************************************************************************************************
737 //*****************************************************************************************************************
738 Sequence
< Sequence
< PropertyValue
> > SvtDynamicMenuOptions::GetMenu( EDynamicMenuType eMenu
) const
740 MutexGuard
aGuard( GetOwnStaticMutex() );
741 return m_pDataContainer
->GetMenu( eMenu
);
746 class theDynamicMenuOptionsMutex
: public rtl::Static
<osl::Mutex
, theDynamicMenuOptionsMutex
>{};
749 //*****************************************************************************************************************
751 //*****************************************************************************************************************
752 Mutex
& SvtDynamicMenuOptions::GetOwnStaticMutex()
754 return theDynamicMenuOptionsMutex::get();
757 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */