CustomMenuBuilder.st
author Jakub Nesveda <jakubnesveda@seznam.cz>
Mon, 29 Dec 2014 09:37:10 +0100
changeset 791 85851bd35faa
parent 790 88f2832e656a
child 795 944c5812e702
permissions -rw-r--r--
Fixed default filter with missing argument in CustomMenuBuilder

"{ Package: 'jn:refactoring_custom' }"

Object subclass:#CustomMenuBuilder
	instanceVariableNames:'perspective menu submenuLabel afterMenuItemLabeled
		generatorOrRefactoringFilter resources navigationState manager'
	classVariableNames:''
	poolDictionaries:''
	category:'Interface-Refactoring-Custom-UI'
!

!CustomMenuBuilder class methodsFor:'documentation'!

documentation
"
    Injects menu item with submenu filled with generators or refactorings to the given menu.
    Basically helps to extend system browser (NewSystemBrowser) context menu (for example
    the menu which pop-ups after right-click on the class list).

    [author:]
        Jakub Nesveda <nesvejak@fit.cvut.cz>
"
! !

!CustomMenuBuilder class methodsFor:'instance creation'!

new
    "return an initialized instance"

    ^ self basicNew initialize.
! !

!CustomMenuBuilder class methodsFor:'building'!

buildMenuForContext:context filter: filter
    ^ self new buildMenuForContext:context filter: filter

    "Created: / 26-08-2014 / 10:12:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!CustomMenuBuilder methodsFor:'accessing'!

afterMenuItemLabeled
    "Returns menu item label after which will be placed 
    new menu item with generators or refactorings"

    ^ afterMenuItemLabeled

    "Modified (comment): / 28-12-2014 / 23:22:55 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
!

afterMenuItemLabeled: aLabel
    "see afterMenuItemLabeled"

    afterMenuItemLabeled := aLabel

    "Modified (comment): / 28-12-2014 / 23:20:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
!

generatorOrRefactoringFilter
    "Returns one argument block which is used to filter generators or refactorings"

    ^ generatorOrRefactoringFilter

    "Modified (comment): / 28-12-2014 / 23:23:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
!

generatorOrRefactoringFilter: aOneArgBlock
    "see generatorOrRefactoringFilter"

    generatorOrRefactoringFilter := aOneArgBlock

    "Modified (comment): / 28-12-2014 / 23:25:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
!

groupsSortBlock
    "Returns a block used to sort generator or refactoring groups"

    ^ [ :a :b | 
        a size = b size ifTrue: [ 
            | i | 

            i := 1.

            [ i < a size and: [ (a at:i) = (b at:i) ] ] whileTrue: [
                i := i + 1 
            ].

            (a at:i) < (b at:i)
        ] ifFalse: [
            a size < b size
        ]
    ]

    "Created: / 28-12-2014 / 20:56:43 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
!

manager
    "Returns generator or refactoring manager which is used to access them.
    See CustomManager for more details."

    ^ manager

    "Modified (comment): / 28-12-2014 / 23:26:48 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
!

manager: aManager
    "see manager"

    manager := aManager

    "Modified (comment): / 28-12-2014 / 23:27:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
!

menu
    "Returns menu (instance of class Menu) in which is created new
    menu item with submenu filled with generators or refactorings"

    ^ menu

    "Modified (comment): / 28-12-2014 / 23:28:28 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
!

menu: aMenu
    "see menu"

    menu := aMenu

    "Modified (comment): / 28-12-2014 / 23:28:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
!

navigationState
    "see Tools::NavigationState"

    ^ navigationState

    "Modified (comment): / 28-12-2014 / 23:29:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
!

navigationState: aNavigationState
    "see Tools::NavigationState"

    navigationState := aNavigationState

    "Created: / 28-12-2014 / 10:09:12 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
    "Modified (comment): / 28-12-2014 / 23:29:54 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
!

perspective
    "see CustomPerspective"

    ^ perspective

    "Modified (comment): / 28-12-2014 / 23:30:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
!

perspective: aCustomPerspective
    "see CustomPerspective"

    perspective := aCustomPerspective

    "Modified (comment): / 28-12-2014 / 23:30:32 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
!

resources
    "Used to translate menu labels (resources string:)"

    ^ resources

    "Modified (comment): / 28-12-2014 / 23:31:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
!

resources: someResources
    "see resources"

    resources := someResources

    "Modified (comment): / 28-12-2014 / 23:32:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
!

submenuLabel
    "Returns label of menu item which contains submenu with generators or refactorings"

    ^ submenuLabel

    "Modified (comment): / 28-12-2014 / 23:33:38 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
!

submenuLabel: aLabel
    "see submenuLabel"

    submenuLabel := aLabel

    "Modified (comment): / 28-12-2014 / 23:33:54 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
! !

!CustomMenuBuilder methodsFor:'building'!

buildMenu
    | item context submenuChannel |

    item := MenuItem label: (resources string: submenuLabel).
    context := CustomBrowserContext 
                    perspective: perspective
                    state: navigationState.

    submenuChannel := [ self buildMenuForContext: context filter: generatorOrRefactoringFilter ].
    "Do not show empty context menu"
    submenuChannel value hasItems ifTrue: [ 
        item submenuChannel: submenuChannel.
        self 
            placeMenuItem: item 
            afterMenuItemLabeled: afterMenuItemLabeled 
            forMenu: menu 
    ]

    "Created: / 27-12-2014 / 17:20:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
    "Modified: / 28-12-2014 / 10:06:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
!

buildMenuForContext: context filter: filter 
    | submenu generatorsAndRefactorings groups groupsMap |

    submenu := Menu new.
    generatorsAndRefactorings := manager generatorsAndRefactoringsSelect: [ :generatorOrRefactoring |
        (generatorOrRefactoring availableInPerspective: context perspective)
            and: [ filter value: generatorOrRefactoring ]
            and: [ generatorOrRefactoring availableForProgrammingLanguagesInContext: context ]
    ].

    "/ Now, group them by group.
    groupsMap := Dictionary new.
    groups := OrderedCollection new.
    generatorsAndRefactorings do:[:each |
        | group |

        group := each group.
        (groupsMap includesKey: group) ifTrue:[ 
            (groupsMap at: group) add: each.
        ] ifFalse:[ 
            groupsMap at: group put: (OrderedCollection with: each).
            groups add: group.
        ].
    ].

    groups sort: self groupsSortBlock.

    groups do:[:name |  
        | items |

        items := groupsMap at: name.
        items sort:[ :a :b | a label < b label ].
        items do:[:each | 
            | item |

            item := MenuItem label: (resources string: each label)
                    itemValue:[ each executeInContextWithWaitCursor: context ].
            item enabled:[ each availableInContext: context ].
            submenu addItem:item.
        ].
    ] separatedBy:[ 
        submenu addSeparator.
    ].

    ^ submenu

    "Created: / 26-08-2014 / 10:13:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified (format): / 28-12-2014 / 23:19:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
!

placeMenuItem: aMenuItem afterMenuItemLabeled: aLabel forMenu: aMenu
    "Places a menu item after another menu item identified by label
    within given menu."    
    | index |

    index := aMenu indexOfMenuItemForWhich:[:each | each label = aLabel ].
    index ~~ 0 ifTrue:[
        "Labeled item found"
        aMenu addItem: aMenuItem beforeIndex: index + 1.
    ] ifFalse:[
        aMenu addItem: aMenuItem.
    ].

    "Created: / 27-12-2014 / 18:45:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
! !

!CustomMenuBuilder methodsFor:'initialization'!

initialize
    "Invoked when a new instance is created."

    menu := Menu new.
    submenuLabel := 'Unknown menu label'.
    generatorOrRefactoringFilter := [ :generatorOrRefactoring | true ].
    resources := self class classResources.
    manager := CustomManager current.

    "Modified (format): / 29-12-2014 / 09:34:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
! !

!CustomMenuBuilder class methodsFor:'documentation'!

version_HG

    ^ '$Changeset: <not expanded> $'
! !