Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo

Close

Visual Basic in Function List (working parser inside)

McLoo
2013-11-29
2014-12-04
  • McLoo
    McLoo
    2013-11-29

    Hi guys,

    it pretty nagged me, that function list does not recognize VB code.
    So I wrote my own VB parser.

    1. open your functionlist.xml

    2. add
      <association langID="18" id="vb_function" />
      inside the associationMap Tag

    3. add following at the bottom of the file

    Update in Post no 4 (Menno)

    Post 5 waiting for corrections :-)

            <parser id="vb_function" displayName="Visual Basic (.NET|Script|for Applications)" commentExpr="(('.*?$)|(REM.*?$))">
                <!-- (sub | function |...                       =   one of the following: sub, function                                                                     -->
                <!-- ... | property([\s]+(get|let))?)           =   OR one of the following: property, property get, property let (VB.NET ha no get/let outside the prop)   -->
                <!-- [\s]+[[:alpha:]][\w]*                  =   1+ whitespaces, 1 non-digit char, 0+ char                                                               -->
                <!-- ([\s]+lib[\s]+&quot;[\w]+&quot;            =   possible appearance of: 1+ whitespaces lib "libname"                                                    -->
                <!-- ...([\s]+alias[\s]+&quot;[\w]+&quot;)?)?       =   with possible appearence of: 1+ whitespaces alias "aliasname"                                           -->
                <!-- [\s]*\([^\)\(]*\)                          =   0+ whitespaces, parenthesescontaining parameters, can be multiline                                     -->
                <function mainExpr="(sub|function|property([\s]+(get|let))?)[\s]+[[:alpha:]][\w]*([\s]+lib[\s]+&quot;[\w]+&quot;([\s]+alias[\s]+&quot;[\w]+&quot;)?)?[\s]*\([^\)\(]*\)" displayMode="$className->$functionName">
                    <functionName>
                        <!-- (re-)move the \K to display more or less of the function declaration -->
                        <nameExpr expr="((sub|function|property)[\s]+)?\K((let|get)?[\s]+)?[\w&quot;]+([\s]+lib[\s]+&quot;[\w]+&quot;([\s]+alias[\s]+&quot;[\w]+&quot;)?)?"/>
                    </functionName>
                </function>
            </parser>
    
    1. save & enjoy!

    2. post improvements or corrections here and hopefully this will be integrated in the next release

    I didn't figure out how to use the class parser.
    However all function inside a class are found, but they are not associated with the class name.
    The class name isn't displayed at all.

    VB.NET has a class format like:

    Class MyClass

    Sub mySub()
    
    End Sub
    
    Private Function mypFunction () as Long
    
    End Function
    

    End Class

    Any suggestions?

    regards
    McLoo

     
    Last edit: McLoo 2013-12-03
  • Menno Vogels
    Menno Vogels
    2013-11-29

    I suggest some additional test cases:

    REM -- Additonal Test cases --
    
    Class Class2 ' Trailing line comment
    
    ' Class2Sub1 header
    Sub Class2Sub1() ' Trailing line comment
    
    End Sub ' End of Class2Sub1
    
        ' Class2Sub2 header
        Sub Class2Sub2() ' Trailing line comment
    
        End Sub ' End of Class2Sub2
    
    ' Class2Sub3 header
    Sub Class2Sub3()
    
    End Sub ' End of Class2Sub3
    
        ' Class2Sub4 header
        Sub Class2Sub4()
    
        End Sub ' End of Class2Sub4
    
    ' Class2PrivateFunction1 header
    Private Function Class2PrivateFunction1 () as Long' Trailing line comment
    
    End Function ' End of Class2PrivateFunction1
    
        ' Class2PrivateFunction2 header
        Private Function Class2PrivateFunction2 () as Long ' Trailing line comment
    
        End Function ' End of Class2PrivateFunction2
    
    End Class ' End of Class2
    
    REM Remark uppercase
     REM Remark uppercase after 1 space
      REM Remark uppercase after 2 spaces
       REM Remark uppercase after 3 spaces
        REM Remark uppercase after 4 spaces
        REM Remark uppercase after 1 tab
            REM Remark uppercase after 2 tabs
                REM Remark uppercase after 3 tabs
                    REM Remark uppercase after 4 tabs
    
    rem Remark lowercase lowercase
     rem Remark lowercase after 1 space
      rem Remark lowercase after 2 spaces
       rem Remark lowercase after 3 spaces
        rem Remark lowercase after 4 spaces
        rem Remark lowercase after 1 tab
            rem Remark lowercase after 2 tabs
                rem Remark lowercase after 3 tabs
                    rem Remark lowercase after 4 tabs
    
    ' Comment
     ' Comment after 1 space
      ' Comment after 2 spaces
       ' Comment after 3 spaces
        ' Comment after 4 spaces
        ' Comment after 1 tab
            ' Comment after 2 tabs
                ' Ccomment after 3 tabs
                    ' Ccomment after 4 tabs
    
    REM Lines w/ a comment indicator w/o comment
    REM
     REM
      REM
       REM
        REM
        REM
            REM
                REM
                    REM
    rem
     rem
      rem
       rem
        rem
        rem
            rem
                rem
                    rem
    '
     '
      '
       '
        '
        '
            '
                '
                    '
    
    REM -- End of File --
    

    Regards,
    Menno

     
  • McLoo
    McLoo
    2013-11-30

    thank you Menno for the additional input.
    After some testing i came up with the following

    <parser id="vb_function" displayName="Visual Basic (.NET|Script|for Applications)"  commentExpr="((^[\s\t]?'.*?$)|(^[\s\t]?REM .*?$))"> 
        <!-- (sub | function |...                       =   one of the following: sub, function                                                                     -->
        <!-- ... | property([\s]+(get|let))?)           =   OR one of the following: property, property get, property let (VB.NET has no get/let outside the prop)   -->
        <!-- [\s]+[[:alpha:]_][\w]*                     =   1+ whitespaces, 1 non-digit char, 0+ char   (VB.NET allows preceding underscore in name declaration)                                                            -->
        <!-- ([\s]+lib[\s]+&quot;[\w]+&quot;            =   possible appearance of: 1+ whitespaces lib "libname"                                                    -->
        <!-- ...([\s]+alias[\s]+&quot;[\w]+&quot;)?)?   =   with possible appearence of: 1+ whitespaces alias "aliasname"                                           -->
        <!-- [\s]*\([^\)\(]*\)                          =   0+ whitespaces, parenthesescontaining parameters, can be multiline                                     -->
        <!-- [^\n\r]*                                   =   everthing but line breaks                                                                               -->
        <function mainExpr="(sub|function|property([\s]+(get|let))?)[\s]+[[:alpha:]_][\w]*([\s]+lib[\s]+&quot;[\w]+&quot;([\s]+alias[\s]+&quot;[\w]+&quot;)?)?[\s]*\([^\)\(]*\)[^\n\r]*" displayMode="$className->$functionName">
            <functionName>
                <!-- (re-)move the \K to display more or less of the function declaration  -->
                <nameExpr expr="((sub|function|property)[\s]+)?\K((let|get)?[\s]+)?[\w&quot;]+([\s]+lib[\s]+&quot;[\w]+&quot;([\s]+alias[\s]+&quot;[\w]+&quot;)?)?"/>
            </functionName>
        </function>
    </parser>
    

    But still i didn't figure out how to use the classRange. Any help is appreciated!
    this is a good test sample (dont mind the highlighting):

    Class HowToShowTheClass
        Public Sub HowToShowThisSubWithinTheClass_1         (213 as as) as aaaaaaa
    
        end sub
        Public Sub HowToShowThisFunctionWithinTheClass_2 (213 as as) as aaaaaaa
    
        end sub
    end class
    
    Type HowToShowTheType 'which is a struct, no sub or function allowed
       lOne As Long
       lTwo As Long
       lArr() As Long
       'notthisone As Long
    End Type
    

    Last Code i tried was:

        <classRange
            mainExpr="class[\s]+[\w]+"
            openSymbole = "\n"
            closeSymbole = "end class"
            displayMode="node">
            <className>
                <nameExpr expr=".*"/> 
            </className>
                <function 
                    mainExpr="(sub|function|property([\s]+(get|let))?)[\s]+[[:alpha:]_][\w]*([\s]+lib[\s]+&quot;[\w]+&quot;([\s]+alias[\s]+&quot;[\w]+&quot;)?)?[\s]*\([^\)\(]*\)[^\n\r]*" 
                    displayMode="$className->$functionName">
                    <functionName></functionName>
                </function>
        </classRange>
    
     
    Last edit: McLoo 2013-11-30
  • Menno Vogels
    Menno Vogels
    2013-12-01

    Hi McLoo,

    Give this parser a try:

      <parser 
          id="vb_function" 
          displayName="Visual Basic (.NET|Script|for Applications)"  
          commentExpr="(?m:((?&lt;=&apos;).*?$)|((?i:REM)([\t ].*?)?$))"> 
        <classRange
            mainExpr="(?s:(?&lt;SCOPE&gt;(?i:CLASS|TYPE)).*?(?i:END[\t ]\k&lt;SCOPE&gt;))"
            displayMode="node" >
          <className>
            <nameExpr expr="(?i:CLASS|TYPE)[\t ]+(?:[A-Za-z_][\w]*\b)(?:.*?[\r\n])" />
            <nameExpr expr="[\t ]+(?:[A-Za-z_][\w]*\b)" />
            <nameExpr expr="[A-Za-z_][\w]*" />
          </className>
          <function
              mainExpr="(?m:^[\t ]*(?i:(?:(?:PRIVATE|PUBLIC)[\t ]+)?(?:STATIC[\t ]+)?(?:SUB|FUNCTION|PROPERTY)).*?(?:\(|$))" >
            <functionName>
              <funcNameExpr expr="(?i:(?:(?:PRIVATE|PUBLIC)[\t ]+)?(?:STATIC[\t ]+)?(?:SUB|FUNCTION|PROPERTY)).*?(?:\(|$)"/>
              <funcNameExpr expr="(?i:(?:SUB|FUNCTION|PROPERTY)).*?(?:\(|$)"/>
              <funcNameExpr expr="[A-Za-z_][\w]*(?=[\t ]*\()"/>
            </functionName>
          </function>
        </classRange>
        <function 
            mainExpr="^[\t ]*(?i:(?:(?:PRIVATE|PUBLIC)[\t ]+)?(?:STATIC[\t ]+)?(?:SUB|FUNCTION|PROPERTY)).*?(?:\(|$)" 
            displayMode="$functionName">
          <functionName>
            <nameExpr expr="(?i:(?:(?:PRIVATE|PUBLIC)[\t ]+)?(?:STATIC[\t ]+)?(?:SUB|FUNCTION|PROPERTY)).*?(?:\(|$)"/>
            <nameExpr expr="(?i:(?:SUB|FUNCTION|PROPERTY)).*?(?:\(|$)"/>
            <nameExpr expr="[A-Za-z_][\w]*(?=[\t ]*\()"/>
          </functionName>
        </function>
      </parser>
    

    Test file:

    Class MyClass
    
    Sub mySubOfMyClass()
    
    End Sub
    
    Private Function myPrivateFunctionOfMyClass () as Long
    
    End Function
    
    End Class
    
    Class HowToShowTheClass ' Class Declaration
    
        Public Sub HowToShowThisSubWithinTheClass_1         (213 as as) as aaaaaaa
    
        End Sub
    
        Public Function HowToShowThisFunctionWithinTheClass_2 (213 as as) as aaaaaaa
    
        End Function
    End Class
    
    Type HowToShowTheType 'which is a struct, no sub or function allowed
       lOne As Long
       lTwo As Long
       lArr() As Long
       'notthisone As Long
    End Type
    
    REM -- Additonal Test cases --
    
    Class Class2' Trailing line comment
    
        Property Class2_Property_1 ()
        End Property
    
        Property Get Class2_PropertyGet_2()
        End Property
    
        Property Set Class2_PropertySet_3()
        End Property
    
    ' Class2_Sub1 header
    Sub Class2_Sub1()' Trailing line comment
    
    End Sub ' End of Class2_Sub1
    
        ' Class2_Sub2 header
        Sub Class2_Sub2() ' Trailing line comment
    
        End Sub ' End of Class2_Sub2
    
    ' Class2_Sub3 header
    Sub Class2_Sub3()
    
    End Sub ' End of Class2_Sub3
    
        ' Class2_Sub4 header
        Sub Class2_Sub4()
    
        End Sub ' End of Class2_Sub4
    
    ' Class2_Sub5 header
    Sub Class2_Sub5(
        arg1,
        arg2,
        arg3 )
    
    End Sub ' End of Class2_Sub5
    
        ' Class2_Sub6 header
        Sub Class2_Sub6(
            arg1,
            arg2,
            arg3 )
    
        End Sub ' End of Class2_Sub6
    
    ' Class2_PrivateFunction1 header
    Private Function Class2_PrivateFunction1 () as Long' Trailing line comment
    
    End Function ' End of Class2_PrivateFunction1
    
        ' Class2_PrivateFunction2 header
        Private Function Class2_PrivateFunction2 () as Long ' Trailing line comment
    
        End Function ' End of Class2_PrivateFunction2
    
    End Class ' End of Class2
    
    REM - Comment lines begin with an apostrophe (') or with Rem followed by a space, 
    REM - and can be added anywhere in a procedure. To add a comment to the same line 
    REM - as a statement, insert an apostrophe after the statement, followed by 
    REM - the comment.
    
    REM Remark uppercase
     REM Remark uppercase after 1 space
      REM Remark uppercase after 2 spaces
       REM Remark uppercase after 3 spaces
        REM Remark uppercase after 4 spaces
        REM Remark uppercase after 1 tab
            REM Remark uppercase after 2 tabs
                REM Remark uppercase after 3 tabs
                    REM Remark uppercase after 4 tabs
    
    rem Remark lowercase lowercase
     rem Remark lowercase after 1 space
      rem Remark lowercase after 2 spaces
       rem Remark lowercase after 3 spaces
        rem Remark lowercase after 4 spaces
        rem Remark lowercase after 1 tab
            rem Remark lowercase after 2 tabs
                rem Remark lowercase after 3 tabs
                    rem Remark lowercase after 4 tabs
    
    'Comment
    ' Comment
     ' Comment after 1 space
      ' Comment after 2 spaces
       ' Comment after 3 spaces
        ' Comment after 4 spaces
        ' Comment after 1 tab
            ' Comment after 2 tabs
                ' Ccomment after 3 tabs
                    ' Ccomment after 4 tabs
    
    REM Lines w/ a comment indicator w/o comment
    REM
     REM
      REM
       REM
        REM
        REM
            REM
                REM
                    REM
    rem
     rem
      rem
       rem
        rem
        rem
            rem
                rem
                    rem
    '
     '
      '
       '
        '
        '
            '
                '
                    '
    
    REM ----------------------------------------------- Sub Procedure declaration --
    rem -
    rem - Sub subname_ ( [ arguments ] )
    rem -   statements
    rem - End Sub
    Sub SubProcedureName_NoArgs ()
        ' statements
    End Sub
    
    rem
    Sub SubProcedureName ( Argument As Object )
        ' statements
    End Sub
    
    REM ---------------------------------------------------- Function declaration --
    rem - 
    rem - Function functionname ( [ arguments ] ) As Type
    rem -   statements
    rem - End Function
    rem -----
    Function FunctionName_NoArgs () As Type
        ' statements
    End Function
    
    rem
    Function FunctionName ( Argument As Object ) As Type
        ' statements
    End Function
    
    REM ---------------------------------------------------- Property declaration --
    rem -
    rem - [Public | Private] [Static] Property {Get | Let | Set} propertyname_ [(arguments)] [As type]
    rem -   statements
    rem - End Property 
    rem -----
    Property Let PropertyName_Let_NoArgs ()
        ' statements
    End Property
    
    rem
    Static Property Let StaticPropertyName_Let_NoArgs ()
        ' statements
    End Property
    
    rem
    Property Let PropertyName_Let ( Arguments As Object )
        ' statements
    End Property
    
    rem
    Static Property Let StaticPropertyName_Let ( Arguments As Object )
        ' statements
    End Property
    
    rem
    Public Property Let PublicPropertyName_Let ( Arguments As Object )
        ' statements
    End Property
    
    rem
    Public Static Property Let PublicStaticPropertyName_Let ( Arguments As Object )
        ' statements
    End Property
    
    rem
    Private Property Let PrivatePropertyName_Let ( Arguments As Object )
        ' statements
    End Property
    
    rem
    Private Static Property Let PrivateStaticPropertyName_Let ( Arguments As Object )
        ' statements
    End Property
    
    rem -----
    Property Get PropertyName_Get_NoArgs ()
        ' statements
    End Property
    
    rem
    Static Property Get StaticPropertyName_Get_NoArgs ()
        ' statements
    End Property
    
    rem
    Property Get PropertyName_Get ( Arguments As Object )
        ' statements
    End Property
    
    rem
    Static Property Get StaticPropertyName_Get ( Arguments As Object )
        ' statements
    End Property
    
    rem
    Public Property Get PublicPropertyName_Get ( Arguments As Object )
        ' statements
    End Property
    
    rem
    Public Static Property Get PublicStaticPropertyName_Get ( Arguments As Object )
        ' statements
    End Property
    
    rem
    Private Property Get PrivatePropertyName_Get ( Arguments As Object )
        ' statements
    End Property
    
    rem
    Private Static Property Get PrivateStaticPropertyName_Get ( Arguments As Object )
        ' statements
    End Property
    
    rem -----
    Property Set PropertyName_Set_NoArgs ()
        ' statements
    End Property
    
    rem
    Static Property Set StaticPropertyName_Set_NoArgs ()
        ' statements
    End Property
    
    rem
    Property Set PropertyName_Set ( Arguments As Object )
        ' statements
    End Property
    
    rem
    Static Property Set StaticPropertyName_Set ( Arguments As Object )
        ' statements
    End Property
    
    rem
    Public Property Set PublicPropertyName_Set ( Arguments As Object )
        ' statements
    End Property
    
    rem
    Public Static Property Set PublicStaticPropertyName_Set ( Arguments As Object )
        ' statements
    End Property
    
    rem
    Private Property Set PrivatePropertyName_Set ( Arguments As Object )
        ' statements
    End Property
    
    rem
    Private Static Property Set PrivateStaticPropertyName_Set ( Arguments As Object )
        ' statements
    End Property
    
    REM ----------------------------------------------------------------------------
    REM -- End of File --
    

    Although I have included 'Type' for e.g. "HowToShowTheType" it will not show up in the FunctionList-tree unless it has methods.

    Regards, Menno

     
  • McLoo
    McLoo
    2013-12-03

    Hi Menno,

    i think i learned a little bit more about regexp with your parser. Though I'm not completely into it, i extended the parser to match some more VB.NET and declare function in VB.
    VB.NET isn't complete yet, but i think most of it is covered.

    I still got a problem with a line breaks before the parameter parenthesis and some other cases.

    The complete test file is attached.

    The tricky parts are posted in compact form underneath the parser.

    <!-- Menno's ++ -->
    <parser 
      id="vb_function" 
      displayName="Visual Basic (.NET|Script|for Applications)"  
      commentExpr="(?m:((?&lt;=&apos;).*?$)|((?i:REM)([\t ].*?)?$))"> 
    <classRange
        mainExpr="(?s:(?&lt;SCOPE&gt;(?i:CLASS|TYPE)).*?(?i:END[\t ]\k&lt;SCOPE&gt;))"
        displayMode="node" >
      <className>
        <nameExpr expr="(?i:CLASS|TYPE)[\t ]+(?:[A-Za-z_][\w]*\b)(?:.*?[\r\n])" />
        <nameExpr expr="[\t ]+(?:[A-Za-z_][\w]*\b)" />
        <nameExpr expr="[A-Za-z_][\w]*" />
      </className>
      <function
          mainExpr="(?m:^[\t ]*(?i:(?:(?:PUBLIC|PRIVATE|PROTECTED|FRIEND|PROTECTED FRIEND)[\t ]+)?(?:(?:STATIC|SHARED|SHADOWS|OVERRIDABLE|OVERRIDES|READONLY|WRITEONLY)[\t ]+)?(?:SUB|FUNCTION|PROPERTY)).*?(?:\(|$))" >
        <functionName>
          <funcNameExpr expr="(?i:(?:(?:PUBLIC|PRIVATE|PROTECTED|FRIEND|PROTECTED FRIEND)[\t ]+)?(?:STATIC[\t ]+)?(?:SUB|FUNCTION|PROPERTY)).*?(?:\(|$)"/>
          <funcNameExpr expr="(?i:(?:SUB|FUNCTION|PROPERTY)).*?(?:\(|$)"/>
          <funcNameExpr expr="(?i:(?:GET|LET|SET)[\t ]+)?[A-Za-z_][\w]*(?=[\t ]*\()"/>
        </functionName>
      </function>
    </classRange>
    <function 
        mainExpr="^[\t ]*(?i:(?:(?:PUBLIC|PRIVATE|PROTECTED|FRIEND|PROTECTED FRIEND)[\t ]+)?(?:(?:STATIC|(?:DECLARE(?:[\t ]+(ANSI|UNICODE|AUTO))?))[\t ]+)?(?:SUB|FUNCTION|PROPERTY)).*?(?:\(|$)" 
        displayMode="$functionName">
      <functionName>
      <nameExpr expr="(?i:(?:(?:PUBLIC|PRIVATE|PROTECTED|FRIEND|PROTECTED FRIEND)[\t ]+)?(?:(?:STATIC|(?:DECLARE(?:[\t ]+(?:ANSI|UNICODE|AUTO))?))[\t ]+)?(?:SUB|FUNCTION|PROPERTY)).*?(?:\(|$)"/>
        <nameExpr expr="(?i:(?:SUB|FUNCTION|PROPERTY)).*?(?:\(|$)"/>
        <nameExpr expr="(?i:(?:GET|LET|SET)[\t ]+)?[A-Za-z_][\w]*(?i:[\t ]+(LIB|ALIAS)[\t ]+[\w&quot;\.]+)*(?=[\t ]*\()"/>
      </functionName>
    </function>
    

    </parser>

    problematic functions

    ' ######################## problematic test start
    sub 1precedingDigit_NOTVISIBLE_1()
    end sub

    sub 222precedingDigit_NOTVISIBLE_2()
    end sub

        REM ' should be visible:
        Declare Function DeclareTest_5 Lib "user32" Alias "DrawStateA" _
            (ByVal hdc As Long, _
            ByVal fuFlags As Long) As Long
        REM ' 3 not should be visible, at least not as empty nodes in list:
        Declare Function DeclareTest_APINOTVISIBLE_1 'Lib "KGB" Alias "SWR" (ByVal hdc As Long) As Long ' Declare Function DeclareTest_APINOTVISIBLE_3 Lib "gdi32" (ByVal hdc As Long) As Long
        Declare Function DeclareTest_APINOTVISIBLE_2 Lib "'JointSituationCenter" Alias "EU" (ByVal h1 As Long, ByVal h2 As Long, l3 As Any) As Long
        Private Declare Function DeclareTest_APINOTVISIBLE_3 Lib "BND" Alias "REM Noob" (ByVal h1 As Long, ByVal h2 As Long, l3 As Any) As Long
    

    Public Property Get a() As b
    Attribute a.VB_Description = "Returns/sets the background color of the grid."
    a = c.a
    End Property

    Public Property Let a(ByVal c As b)
    a() = c
    PropertyChanged "a"
    End Property

    Public Property Let aa()
    Dim bb As Long
    bb = cc("dd", ByVal 0&, ByVal 0&, ByVal 0&)
    End Property

    Public Property Get "SystemColorDepth_3_NOTVISIBLE " ()
    Dim a As Long
    a = b("v", ByVal 0&, ByVal 0&, ByVal 0&)
    d = e(f, g)
    End Property

    Public Function a(
    ByVal b As String,

    ByVal c As d,
    Optional ByVal e As String,

    Optional ByVal f As Boolean = False,
    Optional ByVal g As Variant,

    Optional ByVal h As Long _
    ) As Long

    PropertyChanged "Images"
    PropertyChanged "Size"
    PropertyChanged "Keys"
    End Function

    public sub subtest_2_ _
    (byaval subarray) as sometypearry()

    end sub
    ' ######################## problematic test end

     
    Last edit: McLoo 2013-12-03
    • Nelson
      Nelson
      2014-07-28

      This works great, but the only issue I'm having appears to be where I'm opening .VB files that have "regions" defined in them. For example

      Region "Form Logic"

      Private Sub frmLogin_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
          Try
      

      ...

      End Region

      The function list will not show any functions contained within regions. I hate using them, but this is existing code. Anyway we can get the FunctionList to show them?

      Thank you,
      FGump

       
  • scormer
    scormer
    2014-12-04

    Hi,

    This post helps. Thanks!

    The only thing to note, you need to replace the functionList.xml in the <User>\AppData\Roaming folder as well.

    Thanks,
    Scormer