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