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

Generated by: LCOV version 1.10