summaryrefslogtreecommitdiff
path: root/binfilter/bf_svtools/source/config/svt_dynamicmenuoptions.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'binfilter/bf_svtools/source/config/svt_dynamicmenuoptions.cxx')
-rw-r--r--binfilter/bf_svtools/source/config/svt_dynamicmenuoptions.cxx789
1 files changed, 789 insertions, 0 deletions
diff --git a/binfilter/bf_svtools/source/config/svt_dynamicmenuoptions.cxx b/binfilter/bf_svtools/source/config/svt_dynamicmenuoptions.cxx
new file mode 100644
index 000000000000..f0e50807ebc7
--- /dev/null
+++ b/binfilter/bf_svtools/source/config/svt_dynamicmenuoptions.cxx
@@ -0,0 +1,789 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+
+//_________________________________________________________________________________________________________________
+// includes
+//_________________________________________________________________________________________________________________
+
+#include <bf_svtools/dynamicmenuoptions.hxx>
+
+#include <bf_svtools/moduleoptions.hxx>
+
+#include <unotools/configmgr.hxx>
+
+#include <unotools/configitem.hxx>
+
+#include <tools/debug.hxx>
+
+#include <com/sun/star/uno/Any.hxx>
+
+#include <com/sun/star/uno/Sequence.hxx>
+
+#ifndef __SGI_STL_VECTOR
+#include <vector>
+#endif
+
+#include <itemholder1.hxx>
+
+#include <algorithm>
+
+//_________________________________________________________________________________________________________________
+// namespaces
+//_________________________________________________________________________________________________________________
+
+using namespace ::std ;
+using namespace ::utl ;
+using namespace ::rtl ;
+using namespace ::osl ;
+using namespace ::com::sun::star::uno ;
+using namespace ::com::sun::star::beans ;
+
+namespace binfilter
+{
+
+//_________________________________________________________________________________________________________________
+// const
+//_________________________________________________________________________________________________________________
+
+#define ROOTNODE_MENUS OUString(RTL_CONSTASCII_USTRINGPARAM("Office.Common/Menus/" ))
+#define PATHDELIMITER OUString(RTL_CONSTASCII_USTRINGPARAM("/" ))
+
+#define SETNODE_NEWMENU OUString(RTL_CONSTASCII_USTRINGPARAM("New" ))
+#define SETNODE_WIZARDMENU OUString(RTL_CONSTASCII_USTRINGPARAM("Wizard" ))
+#define SETNODE_HELPBOOKMARKS OUString(RTL_CONSTASCII_USTRINGPARAM("HelpBookmarks" ))
+
+#define PROPERTYNAME_URL DYNAMICMENU_PROPERTYNAME_URL
+#define PROPERTYNAME_TITLE DYNAMICMENU_PROPERTYNAME_TITLE
+#define PROPERTYNAME_IMAGEIDENTIFIER DYNAMICMENU_PROPERTYNAME_IMAGEIDENTIFIER
+#define PROPERTYNAME_TARGETNAME DYNAMICMENU_PROPERTYNAME_TARGETNAME
+
+#define PROPERTYCOUNT 4
+
+#define OFFSET_URL 0
+#define OFFSET_TITLE 1
+#define OFFSET_IMAGEIDENTIFIER 2
+#define OFFSET_TARGETNAME 3
+
+#define PATHPREFIX_SETUP OUString(RTL_CONSTASCII_USTRINGPARAM("m" ))
+#define PATHPREFIX_USER OUString(RTL_CONSTASCII_USTRINGPARAM("u" ))
+
+//_________________________________________________________________________________________________________________
+// private declarations!
+//_________________________________________________________________________________________________________________
+
+/*-****************************************************************************************************************
+ @descr struct to hold information about one menu entry.
+****************************************************************************************************************-*/
+struct SvtDynMenuEntry
+{
+ public:
+ SvtDynMenuEntry() {};
+
+ SvtDynMenuEntry( const OUString& sNewURL ,
+ const OUString& sNewTitle ,
+ const OUString& sNewImageIdentifier ,
+ const OUString& sNewTargetName )
+ {
+ sURL = sNewURL ;
+ sTitle = sNewTitle ;
+ sImageIdentifier = sNewImageIdentifier ;
+ sTargetName = sNewTargetName ;
+ }
+
+ public:
+ OUString sName ;
+ OUString sURL ;
+ OUString sTitle ;
+ OUString sImageIdentifier ;
+ OUString sTargetName ;
+};
+
+/*-****************************************************************************************************************
+ @descr support simple menu structures and operations on it
+****************************************************************************************************************-*/
+class SvtDynMenu
+{
+ public:
+ //---------------------------------------------------------------------------------------------------------
+ // append setup written menu entry
+ // Don't touch name of entry. It was defined by setup and must be the same everytime!
+ // Look for double menu entries here too ... may be some seperator items are supeflous ...
+ void AppendSetupEntry( const SvtDynMenuEntry& rEntry )
+ {
+ if(
+ ( lSetupEntries.size() < 1 ) ||
+ ( lSetupEntries.rbegin()->sURL != rEntry.sURL )
+ )
+ {
+ lSetupEntries.push_back( rEntry );
+ }
+ }
+
+ //---------------------------------------------------------------------------------------------------------
+ // append user specific menu entry
+ // We must find unique name for it by using special prefix
+ // and next count of user setted entries!
+ // Look for double menu entries here too ... may be some seperator items are supeflous ...
+ void AppendUserEntry( SvtDynMenuEntry& rEntry )
+ {
+ if(
+ ( lUserEntries.size() < 1 ) ||
+ ( lUserEntries.rbegin()->sURL != rEntry.sURL )
+ )
+ {
+ rEntry.sName = PATHPREFIX_USER;
+ rEntry.sName += OUString::valueOf( (sal_Int32)impl_getNextUserEntryNr() );
+ lUserEntries.push_back( rEntry );
+ }
+ }
+
+ //---------------------------------------------------------------------------------------------------------
+ // the only way to free memory!
+ void Clear()
+ {
+ lSetupEntries.clear();
+ lUserEntries.clear();
+ }
+
+ //---------------------------------------------------------------------------------------------------------
+ // convert internal list to external format
+ // for using it on right menus realy
+ // Notice: We build a property list with 4 entries and set it on result list then.
+ // The while-loop starts with pointer on internal member list lSetupEntries, change to
+ // lUserEntries then and stop after that with NULL!
+ // Separator entries will be packed in another way then normal entries! We define
+ // special strings "sEmpty" and "sSeperator" to perform too ...
+ Sequence< Sequence< PropertyValue > > GetList() const
+ {
+ sal_Int32 nSetupCount = (sal_Int32)lSetupEntries.size();
+ sal_Int32 nUserCount = (sal_Int32)lUserEntries.size();
+ sal_Int32 nStep = 0;
+ Sequence< PropertyValue > lProperties ( PROPERTYCOUNT );
+ Sequence< Sequence< PropertyValue > > lResult ( nSetupCount+nUserCount );
+ OUString sSeperator ( RTL_CONSTASCII_USTRINGPARAM("private:separator") );
+ OUString sEmpty ;
+ const vector< SvtDynMenuEntry >* pList = &lSetupEntries;
+
+ lProperties[OFFSET_URL ].Name = PROPERTYNAME_URL ;
+ lProperties[OFFSET_TITLE ].Name = PROPERTYNAME_TITLE ;
+ lProperties[OFFSET_IMAGEIDENTIFIER].Name = PROPERTYNAME_IMAGEIDENTIFIER ;
+ lProperties[OFFSET_TARGETNAME ].Name = PROPERTYNAME_TARGETNAME ;
+
+ while( pList != NULL )
+ {
+ for( vector< SvtDynMenuEntry >::const_iterator pItem =pList->begin();
+ pItem!=pList->end() ;
+ ++pItem )
+ {
+ if( pItem->sURL == sSeperator )
+ {
+ lProperties[OFFSET_URL ].Value <<= sSeperator ;
+ lProperties[OFFSET_TITLE ].Value <<= sEmpty ;
+ lProperties[OFFSET_IMAGEIDENTIFIER ].Value <<= sEmpty ;
+ lProperties[OFFSET_TARGETNAME ].Value <<= sEmpty ;
+ }
+ else
+ {
+ lProperties[OFFSET_URL ].Value <<= pItem->sURL ;
+ lProperties[OFFSET_TITLE ].Value <<= pItem->sTitle ;
+ lProperties[OFFSET_IMAGEIDENTIFIER ].Value <<= pItem->sImageIdentifier;
+ lProperties[OFFSET_TARGETNAME ].Value <<= pItem->sTargetName ;
+ }
+ lResult[nStep] = lProperties;
+ ++nStep;
+ }
+ if( pList == &lSetupEntries )
+ pList = &lUserEntries;
+ else
+ pList = NULL;
+ }
+ return lResult;
+ }
+
+ private:
+ //---------------------------------------------------------------------------------------------------------
+ // search for an entry named "ux" with x=[0..i] inside our menu
+ // which has set highest number x. So we can add another user entry.
+ sal_Int32 impl_getNextUserEntryNr() const
+ {
+ sal_Int32 nNr = 0;
+ for( vector< SvtDynMenuEntry >::const_iterator pItem =lUserEntries.begin();
+ pItem!=lUserEntries.end() ;
+ ++pItem )
+ {
+ if( pItem->sName.compareTo( PATHPREFIX_USER, 1 ) == 0 )
+ {
+ OUString sNr = pItem->sName.copy( 1, pItem->sName.getLength()-1 );
+ sal_Int32 nCheckNr = sNr.toInt32();
+ if( nCheckNr > nNr )
+ nNr = nCheckNr;
+ }
+ }
+ // Attention: Code isn't prepared for recyling of unused fragmented numbers!
+ // If we reach end of sal_Int32 range ... we must stop further working ...
+ // But I think nobody expand a menu to more then 1000 ... 100000 ... entries ... or?
+ DBG_ASSERT( !(nNr>0x7fffffff), "Menu::impl_getNextUserEntryNr()\nUser count can be out of range next time ...\n" );
+ return nNr;
+ }
+
+ private:
+ vector< SvtDynMenuEntry > lSetupEntries;
+ vector< SvtDynMenuEntry > lUserEntries ;
+};
+
+class SvtDynamicMenuOptions_Impl : public ConfigItem
+{
+ //-------------------------------------------------------------------------------------------------------------
+ // public methods
+ //-------------------------------------------------------------------------------------------------------------
+
+ public:
+
+ //---------------------------------------------------------------------------------------------------------
+ // constructor / destructor
+ //---------------------------------------------------------------------------------------------------------
+
+ SvtDynamicMenuOptions_Impl();
+ ~SvtDynamicMenuOptions_Impl();
+
+ //---------------------------------------------------------------------------------------------------------
+ // overloaded methods of baseclass
+ //---------------------------------------------------------------------------------------------------------
+
+ /*-****************************************************************************************************//**
+ @short called for notify of configmanager
+ @descr These method is called from the ConfigManager before application ends or from the
+ PropertyChangeListener if the sub tree broadcasts changes. You must update your
+ internal values.
+
+ @seealso baseclass ConfigItem
+
+ @param "lPropertyNames" is the list of properties which should be updated.
+ @return -
+
+ @onerror -
+ *//*-*****************************************************************************************************/
+
+ virtual void Notify( const Sequence< OUString >& lPropertyNames );
+
+ /*-****************************************************************************************************//**
+ @short write changes to configuration
+ @descr These method writes the changed values into the sub tree
+ and should always called in our destructor to guarantee consistency of config data.
+
+ @seealso baseclass ConfigItem
+
+ @param -
+ @return -
+
+ @onerror -
+ *//*-*****************************************************************************************************/
+
+ virtual void Commit();
+
+ //-------------------------------------------------------------------------------------------------------------
+ // private methods
+ //-------------------------------------------------------------------------------------------------------------
+
+ private:
+
+ /*-****************************************************************************************************//**
+ @short return list of key names of our configuration management which represent oue module tree
+ @descr These methods return the current list of key names! We need it to get needed values from our
+ configuration management and support dynamical menu item lists!
+
+ @seealso -
+
+ @param "nNewCount" , returns count of menu entries for "new"
+ @param "nWizardCount" , returns count of menu entries for "wizard"
+ @return A list of configuration key names is returned.
+
+ @onerror -
+ *//*-*****************************************************************************************************/
+
+ Sequence< OUString > impl_GetPropertyNames( sal_uInt32& nNewCount, sal_uInt32& nWizardCount, sal_uInt32& nHelpBookmarksCount );
+
+ /*-****************************************************************************************************//**
+ @short sort given source list and expand it for all well known properties to destination
+ @descr We must support sets of entries with count inside the name .. but some of them could be missing!
+ e.g. s1-s2-s3-s0-u1-s6-u5-u7
+ Then we must sort it by name and expand it to the follow one:
+ sSetNode/s0/URL
+ sSetNode/s0/Title
+ sSetNode/s0/...
+ sSetNode/s1/URL
+ sSetNode/s1/Title
+ sSetNode/s1/...
+ ...
+ sSetNode/s6/URL
+ sSetNode/s6/Title
+ sSetNode/s6/...
+ sSetNode/u1/URL
+ sSetNode/u1/Title
+ sSetNode/u1/...
+ ...
+ sSetNode/u7/URL
+ sSetNode/u7/Title
+ sSetNode/u7/...
+ Rules: We start with all setup written entries names "sx" and x=[0..n].
+ Then we handle all "ux" items. Inside these blocks we sort it ascending by number.
+
+ @attention We add these expanded list to the end of given "lDestination" list!
+ So we must start on "lDestination.getLength()".
+ Reallocation of memory of destination list is done by us!
+
+ @seealso method impl_GetPropertyNames()
+
+ @param "lSource" , original list (e.g. [m1-m2-m3-m6-m0] )
+ @param "lDestination" , destination of operation
+ @param "sSetNode" , name of configuration set to build complete path
+ @return A list of configuration key names is returned.
+
+ @onerror -
+ *//*-*****************************************************************************************************/
+
+ void impl_SortAndExpandPropertyNames( const Sequence< OUString >& lSource ,
+ Sequence< OUString >& lDestination ,
+ const OUString& sSetNode );
+
+ //-------------------------------------------------------------------------------------------------------------
+ // private member
+ //-------------------------------------------------------------------------------------------------------------
+
+ private:
+
+ SvtDynMenu m_aNewMenu ;
+ SvtDynMenu m_aWizardMenu ;
+ SvtDynMenu m_aHelpBookmarksMenu ;
+};
+
+//_________________________________________________________________________________________________________________
+// definitions
+//_________________________________________________________________________________________________________________
+
+//*****************************************************************************************************************
+// constructor
+//*****************************************************************************************************************
+SvtDynamicMenuOptions_Impl::SvtDynamicMenuOptions_Impl()
+ // Init baseclasses first
+ : ConfigItem( ROOTNODE_MENUS )
+ // Init member then...
+{
+ // Get names and values of all accessable menu entries and fill internal structures.
+ // See impl_GetPropertyNames() for further informations.
+ sal_uInt32 nNewCount = 0;
+ sal_uInt32 nWizardCount = 0;
+ sal_uInt32 nHelpBookmarksCount = 0;
+ Sequence< OUString > lNames = impl_GetPropertyNames ( nNewCount ,
+ nWizardCount ,
+ nHelpBookmarksCount );
+ Sequence< Any > lValues = GetProperties ( lNames );
+
+ // Safe impossible cases.
+ // We need values from ALL configuration keys.
+ // Follow assignment use order of values in relation to our list of key names!
+ DBG_ASSERT( !(lNames.getLength()!=lValues.getLength()), "SvtDynamicMenuOptions_Impl::SvtDynamicMenuOptions_Impl()\nI miss some values of configuration keys!\n" );
+
+ // Copy values from list in right order to ouer internal member.
+ // Attention: List for names and values have an internal construction pattern!
+ //
+ // first "New" menu ...
+ // Name Value
+ // /New/1/URL "private:factory/swriter"
+ // /New/1/Title "Neues Writer Dokument"
+ // /New/1/ImageIdentifier "icon_writer"
+ // /New/1/TargetName "_blank"
+ //
+ // /New/2/URL "private:factory/scalc"
+ // /New/2/Title "Neues Calc Dokument"
+ // /New/2/ImageIdentifier "icon_calc"
+ // /New/2/TargetName "_blank"
+ //
+ // second "Wizard" menu ...
+ // /Wizard/1/URL "file://b"
+ // /Wizard/1/Title "MalWas"
+ // /Wizard/1/ImageIdentifier "icon_?"
+ // /Wizard/1/TargetName "_self"
+ //
+ // ... and so on ...
+
+ sal_uInt32 nItem = 0 ;
+ sal_uInt32 nPosition = 0 ;
+ OUString sName ;
+
+ // We must use these one instance object(!) to get information about installed modules.
+ // These information are used to filter menu entries wich need not installed modules ...
+ // Such entries shouldnt be available then!
+ // see impl_IsEntrySupported() too
+ SvtModuleOptions aModuleOptions;
+
+ // Get names/values for new menu.
+ // 4 subkeys for every item!
+ for( nItem=0; nItem<nNewCount; ++nItem )
+ {
+ SvtDynMenuEntry aItem ;
+ lValues[nPosition] >>= aItem.sURL ;
+ ++nPosition;
+ lValues[nPosition] >>= aItem.sTitle ;
+ ++nPosition;
+ lValues[nPosition] >>= aItem.sImageIdentifier ;
+ ++nPosition;
+ lValues[nPosition] >>= aItem.sTargetName ;
+ ++nPosition;
+ m_aNewMenu.AppendSetupEntry( aItem );
+ }
+
+ // Attention: Don't reset nPosition here!
+
+ // Get names/values for wizard menu.
+ // 4 subkeys for every item!
+ for( nItem=0; nItem<nWizardCount; ++nItem )
+ {
+ SvtDynMenuEntry aItem ;
+ lValues[nPosition] >>= aItem.sURL ;
+ ++nPosition;
+ lValues[nPosition] >>= aItem.sTitle ;
+ ++nPosition;
+ lValues[nPosition] >>= aItem.sImageIdentifier ;
+ ++nPosition;
+ lValues[nPosition] >>= aItem.sTargetName ;
+ ++nPosition;
+ m_aWizardMenu.AppendSetupEntry( aItem );
+ }
+
+ // Attention: Don't reset nPosition here!
+
+ // Get names/values for wizard menu.
+ // 4 subkeys for every item!
+ for( nItem=0; nItem<nHelpBookmarksCount; ++nItem )
+ {
+ SvtDynMenuEntry aItem ;
+ lValues[nPosition] >>= aItem.sURL ;
+ ++nPosition;
+ lValues[nPosition] >>= aItem.sTitle ;
+ ++nPosition;
+ lValues[nPosition] >>= aItem.sImageIdentifier ;
+ ++nPosition;
+ lValues[nPosition] >>= aItem.sTargetName ;
+ ++nPosition;
+ m_aHelpBookmarksMenu.AppendSetupEntry( aItem );
+ }
+
+/*TODO: Not used in the moment! see Notify() ...
+ // Enable notification mechanism of ouer baseclass.
+ // We need it to get information about changes outside these class on ouer used configuration keys!
+ EnableNotification( lNames );
+*/
+}
+
+//*****************************************************************************************************************
+// destructor
+//*****************************************************************************************************************
+SvtDynamicMenuOptions_Impl::~SvtDynamicMenuOptions_Impl()
+{
+ // We must save our current values .. if user forget it!
+ if( IsModified() == sal_True )
+ {
+ Commit();
+ }
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+void SvtDynamicMenuOptions_Impl::Notify( const Sequence< OUString >& )
+{
+ 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" );
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+void SvtDynamicMenuOptions_Impl::Commit()
+{
+ DBG_ERROR( "SvtDynamicMenuOptions_Impl::Commit()\nNot implemented yet!\n" );
+ /*
+ // Write all properties!
+ // Delete complete sets first.
+ ClearNodeSet( SETNODE_NEWMENU );
+ ClearNodeSet( SETNODE_WIZARDMENU );
+ ClearNodeSet( SETNODE_HELPBOOKMARKS );
+
+ MenuEntry aItem ;
+ OUString sNode ;
+ Sequence< PropertyValue > lPropertyValues( PROPERTYCOUNT );
+ sal_uInt32 nItem = 0 ;
+
+ // Copy "new" menu entries to save-list!
+ sal_uInt32 nNewCount = m_aNewMenu.size();
+ for( nItem=0; nItem<nNewCount; ++nItem )
+ {
+ aItem = m_aNewMenu[nItem];
+ // Format: "New/1/URL"
+ // "New/1/Title"
+ // ...
+ sNode = SETNODE_NEWMENU + PATHDELIMITER + PATHPREFIX + OUString::valueOf( (sal_Int32)nItem ) + PATHDELIMITER;
+
+ lPropertyValues[OFFSET_URL ].Name = sNode + PROPERTYNAME_URL ;
+ lPropertyValues[OFFSET_TITLE ].Name = sNode + PROPERTYNAME_TITLE ;
+ lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Name = sNode + PROPERTYNAME_IMAGEIDENTIFIER ;
+ lPropertyValues[OFFSET_TARGETNAME ].Name = sNode + PROPERTYNAME_TARGETNAME ;
+
+ lPropertyValues[OFFSET_URL ].Value <<= aItem.sURL ;
+ lPropertyValues[OFFSET_TITLE ].Value <<= aItem.sTitle ;
+ lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Value <<= aItem.sImageIdentifier ;
+ lPropertyValues[OFFSET_TARGETNAME ].Value <<= aItem.sTargetName ;
+
+ SetSetProperties( SETNODE_NEWMENU, lPropertyValues );
+ }
+
+ // Copy "wizard" menu entries to save-list!
+ sal_uInt32 nWizardCount = m_aWizardMenu.size();
+ for( nItem=0; nItem<nWizardCount; ++nItem )
+ {
+ aItem = m_aWizardMenu[nItem];
+ // Format: "Wizard/1/URL"
+ // "Wizard/1/Title"
+ // ...
+ sNode = SETNODE_WIZARDMENU + PATHDELIMITER + PATHPREFIX + OUString::valueOf( (sal_Int32)nItem ) + PATHDELIMITER;
+
+ lPropertyValues[OFFSET_URL ].Name = sNode + PROPERTYNAME_URL ;
+ lPropertyValues[OFFSET_TITLE ].Name = sNode + PROPERTYNAME_TITLE ;
+ lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Name = sNode + PROPERTYNAME_IMAGEIDENTIFIER ;
+ lPropertyValues[OFFSET_TARGETNAME ].Name = sNode + PROPERTYNAME_TARGETNAME ;
+
+ lPropertyValues[OFFSET_URL ].Value <<= aItem.sURL ;
+ lPropertyValues[OFFSET_TITLE ].Value <<= aItem.sTitle ;
+ lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Value <<= aItem.sImageIdentifier ;
+ lPropertyValues[OFFSET_TARGETNAME ].Value <<= aItem.sTargetName ;
+
+ SetSetProperties( SETNODE_WIZARDMENU, lPropertyValues );
+ }
+
+ // Copy help bookmarks entries to save-list!
+ sal_uInt32 nHelpBookmarksCount = m_aHelpBookmarksMenu.size();
+ for( nItem=0; nItem<nHelpBookmarksCount; ++nItem )
+ {
+ aItem = m_aHelpBookmarksMenu[nItem];
+ // Format: "HelpBookmarks/1/URL"
+ // "HelpBookmarks/1/Title"
+ // ...
+ sNode = SETNODE_HELPBOOKMARKS + PATHDELIMITER + PATHPREFIX + OUString::valueOf( (sal_Int32)nItem ) + PATHDELIMITER;
+
+ lPropertyValues[OFFSET_URL ].Name = sNode + PROPERTYNAME_URL ;
+ lPropertyValues[OFFSET_TITLE ].Name = sNode + PROPERTYNAME_TITLE ;
+ lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Name = sNode + PROPERTYNAME_IMAGEIDENTIFIER ;
+ lPropertyValues[OFFSET_TARGETNAME ].Name = sNode + PROPERTYNAME_TARGETNAME ;
+
+ lPropertyValues[OFFSET_URL ].Value <<= aItem.sURL ;
+ lPropertyValues[OFFSET_TITLE ].Value <<= aItem.sTitle ;
+ lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Value <<= aItem.sImageIdentifier ;
+ lPropertyValues[OFFSET_TARGETNAME ].Value <<= aItem.sTargetName ;
+
+ SetSetProperties( SETNODE_HELPBOOKMARKS, lPropertyValues );
+ }
+ */
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+Sequence< OUString > SvtDynamicMenuOptions_Impl::impl_GetPropertyNames( sal_uInt32& nNewCount, sal_uInt32& nWizardCount, sal_uInt32& nHelpBookmarksCount )
+{
+ // First get ALL names of current existing list items in configuration!
+ Sequence< OUString > lNewItems = GetNodeNames( SETNODE_NEWMENU );
+ Sequence< OUString > lWizardItems = GetNodeNames( SETNODE_WIZARDMENU );
+ Sequence< OUString > lHelpBookmarksItems = GetNodeNames( SETNODE_HELPBOOKMARKS );
+
+ // Get information about list counts ...
+ nNewCount = lNewItems.getLength ();
+ nWizardCount = lWizardItems.getLength ();
+ nHelpBookmarksCount = lHelpBookmarksItems.getLength();
+
+ // Sort and expand all three list to result list ...
+ Sequence< OUString > lProperties;
+ impl_SortAndExpandPropertyNames( lNewItems , lProperties, SETNODE_NEWMENU );
+ impl_SortAndExpandPropertyNames( lWizardItems , lProperties, SETNODE_WIZARDMENU );
+ impl_SortAndExpandPropertyNames( lHelpBookmarksItems, lProperties, SETNODE_HELPBOOKMARKS );
+
+ // Return result.
+ return lProperties;
+}
+
+//*****************************************************************************************************************
+// private helper
+//*****************************************************************************************************************
+class CountWithPrefixSort
+{
+ public:
+ int operator() ( const OUString& s1 ,
+ const OUString& s2 ) const
+ {
+ // Get order numbers from entry name without prefix.
+ // e.g. "m10" => 10
+ // "m5" => 5
+ sal_Int32 n1 = s1.copy( 1, s1.getLength()-1 ).toInt32();
+ sal_Int32 n2 = s2.copy( 1, s2.getLength()-1 ).toInt32();
+ // MUST be in [0,1] ... because it's a difference between
+ // insert-positions of given entries in sorted list!
+ return( n1<n2 );
+ }
+};
+
+class SelectByPrefix
+{
+ public:
+ bool operator() ( const OUString& s ) const
+ {
+ // Prefer setup written entries by check first letter of given string. It must be a "s".
+ return( s.indexOf( PATHPREFIX_SETUP ) == 0 );
+ }
+};
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+void SvtDynamicMenuOptions_Impl::impl_SortAndExpandPropertyNames( const Sequence< OUString >& lSource ,
+ Sequence< OUString >& lDestination ,
+ const OUString& sSetNode )
+{
+ OUString sFixPath ;
+ vector< OUString > lTemp ;
+ sal_Int32 nSourceCount = lSource.getLength() ;
+ sal_Int32 nDestinationStep = lDestination.getLength() ; // start on end of current list ...!
+
+ lDestination.realloc( (nSourceCount*PROPERTYCOUNT)+nDestinationStep ); // get enough memory for copy operations after nDestination ...
+
+ // Copy all items to temp. vector to use fast sort operations :-)
+ for( sal_Int32 nSourceStep=0; nSourceStep<nSourceCount; ++nSourceStep )
+ lTemp.push_back( lSource[nSourceStep] );
+
+ // Sort all entries by number ...
+ stable_sort( lTemp.begin(), lTemp.end(), CountWithPrefixSort() );
+ // and split into setup & user written entries!
+ stable_partition( lTemp.begin(), lTemp.end(), SelectByPrefix() );
+
+ // Copy sorted entries to destination and expand every item with
+ // 4 supported sub properties.
+ for( vector< OUString >::const_iterator pItem =lTemp.begin() ;
+ pItem!=lTemp.end() ;
+ ++pItem )
+ {
+ sFixPath = sSetNode ;
+ sFixPath += PATHDELIMITER ;
+ sFixPath += *pItem ;
+ sFixPath += PATHDELIMITER ;
+
+ lDestination[nDestinationStep] = sFixPath ;
+ lDestination[nDestinationStep] += PROPERTYNAME_URL ;
+ ++nDestinationStep;
+ lDestination[nDestinationStep] = sFixPath ;
+ lDestination[nDestinationStep] += PROPERTYNAME_TITLE ;
+ ++nDestinationStep;
+ lDestination[nDestinationStep] = sFixPath ;
+ lDestination[nDestinationStep] += PROPERTYNAME_IMAGEIDENTIFIER ;
+ ++nDestinationStep;
+ lDestination[nDestinationStep] = sFixPath ;
+ lDestination[nDestinationStep] += PROPERTYNAME_TARGETNAME ;
+ ++nDestinationStep;
+ }
+}
+
+//*****************************************************************************************************************
+// initialize static member
+// DON'T DO IT IN YOUR HEADER!
+// see definition for further informations
+//*****************************************************************************************************************
+SvtDynamicMenuOptions_Impl* SvtDynamicMenuOptions::m_pDataContainer = NULL ;
+sal_Int32 SvtDynamicMenuOptions::m_nRefCount = 0 ;
+
+//*****************************************************************************************************************
+// constructor
+//*****************************************************************************************************************
+SvtDynamicMenuOptions::SvtDynamicMenuOptions()
+{
+ // Global access, must be guarded (multithreading!).
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ // Increase ouer refcount ...
+ ++m_nRefCount;
+ // ... and initialize ouer data container only if it not already exist!
+ if( m_pDataContainer == NULL )
+ {
+ m_pDataContainer = new SvtDynamicMenuOptions_Impl;
+ ItemHolder1::holdConfigItem(E_DYNAMICMENUOPTIONS);
+ }
+}
+
+//*****************************************************************************************************************
+// destructor
+//*****************************************************************************************************************
+SvtDynamicMenuOptions::~SvtDynamicMenuOptions()
+{
+ // Global access, must be guarded (multithreading!)
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ // Decrease ouer refcount.
+ --m_nRefCount;
+ // If last instance was deleted ...
+ // we must destroy ouer static data container!
+ if( m_nRefCount <= 0 )
+ {
+ delete m_pDataContainer;
+ m_pDataContainer = NULL;
+ }
+}
+
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+Mutex& SvtDynamicMenuOptions::GetOwnStaticMutex()
+{
+ // Initialize static mutex only for one time!
+ static Mutex* pMutex = NULL;
+ // If these method first called (Mutex not already exist!) ...
+ if( pMutex == NULL )
+ {
+ // ... we must create a new one. Protect follow code with the global mutex -
+ // It must be - we create a static variable!
+ MutexGuard aGuard( Mutex::getGlobalMutex() );
+ // We must check our pointer again - because it can be that another instance of ouer class will be fastr then these!
+ if( pMutex == NULL )
+ {
+ // Create the new mutex and set it for return on static variable.
+ static Mutex aMutex;
+ pMutex = &aMutex;
+ }
+ }
+ // Return new created or already existing mutex object.
+ return *pMutex;
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */