1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_unotools.hxx"
30*cdf0e10cSrcweir #ifndef GCC
31*cdf0e10cSrcweir #endif
32*cdf0e10cSrcweir 
33*cdf0e10cSrcweir //_________________________________________________________________________________________________________________
34*cdf0e10cSrcweir //	includes
35*cdf0e10cSrcweir //_________________________________________________________________________________________________________________
36*cdf0e10cSrcweir 
37*cdf0e10cSrcweir #include <unotools/dynamicmenuoptions.hxx>
38*cdf0e10cSrcweir #include <unotools/moduleoptions.hxx>
39*cdf0e10cSrcweir #include <unotools/configmgr.hxx>
40*cdf0e10cSrcweir #include <unotools/configitem.hxx>
41*cdf0e10cSrcweir #include <tools/debug.hxx>
42*cdf0e10cSrcweir #include <com/sun/star/uno/Any.hxx>
43*cdf0e10cSrcweir #include <com/sun/star/uno/Sequence.hxx>
44*cdf0e10cSrcweir 
45*cdf0e10cSrcweir #ifndef __SGI_STL_VECTOR
46*cdf0e10cSrcweir #include <vector>
47*cdf0e10cSrcweir #endif
48*cdf0e10cSrcweir 
49*cdf0e10cSrcweir #include <itemholder1.hxx>
50*cdf0e10cSrcweir 
51*cdf0e10cSrcweir #include <algorithm>
52*cdf0e10cSrcweir 
53*cdf0e10cSrcweir //_________________________________________________________________________________________________________________
54*cdf0e10cSrcweir //	namespaces
55*cdf0e10cSrcweir //_________________________________________________________________________________________________________________
56*cdf0e10cSrcweir 
57*cdf0e10cSrcweir using namespace ::std					;
58*cdf0e10cSrcweir using namespace ::utl					;
59*cdf0e10cSrcweir using namespace ::rtl					;
60*cdf0e10cSrcweir using namespace ::osl					;
61*cdf0e10cSrcweir using namespace ::com::sun::star::uno	;
62*cdf0e10cSrcweir using namespace ::com::sun::star::beans	;
63*cdf0e10cSrcweir 
64*cdf0e10cSrcweir //_________________________________________________________________________________________________________________
65*cdf0e10cSrcweir //	const
66*cdf0e10cSrcweir //_________________________________________________________________________________________________________________
67*cdf0e10cSrcweir 
68*cdf0e10cSrcweir #define ROOTNODE_MENUS                                  OUString(RTL_CONSTASCII_USTRINGPARAM("Office.Common/Menus/"     ))
69*cdf0e10cSrcweir #define PATHDELIMITER                                   OUString(RTL_CONSTASCII_USTRINGPARAM("/"                        ))
70*cdf0e10cSrcweir 
71*cdf0e10cSrcweir #define SETNODE_NEWMENU                                 OUString(RTL_CONSTASCII_USTRINGPARAM("New"                      ))
72*cdf0e10cSrcweir #define SETNODE_WIZARDMENU                              OUString(RTL_CONSTASCII_USTRINGPARAM("Wizard"                   ))
73*cdf0e10cSrcweir #define SETNODE_HELPBOOKMARKS                           OUString(RTL_CONSTASCII_USTRINGPARAM("HelpBookmarks"            ))
74*cdf0e10cSrcweir 
75*cdf0e10cSrcweir #define PROPERTYNAME_URL                                DYNAMICMENU_PROPERTYNAME_URL
76*cdf0e10cSrcweir #define PROPERTYNAME_TITLE                              DYNAMICMENU_PROPERTYNAME_TITLE
77*cdf0e10cSrcweir #define PROPERTYNAME_IMAGEIDENTIFIER                    DYNAMICMENU_PROPERTYNAME_IMAGEIDENTIFIER
78*cdf0e10cSrcweir #define PROPERTYNAME_TARGETNAME                         DYNAMICMENU_PROPERTYNAME_TARGETNAME
79*cdf0e10cSrcweir 
80*cdf0e10cSrcweir #define PROPERTYCOUNT                                   4
81*cdf0e10cSrcweir 
82*cdf0e10cSrcweir #define OFFSET_URL                                      0
83*cdf0e10cSrcweir #define OFFSET_TITLE                                    1
84*cdf0e10cSrcweir #define OFFSET_IMAGEIDENTIFIER                          2
85*cdf0e10cSrcweir #define OFFSET_TARGETNAME                               3
86*cdf0e10cSrcweir 
87*cdf0e10cSrcweir #define PATHPREFIX_SETUP                                OUString(RTL_CONSTASCII_USTRINGPARAM("m"                        ))
88*cdf0e10cSrcweir #define PATHPREFIX_USER                                 OUString(RTL_CONSTASCII_USTRINGPARAM("u"                        ))
89*cdf0e10cSrcweir 
90*cdf0e10cSrcweir //_________________________________________________________________________________________________________________
91*cdf0e10cSrcweir //	private declarations!
92*cdf0e10cSrcweir //_________________________________________________________________________________________________________________
93*cdf0e10cSrcweir 
94*cdf0e10cSrcweir /*-****************************************************************************************************************
95*cdf0e10cSrcweir     @descr  struct to hold information about one menu entry.
96*cdf0e10cSrcweir ****************************************************************************************************************-*/
97*cdf0e10cSrcweir struct SvtDynMenuEntry
98*cdf0e10cSrcweir {
99*cdf0e10cSrcweir     public:
100*cdf0e10cSrcweir         SvtDynMenuEntry() {};
101*cdf0e10cSrcweir 
102*cdf0e10cSrcweir         SvtDynMenuEntry(  const OUString& sNewURL             ,
103*cdf0e10cSrcweir                     const OUString& sNewTitle           ,
104*cdf0e10cSrcweir                     const OUString& sNewImageIdentifier ,
105*cdf0e10cSrcweir                     const OUString& sNewTargetName      )
106*cdf0e10cSrcweir         {
107*cdf0e10cSrcweir             sURL                = sNewURL               ;
108*cdf0e10cSrcweir             sTitle              = sNewTitle             ;
109*cdf0e10cSrcweir             sImageIdentifier    = sNewImageIdentifier   ;
110*cdf0e10cSrcweir             sTargetName         = sNewTargetName        ;
111*cdf0e10cSrcweir         }
112*cdf0e10cSrcweir 
113*cdf0e10cSrcweir     public:
114*cdf0e10cSrcweir         OUString    sName               ;
115*cdf0e10cSrcweir         OUString    sURL                ;
116*cdf0e10cSrcweir         OUString    sTitle              ;
117*cdf0e10cSrcweir         OUString    sImageIdentifier    ;
118*cdf0e10cSrcweir         OUString    sTargetName         ;
119*cdf0e10cSrcweir };
120*cdf0e10cSrcweir 
121*cdf0e10cSrcweir /*-****************************************************************************************************************
122*cdf0e10cSrcweir     @descr  support simple menu structures and operations on it
123*cdf0e10cSrcweir ****************************************************************************************************************-*/
124*cdf0e10cSrcweir class SvtDynMenu
125*cdf0e10cSrcweir {
126*cdf0e10cSrcweir     public:
127*cdf0e10cSrcweir         //---------------------------------------------------------------------------------------------------------
128*cdf0e10cSrcweir         // append setup written menu entry
129*cdf0e10cSrcweir         // Don't touch name of entry. It was defined by setup and must be the same everytime!
130*cdf0e10cSrcweir         // Look for double menu entries here too ... may be some seperator items are supeflous ...
131*cdf0e10cSrcweir         void AppendSetupEntry( const SvtDynMenuEntry& rEntry )
132*cdf0e10cSrcweir         {
133*cdf0e10cSrcweir             if(
134*cdf0e10cSrcweir                 ( lSetupEntries.size()         <  1           )  ||
135*cdf0e10cSrcweir                 ( lSetupEntries.rbegin()->sURL != rEntry.sURL )
136*cdf0e10cSrcweir               )
137*cdf0e10cSrcweir             {
138*cdf0e10cSrcweir                 lSetupEntries.push_back( rEntry );
139*cdf0e10cSrcweir             }
140*cdf0e10cSrcweir         }
141*cdf0e10cSrcweir 
142*cdf0e10cSrcweir         //---------------------------------------------------------------------------------------------------------
143*cdf0e10cSrcweir         // append user specific menu entry
144*cdf0e10cSrcweir         // We must find unique name for it by using special prefix
145*cdf0e10cSrcweir         // and next count of user setted entries!
146*cdf0e10cSrcweir         // Look for double menu entries here too ... may be some seperator items are supeflous ...
147*cdf0e10cSrcweir         void AppendUserEntry( SvtDynMenuEntry& rEntry )
148*cdf0e10cSrcweir         {
149*cdf0e10cSrcweir             if(
150*cdf0e10cSrcweir                 ( lUserEntries.size()         <  1           )  ||
151*cdf0e10cSrcweir                 ( lUserEntries.rbegin()->sURL != rEntry.sURL )
152*cdf0e10cSrcweir               )
153*cdf0e10cSrcweir             {
154*cdf0e10cSrcweir                 rEntry.sName  = PATHPREFIX_USER;
155*cdf0e10cSrcweir                 rEntry.sName += OUString::valueOf( (sal_Int32)impl_getNextUserEntryNr() );
156*cdf0e10cSrcweir                 lUserEntries.push_back( rEntry );
157*cdf0e10cSrcweir             }
158*cdf0e10cSrcweir         }
159*cdf0e10cSrcweir 
160*cdf0e10cSrcweir         //---------------------------------------------------------------------------------------------------------
161*cdf0e10cSrcweir         // the only way to free memory!
162*cdf0e10cSrcweir         void Clear()
163*cdf0e10cSrcweir         {
164*cdf0e10cSrcweir             lSetupEntries.clear();
165*cdf0e10cSrcweir             lUserEntries.clear();
166*cdf0e10cSrcweir         }
167*cdf0e10cSrcweir 
168*cdf0e10cSrcweir         //---------------------------------------------------------------------------------------------------------
169*cdf0e10cSrcweir         // convert internal list to external format
170*cdf0e10cSrcweir         // for using it on right menus realy
171*cdf0e10cSrcweir         // Notice:   We build a property list with 4 entries and set it on result list then.
172*cdf0e10cSrcweir         //           The while-loop starts with pointer on internal member list lSetupEntries, change to
173*cdf0e10cSrcweir         //           lUserEntries then and stop after that with NULL!
174*cdf0e10cSrcweir         //           Separator entries will be packed in another way then normal entries! We define
175*cdf0e10cSrcweir         //           special strings "sEmpty" and "sSeperator" to perform too ...
176*cdf0e10cSrcweir         Sequence< Sequence< PropertyValue > > GetList() const
177*cdf0e10cSrcweir         {
178*cdf0e10cSrcweir             sal_Int32                             nSetupCount = (sal_Int32)lSetupEntries.size();
179*cdf0e10cSrcweir             sal_Int32                             nUserCount  = (sal_Int32)lUserEntries.size();
180*cdf0e10cSrcweir             sal_Int32                             nStep       = 0;
181*cdf0e10cSrcweir             Sequence< PropertyValue >             lProperties ( PROPERTYCOUNT );
182*cdf0e10cSrcweir             Sequence< Sequence< PropertyValue > > lResult     ( nSetupCount+nUserCount );
183*cdf0e10cSrcweir             OUString                              sSeperator  ( RTL_CONSTASCII_USTRINGPARAM("private:separator") );
184*cdf0e10cSrcweir             OUString                              sEmpty      ;
185*cdf0e10cSrcweir             const vector< SvtDynMenuEntry >*            pList       = &lSetupEntries;
186*cdf0e10cSrcweir 
187*cdf0e10cSrcweir             lProperties[OFFSET_URL            ].Name = PROPERTYNAME_URL             ;
188*cdf0e10cSrcweir             lProperties[OFFSET_TITLE          ].Name = PROPERTYNAME_TITLE           ;
189*cdf0e10cSrcweir             lProperties[OFFSET_IMAGEIDENTIFIER].Name = PROPERTYNAME_IMAGEIDENTIFIER ;
190*cdf0e10cSrcweir             lProperties[OFFSET_TARGETNAME     ].Name = PROPERTYNAME_TARGETNAME      ;
191*cdf0e10cSrcweir 
192*cdf0e10cSrcweir             while( pList != NULL )
193*cdf0e10cSrcweir             {
194*cdf0e10cSrcweir                 for( vector< SvtDynMenuEntry >::const_iterator pItem =pList->begin();
195*cdf0e10cSrcweir                                                          pItem!=pList->end()  ;
196*cdf0e10cSrcweir                                                          ++pItem              )
197*cdf0e10cSrcweir                 {
198*cdf0e10cSrcweir                     if( pItem->sURL == sSeperator )
199*cdf0e10cSrcweir                     {
200*cdf0e10cSrcweir                         lProperties[OFFSET_URL              ].Value <<= sSeperator  ;
201*cdf0e10cSrcweir                         lProperties[OFFSET_TITLE            ].Value <<= sEmpty      ;
202*cdf0e10cSrcweir                         lProperties[OFFSET_IMAGEIDENTIFIER  ].Value <<= sEmpty      ;
203*cdf0e10cSrcweir                         lProperties[OFFSET_TARGETNAME       ].Value <<= sEmpty      ;
204*cdf0e10cSrcweir                     }
205*cdf0e10cSrcweir                     else
206*cdf0e10cSrcweir                     {
207*cdf0e10cSrcweir                         lProperties[OFFSET_URL              ].Value <<= pItem->sURL            ;
208*cdf0e10cSrcweir                         lProperties[OFFSET_TITLE            ].Value <<= pItem->sTitle          ;
209*cdf0e10cSrcweir                         lProperties[OFFSET_IMAGEIDENTIFIER  ].Value <<= pItem->sImageIdentifier;
210*cdf0e10cSrcweir                         lProperties[OFFSET_TARGETNAME       ].Value <<= pItem->sTargetName     ;
211*cdf0e10cSrcweir                     }
212*cdf0e10cSrcweir                     lResult[nStep] = lProperties;
213*cdf0e10cSrcweir                     ++nStep;
214*cdf0e10cSrcweir                 }
215*cdf0e10cSrcweir                 if( pList == &lSetupEntries )
216*cdf0e10cSrcweir                     pList = &lUserEntries;
217*cdf0e10cSrcweir                 else
218*cdf0e10cSrcweir                     pList = NULL;
219*cdf0e10cSrcweir             }
220*cdf0e10cSrcweir             return lResult;
221*cdf0e10cSrcweir         }
222*cdf0e10cSrcweir 
223*cdf0e10cSrcweir     private:
224*cdf0e10cSrcweir         //---------------------------------------------------------------------------------------------------------
225*cdf0e10cSrcweir         // search for an entry named "ux" with x=[0..i] inside our menu
226*cdf0e10cSrcweir         // which has set highest number x. So we can add another user entry.
227*cdf0e10cSrcweir         sal_Int32 impl_getNextUserEntryNr() const
228*cdf0e10cSrcweir         {
229*cdf0e10cSrcweir             sal_Int32 nNr = 0;
230*cdf0e10cSrcweir             for( vector< SvtDynMenuEntry >::const_iterator pItem =lUserEntries.begin();
231*cdf0e10cSrcweir                                                      pItem!=lUserEntries.end()  ;
232*cdf0e10cSrcweir                                                      ++pItem                    )
233*cdf0e10cSrcweir             {
234*cdf0e10cSrcweir                 if( pItem->sName.compareTo( PATHPREFIX_USER, 1 ) == 0 )
235*cdf0e10cSrcweir                 {
236*cdf0e10cSrcweir                     OUString  sNr      = pItem->sName.copy( 1, pItem->sName.getLength()-1 );
237*cdf0e10cSrcweir                     sal_Int32 nCheckNr = sNr.toInt32();
238*cdf0e10cSrcweir                     if( nCheckNr > nNr )
239*cdf0e10cSrcweir                         nNr = nCheckNr;
240*cdf0e10cSrcweir                 }
241*cdf0e10cSrcweir             }
242*cdf0e10cSrcweir             // Attention: Code isn't prepared for recyling of unused fragmented numbers!
243*cdf0e10cSrcweir             // If we reach end of sal_Int32 range ... we must stop further working ...
244*cdf0e10cSrcweir             // But I think nobody expand a menu to more then 1000 ... 100000 ... entries ... or?
245*cdf0e10cSrcweir             DBG_ASSERT( !(nNr>0x7fffffff), "Menu::impl_getNextUserEntryNr()\nUser count can be out of range next time ...\n" );
246*cdf0e10cSrcweir             return nNr;
247*cdf0e10cSrcweir         }
248*cdf0e10cSrcweir 
249*cdf0e10cSrcweir     private:
250*cdf0e10cSrcweir         vector< SvtDynMenuEntry > lSetupEntries;
251*cdf0e10cSrcweir         vector< SvtDynMenuEntry > lUserEntries ;
252*cdf0e10cSrcweir };
253*cdf0e10cSrcweir 
254*cdf0e10cSrcweir class SvtDynamicMenuOptions_Impl : public ConfigItem
255*cdf0e10cSrcweir {
256*cdf0e10cSrcweir 	//-------------------------------------------------------------------------------------------------------------
257*cdf0e10cSrcweir 	//	public methods
258*cdf0e10cSrcweir 	//-------------------------------------------------------------------------------------------------------------
259*cdf0e10cSrcweir 
260*cdf0e10cSrcweir 	public:
261*cdf0e10cSrcweir 
262*cdf0e10cSrcweir 		//---------------------------------------------------------------------------------------------------------
263*cdf0e10cSrcweir 		//	constructor / destructor
264*cdf0e10cSrcweir 		//---------------------------------------------------------------------------------------------------------
265*cdf0e10cSrcweir 
266*cdf0e10cSrcweir          SvtDynamicMenuOptions_Impl();
267*cdf0e10cSrcweir         ~SvtDynamicMenuOptions_Impl();
268*cdf0e10cSrcweir 
269*cdf0e10cSrcweir 		//---------------------------------------------------------------------------------------------------------
270*cdf0e10cSrcweir 		//	overloaded methods of baseclass
271*cdf0e10cSrcweir 		//---------------------------------------------------------------------------------------------------------
272*cdf0e10cSrcweir 
273*cdf0e10cSrcweir 		/*-****************************************************************************************************//**
274*cdf0e10cSrcweir 			@short		called for notify of configmanager
275*cdf0e10cSrcweir 			@descr		These method is called from the ConfigManager before application ends or from the
276*cdf0e10cSrcweir 			 			PropertyChangeListener if the sub tree broadcasts changes. You must update your
277*cdf0e10cSrcweir 						internal values.
278*cdf0e10cSrcweir 
279*cdf0e10cSrcweir 			@seealso	baseclass ConfigItem
280*cdf0e10cSrcweir 
281*cdf0e10cSrcweir             @param      "lPropertyNames" is the list of properties which should be updated.
282*cdf0e10cSrcweir 			@return		-
283*cdf0e10cSrcweir 
284*cdf0e10cSrcweir 			@onerror	-
285*cdf0e10cSrcweir 		*//*-*****************************************************************************************************/
286*cdf0e10cSrcweir 
287*cdf0e10cSrcweir         virtual void Notify( const Sequence< OUString >& lPropertyNames );
288*cdf0e10cSrcweir 
289*cdf0e10cSrcweir 		/*-****************************************************************************************************//**
290*cdf0e10cSrcweir 			@short		write changes to configuration
291*cdf0e10cSrcweir 			@descr		These method writes the changed values into the sub tree
292*cdf0e10cSrcweir 						and should always called in our destructor to guarantee consistency of config data.
293*cdf0e10cSrcweir 
294*cdf0e10cSrcweir 			@seealso	baseclass ConfigItem
295*cdf0e10cSrcweir 
296*cdf0e10cSrcweir 			@param		-
297*cdf0e10cSrcweir 			@return		-
298*cdf0e10cSrcweir 
299*cdf0e10cSrcweir 			@onerror	-
300*cdf0e10cSrcweir 		*//*-*****************************************************************************************************/
301*cdf0e10cSrcweir 
302*cdf0e10cSrcweir     	virtual void Commit();
303*cdf0e10cSrcweir 
304*cdf0e10cSrcweir 		//---------------------------------------------------------------------------------------------------------
305*cdf0e10cSrcweir 		//	public interface
306*cdf0e10cSrcweir 		//---------------------------------------------------------------------------------------------------------
307*cdf0e10cSrcweir 
308*cdf0e10cSrcweir 		/*-****************************************************************************************************//**
309*cdf0e10cSrcweir             @short      base implementation of public interface for "SvtDynamicMenuOptions"!
310*cdf0e10cSrcweir             @descr      These class is used as static member of "SvtDynamicMenuOptions" ...
311*cdf0e10cSrcweir 						=> The code exist only for one time and isn't duplicated for every instance!
312*cdf0e10cSrcweir 
313*cdf0e10cSrcweir 			@seealso	-
314*cdf0e10cSrcweir 
315*cdf0e10cSrcweir 			@param		-
316*cdf0e10cSrcweir 			@return		-
317*cdf0e10cSrcweir 
318*cdf0e10cSrcweir 			@onerror	-
319*cdf0e10cSrcweir 		*//*-*****************************************************************************************************/
320*cdf0e10cSrcweir 
321*cdf0e10cSrcweir         void                                    Clear       (           EDynamicMenuType    eMenu           );
322*cdf0e10cSrcweir         Sequence< Sequence< PropertyValue > >   GetMenu     (           EDynamicMenuType    eMenu           ) const ;
323*cdf0e10cSrcweir         void                                    AppendItem  (           EDynamicMenuType    eMenu           ,
324*cdf0e10cSrcweir                                                                 const   OUString&           sURL            ,
325*cdf0e10cSrcweir                                                                 const   OUString&           sTitle          ,
326*cdf0e10cSrcweir                                                                 const   OUString&           sImageIdentifier,
327*cdf0e10cSrcweir                                                                 const   OUString&           sTargetName     );
328*cdf0e10cSrcweir 
329*cdf0e10cSrcweir 	//-------------------------------------------------------------------------------------------------------------
330*cdf0e10cSrcweir 	//	private methods
331*cdf0e10cSrcweir 	//-------------------------------------------------------------------------------------------------------------
332*cdf0e10cSrcweir 
333*cdf0e10cSrcweir 	private:
334*cdf0e10cSrcweir 
335*cdf0e10cSrcweir 		/*-****************************************************************************************************//**
336*cdf0e10cSrcweir             @short      return list of key names of our configuration management which represent oue module tree
337*cdf0e10cSrcweir 			@descr		These methods return the current list of key names! We need it to get needed values from our
338*cdf0e10cSrcweir                         configuration management and support dynamical menu item lists!
339*cdf0e10cSrcweir 
340*cdf0e10cSrcweir 			@seealso	-
341*cdf0e10cSrcweir 
342*cdf0e10cSrcweir             @param      "nNewCount"     ,   returns count of menu entries for "new"
343*cdf0e10cSrcweir             @param      "nWizardCount"  ,   returns count of menu entries for "wizard"
344*cdf0e10cSrcweir 			@return		A list of configuration key names is returned.
345*cdf0e10cSrcweir 
346*cdf0e10cSrcweir 			@onerror	-
347*cdf0e10cSrcweir 		*//*-*****************************************************************************************************/
348*cdf0e10cSrcweir 
349*cdf0e10cSrcweir         Sequence< OUString > impl_GetPropertyNames( sal_uInt32& nNewCount, sal_uInt32& nWizardCount, sal_uInt32& nHelpBookmarksCount );
350*cdf0e10cSrcweir 
351*cdf0e10cSrcweir         /*-****************************************************************************************************//**
352*cdf0e10cSrcweir             @short      sort given source list and expand it for all well known properties to destination
353*cdf0e10cSrcweir             @descr      We must support sets of entries with count inside the name .. but some of them could be missing!
354*cdf0e10cSrcweir                         e.g. s1-s2-s3-s0-u1-s6-u5-u7
355*cdf0e10cSrcweir                         Then we must sort it by name and expand it to the follow one:
356*cdf0e10cSrcweir                             sSetNode/s0/URL
357*cdf0e10cSrcweir                             sSetNode/s0/Title
358*cdf0e10cSrcweir                             sSetNode/s0/...
359*cdf0e10cSrcweir                             sSetNode/s1/URL
360*cdf0e10cSrcweir                             sSetNode/s1/Title
361*cdf0e10cSrcweir                             sSetNode/s1/...
362*cdf0e10cSrcweir                             ...
363*cdf0e10cSrcweir                             sSetNode/s6/URL
364*cdf0e10cSrcweir                             sSetNode/s6/Title
365*cdf0e10cSrcweir                             sSetNode/s6/...
366*cdf0e10cSrcweir                             sSetNode/u1/URL
367*cdf0e10cSrcweir                             sSetNode/u1/Title
368*cdf0e10cSrcweir                             sSetNode/u1/...
369*cdf0e10cSrcweir                             ...
370*cdf0e10cSrcweir                             sSetNode/u7/URL
371*cdf0e10cSrcweir                             sSetNode/u7/Title
372*cdf0e10cSrcweir                             sSetNode/u7/...
373*cdf0e10cSrcweir                         Rules: We start with all setup written entries names "sx" and x=[0..n].
374*cdf0e10cSrcweir                         Then we handle all "ux" items. Inside these blocks we sort it ascending by number.
375*cdf0e10cSrcweir 
376*cdf0e10cSrcweir             @attention  We add these expanded list to the end of given "lDestination" list!
377*cdf0e10cSrcweir                         So we must start on "lDestination.getLength()".
378*cdf0e10cSrcweir                         Reallocation of memory of destination list is done by us!
379*cdf0e10cSrcweir 
380*cdf0e10cSrcweir             @seealso    method impl_GetPropertyNames()
381*cdf0e10cSrcweir 
382*cdf0e10cSrcweir             @param      "lSource"      ,   original list (e.g. [m1-m2-m3-m6-m0] )
383*cdf0e10cSrcweir             @param      "lDestination" ,   destination of operation
384*cdf0e10cSrcweir             @param      "sSetNode"     ,   name of configuration set to build complete path
385*cdf0e10cSrcweir 			@return		A list of configuration key names is returned.
386*cdf0e10cSrcweir 
387*cdf0e10cSrcweir 			@onerror	-
388*cdf0e10cSrcweir 		*//*-*****************************************************************************************************/
389*cdf0e10cSrcweir 
390*cdf0e10cSrcweir         void impl_SortAndExpandPropertyNames( const Sequence< OUString >& lSource      ,
391*cdf0e10cSrcweir                                                     Sequence< OUString >& lDestination ,
392*cdf0e10cSrcweir                                               const OUString&             sSetNode     );
393*cdf0e10cSrcweir 
394*cdf0e10cSrcweir 	//-------------------------------------------------------------------------------------------------------------
395*cdf0e10cSrcweir 	//	private member
396*cdf0e10cSrcweir 	//-------------------------------------------------------------------------------------------------------------
397*cdf0e10cSrcweir 
398*cdf0e10cSrcweir 	private:
399*cdf0e10cSrcweir 
400*cdf0e10cSrcweir         SvtDynMenu  m_aNewMenu              ;
401*cdf0e10cSrcweir         SvtDynMenu  m_aWizardMenu           ;
402*cdf0e10cSrcweir         SvtDynMenu  m_aHelpBookmarksMenu    ;
403*cdf0e10cSrcweir };
404*cdf0e10cSrcweir 
405*cdf0e10cSrcweir //_________________________________________________________________________________________________________________
406*cdf0e10cSrcweir //	definitions
407*cdf0e10cSrcweir //_________________________________________________________________________________________________________________
408*cdf0e10cSrcweir 
409*cdf0e10cSrcweir //*****************************************************************************************************************
410*cdf0e10cSrcweir //	constructor
411*cdf0e10cSrcweir //*****************************************************************************************************************
412*cdf0e10cSrcweir SvtDynamicMenuOptions_Impl::SvtDynamicMenuOptions_Impl()
413*cdf0e10cSrcweir 	// Init baseclasses first
414*cdf0e10cSrcweir     :   ConfigItem( ROOTNODE_MENUS )
415*cdf0e10cSrcweir 	// Init member then...
416*cdf0e10cSrcweir {
417*cdf0e10cSrcweir     // Get names and values of all accessable menu entries and fill internal structures.
418*cdf0e10cSrcweir 	// See impl_GetPropertyNames() for further informations.
419*cdf0e10cSrcweir     sal_uInt32              nNewCount           = 0;
420*cdf0e10cSrcweir     sal_uInt32              nWizardCount        = 0;
421*cdf0e10cSrcweir     sal_uInt32              nHelpBookmarksCount = 0;
422*cdf0e10cSrcweir     Sequence< OUString >    lNames              = impl_GetPropertyNames ( nNewCount           ,
423*cdf0e10cSrcweir                                                                           nWizardCount        ,
424*cdf0e10cSrcweir                                                                           nHelpBookmarksCount );
425*cdf0e10cSrcweir     Sequence< Any >         lValues             = GetProperties         ( lNames              );
426*cdf0e10cSrcweir 
427*cdf0e10cSrcweir 	// Safe impossible cases.
428*cdf0e10cSrcweir 	// We need values from ALL configuration keys.
429*cdf0e10cSrcweir 	// Follow assignment use order of values in relation to our list of key names!
430*cdf0e10cSrcweir     DBG_ASSERT( !(lNames.getLength()!=lValues.getLength()), "SvtDynamicMenuOptions_Impl::SvtDynamicMenuOptions_Impl()\nI miss some values of configuration keys!\n" );
431*cdf0e10cSrcweir 
432*cdf0e10cSrcweir 	// Copy values from list in right order to ouer internal member.
433*cdf0e10cSrcweir 	// Attention: List for names and values have an internal construction pattern!
434*cdf0e10cSrcweir     //
435*cdf0e10cSrcweir     // first "New" menu ...
436*cdf0e10cSrcweir     //      Name                            Value
437*cdf0e10cSrcweir     //      /New/1/URL                      "private:factory/swriter"
438*cdf0e10cSrcweir     //      /New/1/Title                    "Neues Writer Dokument"
439*cdf0e10cSrcweir     //      /New/1/ImageIdentifier          "icon_writer"
440*cdf0e10cSrcweir     //      /New/1/TargetName               "_blank"
441*cdf0e10cSrcweir     //
442*cdf0e10cSrcweir     //      /New/2/URL                      "private:factory/scalc"
443*cdf0e10cSrcweir     //      /New/2/Title                    "Neues Calc Dokument"
444*cdf0e10cSrcweir     //      /New/2/ImageIdentifier          "icon_calc"
445*cdf0e10cSrcweir     //      /New/2/TargetName               "_blank"
446*cdf0e10cSrcweir     //
447*cdf0e10cSrcweir     // second "Wizard" menu ...
448*cdf0e10cSrcweir     //      /Wizard/1/URL                   "file://b"
449*cdf0e10cSrcweir     //      /Wizard/1/Title                 "MalWas"
450*cdf0e10cSrcweir     //      /Wizard/1/ImageIdentifier       "icon_?"
451*cdf0e10cSrcweir     //      /Wizard/1/TargetName            "_self"
452*cdf0e10cSrcweir     //
453*cdf0e10cSrcweir     //      ... and so on ...
454*cdf0e10cSrcweir 
455*cdf0e10cSrcweir     sal_uInt32  nItem     = 0 ;
456*cdf0e10cSrcweir     sal_uInt32  nPosition = 0 ;
457*cdf0e10cSrcweir     OUString    sName         ;
458*cdf0e10cSrcweir 
459*cdf0e10cSrcweir     // We must use these one instance object(!) to get information about installed modules.
460*cdf0e10cSrcweir     // These information are used to filter menu entries wich need not installed modules ...
461*cdf0e10cSrcweir     // Such entries shouldnt be available then!
462*cdf0e10cSrcweir     // see impl_IsEntrySupported() too
463*cdf0e10cSrcweir     SvtModuleOptions aModuleOptions;
464*cdf0e10cSrcweir 
465*cdf0e10cSrcweir     // Get names/values for new menu.
466*cdf0e10cSrcweir 	// 4 subkeys for every item!
467*cdf0e10cSrcweir     for( nItem=0; nItem<nNewCount; ++nItem )
468*cdf0e10cSrcweir 	{
469*cdf0e10cSrcweir         SvtDynMenuEntry   aItem                       ;
470*cdf0e10cSrcweir         lValues[nPosition] >>= aItem.sURL             ;
471*cdf0e10cSrcweir 		++nPosition;
472*cdf0e10cSrcweir         lValues[nPosition] >>= aItem.sTitle           ;
473*cdf0e10cSrcweir 		++nPosition;
474*cdf0e10cSrcweir         lValues[nPosition] >>= aItem.sImageIdentifier ;
475*cdf0e10cSrcweir 		++nPosition;
476*cdf0e10cSrcweir         lValues[nPosition] >>= aItem.sTargetName      ;
477*cdf0e10cSrcweir 		++nPosition;
478*cdf0e10cSrcweir         m_aNewMenu.AppendSetupEntry( aItem );
479*cdf0e10cSrcweir 	}
480*cdf0e10cSrcweir 
481*cdf0e10cSrcweir 	// Attention: Don't reset nPosition here!
482*cdf0e10cSrcweir 
483*cdf0e10cSrcweir     // Get names/values for wizard menu.
484*cdf0e10cSrcweir 	// 4 subkeys for every item!
485*cdf0e10cSrcweir     for( nItem=0; nItem<nWizardCount; ++nItem )
486*cdf0e10cSrcweir 	{
487*cdf0e10cSrcweir         SvtDynMenuEntry   aItem                       ;
488*cdf0e10cSrcweir         lValues[nPosition] >>= aItem.sURL             ;
489*cdf0e10cSrcweir 		++nPosition;
490*cdf0e10cSrcweir         lValues[nPosition] >>= aItem.sTitle           ;
491*cdf0e10cSrcweir 		++nPosition;
492*cdf0e10cSrcweir         lValues[nPosition] >>= aItem.sImageIdentifier ;
493*cdf0e10cSrcweir 		++nPosition;
494*cdf0e10cSrcweir         lValues[nPosition] >>= aItem.sTargetName      ;
495*cdf0e10cSrcweir 		++nPosition;
496*cdf0e10cSrcweir         m_aWizardMenu.AppendSetupEntry( aItem );
497*cdf0e10cSrcweir 	}
498*cdf0e10cSrcweir 
499*cdf0e10cSrcweir 	// Attention: Don't reset nPosition here!
500*cdf0e10cSrcweir 
501*cdf0e10cSrcweir 	// Get names/values for wizard menu.
502*cdf0e10cSrcweir 	// 4 subkeys for every item!
503*cdf0e10cSrcweir     for( nItem=0; nItem<nHelpBookmarksCount; ++nItem )
504*cdf0e10cSrcweir 	{
505*cdf0e10cSrcweir         SvtDynMenuEntry   aItem                       ;
506*cdf0e10cSrcweir         lValues[nPosition] >>= aItem.sURL             ;
507*cdf0e10cSrcweir 		++nPosition;
508*cdf0e10cSrcweir         lValues[nPosition] >>= aItem.sTitle           ;
509*cdf0e10cSrcweir 		++nPosition;
510*cdf0e10cSrcweir         lValues[nPosition] >>= aItem.sImageIdentifier ;
511*cdf0e10cSrcweir 		++nPosition;
512*cdf0e10cSrcweir         lValues[nPosition] >>= aItem.sTargetName      ;
513*cdf0e10cSrcweir 		++nPosition;
514*cdf0e10cSrcweir         m_aHelpBookmarksMenu.AppendSetupEntry( aItem );
515*cdf0e10cSrcweir 	}
516*cdf0e10cSrcweir 
517*cdf0e10cSrcweir /*TODO: Not used in the moment! see Notify() ...
518*cdf0e10cSrcweir 	// Enable notification mechanism of ouer baseclass.
519*cdf0e10cSrcweir 	// We need it to get information about changes outside these class on ouer used configuration keys!
520*cdf0e10cSrcweir     EnableNotification( lNames );
521*cdf0e10cSrcweir */
522*cdf0e10cSrcweir }
523*cdf0e10cSrcweir 
524*cdf0e10cSrcweir //*****************************************************************************************************************
525*cdf0e10cSrcweir //	destructor
526*cdf0e10cSrcweir //*****************************************************************************************************************
527*cdf0e10cSrcweir SvtDynamicMenuOptions_Impl::~SvtDynamicMenuOptions_Impl()
528*cdf0e10cSrcweir {
529*cdf0e10cSrcweir 	// We must save our current values .. if user forget it!
530*cdf0e10cSrcweir 	if( IsModified() == sal_True )
531*cdf0e10cSrcweir 	{
532*cdf0e10cSrcweir 		Commit();
533*cdf0e10cSrcweir 	}
534*cdf0e10cSrcweir }
535*cdf0e10cSrcweir 
536*cdf0e10cSrcweir //*****************************************************************************************************************
537*cdf0e10cSrcweir //	public method
538*cdf0e10cSrcweir //*****************************************************************************************************************
539*cdf0e10cSrcweir void SvtDynamicMenuOptions_Impl::Notify( const Sequence< OUString >& )
540*cdf0e10cSrcweir {
541*cdf0e10cSrcweir     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" );
542*cdf0e10cSrcweir }
543*cdf0e10cSrcweir 
544*cdf0e10cSrcweir //*****************************************************************************************************************
545*cdf0e10cSrcweir //	public method
546*cdf0e10cSrcweir //*****************************************************************************************************************
547*cdf0e10cSrcweir void SvtDynamicMenuOptions_Impl::Commit()
548*cdf0e10cSrcweir {
549*cdf0e10cSrcweir     DBG_ERROR( "SvtDynamicMenuOptions_Impl::Commit()\nNot implemented yet!\n" );
550*cdf0e10cSrcweir     /*
551*cdf0e10cSrcweir     // Write all properties!
552*cdf0e10cSrcweir     // Delete complete sets first.
553*cdf0e10cSrcweir     ClearNodeSet( SETNODE_NEWMENU    );
554*cdf0e10cSrcweir     ClearNodeSet( SETNODE_WIZARDMENU );
555*cdf0e10cSrcweir     ClearNodeSet( SETNODE_HELPBOOKMARKS );
556*cdf0e10cSrcweir 
557*cdf0e10cSrcweir     MenuEntry                    aItem                           ;
558*cdf0e10cSrcweir     OUString                    sNode                           ;
559*cdf0e10cSrcweir     Sequence< PropertyValue >   lPropertyValues( PROPERTYCOUNT );
560*cdf0e10cSrcweir     sal_uInt32                  nItem          = 0              ;
561*cdf0e10cSrcweir 
562*cdf0e10cSrcweir     // Copy "new" menu entries to save-list!
563*cdf0e10cSrcweir     sal_uInt32 nNewCount = m_aNewMenu.size();
564*cdf0e10cSrcweir     for( nItem=0; nItem<nNewCount; ++nItem )
565*cdf0e10cSrcweir 	{
566*cdf0e10cSrcweir         aItem = m_aNewMenu[nItem];
567*cdf0e10cSrcweir         // Format:  "New/1/URL"
568*cdf0e10cSrcweir         //          "New/1/Title"
569*cdf0e10cSrcweir         //          ...
570*cdf0e10cSrcweir         sNode = SETNODE_NEWMENU + PATHDELIMITER + PATHPREFIX + OUString::valueOf( (sal_Int32)nItem ) + PATHDELIMITER;
571*cdf0e10cSrcweir 
572*cdf0e10cSrcweir         lPropertyValues[OFFSET_URL             ].Name  =   sNode + PROPERTYNAME_URL             ;
573*cdf0e10cSrcweir         lPropertyValues[OFFSET_TITLE           ].Name  =   sNode + PROPERTYNAME_TITLE           ;
574*cdf0e10cSrcweir         lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Name  =   sNode + PROPERTYNAME_IMAGEIDENTIFIER ;
575*cdf0e10cSrcweir         lPropertyValues[OFFSET_TARGETNAME      ].Name  =   sNode + PROPERTYNAME_TARGETNAME      ;
576*cdf0e10cSrcweir 
577*cdf0e10cSrcweir         lPropertyValues[OFFSET_URL             ].Value <<= aItem.sURL                           ;
578*cdf0e10cSrcweir         lPropertyValues[OFFSET_TITLE           ].Value <<= aItem.sTitle                         ;
579*cdf0e10cSrcweir         lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Value <<= aItem.sImageIdentifier               ;
580*cdf0e10cSrcweir         lPropertyValues[OFFSET_TARGETNAME      ].Value <<= aItem.sTargetName                    ;
581*cdf0e10cSrcweir 
582*cdf0e10cSrcweir         SetSetProperties( SETNODE_NEWMENU, lPropertyValues );
583*cdf0e10cSrcweir 	}
584*cdf0e10cSrcweir 
585*cdf0e10cSrcweir     // Copy "wizard" menu entries to save-list!
586*cdf0e10cSrcweir     sal_uInt32 nWizardCount = m_aWizardMenu.size();
587*cdf0e10cSrcweir     for( nItem=0; nItem<nWizardCount; ++nItem )
588*cdf0e10cSrcweir 	{
589*cdf0e10cSrcweir         aItem = m_aWizardMenu[nItem];
590*cdf0e10cSrcweir         // Format:  "Wizard/1/URL"
591*cdf0e10cSrcweir         //          "Wizard/1/Title"
592*cdf0e10cSrcweir         //          ...
593*cdf0e10cSrcweir         sNode = SETNODE_WIZARDMENU + PATHDELIMITER + PATHPREFIX + OUString::valueOf( (sal_Int32)nItem ) + PATHDELIMITER;
594*cdf0e10cSrcweir 
595*cdf0e10cSrcweir         lPropertyValues[OFFSET_URL             ].Name  =   sNode + PROPERTYNAME_URL             ;
596*cdf0e10cSrcweir         lPropertyValues[OFFSET_TITLE           ].Name  =   sNode + PROPERTYNAME_TITLE           ;
597*cdf0e10cSrcweir         lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Name  =   sNode + PROPERTYNAME_IMAGEIDENTIFIER ;
598*cdf0e10cSrcweir         lPropertyValues[OFFSET_TARGETNAME      ].Name  =   sNode + PROPERTYNAME_TARGETNAME      ;
599*cdf0e10cSrcweir 
600*cdf0e10cSrcweir         lPropertyValues[OFFSET_URL             ].Value <<= aItem.sURL                           ;
601*cdf0e10cSrcweir         lPropertyValues[OFFSET_TITLE           ].Value <<= aItem.sTitle                         ;
602*cdf0e10cSrcweir         lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Value <<= aItem.sImageIdentifier               ;
603*cdf0e10cSrcweir         lPropertyValues[OFFSET_TARGETNAME      ].Value <<= aItem.sTargetName                    ;
604*cdf0e10cSrcweir 
605*cdf0e10cSrcweir         SetSetProperties( SETNODE_WIZARDMENU, lPropertyValues );
606*cdf0e10cSrcweir 	}
607*cdf0e10cSrcweir 
608*cdf0e10cSrcweir 	// Copy help bookmarks entries to save-list!
609*cdf0e10cSrcweir     sal_uInt32 nHelpBookmarksCount = m_aHelpBookmarksMenu.size();
610*cdf0e10cSrcweir     for( nItem=0; nItem<nHelpBookmarksCount; ++nItem )
611*cdf0e10cSrcweir 	{
612*cdf0e10cSrcweir         aItem = m_aHelpBookmarksMenu[nItem];
613*cdf0e10cSrcweir         // Format:  "HelpBookmarks/1/URL"
614*cdf0e10cSrcweir         //          "HelpBookmarks/1/Title"
615*cdf0e10cSrcweir         //          ...
616*cdf0e10cSrcweir         sNode = SETNODE_HELPBOOKMARKS + PATHDELIMITER + PATHPREFIX + OUString::valueOf( (sal_Int32)nItem ) + PATHDELIMITER;
617*cdf0e10cSrcweir 
618*cdf0e10cSrcweir         lPropertyValues[OFFSET_URL             ].Name  =   sNode + PROPERTYNAME_URL             ;
619*cdf0e10cSrcweir         lPropertyValues[OFFSET_TITLE           ].Name  =   sNode + PROPERTYNAME_TITLE           ;
620*cdf0e10cSrcweir         lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Name  =   sNode + PROPERTYNAME_IMAGEIDENTIFIER ;
621*cdf0e10cSrcweir         lPropertyValues[OFFSET_TARGETNAME      ].Name  =   sNode + PROPERTYNAME_TARGETNAME      ;
622*cdf0e10cSrcweir 
623*cdf0e10cSrcweir         lPropertyValues[OFFSET_URL             ].Value <<= aItem.sURL                           ;
624*cdf0e10cSrcweir         lPropertyValues[OFFSET_TITLE           ].Value <<= aItem.sTitle                         ;
625*cdf0e10cSrcweir         lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Value <<= aItem.sImageIdentifier               ;
626*cdf0e10cSrcweir         lPropertyValues[OFFSET_TARGETNAME      ].Value <<= aItem.sTargetName                    ;
627*cdf0e10cSrcweir 
628*cdf0e10cSrcweir         SetSetProperties( SETNODE_HELPBOOKMARKS, lPropertyValues );
629*cdf0e10cSrcweir 	}
630*cdf0e10cSrcweir     */
631*cdf0e10cSrcweir }
632*cdf0e10cSrcweir 
633*cdf0e10cSrcweir //*****************************************************************************************************************
634*cdf0e10cSrcweir //	public method
635*cdf0e10cSrcweir //*****************************************************************************************************************
636*cdf0e10cSrcweir void SvtDynamicMenuOptions_Impl::Clear( EDynamicMenuType eMenu )
637*cdf0e10cSrcweir {
638*cdf0e10cSrcweir     switch( eMenu )
639*cdf0e10cSrcweir 	{
640*cdf0e10cSrcweir         case E_NEWMENU      :   {
641*cdf0e10cSrcweir                                     m_aNewMenu.Clear();
642*cdf0e10cSrcweir                                     SetModified();
643*cdf0e10cSrcweir                                 }
644*cdf0e10cSrcweir                                 break;
645*cdf0e10cSrcweir 
646*cdf0e10cSrcweir         case E_WIZARDMENU   :   {
647*cdf0e10cSrcweir                                     m_aWizardMenu.Clear();
648*cdf0e10cSrcweir                                     SetModified();
649*cdf0e10cSrcweir                                 }
650*cdf0e10cSrcweir                                 break;
651*cdf0e10cSrcweir 
652*cdf0e10cSrcweir         case E_HELPBOOKMARKS :  {
653*cdf0e10cSrcweir                                     m_aHelpBookmarksMenu.Clear();
654*cdf0e10cSrcweir                                     SetModified();
655*cdf0e10cSrcweir                                 }
656*cdf0e10cSrcweir                                 break;
657*cdf0e10cSrcweir 	}
658*cdf0e10cSrcweir }
659*cdf0e10cSrcweir 
660*cdf0e10cSrcweir //*****************************************************************************************************************
661*cdf0e10cSrcweir //	public method
662*cdf0e10cSrcweir //*****************************************************************************************************************
663*cdf0e10cSrcweir Sequence< Sequence< PropertyValue > > SvtDynamicMenuOptions_Impl::GetMenu( EDynamicMenuType eMenu ) const
664*cdf0e10cSrcweir {
665*cdf0e10cSrcweir     Sequence< Sequence< PropertyValue > > lReturn;
666*cdf0e10cSrcweir     switch( eMenu )
667*cdf0e10cSrcweir 	{
668*cdf0e10cSrcweir         case E_NEWMENU      :   {
669*cdf0e10cSrcweir                                     lReturn = m_aNewMenu.GetList();
670*cdf0e10cSrcweir                                 }
671*cdf0e10cSrcweir                                 break;
672*cdf0e10cSrcweir 
673*cdf0e10cSrcweir         case E_WIZARDMENU   :   {
674*cdf0e10cSrcweir                                     lReturn = m_aWizardMenu.GetList();
675*cdf0e10cSrcweir                                 }
676*cdf0e10cSrcweir                                 break;
677*cdf0e10cSrcweir 
678*cdf0e10cSrcweir         case E_HELPBOOKMARKS :  {
679*cdf0e10cSrcweir                                     lReturn = m_aHelpBookmarksMenu.GetList();
680*cdf0e10cSrcweir                                 }
681*cdf0e10cSrcweir                                 break;
682*cdf0e10cSrcweir 	}
683*cdf0e10cSrcweir     return lReturn;
684*cdf0e10cSrcweir }
685*cdf0e10cSrcweir 
686*cdf0e10cSrcweir //*****************************************************************************************************************
687*cdf0e10cSrcweir //	public method
688*cdf0e10cSrcweir //*****************************************************************************************************************
689*cdf0e10cSrcweir void SvtDynamicMenuOptions_Impl::AppendItem(            EDynamicMenuType    eMenu           ,
690*cdf0e10cSrcweir                                                 const   OUString&           sURL            ,
691*cdf0e10cSrcweir                                                 const   OUString&           sTitle          ,
692*cdf0e10cSrcweir                                                 const   OUString&           sImageIdentifier,
693*cdf0e10cSrcweir                                                 const   OUString&           sTargetName     )
694*cdf0e10cSrcweir {
695*cdf0e10cSrcweir     SvtDynMenuEntry aItem( sURL, sTitle, sImageIdentifier, sTargetName );
696*cdf0e10cSrcweir 
697*cdf0e10cSrcweir     switch( eMenu )
698*cdf0e10cSrcweir 	{
699*cdf0e10cSrcweir         case E_NEWMENU  :   {
700*cdf0e10cSrcweir                                 m_aNewMenu.AppendUserEntry( aItem );
701*cdf0e10cSrcweir 								SetModified();
702*cdf0e10cSrcweir 							}
703*cdf0e10cSrcweir 							break;
704*cdf0e10cSrcweir 
705*cdf0e10cSrcweir         case E_WIZARDMENU   :   {
706*cdf0e10cSrcweir                                 m_aWizardMenu.AppendUserEntry( aItem );
707*cdf0e10cSrcweir 								SetModified();
708*cdf0e10cSrcweir 							}
709*cdf0e10cSrcweir 							break;
710*cdf0e10cSrcweir 
711*cdf0e10cSrcweir         case E_HELPBOOKMARKS :  {
712*cdf0e10cSrcweir                                 m_aHelpBookmarksMenu.AppendUserEntry( aItem );
713*cdf0e10cSrcweir 								SetModified();
714*cdf0e10cSrcweir 							}
715*cdf0e10cSrcweir 							break;
716*cdf0e10cSrcweir 	}
717*cdf0e10cSrcweir }
718*cdf0e10cSrcweir 
719*cdf0e10cSrcweir //*****************************************************************************************************************
720*cdf0e10cSrcweir //	private method
721*cdf0e10cSrcweir //*****************************************************************************************************************
722*cdf0e10cSrcweir Sequence< OUString > SvtDynamicMenuOptions_Impl::impl_GetPropertyNames( sal_uInt32& nNewCount, sal_uInt32& nWizardCount, sal_uInt32& nHelpBookmarksCount )
723*cdf0e10cSrcweir {
724*cdf0e10cSrcweir 	// First get ALL names of current existing list items in configuration!
725*cdf0e10cSrcweir     Sequence< OUString > lNewItems           = GetNodeNames( SETNODE_NEWMENU       );
726*cdf0e10cSrcweir     Sequence< OUString > lWizardItems        = GetNodeNames( SETNODE_WIZARDMENU    );
727*cdf0e10cSrcweir     Sequence< OUString > lHelpBookmarksItems = GetNodeNames( SETNODE_HELPBOOKMARKS );
728*cdf0e10cSrcweir 
729*cdf0e10cSrcweir 	// Get information about list counts ...
730*cdf0e10cSrcweir     nNewCount           = lNewItems.getLength          ();
731*cdf0e10cSrcweir     nWizardCount        = lWizardItems.getLength       ();
732*cdf0e10cSrcweir     nHelpBookmarksCount = lHelpBookmarksItems.getLength();
733*cdf0e10cSrcweir 
734*cdf0e10cSrcweir     // Sort and expand all three list to result list ...
735*cdf0e10cSrcweir     Sequence< OUString > lProperties;
736*cdf0e10cSrcweir     impl_SortAndExpandPropertyNames( lNewItems          , lProperties, SETNODE_NEWMENU       );
737*cdf0e10cSrcweir     impl_SortAndExpandPropertyNames( lWizardItems       , lProperties, SETNODE_WIZARDMENU    );
738*cdf0e10cSrcweir     impl_SortAndExpandPropertyNames( lHelpBookmarksItems, lProperties, SETNODE_HELPBOOKMARKS );
739*cdf0e10cSrcweir 
740*cdf0e10cSrcweir 	// Return result.
741*cdf0e10cSrcweir     return lProperties;
742*cdf0e10cSrcweir }
743*cdf0e10cSrcweir 
744*cdf0e10cSrcweir //*****************************************************************************************************************
745*cdf0e10cSrcweir //  private helper
746*cdf0e10cSrcweir //*****************************************************************************************************************
747*cdf0e10cSrcweir class CountWithPrefixSort
748*cdf0e10cSrcweir {
749*cdf0e10cSrcweir     public:
750*cdf0e10cSrcweir         int operator() ( const OUString& s1 ,
751*cdf0e10cSrcweir                          const OUString& s2 ) const
752*cdf0e10cSrcweir         {
753*cdf0e10cSrcweir             // Get order numbers from entry name without prefix.
754*cdf0e10cSrcweir             // e.g. "m10" => 10
755*cdf0e10cSrcweir             //      "m5"  => 5
756*cdf0e10cSrcweir             sal_Int32 n1 = s1.copy( 1, s1.getLength()-1 ).toInt32();
757*cdf0e10cSrcweir             sal_Int32 n2 = s2.copy( 1, s2.getLength()-1 ).toInt32();
758*cdf0e10cSrcweir             // MUST be in [0,1] ... because it's a difference between
759*cdf0e10cSrcweir             // insert-positions of given entries in sorted list!
760*cdf0e10cSrcweir             return( n1<n2 );
761*cdf0e10cSrcweir         }
762*cdf0e10cSrcweir };
763*cdf0e10cSrcweir 
764*cdf0e10cSrcweir class SelectByPrefix
765*cdf0e10cSrcweir {
766*cdf0e10cSrcweir     public:
767*cdf0e10cSrcweir         bool operator() ( const OUString& s ) const
768*cdf0e10cSrcweir         {
769*cdf0e10cSrcweir             // Prefer setup written entries by check first letter of given string. It must be a "s".
770*cdf0e10cSrcweir             return( s.indexOf( PATHPREFIX_SETUP ) == 0 );
771*cdf0e10cSrcweir         }
772*cdf0e10cSrcweir };
773*cdf0e10cSrcweir 
774*cdf0e10cSrcweir //*****************************************************************************************************************
775*cdf0e10cSrcweir //	private method
776*cdf0e10cSrcweir //*****************************************************************************************************************
777*cdf0e10cSrcweir void SvtDynamicMenuOptions_Impl::impl_SortAndExpandPropertyNames( const Sequence< OUString >& lSource      ,
778*cdf0e10cSrcweir                                                                         Sequence< OUString >& lDestination ,
779*cdf0e10cSrcweir                                                                   const OUString&             sSetNode     )
780*cdf0e10cSrcweir {
781*cdf0e10cSrcweir     OUString            sFixPath                                    ;
782*cdf0e10cSrcweir     vector< OUString >  lTemp                                       ;
783*cdf0e10cSrcweir     sal_Int32           nSourceCount     = lSource.getLength()      ;
784*cdf0e10cSrcweir     sal_Int32           nDestinationStep = lDestination.getLength() ; // start on end of current list ...!
785*cdf0e10cSrcweir 
786*cdf0e10cSrcweir     lDestination.realloc( (nSourceCount*PROPERTYCOUNT)+nDestinationStep ); // get enough memory for copy operations after nDestination ...
787*cdf0e10cSrcweir 
788*cdf0e10cSrcweir     // Copy all items to temp. vector to use fast sort operations :-)
789*cdf0e10cSrcweir     for( sal_Int32 nSourceStep=0; nSourceStep<nSourceCount; ++nSourceStep )
790*cdf0e10cSrcweir         lTemp.push_back( lSource[nSourceStep] );
791*cdf0e10cSrcweir 
792*cdf0e10cSrcweir     // Sort all entries by number ...
793*cdf0e10cSrcweir     stable_sort( lTemp.begin(), lTemp.end(), CountWithPrefixSort() );
794*cdf0e10cSrcweir     // and split into setup & user written entries!
795*cdf0e10cSrcweir     stable_partition( lTemp.begin(), lTemp.end(), SelectByPrefix() );
796*cdf0e10cSrcweir 
797*cdf0e10cSrcweir     // Copy sorted entries to destination and expand every item with
798*cdf0e10cSrcweir     // 4 supported sub properties.
799*cdf0e10cSrcweir     for( vector< OUString >::const_iterator pItem =lTemp.begin() ;
800*cdf0e10cSrcweir                                             pItem!=lTemp.end()   ;
801*cdf0e10cSrcweir                                             ++pItem              )
802*cdf0e10cSrcweir     {
803*cdf0e10cSrcweir         sFixPath  = sSetNode       ;
804*cdf0e10cSrcweir         sFixPath += PATHDELIMITER  ;
805*cdf0e10cSrcweir         sFixPath += *pItem         ;
806*cdf0e10cSrcweir         sFixPath += PATHDELIMITER  ;
807*cdf0e10cSrcweir 
808*cdf0e10cSrcweir         lDestination[nDestinationStep]  = sFixPath                      ;
809*cdf0e10cSrcweir         lDestination[nDestinationStep] += PROPERTYNAME_URL              ;
810*cdf0e10cSrcweir         ++nDestinationStep;
811*cdf0e10cSrcweir         lDestination[nDestinationStep]  = sFixPath                      ;
812*cdf0e10cSrcweir         lDestination[nDestinationStep] += PROPERTYNAME_TITLE            ;
813*cdf0e10cSrcweir         ++nDestinationStep;
814*cdf0e10cSrcweir         lDestination[nDestinationStep]  = sFixPath                      ;
815*cdf0e10cSrcweir         lDestination[nDestinationStep] += PROPERTYNAME_IMAGEIDENTIFIER  ;
816*cdf0e10cSrcweir         ++nDestinationStep;
817*cdf0e10cSrcweir         lDestination[nDestinationStep]  = sFixPath                      ;
818*cdf0e10cSrcweir         lDestination[nDestinationStep] += PROPERTYNAME_TARGETNAME       ;
819*cdf0e10cSrcweir         ++nDestinationStep;
820*cdf0e10cSrcweir     }
821*cdf0e10cSrcweir }
822*cdf0e10cSrcweir 
823*cdf0e10cSrcweir //*****************************************************************************************************************
824*cdf0e10cSrcweir //	initialize static member
825*cdf0e10cSrcweir //	DON'T DO IT IN YOUR HEADER!
826*cdf0e10cSrcweir //	see definition for further informations
827*cdf0e10cSrcweir //*****************************************************************************************************************
828*cdf0e10cSrcweir SvtDynamicMenuOptions_Impl*     SvtDynamicMenuOptions::m_pDataContainer = NULL  ;
829*cdf0e10cSrcweir sal_Int32                       SvtDynamicMenuOptions::m_nRefCount      = 0     ;
830*cdf0e10cSrcweir 
831*cdf0e10cSrcweir //*****************************************************************************************************************
832*cdf0e10cSrcweir //	constructor
833*cdf0e10cSrcweir //*****************************************************************************************************************
834*cdf0e10cSrcweir SvtDynamicMenuOptions::SvtDynamicMenuOptions()
835*cdf0e10cSrcweir {
836*cdf0e10cSrcweir     // Global access, must be guarded (multithreading!).
837*cdf0e10cSrcweir     MutexGuard aGuard( GetOwnStaticMutex() );
838*cdf0e10cSrcweir 	// Increase ouer refcount ...
839*cdf0e10cSrcweir 	++m_nRefCount;
840*cdf0e10cSrcweir 	// ... and initialize ouer data container only if it not already exist!
841*cdf0e10cSrcweir     if( m_pDataContainer == NULL )
842*cdf0e10cSrcweir 	{
843*cdf0e10cSrcweir         m_pDataContainer = new SvtDynamicMenuOptions_Impl;
844*cdf0e10cSrcweir         ItemHolder1::holdConfigItem(E_DYNAMICMENUOPTIONS);
845*cdf0e10cSrcweir 	}
846*cdf0e10cSrcweir }
847*cdf0e10cSrcweir 
848*cdf0e10cSrcweir //*****************************************************************************************************************
849*cdf0e10cSrcweir //	destructor
850*cdf0e10cSrcweir //*****************************************************************************************************************
851*cdf0e10cSrcweir SvtDynamicMenuOptions::~SvtDynamicMenuOptions()
852*cdf0e10cSrcweir {
853*cdf0e10cSrcweir     // Global access, must be guarded (multithreading!)
854*cdf0e10cSrcweir     MutexGuard aGuard( GetOwnStaticMutex() );
855*cdf0e10cSrcweir 	// Decrease ouer refcount.
856*cdf0e10cSrcweir 	--m_nRefCount;
857*cdf0e10cSrcweir 	// If last instance was deleted ...
858*cdf0e10cSrcweir 	// we must destroy ouer static data container!
859*cdf0e10cSrcweir     if( m_nRefCount <= 0 )
860*cdf0e10cSrcweir 	{
861*cdf0e10cSrcweir 		delete m_pDataContainer;
862*cdf0e10cSrcweir 		m_pDataContainer = NULL;
863*cdf0e10cSrcweir 	}
864*cdf0e10cSrcweir }
865*cdf0e10cSrcweir 
866*cdf0e10cSrcweir //*****************************************************************************************************************
867*cdf0e10cSrcweir //	public method
868*cdf0e10cSrcweir //*****************************************************************************************************************
869*cdf0e10cSrcweir void SvtDynamicMenuOptions::Clear( EDynamicMenuType eMenu )
870*cdf0e10cSrcweir {
871*cdf0e10cSrcweir     MutexGuard aGuard( GetOwnStaticMutex() );
872*cdf0e10cSrcweir     m_pDataContainer->Clear( eMenu );
873*cdf0e10cSrcweir }
874*cdf0e10cSrcweir 
875*cdf0e10cSrcweir //*****************************************************************************************************************
876*cdf0e10cSrcweir //	public method
877*cdf0e10cSrcweir //*****************************************************************************************************************
878*cdf0e10cSrcweir Sequence< Sequence< PropertyValue > > SvtDynamicMenuOptions::GetMenu( EDynamicMenuType eMenu ) const
879*cdf0e10cSrcweir {
880*cdf0e10cSrcweir     MutexGuard aGuard( GetOwnStaticMutex() );
881*cdf0e10cSrcweir     return m_pDataContainer->GetMenu( eMenu );
882*cdf0e10cSrcweir }
883*cdf0e10cSrcweir 
884*cdf0e10cSrcweir //*****************************************************************************************************************
885*cdf0e10cSrcweir //	public method
886*cdf0e10cSrcweir //*****************************************************************************************************************
887*cdf0e10cSrcweir void SvtDynamicMenuOptions::AppendItem(         EDynamicMenuType    eMenu           ,
888*cdf0e10cSrcweir                                         const   OUString&           sURL            ,
889*cdf0e10cSrcweir                                         const   OUString&           sTitle          ,
890*cdf0e10cSrcweir                                         const   OUString&           sImageIdentifier,
891*cdf0e10cSrcweir                                         const   OUString&           sTargetName     )
892*cdf0e10cSrcweir {
893*cdf0e10cSrcweir     MutexGuard aGuard( GetOwnStaticMutex() );
894*cdf0e10cSrcweir     m_pDataContainer->AppendItem( eMenu, sURL, sTitle, sImageIdentifier, sTargetName );
895*cdf0e10cSrcweir }
896*cdf0e10cSrcweir 
897*cdf0e10cSrcweir //*****************************************************************************************************************
898*cdf0e10cSrcweir //	private method
899*cdf0e10cSrcweir //*****************************************************************************************************************
900*cdf0e10cSrcweir Mutex& SvtDynamicMenuOptions::GetOwnStaticMutex()
901*cdf0e10cSrcweir {
902*cdf0e10cSrcweir 	// Initialize static mutex only for one time!
903*cdf0e10cSrcweir     static Mutex* pMutex = NULL;
904*cdf0e10cSrcweir 	// If these method first called (Mutex not already exist!) ...
905*cdf0e10cSrcweir     if( pMutex == NULL )
906*cdf0e10cSrcweir     {
907*cdf0e10cSrcweir 		// ... we must create a new one. Protect follow code with the global mutex -
908*cdf0e10cSrcweir 		// It must be - we create a static variable!
909*cdf0e10cSrcweir         MutexGuard aGuard( Mutex::getGlobalMutex() );
910*cdf0e10cSrcweir 		// We must check our pointer again - because it can be that another instance of ouer class will be fastr then these!
911*cdf0e10cSrcweir         if( pMutex == NULL )
912*cdf0e10cSrcweir         {
913*cdf0e10cSrcweir 			// Create the new mutex and set it for return on static variable.
914*cdf0e10cSrcweir             static Mutex aMutex;
915*cdf0e10cSrcweir             pMutex = &aMutex;
916*cdf0e10cSrcweir         }
917*cdf0e10cSrcweir     }
918*cdf0e10cSrcweir 	// Return new created or already existing mutex object.
919*cdf0e10cSrcweir     return *pMutex;
920*cdf0e10cSrcweir }
921