LCOV - code coverage report
Current view: top level - unotools/source/config - dynamicmenuoptions.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 156 175 89.1 %
Date: 2012-08-25 Functions: 20 22 90.9 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 140 282 49.6 %

           Branch data     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                 :       8460 : struct SvtDynMenuEntry
      68                 :            : {
      69                 :            :     public:
      70                 :       1620 :         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         [ +  - ]:        360 : 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                 :       1620 :         void AppendSetupEntry( const SvtDynMenuEntry& rEntry )
     101                 :            :         {
     102         [ +  - ]:       4740 :             if(
           [ +  +  +  - ]
     103                 :       1620 :                 ( lSetupEntries.size()         <  1           )  ||
     104 [ +  - ][ +  + ]:       3120 :                 ( lSetupEntries.rbegin()->sURL != rEntry.sURL )
                 [ #  # ]
     105                 :            :               )
     106                 :            :             {
     107                 :       1620 :                 lSetupEntries.push_back( rEntry );
     108                 :            :             }
     109                 :       1620 :         }
     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                 :       1106 :         Sequence< Sequence< PropertyValue > > GetList() const
     143                 :            :         {
     144                 :       1106 :             sal_Int32                             nSetupCount = (sal_Int32)lSetupEntries.size();
     145                 :       1106 :             sal_Int32                             nUserCount  = (sal_Int32)lUserEntries.size();
     146                 :       1106 :             sal_Int32                             nStep       = 0;
     147         [ +  - ]:       1106 :             Sequence< PropertyValue >             lProperties ( PROPERTYCOUNT );
     148         [ +  - ]:       1106 :             Sequence< Sequence< PropertyValue > > lResult     ( nSetupCount+nUserCount );
     149         [ +  - ]:       1106 :             OUString                              sSeperator  ( RTL_CONSTASCII_USTRINGPARAM("private:separator") );
     150                 :       1106 :             OUString                              sEmpty      ;
     151                 :       1106 :             const vector< SvtDynMenuEntry >*            pList       = &lSetupEntries;
     152                 :            : 
     153 [ +  - ][ +  - ]:       1106 :             lProperties[OFFSET_URL            ].Name = PROPERTYNAME_URL             ;
     154 [ +  - ][ +  - ]:       1106 :             lProperties[OFFSET_TITLE          ].Name = PROPERTYNAME_TITLE           ;
     155 [ +  - ][ +  - ]:       1106 :             lProperties[OFFSET_IMAGEIDENTIFIER].Name = PROPERTYNAME_IMAGEIDENTIFIER ;
     156 [ +  - ][ +  - ]:       1106 :             lProperties[OFFSET_TARGETNAME     ].Name = PROPERTYNAME_TARGETNAME      ;
     157                 :            : 
     158         [ +  + ]:       3318 :             while( pList != NULL )
     159                 :            :             {
     160 [ +  - ][ +  + ]:      37604 :                 for( vector< SvtDynMenuEntry >::const_iterator pItem =pList->begin();
     161                 :      18802 :                                                          pItem!=pList->end()  ;
     162                 :            :                                                          ++pItem              )
     163                 :            :                 {
     164         [ +  + ]:      16590 :                     if( pItem->sURL == sSeperator )
     165                 :            :                     {
     166 [ +  - ][ +  - ]:       3318 :                         lProperties[OFFSET_URL              ].Value <<= sSeperator  ;
     167 [ +  - ][ +  - ]:       3318 :                         lProperties[OFFSET_TITLE            ].Value <<= sEmpty      ;
     168 [ +  - ][ +  - ]:       3318 :                         lProperties[OFFSET_IMAGEIDENTIFIER  ].Value <<= sEmpty      ;
     169 [ +  - ][ +  - ]:       3318 :                         lProperties[OFFSET_TARGETNAME       ].Value <<= sEmpty      ;
     170                 :            :                     }
     171                 :            :                     else
     172                 :            :                     {
     173 [ +  - ][ +  - ]:      13272 :                         lProperties[OFFSET_URL              ].Value <<= pItem->sURL            ;
     174 [ +  - ][ +  - ]:      13272 :                         lProperties[OFFSET_TITLE            ].Value <<= pItem->sTitle          ;
     175 [ +  - ][ +  - ]:      13272 :                         lProperties[OFFSET_IMAGEIDENTIFIER  ].Value <<= pItem->sImageIdentifier;
     176 [ +  - ][ +  - ]:      13272 :                         lProperties[OFFSET_TARGETNAME       ].Value <<= pItem->sTargetName     ;
     177                 :            :                     }
     178 [ +  - ][ +  - ]:      16590 :                     lResult[nStep] = lProperties;
     179                 :      16590 :                     ++nStep;
     180                 :            :                 }
     181         [ +  + ]:       2212 :                 if( pList == &lSetupEntries )
     182                 :       1106 :                     pList = &lUserEntries;
     183                 :            :                 else
     184                 :       1106 :                     pList = NULL;
     185                 :            :             }
     186         [ +  - ]:       1106 :             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                 :         60 : SvtDynamicMenuOptions_Impl::SvtDynamicMenuOptions_Impl()
     349                 :            :     // Init baseclasses first
     350 [ +  - ][ +  - ]:         60 :     :   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                 :         60 :     sal_uInt32              nNewCount           = 0;
     356                 :         60 :     sal_uInt32              nWizardCount        = 0;
     357                 :         60 :     sal_uInt32              nHelpBookmarksCount = 0;
     358                 :            :     Sequence< OUString >    lNames              = impl_GetPropertyNames ( nNewCount           ,
     359                 :            :                                                                           nWizardCount        ,
     360         [ +  - ]:         60 :                                                                           nHelpBookmarksCount );
     361         [ +  - ]:         60 :     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                 :         60 :     sal_uInt32  nItem     = 0 ;
     392                 :         60 :     sal_uInt32  nPosition = 0 ;
     393                 :         60 :     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         [ +  - ]:         60 :     SvtModuleOptions aModuleOptions;
     400                 :            : 
     401                 :            :     // Get names/values for new menu.
     402                 :            :     // 4 subkeys for every item!
     403         [ +  + ]:        960 :     for( nItem=0; nItem<nNewCount; ++nItem )
     404                 :            :     {
     405                 :        900 :         SvtDynMenuEntry   aItem                       ;
     406         [ +  - ]:        900 :         lValues[nPosition] >>= aItem.sURL             ;
     407                 :        900 :         ++nPosition;
     408         [ +  - ]:        900 :         lValues[nPosition] >>= aItem.sTitle           ;
     409                 :        900 :         ++nPosition;
     410         [ +  - ]:        900 :         lValues[nPosition] >>= aItem.sImageIdentifier ;
     411                 :        900 :         ++nPosition;
     412         [ +  - ]:        900 :         lValues[nPosition] >>= aItem.sTargetName      ;
     413                 :        900 :         ++nPosition;
     414         [ +  - ]:        900 :         m_aNewMenu.AppendSetupEntry( aItem );
     415                 :        900 :     }
     416                 :            : 
     417                 :            :     // Attention: Don't reset nPosition here!
     418                 :            : 
     419                 :            :     // Get names/values for wizard menu.
     420                 :            :     // 4 subkeys for every item!
     421         [ +  + ]:        780 :     for( nItem=0; nItem<nWizardCount; ++nItem )
     422                 :            :     {
     423                 :        720 :         SvtDynMenuEntry   aItem                       ;
     424         [ +  - ]:        720 :         lValues[nPosition] >>= aItem.sURL             ;
     425                 :        720 :         ++nPosition;
     426         [ +  - ]:        720 :         lValues[nPosition] >>= aItem.sTitle           ;
     427                 :        720 :         ++nPosition;
     428         [ +  - ]:        720 :         lValues[nPosition] >>= aItem.sImageIdentifier ;
     429                 :        720 :         ++nPosition;
     430         [ +  - ]:        720 :         lValues[nPosition] >>= aItem.sTargetName      ;
     431                 :        720 :         ++nPosition;
     432         [ +  - ]:        720 :         m_aWizardMenu.AppendSetupEntry( aItem );
     433                 :        720 :     }
     434                 :            : 
     435                 :            :     // Attention: Don't reset nPosition here!
     436                 :            : 
     437                 :            :     // Get names/values for wizard menu.
     438                 :            :     // 4 subkeys for every item!
     439         [ -  + ]:         60 :     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 [ +  - ][ +  - ]:         60 :     }
                 [ +  - ]
     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                 :         60 : }
     459                 :            : 
     460                 :            : //*****************************************************************************************************************
     461                 :            : //  destructor
     462                 :            : //*****************************************************************************************************************
     463                 :         60 : SvtDynamicMenuOptions_Impl::~SvtDynamicMenuOptions_Impl()
     464                 :            : {
     465                 :            :     // We must save our current values .. if user forget it!
     466 [ +  - ][ -  + ]:         60 :     if( IsModified() == sal_True )
     467                 :            :     {
     468                 :          0 :         Commit();
     469                 :            :     }
     470         [ -  + ]:        120 : }
     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                 :       1106 : Sequence< Sequence< PropertyValue > > SvtDynamicMenuOptions_Impl::GetMenu( EDynamicMenuType eMenu ) const
     573                 :            : {
     574                 :       1106 :     Sequence< Sequence< PropertyValue > > lReturn;
     575   [ +  -  -  - ]:       1106 :     switch( eMenu )
     576                 :            :     {
     577                 :            :         case E_NEWMENU      :   {
     578 [ +  - ][ +  - ]:       1106 :                                     lReturn = m_aNewMenu.GetList();
                 [ +  - ]
     579                 :            :                                 }
     580                 :       1106 :                                 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                 :       1106 :     return lReturn;
     593                 :            : }
     594                 :            : 
     595                 :            : //*****************************************************************************************************************
     596                 :            : //  private method
     597                 :            : //*****************************************************************************************************************
     598                 :         60 : 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 [ +  - ][ +  - ]:         60 :     Sequence< OUString > lNewItems           = GetNodeNames( SETNODE_NEWMENU       );
     602 [ +  - ][ +  - ]:         60 :     Sequence< OUString > lWizardItems        = GetNodeNames( SETNODE_WIZARDMENU    );
     603 [ +  - ][ +  - ]:         60 :     Sequence< OUString > lHelpBookmarksItems = GetNodeNames( SETNODE_HELPBOOKMARKS );
     604                 :            : 
     605                 :            :     // Get information about list counts ...
     606                 :         60 :     nNewCount           = lNewItems.getLength          ();
     607                 :         60 :     nWizardCount        = lWizardItems.getLength       ();
     608                 :         60 :     nHelpBookmarksCount = lHelpBookmarksItems.getLength();
     609                 :            : 
     610                 :            :     // Sort and expand all three list to result list ...
     611         [ +  - ]:         60 :     Sequence< OUString > lProperties;
     612 [ +  - ][ +  - ]:         60 :     impl_SortAndExpandPropertyNames( lNewItems          , lProperties, SETNODE_NEWMENU       );
     613 [ +  - ][ +  - ]:         60 :     impl_SortAndExpandPropertyNames( lWizardItems       , lProperties, SETNODE_WIZARDMENU    );
     614 [ +  - ][ +  - ]:         60 :     impl_SortAndExpandPropertyNames( lHelpBookmarksItems, lProperties, SETNODE_HELPBOOKMARKS );
     615                 :            : 
     616                 :            :     // Return result.
     617 [ +  - ][ +  - ]:         60 :     return lProperties;
                 [ +  - ]
     618                 :            : }
     619                 :            : 
     620                 :            : //*****************************************************************************************************************
     621                 :            : //  private helper
     622                 :            : //*****************************************************************************************************************
     623                 :            : class CountWithPrefixSort
     624                 :            : {
     625                 :            :     public:
     626                 :       4380 :         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                 :       4380 :             sal_Int32 n1 = s1.copy( 1, s1.getLength()-1 ).toInt32();
     633                 :       4380 :             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                 :       4380 :             return( n1<n2 );
     637                 :            :         }
     638                 :            : };
     639                 :            : 
     640                 :            : class SelectByPrefix
     641                 :            : {
     642                 :            :     public:
     643                 :       1620 :         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                 :       1620 :             return( s.indexOf( PATHPREFIX_SETUP ) == 0 );
     647                 :            :         }
     648                 :            : };
     649                 :            : 
     650                 :            : //*****************************************************************************************************************
     651                 :            : //  private method
     652                 :            : //*****************************************************************************************************************
     653                 :        180 : void SvtDynamicMenuOptions_Impl::impl_SortAndExpandPropertyNames( const Sequence< OUString >& lSource      ,
     654                 :            :                                                                         Sequence< OUString >& lDestination ,
     655                 :            :                                                                   const OUString&             sSetNode     )
     656                 :            : {
     657                 :        180 :     OUString            sFixPath                                    ;
     658         [ +  - ]:        180 :     vector< OUString >  lTemp                                       ;
     659                 :        180 :     sal_Int32           nSourceCount     = lSource.getLength()      ;
     660                 :        180 :     sal_Int32           nDestinationStep = lDestination.getLength() ; // start on end of current list ...!
     661                 :            : 
     662         [ +  - ]:        180 :     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         [ +  + ]:       1800 :     for( sal_Int32 nSourceStep=0; nSourceStep<nSourceCount; ++nSourceStep )
     666         [ +  - ]:       1620 :         lTemp.push_back( lSource[nSourceStep] );
     667                 :            : 
     668                 :            :     // Sort all entries by number ...
     669         [ +  - ]:        180 :     stable_sort( lTemp.begin(), lTemp.end(), CountWithPrefixSort() );
     670                 :            :     // and split into setup & user written entries!
     671         [ +  - ]:        180 :     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 [ +  - ][ +  - ]:       3600 :     for( vector< OUString >::const_iterator pItem =lTemp.begin() ;
                 [ +  + ]
     676                 :       1800 :                                             pItem!=lTemp.end()   ;
     677                 :            :                                             ++pItem              )
     678                 :            :     {
     679                 :       1620 :         sFixPath  = sSetNode       ;
     680         [ +  - ]:       1620 :         sFixPath += PATHDELIMITER  ;
     681                 :       1620 :         sFixPath += *pItem         ;
     682         [ +  - ]:       1620 :         sFixPath += PATHDELIMITER  ;
     683                 :            : 
     684         [ +  - ]:       1620 :         lDestination[nDestinationStep]  = sFixPath                      ;
     685 [ +  - ][ +  - ]:       1620 :         lDestination[nDestinationStep] += PROPERTYNAME_URL              ;
     686                 :       1620 :         ++nDestinationStep;
     687         [ +  - ]:       1620 :         lDestination[nDestinationStep]  = sFixPath                      ;
     688 [ +  - ][ +  - ]:       1620 :         lDestination[nDestinationStep] += PROPERTYNAME_TITLE            ;
     689                 :       1620 :         ++nDestinationStep;
     690         [ +  - ]:       1620 :         lDestination[nDestinationStep]  = sFixPath                      ;
     691 [ +  - ][ +  - ]:       1620 :         lDestination[nDestinationStep] += PROPERTYNAME_IMAGEIDENTIFIER  ;
     692                 :       1620 :         ++nDestinationStep;
     693         [ +  - ]:       1620 :         lDestination[nDestinationStep]  = sFixPath                      ;
     694 [ +  - ][ +  - ]:       1620 :         lDestination[nDestinationStep] += PROPERTYNAME_TARGETNAME       ;
     695                 :       1620 :         ++nDestinationStep;
     696                 :        180 :     }
     697                 :        180 : }
     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                 :       1166 : SvtDynamicMenuOptions::SvtDynamicMenuOptions()
     711                 :            : {
     712                 :            :     // Global access, must be guarded (multithreading!).
     713 [ +  - ][ +  - ]:       1166 :     MutexGuard aGuard( GetOwnStaticMutex() );
     714                 :            :     // Increase ouer refcount ...
     715                 :       1166 :     ++m_nRefCount;
     716                 :            :     // ... and initialize ouer data container only if it not already exist!
     717         [ +  + ]:       1166 :     if( m_pDataContainer == NULL )
     718                 :            :     {
     719 [ +  - ][ +  - ]:         60 :         m_pDataContainer = new SvtDynamicMenuOptions_Impl;
     720         [ +  - ]:         60 :         ItemHolder1::holdConfigItem(E_DYNAMICMENUOPTIONS);
     721         [ +  - ]:       1166 :     }
     722                 :       1166 : }
     723                 :            : 
     724                 :            : //*****************************************************************************************************************
     725                 :            : //  destructor
     726                 :            : //*****************************************************************************************************************
     727                 :       1166 : SvtDynamicMenuOptions::~SvtDynamicMenuOptions()
     728                 :            : {
     729                 :            :     // Global access, must be guarded (multithreading!)
     730 [ +  - ][ +  - ]:       1166 :     MutexGuard aGuard( GetOwnStaticMutex() );
     731                 :            :     // Decrease ouer refcount.
     732                 :       1166 :     --m_nRefCount;
     733                 :            :     // If last instance was deleted ...
     734                 :            :     // we must destroy ouer static data container!
     735         [ +  + ]:       1166 :     if( m_nRefCount <= 0 )
     736                 :            :     {
     737 [ +  - ][ +  - ]:         60 :         delete m_pDataContainer;
     738                 :         60 :         m_pDataContainer = NULL;
     739         [ +  - ]:       1166 :     }
     740         [ -  + ]:       1226 : }
     741                 :            : 
     742                 :            : //*****************************************************************************************************************
     743                 :            : //  public method
     744                 :            : //*****************************************************************************************************************
     745                 :       1106 : Sequence< Sequence< PropertyValue > > SvtDynamicMenuOptions::GetMenu( EDynamicMenuType eMenu ) const
     746                 :            : {
     747 [ +  - ][ +  - ]:       1106 :     MutexGuard aGuard( GetOwnStaticMutex() );
     748 [ +  - ][ +  - ]:       1106 :     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                 :       3438 : Mutex& SvtDynamicMenuOptions::GetOwnStaticMutex()
     760                 :            : {
     761                 :       3438 :     return theDynamicMenuOptionsMutex::get();
     762                 :            : }
     763                 :            : 
     764                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10