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: dynamicmenuoptions.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"
36 //_________________________________________________________________________________________________________________
38 //_________________________________________________________________________________________________________________
40 #include <svtools/dynamicmenuoptions.hxx>
41 #include <svtools/moduleoptions.hxx>
42 #include <unotools/configmgr.hxx>
43 #include <unotools/configitem.hxx>
44 #include <tools/debug.hxx>
45 #include <com/sun/star/uno/Any.hxx>
46 #include <com/sun/star/uno/Sequence.hxx>
48 #ifndef __SGI_STL_VECTOR
52 #include <itemholder1.hxx>
56 //_________________________________________________________________________________________________________________
58 //_________________________________________________________________________________________________________________
60 using namespace ::std
;
61 using namespace ::utl
;
62 using namespace ::rtl
;
63 using namespace ::osl
;
64 using namespace ::com::sun::star::uno
;
65 using namespace ::com::sun::star::beans
;
67 //_________________________________________________________________________________________________________________
69 //_________________________________________________________________________________________________________________
71 #define ROOTNODE_MENUS OUString(RTL_CONSTASCII_USTRINGPARAM("Office.Common/Menus/" ))
72 #define PATHDELIMITER OUString(RTL_CONSTASCII_USTRINGPARAM("/" ))
74 #define SETNODE_NEWMENU OUString(RTL_CONSTASCII_USTRINGPARAM("New" ))
75 #define SETNODE_WIZARDMENU OUString(RTL_CONSTASCII_USTRINGPARAM("Wizard" ))
76 #define SETNODE_HELPBOOKMARKS OUString(RTL_CONSTASCII_USTRINGPARAM("HelpBookmarks" ))
78 #define PROPERTYNAME_URL DYNAMICMENU_PROPERTYNAME_URL
79 #define PROPERTYNAME_TITLE DYNAMICMENU_PROPERTYNAME_TITLE
80 #define PROPERTYNAME_IMAGEIDENTIFIER DYNAMICMENU_PROPERTYNAME_IMAGEIDENTIFIER
81 #define PROPERTYNAME_TARGETNAME DYNAMICMENU_PROPERTYNAME_TARGETNAME
83 #define PROPERTYCOUNT 4
86 #define OFFSET_TITLE 1
87 #define OFFSET_IMAGEIDENTIFIER 2
88 #define OFFSET_TARGETNAME 3
90 #define PATHPREFIX_SETUP OUString(RTL_CONSTASCII_USTRINGPARAM("m" ))
91 #define PATHPREFIX_USER OUString(RTL_CONSTASCII_USTRINGPARAM("u" ))
93 //_________________________________________________________________________________________________________________
94 // private declarations!
95 //_________________________________________________________________________________________________________________
97 /*-****************************************************************************************************************
98 @descr struct to hold information about one menu entry.
99 ****************************************************************************************************************-*/
100 struct SvtDynMenuEntry
103 SvtDynMenuEntry() {};
105 SvtDynMenuEntry( const OUString
& sNewURL
,
106 const OUString
& sNewTitle
,
107 const OUString
& sNewImageIdentifier
,
108 const OUString
& sNewTargetName
)
112 sImageIdentifier
= sNewImageIdentifier
;
113 sTargetName
= sNewTargetName
;
120 OUString sImageIdentifier
;
121 OUString sTargetName
;
124 /*-****************************************************************************************************************
125 @descr support simple menu structures and operations on it
126 ****************************************************************************************************************-*/
130 //---------------------------------------------------------------------------------------------------------
131 // append setup written menu entry
132 // Don't touch name of entry. It was defined by setup and must be the same everytime!
133 // Look for double menu entries here too ... may be some seperator items are supeflous ...
134 void AppendSetupEntry( const SvtDynMenuEntry
& rEntry
)
137 ( lSetupEntries
.size() < 1 ) ||
138 ( lSetupEntries
.rbegin()->sURL
!= rEntry
.sURL
)
141 lSetupEntries
.push_back( rEntry
);
145 //---------------------------------------------------------------------------------------------------------
146 // append user specific menu entry
147 // We must find unique name for it by using special prefix
148 // and next count of user setted entries!
149 // Look for double menu entries here too ... may be some seperator items are supeflous ...
150 void AppendUserEntry( SvtDynMenuEntry
& rEntry
)
153 ( lUserEntries
.size() < 1 ) ||
154 ( lUserEntries
.rbegin()->sURL
!= rEntry
.sURL
)
157 rEntry
.sName
= PATHPREFIX_USER
;
158 rEntry
.sName
+= OUString::valueOf( (sal_Int32
)impl_getNextUserEntryNr() );
159 lUserEntries
.push_back( rEntry
);
163 //---------------------------------------------------------------------------------------------------------
164 // the only way to free memory!
167 lSetupEntries
.clear();
168 lUserEntries
.clear();
171 //---------------------------------------------------------------------------------------------------------
172 // convert internal list to external format
173 // for using it on right menus realy
174 // Notice: We build a property list with 4 entries and set it on result list then.
175 // The while-loop starts with pointer on internal member list lSetupEntries, change to
176 // lUserEntries then and stop after that with NULL!
177 // Separator entries will be packed in another way then normal entries! We define
178 // special strings "sEmpty" and "sSeperator" to perform too ...
179 Sequence
< Sequence
< PropertyValue
> > GetList() const
181 sal_Int32 nSetupCount
= (sal_Int32
)lSetupEntries
.size();
182 sal_Int32 nUserCount
= (sal_Int32
)lUserEntries
.size();
184 Sequence
< PropertyValue
> lProperties ( PROPERTYCOUNT
);
185 Sequence
< Sequence
< PropertyValue
> > lResult ( nSetupCount
+nUserCount
);
186 OUString
sSeperator ( RTL_CONSTASCII_USTRINGPARAM("private:separator") );
188 const vector
< SvtDynMenuEntry
>* pList
= &lSetupEntries
;
190 lProperties
[OFFSET_URL
].Name
= PROPERTYNAME_URL
;
191 lProperties
[OFFSET_TITLE
].Name
= PROPERTYNAME_TITLE
;
192 lProperties
[OFFSET_IMAGEIDENTIFIER
].Name
= PROPERTYNAME_IMAGEIDENTIFIER
;
193 lProperties
[OFFSET_TARGETNAME
].Name
= PROPERTYNAME_TARGETNAME
;
195 while( pList
!= NULL
)
197 for( vector
< SvtDynMenuEntry
>::const_iterator pItem
=pList
->begin();
198 pItem
!=pList
->end() ;
201 if( pItem
->sURL
== sSeperator
)
203 lProperties
[OFFSET_URL
].Value
<<= sSeperator
;
204 lProperties
[OFFSET_TITLE
].Value
<<= sEmpty
;
205 lProperties
[OFFSET_IMAGEIDENTIFIER
].Value
<<= sEmpty
;
206 lProperties
[OFFSET_TARGETNAME
].Value
<<= sEmpty
;
210 lProperties
[OFFSET_URL
].Value
<<= pItem
->sURL
;
211 lProperties
[OFFSET_TITLE
].Value
<<= pItem
->sTitle
;
212 lProperties
[OFFSET_IMAGEIDENTIFIER
].Value
<<= pItem
->sImageIdentifier
;
213 lProperties
[OFFSET_TARGETNAME
].Value
<<= pItem
->sTargetName
;
215 lResult
[nStep
] = lProperties
;
218 if( pList
== &lSetupEntries
)
219 pList
= &lUserEntries
;
227 //---------------------------------------------------------------------------------------------------------
228 // search for an entry named "ux" with x=[0..i] inside our menu
229 // which has set highest number x. So we can add another user entry.
230 sal_Int32
impl_getNextUserEntryNr() const
233 for( vector
< SvtDynMenuEntry
>::const_iterator pItem
=lUserEntries
.begin();
234 pItem
!=lUserEntries
.end() ;
237 if( pItem
->sName
.compareTo( PATHPREFIX_USER
, 1 ) == 0 )
239 OUString sNr
= pItem
->sName
.copy( 1, pItem
->sName
.getLength()-1 );
240 sal_Int32 nCheckNr
= sNr
.toInt32();
245 // Attention: Code isn't prepared for recyling of unused fragmented numbers!
246 // If we reach end of sal_Int32 range ... we must stop further working ...
247 // But I think nobody expand a menu to more then 1000 ... 100000 ... entries ... or?
248 DBG_ASSERT( !(nNr
>0x7fffffff), "Menu::impl_getNextUserEntryNr()\nUser count can be out of range next time ...\n" );
253 vector
< SvtDynMenuEntry
> lSetupEntries
;
254 vector
< SvtDynMenuEntry
> lUserEntries
;
257 class SvtDynamicMenuOptions_Impl
: public ConfigItem
259 //-------------------------------------------------------------------------------------------------------------
261 //-------------------------------------------------------------------------------------------------------------
265 //---------------------------------------------------------------------------------------------------------
266 // constructor / destructor
267 //---------------------------------------------------------------------------------------------------------
269 SvtDynamicMenuOptions_Impl();
270 ~SvtDynamicMenuOptions_Impl();
272 //---------------------------------------------------------------------------------------------------------
273 // overloaded methods of baseclass
274 //---------------------------------------------------------------------------------------------------------
276 /*-****************************************************************************************************//**
277 @short called for notify of configmanager
278 @descr These method is called from the ConfigManager before application ends or from the
279 PropertyChangeListener if the sub tree broadcasts changes. You must update your
282 @seealso baseclass ConfigItem
284 @param "lPropertyNames" is the list of properties which should be updated.
288 *//*-*****************************************************************************************************/
290 virtual void Notify( const Sequence
< OUString
>& lPropertyNames
);
292 /*-****************************************************************************************************//**
293 @short write changes to configuration
294 @descr These method writes the changed values into the sub tree
295 and should always called in our destructor to guarantee consistency of config data.
297 @seealso baseclass ConfigItem
303 *//*-*****************************************************************************************************/
305 virtual void Commit();
307 //---------------------------------------------------------------------------------------------------------
309 //---------------------------------------------------------------------------------------------------------
311 /*-****************************************************************************************************//**
312 @short base implementation of public interface for "SvtDynamicMenuOptions"!
313 @descr These class is used as static member of "SvtDynamicMenuOptions" ...
314 => The code exist only for one time and isn't duplicated for every instance!
322 *//*-*****************************************************************************************************/
324 void Clear ( EDynamicMenuType eMenu
);
325 Sequence
< Sequence
< PropertyValue
> > GetMenu ( EDynamicMenuType eMenu
) const ;
326 void AppendItem ( EDynamicMenuType eMenu
,
327 const OUString
& sURL
,
328 const OUString
& sTitle
,
329 const OUString
& sImageIdentifier
,
330 const OUString
& sTargetName
);
332 //-------------------------------------------------------------------------------------------------------------
334 //-------------------------------------------------------------------------------------------------------------
338 /*-****************************************************************************************************//**
339 @short return list of key names of our configuration management which represent oue module tree
340 @descr These methods return the current list of key names! We need it to get needed values from our
341 configuration management and support dynamical menu item lists!
345 @param "nNewCount" , returns count of menu entries for "new"
346 @param "nWizardCount" , returns count of menu entries for "wizard"
347 @return A list of configuration key names is returned.
350 *//*-*****************************************************************************************************/
352 Sequence
< OUString
> impl_GetPropertyNames( sal_uInt32
& nNewCount
, sal_uInt32
& nWizardCount
, sal_uInt32
& nHelpBookmarksCount
);
354 /*-****************************************************************************************************//**
355 @short sort given source list and expand it for all well known properties to destination
356 @descr We must support sets of entries with count inside the name .. but some of them could be missing!
357 e.g. s1-s2-s3-s0-u1-s6-u5-u7
358 Then we must sort it by name and expand it to the follow one:
376 Rules: We start with all setup written entries names "sx" and x=[0..n].
377 Then we handle all "ux" items. Inside these blocks we sort it ascending by number.
379 @attention We add these expanded list to the end of given "lDestination" list!
380 So we must start on "lDestination.getLength()".
381 Reallocation of memory of destination list is done by us!
383 @seealso method impl_GetPropertyNames()
385 @param "lSource" , original list (e.g. [m1-m2-m3-m6-m0] )
386 @param "lDestination" , destination of operation
387 @param "sSetNode" , name of configuration set to build complete path
388 @return A list of configuration key names is returned.
391 *//*-*****************************************************************************************************/
393 void impl_SortAndExpandPropertyNames( const Sequence
< OUString
>& lSource
,
394 Sequence
< OUString
>& lDestination
,
395 const OUString
& sSetNode
);
397 //-------------------------------------------------------------------------------------------------------------
399 //-------------------------------------------------------------------------------------------------------------
403 SvtDynMenu m_aNewMenu
;
404 SvtDynMenu m_aWizardMenu
;
405 SvtDynMenu m_aHelpBookmarksMenu
;
408 //_________________________________________________________________________________________________________________
410 //_________________________________________________________________________________________________________________
412 //*****************************************************************************************************************
414 //*****************************************************************************************************************
415 SvtDynamicMenuOptions_Impl::SvtDynamicMenuOptions_Impl()
416 // Init baseclasses first
417 : ConfigItem( ROOTNODE_MENUS
)
418 // Init member then...
420 // Get names and values of all accessable menu entries and fill internal structures.
421 // See impl_GetPropertyNames() for further informations.
422 sal_uInt32 nNewCount
= 0;
423 sal_uInt32 nWizardCount
= 0;
424 sal_uInt32 nHelpBookmarksCount
= 0;
425 Sequence
< OUString
> lNames
= impl_GetPropertyNames ( nNewCount
,
427 nHelpBookmarksCount
);
428 Sequence
< Any
> lValues
= GetProperties ( lNames
);
430 // Safe impossible cases.
431 // We need values from ALL configuration keys.
432 // Follow assignment use order of values in relation to our list of key names!
433 DBG_ASSERT( !(lNames
.getLength()!=lValues
.getLength()), "SvtDynamicMenuOptions_Impl::SvtDynamicMenuOptions_Impl()\nI miss some values of configuration keys!\n" );
435 // Copy values from list in right order to ouer internal member.
436 // Attention: List for names and values have an internal construction pattern!
438 // first "New" menu ...
440 // /New/1/URL "private:factory/swriter"
441 // /New/1/Title "Neues Writer Dokument"
442 // /New/1/ImageIdentifier "icon_writer"
443 // /New/1/TargetName "_blank"
445 // /New/2/URL "private:factory/scalc"
446 // /New/2/Title "Neues Calc Dokument"
447 // /New/2/ImageIdentifier "icon_calc"
448 // /New/2/TargetName "_blank"
450 // second "Wizard" menu ...
451 // /Wizard/1/URL "file://b"
452 // /Wizard/1/Title "MalWas"
453 // /Wizard/1/ImageIdentifier "icon_?"
454 // /Wizard/1/TargetName "_self"
458 sal_uInt32 nItem
= 0 ;
459 sal_uInt32 nPosition
= 0 ;
462 // We must use these one instance object(!) to get information about installed modules.
463 // These information are used to filter menu entries wich need not installed modules ...
464 // Such entries shouldnt be available then!
465 // see impl_IsEntrySupported() too
466 SvtModuleOptions aModuleOptions
;
468 // Get names/values for new menu.
469 // 4 subkeys for every item!
470 for( nItem
=0; nItem
<nNewCount
; ++nItem
)
472 SvtDynMenuEntry aItem
;
473 lValues
[nPosition
] >>= aItem
.sURL
;
475 lValues
[nPosition
] >>= aItem
.sTitle
;
477 lValues
[nPosition
] >>= aItem
.sImageIdentifier
;
479 lValues
[nPosition
] >>= aItem
.sTargetName
;
481 m_aNewMenu
.AppendSetupEntry( aItem
);
484 // Attention: Don't reset nPosition here!
486 // Get names/values for wizard menu.
487 // 4 subkeys for every item!
488 for( nItem
=0; nItem
<nWizardCount
; ++nItem
)
490 SvtDynMenuEntry aItem
;
491 lValues
[nPosition
] >>= aItem
.sURL
;
493 lValues
[nPosition
] >>= aItem
.sTitle
;
495 lValues
[nPosition
] >>= aItem
.sImageIdentifier
;
497 lValues
[nPosition
] >>= aItem
.sTargetName
;
499 m_aWizardMenu
.AppendSetupEntry( aItem
);
502 // Attention: Don't reset nPosition here!
504 // Get names/values for wizard menu.
505 // 4 subkeys for every item!
506 for( nItem
=0; nItem
<nHelpBookmarksCount
; ++nItem
)
508 SvtDynMenuEntry aItem
;
509 lValues
[nPosition
] >>= aItem
.sURL
;
511 lValues
[nPosition
] >>= aItem
.sTitle
;
513 lValues
[nPosition
] >>= aItem
.sImageIdentifier
;
515 lValues
[nPosition
] >>= aItem
.sTargetName
;
517 m_aHelpBookmarksMenu
.AppendSetupEntry( aItem
);
520 /*TODO: Not used in the moment! see Notify() ...
521 // Enable notification mechanism of ouer baseclass.
522 // We need it to get information about changes outside these class on ouer used configuration keys!
523 EnableNotification( lNames );
527 //*****************************************************************************************************************
529 //*****************************************************************************************************************
530 SvtDynamicMenuOptions_Impl::~SvtDynamicMenuOptions_Impl()
532 // We must save our current values .. if user forget it!
533 if( IsModified() == sal_True
)
539 //*****************************************************************************************************************
541 //*****************************************************************************************************************
542 void SvtDynamicMenuOptions_Impl::Notify( const Sequence
< OUString
>& )
544 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" );
547 //*****************************************************************************************************************
549 //*****************************************************************************************************************
550 void SvtDynamicMenuOptions_Impl::Commit()
552 DBG_ERROR( "SvtDynamicMenuOptions_Impl::Commit()\nNot implemented yet!\n" );
554 // Write all properties!
555 // Delete complete sets first.
556 ClearNodeSet( SETNODE_NEWMENU );
557 ClearNodeSet( SETNODE_WIZARDMENU );
558 ClearNodeSet( SETNODE_HELPBOOKMARKS );
562 Sequence< PropertyValue > lPropertyValues( PROPERTYCOUNT );
563 sal_uInt32 nItem = 0 ;
565 // Copy "new" menu entries to save-list!
566 sal_uInt32 nNewCount = m_aNewMenu.size();
567 for( nItem=0; nItem<nNewCount; ++nItem )
569 aItem = m_aNewMenu[nItem];
570 // Format: "New/1/URL"
573 sNode = SETNODE_NEWMENU + PATHDELIMITER + PATHPREFIX + OUString::valueOf( (sal_Int32)nItem ) + PATHDELIMITER;
575 lPropertyValues[OFFSET_URL ].Name = sNode + PROPERTYNAME_URL ;
576 lPropertyValues[OFFSET_TITLE ].Name = sNode + PROPERTYNAME_TITLE ;
577 lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Name = sNode + PROPERTYNAME_IMAGEIDENTIFIER ;
578 lPropertyValues[OFFSET_TARGETNAME ].Name = sNode + PROPERTYNAME_TARGETNAME ;
580 lPropertyValues[OFFSET_URL ].Value <<= aItem.sURL ;
581 lPropertyValues[OFFSET_TITLE ].Value <<= aItem.sTitle ;
582 lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Value <<= aItem.sImageIdentifier ;
583 lPropertyValues[OFFSET_TARGETNAME ].Value <<= aItem.sTargetName ;
585 SetSetProperties( SETNODE_NEWMENU, lPropertyValues );
588 // Copy "wizard" menu entries to save-list!
589 sal_uInt32 nWizardCount = m_aWizardMenu.size();
590 for( nItem=0; nItem<nWizardCount; ++nItem )
592 aItem = m_aWizardMenu[nItem];
593 // Format: "Wizard/1/URL"
596 sNode = SETNODE_WIZARDMENU + PATHDELIMITER + PATHPREFIX + OUString::valueOf( (sal_Int32)nItem ) + PATHDELIMITER;
598 lPropertyValues[OFFSET_URL ].Name = sNode + PROPERTYNAME_URL ;
599 lPropertyValues[OFFSET_TITLE ].Name = sNode + PROPERTYNAME_TITLE ;
600 lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Name = sNode + PROPERTYNAME_IMAGEIDENTIFIER ;
601 lPropertyValues[OFFSET_TARGETNAME ].Name = sNode + PROPERTYNAME_TARGETNAME ;
603 lPropertyValues[OFFSET_URL ].Value <<= aItem.sURL ;
604 lPropertyValues[OFFSET_TITLE ].Value <<= aItem.sTitle ;
605 lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Value <<= aItem.sImageIdentifier ;
606 lPropertyValues[OFFSET_TARGETNAME ].Value <<= aItem.sTargetName ;
608 SetSetProperties( SETNODE_WIZARDMENU, lPropertyValues );
611 // Copy help bookmarks entries to save-list!
612 sal_uInt32 nHelpBookmarksCount = m_aHelpBookmarksMenu.size();
613 for( nItem=0; nItem<nHelpBookmarksCount; ++nItem )
615 aItem = m_aHelpBookmarksMenu[nItem];
616 // Format: "HelpBookmarks/1/URL"
617 // "HelpBookmarks/1/Title"
619 sNode = SETNODE_HELPBOOKMARKS + PATHDELIMITER + PATHPREFIX + OUString::valueOf( (sal_Int32)nItem ) + PATHDELIMITER;
621 lPropertyValues[OFFSET_URL ].Name = sNode + PROPERTYNAME_URL ;
622 lPropertyValues[OFFSET_TITLE ].Name = sNode + PROPERTYNAME_TITLE ;
623 lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Name = sNode + PROPERTYNAME_IMAGEIDENTIFIER ;
624 lPropertyValues[OFFSET_TARGETNAME ].Name = sNode + PROPERTYNAME_TARGETNAME ;
626 lPropertyValues[OFFSET_URL ].Value <<= aItem.sURL ;
627 lPropertyValues[OFFSET_TITLE ].Value <<= aItem.sTitle ;
628 lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Value <<= aItem.sImageIdentifier ;
629 lPropertyValues[OFFSET_TARGETNAME ].Value <<= aItem.sTargetName ;
631 SetSetProperties( SETNODE_HELPBOOKMARKS, lPropertyValues );
636 //*****************************************************************************************************************
638 //*****************************************************************************************************************
639 void SvtDynamicMenuOptions_Impl::Clear( EDynamicMenuType eMenu
)
649 case E_WIZARDMENU
: {
650 m_aWizardMenu
.Clear();
655 case E_HELPBOOKMARKS
: {
656 m_aHelpBookmarksMenu
.Clear();
663 //*****************************************************************************************************************
665 //*****************************************************************************************************************
666 Sequence
< Sequence
< PropertyValue
> > SvtDynamicMenuOptions_Impl::GetMenu( EDynamicMenuType eMenu
) const
668 Sequence
< Sequence
< PropertyValue
> > lReturn
;
672 lReturn
= m_aNewMenu
.GetList();
676 case E_WIZARDMENU
: {
677 lReturn
= m_aWizardMenu
.GetList();
681 case E_HELPBOOKMARKS
: {
682 lReturn
= m_aHelpBookmarksMenu
.GetList();
689 //*****************************************************************************************************************
691 //*****************************************************************************************************************
692 void SvtDynamicMenuOptions_Impl::AppendItem( EDynamicMenuType eMenu
,
693 const OUString
& sURL
,
694 const OUString
& sTitle
,
695 const OUString
& sImageIdentifier
,
696 const OUString
& sTargetName
)
698 SvtDynMenuEntry
aItem( sURL
, sTitle
, sImageIdentifier
, sTargetName
);
703 m_aNewMenu
.AppendUserEntry( aItem
);
708 case E_WIZARDMENU
: {
709 m_aWizardMenu
.AppendUserEntry( aItem
);
714 case E_HELPBOOKMARKS
: {
715 m_aHelpBookmarksMenu
.AppendUserEntry( aItem
);
722 //*****************************************************************************************************************
724 //*****************************************************************************************************************
725 Sequence
< OUString
> SvtDynamicMenuOptions_Impl::impl_GetPropertyNames( sal_uInt32
& nNewCount
, sal_uInt32
& nWizardCount
, sal_uInt32
& nHelpBookmarksCount
)
727 // First get ALL names of current existing list items in configuration!
728 Sequence
< OUString
> lNewItems
= GetNodeNames( SETNODE_NEWMENU
);
729 Sequence
< OUString
> lWizardItems
= GetNodeNames( SETNODE_WIZARDMENU
);
730 Sequence
< OUString
> lHelpBookmarksItems
= GetNodeNames( SETNODE_HELPBOOKMARKS
);
732 // Get information about list counts ...
733 nNewCount
= lNewItems
.getLength ();
734 nWizardCount
= lWizardItems
.getLength ();
735 nHelpBookmarksCount
= lHelpBookmarksItems
.getLength();
737 // Sort and expand all three list to result list ...
738 Sequence
< OUString
> lProperties
;
739 impl_SortAndExpandPropertyNames( lNewItems
, lProperties
, SETNODE_NEWMENU
);
740 impl_SortAndExpandPropertyNames( lWizardItems
, lProperties
, SETNODE_WIZARDMENU
);
741 impl_SortAndExpandPropertyNames( lHelpBookmarksItems
, lProperties
, SETNODE_HELPBOOKMARKS
);
747 //*****************************************************************************************************************
749 //*****************************************************************************************************************
750 class CountWithPrefixSort
753 int operator() ( const OUString
& s1
,
754 const OUString
& s2
) const
756 // Get order numbers from entry name without prefix.
759 sal_Int32 n1
= s1
.copy( 1, s1
.getLength()-1 ).toInt32();
760 sal_Int32 n2
= s2
.copy( 1, s2
.getLength()-1 ).toInt32();
761 // MUST be in [0,1] ... because it's a difference between
762 // insert-positions of given entries in sorted list!
770 bool operator() ( const OUString
& s
) const
772 // Prefer setup written entries by check first letter of given string. It must be a "s".
773 return( s
.indexOf( PATHPREFIX_SETUP
) == 0 );
777 //*****************************************************************************************************************
779 //*****************************************************************************************************************
780 void SvtDynamicMenuOptions_Impl::impl_SortAndExpandPropertyNames( const Sequence
< OUString
>& lSource
,
781 Sequence
< OUString
>& lDestination
,
782 const OUString
& sSetNode
)
785 vector
< OUString
> lTemp
;
786 sal_Int32 nSourceCount
= lSource
.getLength() ;
787 sal_Int32 nDestinationStep
= lDestination
.getLength() ; // start on end of current list ...!
789 lDestination
.realloc( (nSourceCount
*PROPERTYCOUNT
)+nDestinationStep
); // get enough memory for copy operations after nDestination ...
791 // Copy all items to temp. vector to use fast sort operations :-)
792 for( sal_Int32 nSourceStep
=0; nSourceStep
<nSourceCount
; ++nSourceStep
)
793 lTemp
.push_back( lSource
[nSourceStep
] );
795 // Sort all entries by number ...
796 stable_sort( lTemp
.begin(), lTemp
.end(), CountWithPrefixSort() );
797 // and split into setup & user written entries!
798 stable_partition( lTemp
.begin(), lTemp
.end(), SelectByPrefix() );
800 // Copy sorted entries to destination and expand every item with
801 // 4 supported sub properties.
802 for( vector
< OUString
>::const_iterator pItem
=lTemp
.begin() ;
806 sFixPath
= sSetNode
;
807 sFixPath
+= PATHDELIMITER
;
809 sFixPath
+= PATHDELIMITER
;
811 lDestination
[nDestinationStep
] = sFixPath
;
812 lDestination
[nDestinationStep
] += PROPERTYNAME_URL
;
814 lDestination
[nDestinationStep
] = sFixPath
;
815 lDestination
[nDestinationStep
] += PROPERTYNAME_TITLE
;
817 lDestination
[nDestinationStep
] = sFixPath
;
818 lDestination
[nDestinationStep
] += PROPERTYNAME_IMAGEIDENTIFIER
;
820 lDestination
[nDestinationStep
] = sFixPath
;
821 lDestination
[nDestinationStep
] += PROPERTYNAME_TARGETNAME
;
826 //*****************************************************************************************************************
827 // initialize static member
828 // DON'T DO IT IN YOUR HEADER!
829 // see definition for further informations
830 //*****************************************************************************************************************
831 SvtDynamicMenuOptions_Impl
* SvtDynamicMenuOptions::m_pDataContainer
= NULL
;
832 sal_Int32
SvtDynamicMenuOptions::m_nRefCount
= 0 ;
834 //*****************************************************************************************************************
836 //*****************************************************************************************************************
837 SvtDynamicMenuOptions::SvtDynamicMenuOptions()
839 // Global access, must be guarded (multithreading!).
840 MutexGuard
aGuard( GetOwnStaticMutex() );
841 // Increase ouer refcount ...
843 // ... and initialize ouer data container only if it not already exist!
844 if( m_pDataContainer
== NULL
)
846 m_pDataContainer
= new SvtDynamicMenuOptions_Impl
;
847 ItemHolder1::holdConfigItem(E_DYNAMICMENUOPTIONS
);
851 //*****************************************************************************************************************
853 //*****************************************************************************************************************
854 SvtDynamicMenuOptions::~SvtDynamicMenuOptions()
856 // Global access, must be guarded (multithreading!)
857 MutexGuard
aGuard( GetOwnStaticMutex() );
858 // Decrease ouer refcount.
860 // If last instance was deleted ...
861 // we must destroy ouer static data container!
862 if( m_nRefCount
<= 0 )
864 delete m_pDataContainer
;
865 m_pDataContainer
= NULL
;
869 //*****************************************************************************************************************
871 //*****************************************************************************************************************
872 void SvtDynamicMenuOptions::Clear( EDynamicMenuType eMenu
)
874 MutexGuard
aGuard( GetOwnStaticMutex() );
875 m_pDataContainer
->Clear( eMenu
);
878 //*****************************************************************************************************************
880 //*****************************************************************************************************************
881 Sequence
< Sequence
< PropertyValue
> > SvtDynamicMenuOptions::GetMenu( EDynamicMenuType eMenu
) const
883 MutexGuard
aGuard( GetOwnStaticMutex() );
884 return m_pDataContainer
->GetMenu( eMenu
);
887 //*****************************************************************************************************************
889 //*****************************************************************************************************************
890 void SvtDynamicMenuOptions::AppendItem( EDynamicMenuType eMenu
,
891 const OUString
& sURL
,
892 const OUString
& sTitle
,
893 const OUString
& sImageIdentifier
,
894 const OUString
& sTargetName
)
896 MutexGuard
aGuard( GetOwnStaticMutex() );
897 m_pDataContainer
->AppendItem( eMenu
, sURL
, sTitle
, sImageIdentifier
, sTargetName
);
900 //*****************************************************************************************************************
902 //*****************************************************************************************************************
903 Mutex
& SvtDynamicMenuOptions::GetOwnStaticMutex()
905 // Initialize static mutex only for one time!
906 static Mutex
* pMutex
= NULL
;
907 // If these method first called (Mutex not already exist!) ...
910 // ... we must create a new one. Protect follow code with the global mutex -
911 // It must be - we create a static variable!
912 MutexGuard
aGuard( Mutex::getGlobalMutex() );
913 // We must check our pointer again - because it can be that another instance of ouer class will be fastr then these!
916 // Create the new mutex and set it for return on static variable.
921 // Return new created or already existing mutex object.