LCOV - code coverage report
Current view: top level - unotools/source/config - dynamicmenuoptions.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 152 170 89.4 %
Date: 2015-06-13 12:38:46 Functions: 20 22 90.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       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/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      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 .
      18             :  */
      19             : 
      20             : #include <sal/config.h>
      21             : 
      22             : #include <sal/log.hxx>
      23             : #include <unotools/dynamicmenuoptions.hxx>
      24             : #include <unotools/moduleoptions.hxx>
      25             : #include <unotools/configmgr.hxx>
      26             : #include <unotools/configitem.hxx>
      27             : #include <tools/debug.hxx>
      28             : #include <com/sun/star/uno/Any.hxx>
      29             : #include <com/sun/star/uno/Sequence.hxx>
      30             : 
      31             : #include <vector>
      32             : 
      33             : #include "itemholder1.hxx"
      34             : 
      35             : #include <algorithm>
      36             : 
      37             : using namespace ::std;
      38             : using namespace ::utl;
      39             : using namespace ::osl;
      40             : using namespace ::com::sun::star::uno;
      41             : using namespace ::com::sun::star::beans;
      42             : 
      43             : #define ROOTNODE_MENUS                                  OUString("Office.Common/Menus/")
      44             : #define PATHDELIMITER                                   OUString("/")
      45             : 
      46             : #define SETNODE_NEWMENU                                 OUString("New")
      47             : #define SETNODE_WIZARDMENU                              OUString("Wizard")
      48             : #define SETNODE_HELPBOOKMARKS                           OUString("HelpBookmarks")
      49             : 
      50             : #define PROPERTYNAME_URL                                DYNAMICMENU_PROPERTYNAME_URL
      51             : #define PROPERTYNAME_TITLE                              DYNAMICMENU_PROPERTYNAME_TITLE
      52             : #define PROPERTYNAME_IMAGEIDENTIFIER                    DYNAMICMENU_PROPERTYNAME_IMAGEIDENTIFIER
      53             : #define PROPERTYNAME_TARGETNAME                         DYNAMICMENU_PROPERTYNAME_TARGETNAME
      54             : 
      55             : #define PROPERTYCOUNT                                   4
      56             : 
      57             : #define OFFSET_URL                                      0
      58             : #define OFFSET_TITLE                                    1
      59             : #define OFFSET_IMAGEIDENTIFIER                          2
      60             : #define OFFSET_TARGETNAME                               3
      61             : 
      62             : #define PATHPREFIX_SETUP                                OUString("m")
      63             : 
      64             : /*-****************************************************************************************************************
      65             :     @descr  struct to hold information about one menu entry.
      66             : ****************************************************************************************************************-*/
      67        7197 : struct SvtDynMenuEntry
      68             : {
      69             :         OUString    sName;
      70             :         OUString    sURL;
      71             :         OUString    sTitle;
      72             :         OUString    sImageIdentifier;
      73             :         OUString    sTargetName;
      74             : };
      75             : 
      76             : /*-****************************************************************************************************************
      77             :     @descr  support simple menu structures and operations on it
      78             : ****************************************************************************************************************-*/
      79         255 : class SvtDynMenu
      80             : {
      81             :     public:
      82             :         // append setup written menu entry
      83             :         // Don't touch name of entry. It was defined by setup and must be the same every time!
      84             :         // Look for double menu entries here too... may be some separator items are superflous...
      85        1161 :         void AppendSetupEntry( const SvtDynMenuEntry& rEntry )
      86             :         {
      87        2408 :             if(
      88        3311 :                 ( lSetupEntries.size()         <  1           )  ||
      89        4386 :                 ( lSetupEntries.rbegin()->sURL != rEntry.sURL )
      90             :               )
      91             :             {
      92        1161 :                 lSetupEntries.push_back( rEntry );
      93             :             }
      94        1161 :         }
      95             : 
      96             :         // convert internal list to external format
      97             :         // for using it on right menus really
      98             :         // Notice:   We build a property list with 4 entries and set it on result list then.
      99             :         //           The while-loop starts with pointer on internal member list lSetupEntries, change to
     100             :         //           lUserEntries then and stop after that with NULL!
     101             :         //           Separator entries will be packed in another way then normal entries! We define
     102             :         //           special strings "sEmpty" and "sSeparator" to perform too ...
     103         607 :         Sequence< Sequence< PropertyValue > > GetList() const
     104             :         {
     105         607 :             sal_Int32                             nSetupCount = (sal_Int32)lSetupEntries.size();
     106         607 :             sal_Int32                             nUserCount  = (sal_Int32)lUserEntries.size();
     107         607 :             sal_Int32                             nStep       = 0;
     108         607 :             Sequence< PropertyValue >             lProperties ( PROPERTYCOUNT );
     109         607 :             Sequence< Sequence< PropertyValue > > lResult     ( nSetupCount+nUserCount );
     110        1214 :             OUString                              sSeparator  ( "private:separator" );
     111        1214 :             OUString                              sEmpty;
     112         607 :             const vector< SvtDynMenuEntry >*            pList       = &lSetupEntries;
     113             : 
     114         607 :             lProperties[OFFSET_URL            ].Name = PROPERTYNAME_URL;
     115         607 :             lProperties[OFFSET_TITLE          ].Name = PROPERTYNAME_TITLE;
     116         607 :             lProperties[OFFSET_IMAGEIDENTIFIER].Name = PROPERTYNAME_IMAGEIDENTIFIER;
     117         607 :             lProperties[OFFSET_TARGETNAME     ].Name = PROPERTYNAME_TARGETNAME;
     118             : 
     119        2428 :             while( pList != NULL )
     120             :             {
     121       30957 :                 for( vector< SvtDynMenuEntry >::const_iterator pItem =pList->begin();
     122       20638 :                                                          pItem!=pList->end();
     123             :                                                          ++pItem              )
     124             :                 {
     125        9105 :                     if( pItem->sURL == sSeparator )
     126             :                     {
     127        1821 :                         lProperties[OFFSET_URL              ].Value <<= sSeparator;
     128        1821 :                         lProperties[OFFSET_TITLE            ].Value <<= sEmpty;
     129        1821 :                         lProperties[OFFSET_IMAGEIDENTIFIER  ].Value <<= sEmpty;
     130        1821 :                         lProperties[OFFSET_TARGETNAME       ].Value <<= sEmpty;
     131             :                     }
     132             :                     else
     133             :                     {
     134        7284 :                         lProperties[OFFSET_URL              ].Value <<= pItem->sURL;
     135        7284 :                         lProperties[OFFSET_TITLE            ].Value <<= pItem->sTitle;
     136        7284 :                         lProperties[OFFSET_IMAGEIDENTIFIER  ].Value <<= pItem->sImageIdentifier;
     137        7284 :                         lProperties[OFFSET_TARGETNAME       ].Value <<= pItem->sTargetName;
     138             :                     }
     139        9105 :                     lResult[nStep] = lProperties;
     140        9105 :                     ++nStep;
     141             :                 }
     142        1214 :                 if( pList == &lSetupEntries )
     143         607 :                     pList = &lUserEntries;
     144             :                 else
     145         607 :                     pList = NULL;
     146             :             }
     147        1214 :             return lResult;
     148             :         }
     149             : 
     150             :     private:
     151             :         vector< SvtDynMenuEntry > lSetupEntries;
     152             :         vector< SvtDynMenuEntry > lUserEntries;
     153             : };
     154             : 
     155             : class SvtDynamicMenuOptions_Impl : public ConfigItem
     156             : {
     157             :     public:
     158             : 
     159             :          SvtDynamicMenuOptions_Impl();
     160             :         virtual ~SvtDynamicMenuOptions_Impl();
     161             : 
     162             :         /*-****************************************************************************************************
     163             :             @short      called for notify of configmanager
     164             :             @descr      These method is called from the ConfigManager before application ends or from the
     165             :                          PropertyChangeListener if the sub tree broadcasts changes. You must update your
     166             :                         internal values.
     167             : 
     168             :             @seealso    baseclass ConfigItem
     169             : 
     170             :             @param      "lPropertyNames" is the list of properties which should be updated.
     171             :         *//*-*****************************************************************************************************/
     172             : 
     173             :         virtual void Notify( const Sequence< OUString >& lPropertyNames ) SAL_OVERRIDE;
     174             : 
     175             :         /*-****************************************************************************************************
     176             :             @short      base implementation of public interface for "SvtDynamicMenuOptions"!
     177             :             @descr      These class is used as static member of "SvtDynamicMenuOptions" ...
     178             :                         => The code exist only for one time and isn't duplicated for every instance!
     179             :         *//*-*****************************************************************************************************/
     180             : 
     181             :         Sequence< Sequence< PropertyValue > >   GetMenu     (           EDynamicMenuType    eMenu           ) const;
     182             : 
     183             :     private:
     184             : 
     185             :         virtual void ImplCommit() SAL_OVERRIDE;
     186             : 
     187             :         /*-****************************************************************************************************
     188             :             @short      return list of key names of our configuration management which represent oue module tree
     189             :             @descr      These methods return the current list of key names! We need it to get needed values from our
     190             :                         configuration management and support dynamical menu item lists!
     191             :             @param      "nNewCount"     ,   returns count of menu entries for "new"
     192             :             @param      "nWizardCount"  ,   returns count of menu entries for "wizard"
     193             :             @return     A list of configuration key names is returned.
     194             :         *//*-*****************************************************************************************************/
     195             : 
     196             :         Sequence< OUString > impl_GetPropertyNames( sal_uInt32& nNewCount, sal_uInt32& nWizardCount, sal_uInt32& nHelpBookmarksCount );
     197             : 
     198             :         /*-****************************************************************************************************
     199             :             @short      sort given source list and expand it for all well known properties to destination
     200             :             @descr      We must support sets of entries with count inside the name .. but some of them could be missing!
     201             :                         e.g. s1-s2-s3-s0-u1-s6-u5-u7
     202             :                         Then we must sort it by name and expand it to the follow one:
     203             :                             sSetNode/s0/URL
     204             :                             sSetNode/s0/Title
     205             :                             sSetNode/s0/...
     206             :                             sSetNode/s1/URL
     207             :                             sSetNode/s1/Title
     208             :                             sSetNode/s1/...
     209             :                             ...
     210             :                             sSetNode/s6/URL
     211             :                             sSetNode/s6/Title
     212             :                             sSetNode/s6/...
     213             :                             sSetNode/u1/URL
     214             :                             sSetNode/u1/Title
     215             :                             sSetNode/u1/...
     216             :                             ...
     217             :                             sSetNode/u7/URL
     218             :                             sSetNode/u7/Title
     219             :                             sSetNode/u7/...
     220             :                         Rules: We start with all setup written entries names "sx" and x=[0..n].
     221             :                         Then we handle all "ux" items. Inside these blocks we sort it ascending by number.
     222             : 
     223             :             @attention  We add these expanded list to the end of given "lDestination" list!
     224             :                         So we must start on "lDestination.getLength()".
     225             :                         Reallocation of memory of destination list is done by us!
     226             : 
     227             :             @seealso    method impl_GetPropertyNames()
     228             : 
     229             :             @param      "lSource"      ,   original list (e.g. [m1-m2-m3-m6-m0] )
     230             :             @param      "lDestination" ,   destination of operation
     231             :             @param      "sSetNode"     ,   name of configuration set to build complete path
     232             :             @return     A list of configuration key names is returned.
     233             :         *//*-*****************************************************************************************************/
     234             : 
     235             :         static void impl_SortAndExpandPropertyNames( const Sequence< OUString >& lSource      ,
     236             :                                                      Sequence< OUString >& lDestination ,
     237             :                                                      const OUString&             sSetNode     );
     238             : 
     239             :     //  private member
     240             : 
     241             :     private:
     242             : 
     243             :         SvtDynMenu  m_aNewMenu;
     244             :         SvtDynMenu  m_aWizardMenu;
     245             :         SvtDynMenu  m_aHelpBookmarksMenu;
     246             : };
     247             : 
     248             : //  constructor
     249             : 
     250          43 : SvtDynamicMenuOptions_Impl::SvtDynamicMenuOptions_Impl()
     251             :     // Init baseclasses first
     252          43 :     :   ConfigItem( ROOTNODE_MENUS )
     253             :     // Init member then...
     254             : {
     255             :     // Get names and values of all accessible menu entries and fill internal structures.
     256             :     // See impl_GetPropertyNames() for further information.
     257          43 :     sal_uInt32              nNewCount           = 0;
     258          43 :     sal_uInt32              nWizardCount        = 0;
     259          43 :     sal_uInt32              nHelpBookmarksCount = 0;
     260             :     Sequence< OUString >    lNames              = impl_GetPropertyNames ( nNewCount           ,
     261             :                                                                           nWizardCount        ,
     262          43 :                                                                           nHelpBookmarksCount );
     263          86 :     Sequence< Any >         lValues             = GetProperties         ( lNames              );
     264             : 
     265             :     // Safe impossible cases.
     266             :     // We need values from ALL configuration keys.
     267             :     // Follow assignment use order of values in relation to our list of key names!
     268             :     DBG_ASSERT( !(lNames.getLength()!=lValues.getLength()), "SvtDynamicMenuOptions_Impl::SvtDynamicMenuOptions_Impl()\nI miss some values of configuration keys!\n" );
     269             : 
     270             :     // Copy values from list in right order to our internal member.
     271             :     // Attention: List for names and values have an internal construction pattern!
     272             : 
     273             :     // first "New" menu ...
     274             :     //      Name                            Value
     275             :     //      /New/1/URL                      "private:factory/swriter"
     276             :     //      /New/1/Title                    "Neues Writer Dokument"
     277             :     //      /New/1/ImageIdentifier          "icon_writer"
     278             :     //      /New/1/TargetName               "_blank"
     279             : 
     280             :     //      /New/2/URL                      "private:factory/scalc"
     281             :     //      /New/2/Title                    "Neues Calc Dokument"
     282             :     //      /New/2/ImageIdentifier          "icon_calc"
     283             :     //      /New/2/TargetName               "_blank"
     284             : 
     285             :     // second "Wizard" menu ...
     286             :     //      /Wizard/1/URL                   "file://b"
     287             :     //      /Wizard/1/Title                 "MalWas"
     288             :     //      /Wizard/1/ImageIdentifier       "icon_?"
     289             :     //      /Wizard/1/TargetName            "_self"
     290             : 
     291             :     //      ... and so on ...
     292             : 
     293          43 :     sal_uInt32  nItem     = 0;
     294          43 :     sal_uInt32  nPosition = 0;
     295             : 
     296             :     // Get names/values for new menu.
     297             :     // 4 subkeys for every item!
     298         688 :     for( nItem=0; nItem<nNewCount; ++nItem )
     299             :     {
     300         645 :         SvtDynMenuEntry   aItem;
     301         645 :         lValues[nPosition] >>= aItem.sURL;
     302         645 :         ++nPosition;
     303         645 :         lValues[nPosition] >>= aItem.sTitle;
     304         645 :         ++nPosition;
     305         645 :         lValues[nPosition] >>= aItem.sImageIdentifier;
     306         645 :         ++nPosition;
     307         645 :         lValues[nPosition] >>= aItem.sTargetName;
     308         645 :         ++nPosition;
     309         645 :         m_aNewMenu.AppendSetupEntry( aItem );
     310         645 :     }
     311             : 
     312             :     // Attention: Don't reset nPosition here!
     313             : 
     314             :     // Get names/values for wizard menu.
     315             :     // 4 subkeys for every item!
     316         559 :     for( nItem=0; nItem<nWizardCount; ++nItem )
     317             :     {
     318         516 :         SvtDynMenuEntry   aItem;
     319         516 :         lValues[nPosition] >>= aItem.sURL;
     320         516 :         ++nPosition;
     321         516 :         lValues[nPosition] >>= aItem.sTitle;
     322         516 :         ++nPosition;
     323         516 :         lValues[nPosition] >>= aItem.sImageIdentifier;
     324         516 :         ++nPosition;
     325         516 :         lValues[nPosition] >>= aItem.sTargetName;
     326         516 :         ++nPosition;
     327         516 :         m_aWizardMenu.AppendSetupEntry( aItem );
     328         516 :     }
     329             : 
     330             :     // Attention: Don't reset nPosition here!
     331             : 
     332             :     // Get names/values for wizard menu.
     333             :     // 4 subkeys for every item!
     334          43 :     for( nItem=0; nItem<nHelpBookmarksCount; ++nItem )
     335             :     {
     336           0 :         SvtDynMenuEntry   aItem;
     337           0 :         lValues[nPosition] >>= aItem.sURL;
     338           0 :         ++nPosition;
     339           0 :         lValues[nPosition] >>= aItem.sTitle;
     340           0 :         ++nPosition;
     341           0 :         lValues[nPosition] >>= aItem.sImageIdentifier;
     342           0 :         ++nPosition;
     343           0 :         lValues[nPosition] >>= aItem.sTargetName;
     344           0 :         ++nPosition;
     345           0 :         m_aHelpBookmarksMenu.AppendSetupEntry( aItem );
     346          43 :     }
     347             : 
     348             : /*TODO: Not used in the moment! see Notify() ...
     349             :     // Enable notification mechanism of our baseclass.
     350             :     // We need it to get information about changes outside these class on our used configuration keys!
     351             :     EnableNotification( lNames );
     352             : */
     353          43 : }
     354             : 
     355             : //  destructor
     356             : 
     357          84 : SvtDynamicMenuOptions_Impl::~SvtDynamicMenuOptions_Impl()
     358             : {
     359             :     assert(!IsModified()); // should have been committed
     360          84 : }
     361             : 
     362             : //  public method
     363             : 
     364           0 : void SvtDynamicMenuOptions_Impl::Notify( const Sequence< OUString >& )
     365             : {
     366             :     DBG_ASSERT( false, "SvtDynamicMenuOptions_Impl::Notify()\nNot implemented yet! I don't know how I can handle a dynamical list of unknown properties ...\n" );
     367           0 : }
     368             : 
     369             : //  public method
     370             : 
     371           0 : void SvtDynamicMenuOptions_Impl::ImplCommit()
     372             : {
     373             :     SAL_WARN("unotools.config", "SvtDynamicMenuOptions_Impl::ImplCommit(): Not implemented yet!");
     374             :     /*
     375             :     // Write all properties!
     376             :     // Delete complete sets first.
     377             :     ClearNodeSet( SETNODE_NEWMENU    );
     378             :     ClearNodeSet( SETNODE_WIZARDMENU );
     379             :     ClearNodeSet( SETNODE_HELPBOOKMARKS );
     380             : 
     381             :     MenuEntry                    aItem;
     382             :     OUString                    sNode;
     383             :     Sequence< PropertyValue >   lPropertyValues( PROPERTYCOUNT );
     384             :     sal_uInt32                  nItem          = 0;
     385             : 
     386             :     // Copy "new" menu entries to save-list!
     387             :     sal_uInt32 nNewCount = m_aNewMenu.size();
     388             :     for( nItem=0; nItem<nNewCount; ++nItem )
     389             :     {
     390             :         aItem = m_aNewMenu[nItem];
     391             :         // Format:  "New/1/URL"
     392             :         //          "New/1/Title"
     393             :         //          ...
     394             :         sNode = SETNODE_NEWMENU + PATHDELIMITER + PATHPREFIX + OUString::valueOf( (sal_Int32)nItem ) + PATHDELIMITER;
     395             : 
     396             :         lPropertyValues[OFFSET_URL             ].Name  =   sNode + PROPERTYNAME_URL;
     397             :         lPropertyValues[OFFSET_TITLE           ].Name  =   sNode + PROPERTYNAME_TITLE;
     398             :         lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Name  =   sNode + PROPERTYNAME_IMAGEIDENTIFIER;
     399             :         lPropertyValues[OFFSET_TARGETNAME      ].Name  =   sNode + PROPERTYNAME_TARGETNAME;
     400             : 
     401             :         lPropertyValues[OFFSET_URL             ].Value <<= aItem.sURL;
     402             :         lPropertyValues[OFFSET_TITLE           ].Value <<= aItem.sTitle;
     403             :         lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Value <<= aItem.sImageIdentifier;
     404             :         lPropertyValues[OFFSET_TARGETNAME      ].Value <<= aItem.sTargetName;
     405             : 
     406             :         SetSetProperties( SETNODE_NEWMENU, lPropertyValues );
     407             :     }
     408             : 
     409             :     // Copy "wizard" menu entries to save-list!
     410             :     sal_uInt32 nWizardCount = m_aWizardMenu.size();
     411             :     for( nItem=0; nItem<nWizardCount; ++nItem )
     412             :     {
     413             :         aItem = m_aWizardMenu[nItem];
     414             :         // Format:  "Wizard/1/URL"
     415             :         //          "Wizard/1/Title"
     416             :         //          ...
     417             :         sNode = SETNODE_WIZARDMENU + PATHDELIMITER + PATHPREFIX + OUString::valueOf( (sal_Int32)nItem ) + PATHDELIMITER;
     418             : 
     419             :         lPropertyValues[OFFSET_URL             ].Name  =   sNode + PROPERTYNAME_URL;
     420             :         lPropertyValues[OFFSET_TITLE           ].Name  =   sNode + PROPERTYNAME_TITLE;
     421             :         lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Name  =   sNode + PROPERTYNAME_IMAGEIDENTIFIER;
     422             :         lPropertyValues[OFFSET_TARGETNAME      ].Name  =   sNode + PROPERTYNAME_TARGETNAME;
     423             : 
     424             :         lPropertyValues[OFFSET_URL             ].Value <<= aItem.sURL;
     425             :         lPropertyValues[OFFSET_TITLE           ].Value <<= aItem.sTitle;
     426             :         lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Value <<= aItem.sImageIdentifier;
     427             :         lPropertyValues[OFFSET_TARGETNAME      ].Value <<= aItem.sTargetName;
     428             : 
     429             :         SetSetProperties( SETNODE_WIZARDMENU, lPropertyValues );
     430             :     }
     431             : 
     432             :     // Copy help bookmarks entries to save-list!
     433             :     sal_uInt32 nHelpBookmarksCount = m_aHelpBookmarksMenu.size();
     434             :     for( nItem=0; nItem<nHelpBookmarksCount; ++nItem )
     435             :     {
     436             :         aItem = m_aHelpBookmarksMenu[nItem];
     437             :         // Format:  "HelpBookmarks/1/URL"
     438             :         //          "HelpBookmarks/1/Title"
     439             :         //          ...
     440             :         sNode = SETNODE_HELPBOOKMARKS + PATHDELIMITER + PATHPREFIX + OUString::valueOf( (sal_Int32)nItem ) + PATHDELIMITER;
     441             : 
     442             :         lPropertyValues[OFFSET_URL             ].Name  =   sNode + PROPERTYNAME_URL;
     443             :         lPropertyValues[OFFSET_TITLE           ].Name  =   sNode + PROPERTYNAME_TITLE;
     444             :         lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Name  =   sNode + PROPERTYNAME_IMAGEIDENTIFIER;
     445             :         lPropertyValues[OFFSET_TARGETNAME      ].Name  =   sNode + PROPERTYNAME_TARGETNAME;
     446             : 
     447             :         lPropertyValues[OFFSET_URL             ].Value <<= aItem.sURL;
     448             :         lPropertyValues[OFFSET_TITLE           ].Value <<= aItem.sTitle;
     449             :         lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Value <<= aItem.sImageIdentifier;
     450             :         lPropertyValues[OFFSET_TARGETNAME      ].Value <<= aItem.sTargetName;
     451             : 
     452             :         SetSetProperties( SETNODE_HELPBOOKMARKS, lPropertyValues );
     453             :     }
     454             :     */
     455           0 : }
     456             : 
     457             : //  public method
     458             : 
     459         607 : Sequence< Sequence< PropertyValue > > SvtDynamicMenuOptions_Impl::GetMenu( EDynamicMenuType eMenu ) const
     460             : {
     461         607 :     Sequence< Sequence< PropertyValue > > lReturn;
     462         607 :     switch( eMenu )
     463             :     {
     464             :         case E_NEWMENU      :   {
     465         607 :                                     lReturn = m_aNewMenu.GetList();
     466             :                                 }
     467         607 :                                 break;
     468             : 
     469             :         case E_WIZARDMENU   :   {
     470           0 :                                     lReturn = m_aWizardMenu.GetList();
     471             :                                 }
     472           0 :                                 break;
     473             : 
     474             :         case E_HELPBOOKMARKS :  {
     475           0 :                                     lReturn = m_aHelpBookmarksMenu.GetList();
     476             :                                 }
     477           0 :                                 break;
     478             :     }
     479         607 :     return lReturn;
     480             : }
     481             : 
     482             : //  private method
     483             : 
     484          43 : Sequence< OUString > SvtDynamicMenuOptions_Impl::impl_GetPropertyNames( sal_uInt32& nNewCount, sal_uInt32& nWizardCount, sal_uInt32& nHelpBookmarksCount )
     485             : {
     486             :     // First get ALL names of current existing list items in configuration!
     487          43 :     Sequence< OUString > lNewItems           = GetNodeNames( SETNODE_NEWMENU       );
     488          86 :     Sequence< OUString > lWizardItems        = GetNodeNames( SETNODE_WIZARDMENU    );
     489          86 :     Sequence< OUString > lHelpBookmarksItems = GetNodeNames( SETNODE_HELPBOOKMARKS );
     490             : 
     491             :     // Get information about list counts ...
     492          43 :     nNewCount           = lNewItems.getLength          ();
     493          43 :     nWizardCount        = lWizardItems.getLength       ();
     494          43 :     nHelpBookmarksCount = lHelpBookmarksItems.getLength();
     495             : 
     496             :     // Sort and expand all three list to result list ...
     497          43 :     Sequence< OUString > lProperties;
     498          43 :     impl_SortAndExpandPropertyNames( lNewItems          , lProperties, SETNODE_NEWMENU       );
     499          43 :     impl_SortAndExpandPropertyNames( lWizardItems       , lProperties, SETNODE_WIZARDMENU    );
     500          43 :     impl_SortAndExpandPropertyNames( lHelpBookmarksItems, lProperties, SETNODE_HELPBOOKMARKS );
     501             : 
     502             :     // Return result.
     503          86 :     return lProperties;
     504             : }
     505             : 
     506             : //  private helper
     507             : 
     508             : class CountWithPrefixSort
     509             : {
     510             :     public:
     511        2752 :         bool operator() ( const OUString& s1 ,
     512             :                          const OUString& s2 ) const
     513             :         {
     514             :             // Get order numbers from entry name without prefix.
     515             :             // e.g. "m10" => 10
     516             :             //      "m5"  => 5
     517        2752 :             sal_Int32 n1 = s1.copy( 1, s1.getLength()-1 ).toInt32();
     518        2752 :             sal_Int32 n2 = s2.copy( 1, s2.getLength()-1 ).toInt32();
     519             :             // MUST be in [0,1] ... because it's a difference between
     520             :             // insert-positions of given entries in sorted list!
     521        2752 :             return( n1<n2 );
     522             :         }
     523             : };
     524             : 
     525             : class SelectByPrefix
     526             : {
     527             :     public:
     528        1161 :         bool operator() ( const OUString& s ) const
     529             :         {
     530             :             // Prefer setup written entries by check first letter of given string. It must be a "s".
     531        1161 :             return s.startsWith( PATHPREFIX_SETUP );
     532             :         }
     533             : };
     534             : 
     535             : //  private method
     536             : 
     537         129 : void SvtDynamicMenuOptions_Impl::impl_SortAndExpandPropertyNames( const Sequence< OUString >& lSource      ,
     538             :                                                                         Sequence< OUString >& lDestination ,
     539             :                                                                   const OUString&             sSetNode     )
     540             : {
     541         129 :     OUString            sFixPath;
     542         258 :     vector< OUString >  lTemp;
     543         129 :     sal_Int32           nSourceCount     = lSource.getLength();
     544         129 :     sal_Int32           nDestinationStep = lDestination.getLength(); // start on end of current list ...!
     545             : 
     546         129 :     lDestination.realloc( (nSourceCount*PROPERTYCOUNT)+nDestinationStep ); // get enough memory for copy operations after nDestination ...
     547             : 
     548             :     // Copy all items to temp. vector to use fast sort operations :-)
     549        1290 :     for( sal_Int32 nSourceStep=0; nSourceStep<nSourceCount; ++nSourceStep )
     550        1161 :         lTemp.push_back( lSource[nSourceStep] );
     551             : 
     552             :     // Sort all entries by number ...
     553         129 :     stable_sort( lTemp.begin(), lTemp.end(), CountWithPrefixSort() );
     554             :     // and split into setup & user written entries!
     555         129 :     stable_partition( lTemp.begin(), lTemp.end(), SelectByPrefix() );
     556             : 
     557             :     // Copy sorted entries to destination and expand every item with
     558             :     // 4 supported sub properties.
     559        3870 :     for( vector< OUString >::const_iterator pItem =lTemp.begin();
     560        2580 :                                             pItem!=lTemp.end();
     561             :                                             ++pItem              )
     562             :     {
     563        1161 :         sFixPath  = sSetNode;
     564        1161 :         sFixPath += PATHDELIMITER;
     565        1161 :         sFixPath += *pItem;
     566        1161 :         sFixPath += PATHDELIMITER;
     567             : 
     568        1161 :         lDestination[nDestinationStep]  = sFixPath;
     569        1161 :         lDestination[nDestinationStep] += PROPERTYNAME_URL;
     570        1161 :         ++nDestinationStep;
     571        1161 :         lDestination[nDestinationStep]  = sFixPath;
     572        1161 :         lDestination[nDestinationStep] += PROPERTYNAME_TITLE;
     573        1161 :         ++nDestinationStep;
     574        1161 :         lDestination[nDestinationStep]  = sFixPath;
     575        1161 :         lDestination[nDestinationStep] += PROPERTYNAME_IMAGEIDENTIFIER;
     576        1161 :         ++nDestinationStep;
     577        1161 :         lDestination[nDestinationStep]  = sFixPath;
     578        1161 :         lDestination[nDestinationStep] += PROPERTYNAME_TARGETNAME;
     579        1161 :         ++nDestinationStep;
     580         129 :     }
     581         129 : }
     582             : 
     583             : //  initialize static member
     584             : //  DON'T DO IT IN YOUR HEADER!
     585             : //  see definition for further information
     586             : 
     587             : SvtDynamicMenuOptions_Impl*     SvtDynamicMenuOptions::m_pDataContainer = NULL;
     588             : sal_Int32                       SvtDynamicMenuOptions::m_nRefCount      = 0;
     589             : 
     590             : //  constructor
     591             : 
     592         650 : SvtDynamicMenuOptions::SvtDynamicMenuOptions()
     593             : {
     594             :     // Global access, must be guarded (multithreading!).
     595         650 :     MutexGuard aGuard( GetOwnStaticMutex() );
     596             :     // Increase our refcount ...
     597         650 :     ++m_nRefCount;
     598             :     // ... and initialize our data container only if it not already exist!
     599         650 :     if( m_pDataContainer == NULL )
     600             :     {
     601          43 :         m_pDataContainer = new SvtDynamicMenuOptions_Impl;
     602          43 :         ItemHolder1::holdConfigItem(E_DYNAMICMENUOPTIONS);
     603         650 :     }
     604         650 : }
     605             : 
     606             : //  destructor
     607             : 
     608        1340 : SvtDynamicMenuOptions::~SvtDynamicMenuOptions()
     609             : {
     610             :     // Global access, must be guarded (multithreading!)
     611         649 :     MutexGuard aGuard( GetOwnStaticMutex() );
     612             :     // Decrease our refcount.
     613         649 :     --m_nRefCount;
     614             :     // If last instance was deleted ...
     615             :     // we must destroy our static data container!
     616         649 :     if( m_nRefCount <= 0 )
     617             :     {
     618          42 :         delete m_pDataContainer;
     619          42 :         m_pDataContainer = NULL;
     620         649 :     }
     621         691 : }
     622             : 
     623             : //  public method
     624             : 
     625         607 : Sequence< Sequence< PropertyValue > > SvtDynamicMenuOptions::GetMenu( EDynamicMenuType eMenu ) const
     626             : {
     627         607 :     MutexGuard aGuard( GetOwnStaticMutex() );
     628         607 :     return m_pDataContainer->GetMenu( eMenu );
     629             : }
     630             : 
     631             : namespace
     632             : {
     633             :     class theDynamicMenuOptionsMutex : public rtl::Static<osl::Mutex, theDynamicMenuOptionsMutex>{};
     634             : }
     635             : 
     636             : //  private method
     637             : 
     638        1906 : Mutex& SvtDynamicMenuOptions::GetOwnStaticMutex()
     639             : {
     640        1906 :     return theDynamicMenuOptionsMutex::get();
     641             : }
     642             : 
     643             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11