LCOV - code coverage report
Current view: top level - libreoffice/unotools/source/config - dynamicmenuoptions.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 175 0.0 %
Date: 2012-12-27 Functions: 0 22 0.0 %
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             : 
      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>
      28             : 
      29             : #include <vector>
      30             : 
      31             : #include <itemholder1.hxx>
      32             : 
      33             : #include <algorithm>
      34             : 
      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 ;
      41             : 
      42             : #define ROOTNODE_MENUS                                  OUString(RTL_CONSTASCII_USTRINGPARAM("Office.Common/Menus/"     ))
      43             : #define PATHDELIMITER                                   OUString(RTL_CONSTASCII_USTRINGPARAM("/"                        ))
      44             : 
      45             : #define SETNODE_NEWMENU                                 OUString(RTL_CONSTASCII_USTRINGPARAM("New"                      ))
      46             : #define SETNODE_WIZARDMENU                              OUString(RTL_CONSTASCII_USTRINGPARAM("Wizard"                   ))
      47             : #define SETNODE_HELPBOOKMARKS                           OUString(RTL_CONSTASCII_USTRINGPARAM("HelpBookmarks"            ))
      48             : 
      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
      53             : 
      54             : #define PROPERTYCOUNT                                   4
      55             : 
      56             : #define OFFSET_URL                                      0
      57             : #define OFFSET_TITLE                                    1
      58             : #define OFFSET_IMAGEIDENTIFIER                          2
      59             : #define OFFSET_TARGETNAME                               3
      60             : 
      61             : #define PATHPREFIX_SETUP                                OUString(RTL_CONSTASCII_USTRINGPARAM("m"                        ))
      62             : #define PATHPREFIX_USER                                 OUString(RTL_CONSTASCII_USTRINGPARAM("u"                        ))
      63             : 
      64             : /*-****************************************************************************************************************
      65             :     @descr  struct to hold information about one menu entry.
      66             : ****************************************************************************************************************-*/
      67           0 : struct SvtDynMenuEntry
      68             : {
      69             :     public:
      70           0 :         SvtDynMenuEntry() {};
      71             : 
      72             :         SvtDynMenuEntry(  const OUString& sNewURL             ,
      73             :                     const OUString& sNewTitle           ,
      74             :                     const OUString& sNewImageIdentifier ,
      75             :                     const OUString& sNewTargetName      )
      76             :         {
      77             :             sURL                = sNewURL               ;
      78             :             sTitle              = sNewTitle             ;
      79             :             sImageIdentifier    = sNewImageIdentifier   ;
      80             :             sTargetName         = sNewTargetName        ;
      81             :         }
      82             : 
      83             :     public:
      84             :         OUString    sName               ;
      85             :         OUString    sURL                ;
      86             :         OUString    sTitle              ;
      87             :         OUString    sImageIdentifier    ;
      88             :         OUString    sTargetName         ;
      89             : };
      90             : 
      91             : /*-****************************************************************************************************************
      92             :     @descr  support simple menu structures and operations on it
      93             : ****************************************************************************************************************-*/
      94           0 : class SvtDynMenu
      95             : {
      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 seperator items are supeflous ...
     100           0 :         void AppendSetupEntry( const SvtDynMenuEntry& rEntry )
     101             :         {
     102           0 :             if(
     103           0 :                 ( lSetupEntries.size()         <  1           )  ||
     104           0 :                 ( lSetupEntries.rbegin()->sURL != rEntry.sURL )
     105             :               )
     106             :             {
     107           0 :                 lSetupEntries.push_back( rEntry );
     108             :             }
     109           0 :         }
     110             : 
     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 seperator items are supeflous ...
     115             :         void AppendUserEntry( SvtDynMenuEntry& rEntry )
     116             :         {
     117             :             if(
     118             :                 ( lUserEntries.size()         <  1           )  ||
     119             :                 ( lUserEntries.rbegin()->sURL != rEntry.sURL )
     120             :               )
     121             :             {
     122             :                 rEntry.sName  = PATHPREFIX_USER;
     123             :                 rEntry.sName += OUString::valueOf( (sal_Int32)impl_getNextUserEntryNr() );
     124             :                 lUserEntries.push_back( rEntry );
     125             :             }
     126             :         }
     127             : 
     128             :         // the only way to free memory!
     129             :         void Clear()
     130             :         {
     131             :             lSetupEntries.clear();
     132             :             lUserEntries.clear();
     133             :         }
     134             : 
     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 "sSeperator" to perform too ...
     142           0 :         Sequence< Sequence< PropertyValue > > GetList() const
     143             :         {
     144           0 :             sal_Int32                             nSetupCount = (sal_Int32)lSetupEntries.size();
     145           0 :             sal_Int32                             nUserCount  = (sal_Int32)lUserEntries.size();
     146           0 :             sal_Int32                             nStep       = 0;
     147           0 :             Sequence< PropertyValue >             lProperties ( PROPERTYCOUNT );
     148           0 :             Sequence< Sequence< PropertyValue > > lResult     ( nSetupCount+nUserCount );
     149           0 :             OUString                              sSeperator  ( RTL_CONSTASCII_USTRINGPARAM("private:separator") );
     150           0 :             OUString                              sEmpty      ;
     151           0 :             const vector< SvtDynMenuEntry >*            pList       = &lSetupEntries;
     152             : 
     153           0 :             lProperties[OFFSET_URL            ].Name = PROPERTYNAME_URL             ;
     154           0 :             lProperties[OFFSET_TITLE          ].Name = PROPERTYNAME_TITLE           ;
     155           0 :             lProperties[OFFSET_IMAGEIDENTIFIER].Name = PROPERTYNAME_IMAGEIDENTIFIER ;
     156           0 :             lProperties[OFFSET_TARGETNAME     ].Name = PROPERTYNAME_TARGETNAME      ;
     157             : 
     158           0 :             while( pList != NULL )
     159             :             {
     160           0 :                 for( vector< SvtDynMenuEntry >::const_iterator pItem =pList->begin();
     161           0 :                                                          pItem!=pList->end()  ;
     162             :                                                          ++pItem              )
     163             :                 {
     164           0 :                     if( pItem->sURL == sSeperator )
     165             :                     {
     166           0 :                         lProperties[OFFSET_URL              ].Value <<= sSeperator  ;
     167           0 :                         lProperties[OFFSET_TITLE            ].Value <<= sEmpty      ;
     168           0 :                         lProperties[OFFSET_IMAGEIDENTIFIER  ].Value <<= sEmpty      ;
     169           0 :                         lProperties[OFFSET_TARGETNAME       ].Value <<= sEmpty      ;
     170             :                     }
     171             :                     else
     172             :                     {
     173           0 :                         lProperties[OFFSET_URL              ].Value <<= pItem->sURL            ;
     174           0 :                         lProperties[OFFSET_TITLE            ].Value <<= pItem->sTitle          ;
     175           0 :                         lProperties[OFFSET_IMAGEIDENTIFIER  ].Value <<= pItem->sImageIdentifier;
     176           0 :                         lProperties[OFFSET_TARGETNAME       ].Value <<= pItem->sTargetName     ;
     177             :                     }
     178           0 :                     lResult[nStep] = lProperties;
     179           0 :                     ++nStep;
     180             :                 }
     181           0 :                 if( pList == &lSetupEntries )
     182           0 :                     pList = &lUserEntries;
     183             :                 else
     184           0 :                     pList = NULL;
     185             :             }
     186           0 :             return lResult;
     187             :         }
     188             : 
     189             :     private:
     190             : 
     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
     194             :         {
     195             :             sal_Int32 nNr = 0;
     196             :             for( vector< SvtDynMenuEntry >::const_iterator pItem =lUserEntries.begin();
     197             :                                                      pItem!=lUserEntries.end()  ;
     198             :                                                      ++pItem                    )
     199             :             {
     200             :                 if( pItem->sName.compareTo( PATHPREFIX_USER, 1 ) == 0 )
     201             :                 {
     202             :                     OUString  sNr      = pItem->sName.copy( 1, pItem->sName.getLength()-1 );
     203             :                     sal_Int32 nCheckNr = sNr.toInt32();
     204             :                     if( nCheckNr > nNr )
     205             :                         nNr = nCheckNr;
     206             :                 }
     207             :             }
     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;
     213             :         }
     214             : 
     215             :     private:
     216             :         vector< SvtDynMenuEntry > lSetupEntries;
     217             :         vector< SvtDynMenuEntry > lUserEntries ;
     218             : };
     219             : 
     220             : class SvtDynamicMenuOptions_Impl : public ConfigItem
     221             : {
     222             :     public:
     223             : 
     224             :          SvtDynamicMenuOptions_Impl();
     225             :         ~SvtDynamicMenuOptions_Impl();
     226             : 
     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.
     232             : 
     233             :             @seealso    baseclass ConfigItem
     234             : 
     235             :             @param      "lPropertyNames" is the list of properties which should be updated.
     236             :             @return     -
     237             : 
     238             :             @onerror    -
     239             :         *//*-*****************************************************************************************************/
     240             : 
     241             :         virtual void Notify( const Sequence< OUString >& lPropertyNames );
     242             : 
     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.
     247             : 
     248             :             @seealso    baseclass ConfigItem
     249             : 
     250             :             @param      -
     251             :             @return     -
     252             : 
     253             :             @onerror    -
     254             :         *//*-*****************************************************************************************************/
     255             : 
     256             :         virtual void Commit();
     257             : 
     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!
     262             : 
     263             :             @seealso    -
     264             : 
     265             :             @param      -
     266             :             @return     -
     267             : 
     268             :             @onerror    -
     269             :         *//*-*****************************************************************************************************/
     270             : 
     271             :         Sequence< Sequence< PropertyValue > >   GetMenu     (           EDynamicMenuType    eMenu           ) const ;
     272             : 
     273             :     private:
     274             : 
     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!
     279             : 
     280             :             @seealso    -
     281             : 
     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.
     285             : 
     286             :             @onerror    -
     287             :         *//*-*****************************************************************************************************/
     288             : 
     289             :         Sequence< OUString > impl_GetPropertyNames( sal_uInt32& nNewCount, sal_uInt32& nWizardCount, sal_uInt32& nHelpBookmarksCount );
     290             : 
     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/...
     302             :                             ...
     303             :                             sSetNode/s6/URL
     304             :                             sSetNode/s6/Title
     305             :                             sSetNode/s6/...
     306             :                             sSetNode/u1/URL
     307             :                             sSetNode/u1/Title
     308             :                             sSetNode/u1/...
     309             :                             ...
     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.
     315             : 
     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!
     319             : 
     320             :             @seealso    method impl_GetPropertyNames()
     321             : 
     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.
     326             : 
     327             :             @onerror    -
     328             :         *//*-*****************************************************************************************************/
     329             : 
     330             :         void impl_SortAndExpandPropertyNames( const Sequence< OUString >& lSource      ,
     331             :                                                     Sequence< OUString >& lDestination ,
     332             :                                               const OUString&             sSetNode     );
     333             : 
     334             :     //-------------------------------------------------------------------------------------------------------------
     335             :     //  private member
     336             :     //-------------------------------------------------------------------------------------------------------------
     337             : 
     338             :     private:
     339             : 
     340             :         SvtDynMenu  m_aNewMenu              ;
     341             :         SvtDynMenu  m_aWizardMenu           ;
     342             :         SvtDynMenu  m_aHelpBookmarksMenu    ;
     343             : };
     344             : 
     345             : //*****************************************************************************************************************
     346             : //  constructor
     347             : //*****************************************************************************************************************
     348           0 : SvtDynamicMenuOptions_Impl::SvtDynamicMenuOptions_Impl()
     349             :     // Init baseclasses first
     350           0 :     :   ConfigItem( ROOTNODE_MENUS )
     351             :     // Init member then...
     352             : {
     353             :     // Get names and values of all accessable menu entries and fill internal structures.
     354             :     // See impl_GetPropertyNames() for further informations.
     355           0 :     sal_uInt32              nNewCount           = 0;
     356           0 :     sal_uInt32              nWizardCount        = 0;
     357           0 :     sal_uInt32              nHelpBookmarksCount = 0;
     358             :     Sequence< OUString >    lNames              = impl_GetPropertyNames ( nNewCount           ,
     359             :                                                                           nWizardCount        ,
     360           0 :                                                                           nHelpBookmarksCount );
     361           0 :     Sequence< Any >         lValues             = GetProperties         ( lNames              );
     362             : 
     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" );
     367             : 
     368             :     // Copy values from list in right order to ouer internal member.
     369             :     // Attention: List for names and values have an internal construction pattern!
     370             :     //
     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"
     377             :     //
     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"
     382             :     //
     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"
     388             :     //
     389             :     //      ... and so on ...
     390             : 
     391           0 :     sal_uInt32  nItem     = 0 ;
     392           0 :     sal_uInt32  nPosition = 0 ;
     393           0 :     OUString    sName         ;
     394             : 
     395             :     // We must use these one instance object(!) to get information about installed modules.
     396             :     // These information are used to filter menu entries wich need not installed modules ...
     397             :     // Such entries shouldnt be available then!
     398             :     // see impl_IsEntrySupported() too
     399           0 :     SvtModuleOptions aModuleOptions;
     400             : 
     401             :     // Get names/values for new menu.
     402             :     // 4 subkeys for every item!
     403           0 :     for( nItem=0; nItem<nNewCount; ++nItem )
     404             :     {
     405           0 :         SvtDynMenuEntry   aItem                       ;
     406           0 :         lValues[nPosition] >>= aItem.sURL             ;
     407           0 :         ++nPosition;
     408           0 :         lValues[nPosition] >>= aItem.sTitle           ;
     409           0 :         ++nPosition;
     410           0 :         lValues[nPosition] >>= aItem.sImageIdentifier ;
     411           0 :         ++nPosition;
     412           0 :         lValues[nPosition] >>= aItem.sTargetName      ;
     413           0 :         ++nPosition;
     414           0 :         m_aNewMenu.AppendSetupEntry( aItem );
     415           0 :     }
     416             : 
     417             :     // Attention: Don't reset nPosition here!
     418             : 
     419             :     // Get names/values for wizard menu.
     420             :     // 4 subkeys for every item!
     421           0 :     for( nItem=0; nItem<nWizardCount; ++nItem )
     422             :     {
     423           0 :         SvtDynMenuEntry   aItem                       ;
     424           0 :         lValues[nPosition] >>= aItem.sURL             ;
     425           0 :         ++nPosition;
     426           0 :         lValues[nPosition] >>= aItem.sTitle           ;
     427           0 :         ++nPosition;
     428           0 :         lValues[nPosition] >>= aItem.sImageIdentifier ;
     429           0 :         ++nPosition;
     430           0 :         lValues[nPosition] >>= aItem.sTargetName      ;
     431           0 :         ++nPosition;
     432           0 :         m_aWizardMenu.AppendSetupEntry( aItem );
     433           0 :     }
     434             : 
     435             :     // Attention: Don't reset nPosition here!
     436             : 
     437             :     // Get names/values for wizard menu.
     438             :     // 4 subkeys for every item!
     439           0 :     for( nItem=0; nItem<nHelpBookmarksCount; ++nItem )
     440             :     {
     441           0 :         SvtDynMenuEntry   aItem                       ;
     442           0 :         lValues[nPosition] >>= aItem.sURL             ;
     443           0 :         ++nPosition;
     444           0 :         lValues[nPosition] >>= aItem.sTitle           ;
     445           0 :         ++nPosition;
     446           0 :         lValues[nPosition] >>= aItem.sImageIdentifier ;
     447           0 :         ++nPosition;
     448           0 :         lValues[nPosition] >>= aItem.sTargetName      ;
     449           0 :         ++nPosition;
     450           0 :         m_aHelpBookmarksMenu.AppendSetupEntry( aItem );
     451           0 :     }
     452             : 
     453             : /*TODO: Not used in the moment! see Notify() ...
     454             :     // Enable notification mechanism of ouer baseclass.
     455             :     // We need it to get information about changes outside these class on ouer used configuration keys!
     456             :     EnableNotification( lNames );
     457             : */
     458           0 : }
     459             : 
     460             : //*****************************************************************************************************************
     461             : //  destructor
     462             : //*****************************************************************************************************************
     463           0 : SvtDynamicMenuOptions_Impl::~SvtDynamicMenuOptions_Impl()
     464             : {
     465             :     // We must save our current values .. if user forget it!
     466           0 :     if( IsModified() == sal_True )
     467             :     {
     468           0 :         Commit();
     469             :     }
     470           0 : }
     471             : 
     472             : //*****************************************************************************************************************
     473             : //  public method
     474             : //*****************************************************************************************************************
     475           0 : void SvtDynamicMenuOptions_Impl::Notify( const Sequence< OUString >& )
     476             : {
     477             :     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" );
     478           0 : }
     479             : 
     480             : //*****************************************************************************************************************
     481             : //  public method
     482             : //*****************************************************************************************************************
     483           0 : void SvtDynamicMenuOptions_Impl::Commit()
     484             : {
     485             :     OSL_FAIL( "SvtDynamicMenuOptions_Impl::Commit()\nNot implemented yet!\n" );
     486             :     /*
     487             :     // Write all properties!
     488             :     // Delete complete sets first.
     489             :     ClearNodeSet( SETNODE_NEWMENU    );
     490             :     ClearNodeSet( SETNODE_WIZARDMENU );
     491             :     ClearNodeSet( SETNODE_HELPBOOKMARKS );
     492             : 
     493             :     MenuEntry                    aItem                           ;
     494             :     OUString                    sNode                           ;
     495             :     Sequence< PropertyValue >   lPropertyValues( PROPERTYCOUNT );
     496             :     sal_uInt32                  nItem          = 0              ;
     497             : 
     498             :     // Copy "new" menu entries to save-list!
     499             :     sal_uInt32 nNewCount = m_aNewMenu.size();
     500             :     for( nItem=0; nItem<nNewCount; ++nItem )
     501             :     {
     502             :         aItem = m_aNewMenu[nItem];
     503             :         // Format:  "New/1/URL"
     504             :         //          "New/1/Title"
     505             :         //          ...
     506             :         sNode = SETNODE_NEWMENU + PATHDELIMITER + PATHPREFIX + OUString::valueOf( (sal_Int32)nItem ) + PATHDELIMITER;
     507             : 
     508             :         lPropertyValues[OFFSET_URL             ].Name  =   sNode + PROPERTYNAME_URL             ;
     509             :         lPropertyValues[OFFSET_TITLE           ].Name  =   sNode + PROPERTYNAME_TITLE           ;
     510             :         lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Name  =   sNode + PROPERTYNAME_IMAGEIDENTIFIER ;
     511             :         lPropertyValues[OFFSET_TARGETNAME      ].Name  =   sNode + PROPERTYNAME_TARGETNAME      ;
     512             : 
     513             :         lPropertyValues[OFFSET_URL             ].Value <<= aItem.sURL                           ;
     514             :         lPropertyValues[OFFSET_TITLE           ].Value <<= aItem.sTitle                         ;
     515             :         lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Value <<= aItem.sImageIdentifier               ;
     516             :         lPropertyValues[OFFSET_TARGETNAME      ].Value <<= aItem.sTargetName                    ;
     517             : 
     518             :         SetSetProperties( SETNODE_NEWMENU, lPropertyValues );
     519             :     }
     520             : 
     521             :     // Copy "wizard" menu entries to save-list!
     522             :     sal_uInt32 nWizardCount = m_aWizardMenu.size();
     523             :     for( nItem=0; nItem<nWizardCount; ++nItem )
     524             :     {
     525             :         aItem = m_aWizardMenu[nItem];
     526             :         // Format:  "Wizard/1/URL"
     527             :         //          "Wizard/1/Title"
     528             :         //          ...
     529             :         sNode = SETNODE_WIZARDMENU + PATHDELIMITER + PATHPREFIX + OUString::valueOf( (sal_Int32)nItem ) + PATHDELIMITER;
     530             : 
     531             :         lPropertyValues[OFFSET_URL             ].Name  =   sNode + PROPERTYNAME_URL             ;
     532             :         lPropertyValues[OFFSET_TITLE           ].Name  =   sNode + PROPERTYNAME_TITLE           ;
     533             :         lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Name  =   sNode + PROPERTYNAME_IMAGEIDENTIFIER ;
     534             :         lPropertyValues[OFFSET_TARGETNAME      ].Name  =   sNode + PROPERTYNAME_TARGETNAME      ;
     535             : 
     536             :         lPropertyValues[OFFSET_URL             ].Value <<= aItem.sURL                           ;
     537             :         lPropertyValues[OFFSET_TITLE           ].Value <<= aItem.sTitle                         ;
     538             :         lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Value <<= aItem.sImageIdentifier               ;
     539             :         lPropertyValues[OFFSET_TARGETNAME      ].Value <<= aItem.sTargetName                    ;
     540             : 
     541             :         SetSetProperties( SETNODE_WIZARDMENU, lPropertyValues );
     542             :     }
     543             : 
     544             :     // Copy help bookmarks entries to save-list!
     545             :     sal_uInt32 nHelpBookmarksCount = m_aHelpBookmarksMenu.size();
     546             :     for( nItem=0; nItem<nHelpBookmarksCount; ++nItem )
     547             :     {
     548             :         aItem = m_aHelpBookmarksMenu[nItem];
     549             :         // Format:  "HelpBookmarks/1/URL"
     550             :         //          "HelpBookmarks/1/Title"
     551             :         //          ...
     552             :         sNode = SETNODE_HELPBOOKMARKS + PATHDELIMITER + PATHPREFIX + OUString::valueOf( (sal_Int32)nItem ) + PATHDELIMITER;
     553             : 
     554             :         lPropertyValues[OFFSET_URL             ].Name  =   sNode + PROPERTYNAME_URL             ;
     555             :         lPropertyValues[OFFSET_TITLE           ].Name  =   sNode + PROPERTYNAME_TITLE           ;
     556             :         lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Name  =   sNode + PROPERTYNAME_IMAGEIDENTIFIER ;
     557             :         lPropertyValues[OFFSET_TARGETNAME      ].Name  =   sNode + PROPERTYNAME_TARGETNAME      ;
     558             : 
     559             :         lPropertyValues[OFFSET_URL             ].Value <<= aItem.sURL                           ;
     560             :         lPropertyValues[OFFSET_TITLE           ].Value <<= aItem.sTitle                         ;
     561             :         lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Value <<= aItem.sImageIdentifier               ;
     562             :         lPropertyValues[OFFSET_TARGETNAME      ].Value <<= aItem.sTargetName                    ;
     563             : 
     564             :         SetSetProperties( SETNODE_HELPBOOKMARKS, lPropertyValues );
     565             :     }
     566             :     */
     567           0 : }
     568             : 
     569             : //*****************************************************************************************************************
     570             : //  public method
     571             : //*****************************************************************************************************************
     572           0 : Sequence< Sequence< PropertyValue > > SvtDynamicMenuOptions_Impl::GetMenu( EDynamicMenuType eMenu ) const
     573             : {
     574           0 :     Sequence< Sequence< PropertyValue > > lReturn;
     575           0 :     switch( eMenu )
     576             :     {
     577             :         case E_NEWMENU      :   {
     578           0 :                                     lReturn = m_aNewMenu.GetList();
     579             :                                 }
     580           0 :                                 break;
     581             : 
     582             :         case E_WIZARDMENU   :   {
     583           0 :                                     lReturn = m_aWizardMenu.GetList();
     584             :                                 }
     585           0 :                                 break;
     586             : 
     587             :         case E_HELPBOOKMARKS :  {
     588           0 :                                     lReturn = m_aHelpBookmarksMenu.GetList();
     589             :                                 }
     590           0 :                                 break;
     591             :     }
     592           0 :     return lReturn;
     593             : }
     594             : 
     595             : //*****************************************************************************************************************
     596             : //  private method
     597             : //*****************************************************************************************************************
     598           0 : Sequence< OUString > SvtDynamicMenuOptions_Impl::impl_GetPropertyNames( sal_uInt32& nNewCount, sal_uInt32& nWizardCount, sal_uInt32& nHelpBookmarksCount )
     599             : {
     600             :     // First get ALL names of current existing list items in configuration!
     601           0 :     Sequence< OUString > lNewItems           = GetNodeNames( SETNODE_NEWMENU       );
     602           0 :     Sequence< OUString > lWizardItems        = GetNodeNames( SETNODE_WIZARDMENU    );
     603           0 :     Sequence< OUString > lHelpBookmarksItems = GetNodeNames( SETNODE_HELPBOOKMARKS );
     604             : 
     605             :     // Get information about list counts ...
     606           0 :     nNewCount           = lNewItems.getLength          ();
     607           0 :     nWizardCount        = lWizardItems.getLength       ();
     608           0 :     nHelpBookmarksCount = lHelpBookmarksItems.getLength();
     609             : 
     610             :     // Sort and expand all three list to result list ...
     611           0 :     Sequence< OUString > lProperties;
     612           0 :     impl_SortAndExpandPropertyNames( lNewItems          , lProperties, SETNODE_NEWMENU       );
     613           0 :     impl_SortAndExpandPropertyNames( lWizardItems       , lProperties, SETNODE_WIZARDMENU    );
     614           0 :     impl_SortAndExpandPropertyNames( lHelpBookmarksItems, lProperties, SETNODE_HELPBOOKMARKS );
     615             : 
     616             :     // Return result.
     617           0 :     return lProperties;
     618             : }
     619             : 
     620             : //*****************************************************************************************************************
     621             : //  private helper
     622             : //*****************************************************************************************************************
     623             : class CountWithPrefixSort
     624             : {
     625             :     public:
     626           0 :         int operator() ( const OUString& s1 ,
     627             :                          const OUString& s2 ) const
     628             :         {
     629             :             // Get order numbers from entry name without prefix.
     630             :             // e.g. "m10" => 10
     631             :             //      "m5"  => 5
     632           0 :             sal_Int32 n1 = s1.copy( 1, s1.getLength()-1 ).toInt32();
     633           0 :             sal_Int32 n2 = s2.copy( 1, s2.getLength()-1 ).toInt32();
     634             :             // MUST be in [0,1] ... because it's a difference between
     635             :             // insert-positions of given entries in sorted list!
     636           0 :             return( n1<n2 );
     637             :         }
     638             : };
     639             : 
     640             : class SelectByPrefix
     641             : {
     642             :     public:
     643           0 :         bool operator() ( const OUString& s ) const
     644             :         {
     645             :             // Prefer setup written entries by check first letter of given string. It must be a "s".
     646           0 :             return( s.indexOf( PATHPREFIX_SETUP ) == 0 );
     647             :         }
     648             : };
     649             : 
     650             : //*****************************************************************************************************************
     651             : //  private method
     652             : //*****************************************************************************************************************
     653           0 : void SvtDynamicMenuOptions_Impl::impl_SortAndExpandPropertyNames( const Sequence< OUString >& lSource      ,
     654             :                                                                         Sequence< OUString >& lDestination ,
     655             :                                                                   const OUString&             sSetNode     )
     656             : {
     657           0 :     OUString            sFixPath                                    ;
     658           0 :     vector< OUString >  lTemp                                       ;
     659           0 :     sal_Int32           nSourceCount     = lSource.getLength()      ;
     660           0 :     sal_Int32           nDestinationStep = lDestination.getLength() ; // start on end of current list ...!
     661             : 
     662           0 :     lDestination.realloc( (nSourceCount*PROPERTYCOUNT)+nDestinationStep ); // get enough memory for copy operations after nDestination ...
     663             : 
     664             :     // Copy all items to temp. vector to use fast sort operations :-)
     665           0 :     for( sal_Int32 nSourceStep=0; nSourceStep<nSourceCount; ++nSourceStep )
     666           0 :         lTemp.push_back( lSource[nSourceStep] );
     667             : 
     668             :     // Sort all entries by number ...
     669           0 :     stable_sort( lTemp.begin(), lTemp.end(), CountWithPrefixSort() );
     670             :     // and split into setup & user written entries!
     671           0 :     stable_partition( lTemp.begin(), lTemp.end(), SelectByPrefix() );
     672             : 
     673             :     // Copy sorted entries to destination and expand every item with
     674             :     // 4 supported sub properties.
     675           0 :     for( vector< OUString >::const_iterator pItem =lTemp.begin() ;
     676           0 :                                             pItem!=lTemp.end()   ;
     677             :                                             ++pItem              )
     678             :     {
     679           0 :         sFixPath  = sSetNode       ;
     680           0 :         sFixPath += PATHDELIMITER  ;
     681           0 :         sFixPath += *pItem         ;
     682           0 :         sFixPath += PATHDELIMITER  ;
     683             : 
     684           0 :         lDestination[nDestinationStep]  = sFixPath                      ;
     685           0 :         lDestination[nDestinationStep] += PROPERTYNAME_URL              ;
     686           0 :         ++nDestinationStep;
     687           0 :         lDestination[nDestinationStep]  = sFixPath                      ;
     688           0 :         lDestination[nDestinationStep] += PROPERTYNAME_TITLE            ;
     689           0 :         ++nDestinationStep;
     690           0 :         lDestination[nDestinationStep]  = sFixPath                      ;
     691           0 :         lDestination[nDestinationStep] += PROPERTYNAME_IMAGEIDENTIFIER  ;
     692           0 :         ++nDestinationStep;
     693           0 :         lDestination[nDestinationStep]  = sFixPath                      ;
     694           0 :         lDestination[nDestinationStep] += PROPERTYNAME_TARGETNAME       ;
     695           0 :         ++nDestinationStep;
     696           0 :     }
     697           0 : }
     698             : 
     699             : //*****************************************************************************************************************
     700             : //  initialize static member
     701             : //  DON'T DO IT IN YOUR HEADER!
     702             : //  see definition for further informations
     703             : //*****************************************************************************************************************
     704             : SvtDynamicMenuOptions_Impl*     SvtDynamicMenuOptions::m_pDataContainer = NULL  ;
     705             : sal_Int32                       SvtDynamicMenuOptions::m_nRefCount      = 0     ;
     706             : 
     707             : //*****************************************************************************************************************
     708             : //  constructor
     709             : //*****************************************************************************************************************
     710           0 : SvtDynamicMenuOptions::SvtDynamicMenuOptions()
     711             : {
     712             :     // Global access, must be guarded (multithreading!).
     713           0 :     MutexGuard aGuard( GetOwnStaticMutex() );
     714             :     // Increase ouer refcount ...
     715           0 :     ++m_nRefCount;
     716             :     // ... and initialize ouer data container only if it not already exist!
     717           0 :     if( m_pDataContainer == NULL )
     718             :     {
     719           0 :         m_pDataContainer = new SvtDynamicMenuOptions_Impl;
     720           0 :         ItemHolder1::holdConfigItem(E_DYNAMICMENUOPTIONS);
     721           0 :     }
     722           0 : }
     723             : 
     724             : //*****************************************************************************************************************
     725             : //  destructor
     726             : //*****************************************************************************************************************
     727           0 : SvtDynamicMenuOptions::~SvtDynamicMenuOptions()
     728             : {
     729             :     // Global access, must be guarded (multithreading!)
     730           0 :     MutexGuard aGuard( GetOwnStaticMutex() );
     731             :     // Decrease ouer refcount.
     732           0 :     --m_nRefCount;
     733             :     // If last instance was deleted ...
     734             :     // we must destroy ouer static data container!
     735           0 :     if( m_nRefCount <= 0 )
     736             :     {
     737           0 :         delete m_pDataContainer;
     738           0 :         m_pDataContainer = NULL;
     739           0 :     }
     740           0 : }
     741             : 
     742             : //*****************************************************************************************************************
     743             : //  public method
     744             : //*****************************************************************************************************************
     745           0 : Sequence< Sequence< PropertyValue > > SvtDynamicMenuOptions::GetMenu( EDynamicMenuType eMenu ) const
     746             : {
     747           0 :     MutexGuard aGuard( GetOwnStaticMutex() );
     748           0 :     return m_pDataContainer->GetMenu( eMenu );
     749             : }
     750             : 
     751             : namespace
     752             : {
     753             :     class theDynamicMenuOptionsMutex : public rtl::Static<osl::Mutex, theDynamicMenuOptionsMutex>{};
     754             : }
     755             : 
     756             : //*****************************************************************************************************************
     757             : //  private method
     758             : //*****************************************************************************************************************
     759           0 : Mutex& SvtDynamicMenuOptions::GetOwnStaticMutex()
     760             : {
     761           0 :     return theDynamicMenuOptionsMutex::get();
     762             : }
     763             : 
     764             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10