AssistantApplication.st
author Claus Gittinger <cg@exept.de>
Mon, 09 Mar 2020 14:19:10 +0100
changeset 6238 1f70ed3090a4
parent 6197 4f1de496aade
permissions -rw-r--r--
#UI_ENHANCEMENT by cg class: CheckBox changed: #initialize

"
 COPYRIGHT (c) 2018 by eXept Software AG
              All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.  This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"
"{ Package: 'stx:libwidg2' }"

"{ NameSpace: Smalltalk }"

ToolApplicationModel subclass:#AssistantApplication
	instanceVariableNames:'currentPageSpecHolder backButtonEnabled forwardButtonEnabled
		backButtonVisible forwardButtonVisible finishButtonVisible
		finishButtonEnabled currentPageInfoHTMLHolder
		currentPageIndexHolder backButtonLabelHolder
		nextButtonLabelHolder pageLabelsInList pageInfoHolder infoHolder
		cancelButtonVisible'
	classVariableNames:''
	poolDictionaries:''
	category:'Views-DialogBoxes'
!

!AssistantApplication class methodsFor:'documentation'!

copyright
"
 COPYRIGHT (c) 2018 by eXept Software AG
              All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.  This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.

"
!

documentation
"
    an easy to use framework for assistant-dialog applications.
    These are multipage applications, in which the user is able to navigate
    along achain of pages as specified in the AssistantSpec

    see stx:doc/coding:DemoAssistant for a demo example.
    see ProjectBuilderAssistantApplication for a concrete example.

    caveat: should have called this WizardApplication

    [author:]
        Claus Gittinger
"
! !

!AssistantApplication class methodsFor:'defaults'!

windowLabelTemplate
    ^ 'Assistant: %1'

    "Modified: / 14-02-2017 / 11:50:53 / cg"
! !

!AssistantApplication class methodsFor:'help'!

helpSpec
    <resource: #help>

    ^ super helpSpec addPairsFrom:#(

#backButton
'Navigate to the previous page %(previousPageInfo)'

#nextButton
'Navigate to the next page %(nextPageInfo)'

)
! !

!AssistantApplication class methodsFor:'image specs'!

bulletIcon
    "This resource specification was automatically generated
     by the ImageEditor of ST/X."

    "Do not manually edit this!! If it is corrupted,
     the ImageEditor may not be able to read the specification."

    "
     self bulletIcon inspect
     ImageEditor openOnClass:self andSelector:#bulletIcon
     Icon flushCachedIcons
    "

    <resource: #image>

    ^Icon
        constantNamed:'AssistantApplication class bulletIcon'
        ifAbsentPut:[(Depth2Image new) width: 16; height: 16; photometric:(#palette); bitsPerSample:(#[2]); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@@@@@@@@@@@@% @@BPA @@P@D@@ @@ @D@@D@A@@A@@ @@ @A@@P@@$@X@@@% @@@@@@@@@@@@@@@@@@@a') ; colorMapFromArray:#[0 0 0 84 84 84 170 170 170 255 255 255]; mask:((ImageMask new) width: 16; height: 16; photometric:(#blackIs0); bitsPerSample:(#[1]); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@@@<@O<@?0G? _>A?8G? O<@?0@<@@@@@@@@@b') ; yourself); yourself]
!

leftArrowIcon
    "This resource specification was automatically generated
     by the ImageEditor of ST/X."

    "Do not manually edit this!! If it is corrupted,
     the ImageEditor may not be able to read the specification."

    "
     self leftArrowIcon inspect
     ImageEditor openOnClass:self andSelector:#leftArrowIcon
     Icon flushCachedIcons
    "

    <resource: #image>

    ^Icon
        constantNamed:'AssistantApplication class leftArrowIcon'
        ifAbsentPut:[(Depth2Image new) width: 16; height: 16; photometric:(#palette); bitsPerSample:(#[2]); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@@@@@@@@@@@@@@@@@@@@@@D@@@@G@@@@G??<@A???@@G@@@@@P@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@a') ; colorMapFromArray:#[0 0 0 84 84 84 170 170 170 255 255 255]; mask:((ImageMask new) width: 16; height: 16; photometric:(#blackIs0); bitsPerSample:(#[1]); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@A@@L@A0@O@A?>O?9??''?>O?8_? <@A0@C@@D@@@@b') ; yourself); yourself]
!

rightArrowIcon
    "This resource specification was automatically generated
     by the ImageEditor of ST/X."

    "Do not manually edit this!! If it is corrupted,
     the ImageEditor may not be able to read the specification."

    "
     self rightArrowIcon inspect
     ImageEditor openOnClass:self andSelector:#rightArrowIcon
     Icon flushCachedIcons
    "

    <resource: #image>

    ^Icon
        constantNamed:'AssistantApplication class rightArrowIcon'
        ifAbsentPut:[(Depth2Image new) width: 16; height: 16; photometric:(#palette); bitsPerSample:(#[2]); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@P@@@@M@@O??4@C??=@@@@M@@@@A@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@a') ; colorMapFromArray:#[0 0 0 84 84 84 170 170 170 255 255 255]; mask:((ImageMask new) width: 16; height: 16; photometric:(#blackIs0); bitsPerSample:(#[1]); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@ @C@@N@@<G?8_?1??''?>_?1?>@C0@N@@0@B@@@@b') ; yourself); yourself]
! !

!AssistantApplication class methodsFor:'interface specs'!

windowSpec
    "This resource specification was automatically generated
     by the UIPainter of ST/X."

    "Do not manually edit this!! If it is corrupted,
     the UIPainter may not be able to read the specification."

    "
     UIPainter new openOnClass:AssistantApplication andSelector:#windowSpec
     AssistantApplication new openInterface:#windowSpec
     AssistantApplication open
    "

    <resource: #canvas>

    ^ 
    #(FullSpec
       name: windowSpec
       window: 
      (WindowSpec
         label: 'Assistant'
         name: 'Assistant'
         bounds: (Rectangle 0 0 806 608)
         menu: mainMenu
         icon: defaultIcon
       )
       component: 
      (SpecCollection
         collection: (
          (ViewSpec
             name: 'Box1'
             layout: (LayoutFrame 0 0 0 0 0 1 -25 1)
             component: 
            (SpecCollection
               collection: (
                (VariableHorizontalPanelSpec
                   name: 'MainHorizontalPanel'
                   layout: (LayoutFrame 0 0 0 0 0 1 -40 1)
                   component: 
                  (SpecCollection
                     collection: (
                      (ViewSpec
                         name: 'Box2'
                         component: 
                        (SpecCollection
                           collection: (
                            (VariableVerticalPanelSpec
                               name: 'VariableVerticalPanel1'
                               layout: (LayoutFrame 0 0 0 0 0 1 0 1)
                               component: 
                              (SpecCollection
                                 collection: (
                                  (SequenceViewSpec
                                     name: 'PagesLabelList'
                                     level: 0
                                     enableChannel: false
                                     hasHorizontalScrollBar: true
                                     hasVerticalScrollBar: true
                                     miniScrollerHorizontal: true
                                     useIndex: true
                                     sequenceList: pageLabelsInList
                                   )
                                  (HTMLViewSpec
                                     name: 'HTMLBrowser1'
                                     level: 0
                                     hasHorizontalScrollBar: true
                                     hasVerticalScrollBar: true
                                     miniScrollerHorizontal: true
                                     miniScrollerVertical: false
                                     htmlText: pageInfoHolder
                                   )
                                  )
                                
                               )
                               handles: (Any 0.5 1.0)
                             )
                            )
                          
                         )
                       )
                      (SubCanvasSpec
                         name: 'SubCanvas1'
                         hasHorizontalScrollBar: false
                         hasVerticalScrollBar: false
                         miniScrollerHorizontal: false
                         miniScrollerVertical: false
                         specHolder: currentPageSpecHolder
                         createNewBuilder: false
                       )
                      )
                    
                   )
                   handles: (Any 0.5 1.0)
                 )
                (HorizontalPanelViewSpec
                   name: 'TwoPanelsPanel'
                   layout: (LayoutFrame 0 0 -40 1 0 1 0 1)
                   horizontalLayout: fit
                   verticalLayout: fit
                   horizontalSpace: 3
                   verticalSpace: 3
                   reverseOrderIfOKAtLeft: true
                   component: 
                  (SpecCollection
                     collection: (
                      (HorizontalPanelViewSpec
                         name: 'ButtonPanel2'
                         horizontalLayout: rightSpaceMax
                         verticalLayout: center
                         horizontalSpace: 3
                         verticalSpace: 3
                         ignoreInvisibleComponents: false
                         reverseOrderIfOKAtLeft: true
                         component: 
                        (SpecCollection
                           collection: (
                            (ActionButtonSpec
                               label: 'Cancel'
                               name: 'Button8'
                               visibilityChannel: cancelButtonVisible
                               translateLabel: true
                               resizeForLabel: true
                               model: doCancel
                               extent: (Point 80 22)
                             )
                            (ActionButtonSpec
                               label: 'Finish'
                               name: 'Button7'
                               visibilityChannel: finishButtonVisible
                               translateLabel: true
                               resizeForLabel: true
                               model: doFinish
                               enableChannel: finishButtonEnabled
                               extent: (Point 80 22)
                             )
                            )
                          
                         )
                         extent: (Point 401 40)
                       )
                      (HorizontalPanelViewSpec
                         name: 'ButtonPanel1'
                         horizontalLayout: centerMax
                         verticalLayout: center
                         horizontalSpace: 3
                         verticalSpace: 3
                         component: 
                        (SpecCollection
                           collection: (
                            (ActionButtonSpec
                               label: 'Back'
                               name: 'Button1'
                               activeHelpKey: backButton
                               visibilityChannel: backButtonVisible
                               translateLabel: true
                               labelChannel: backButtonLabelHolder
                               model: goBackward
                               enableChannel: backButtonEnabled
                               useDefaultExtent: true
                             )
                            (ActionButtonSpec
                               label: 'Next'
                               name: 'Button2'
                               activeHelpKey: nextButton
                               visibilityChannel: forwardButtonVisible
                               translateLabel: true
                               labelChannel: nextButtonLabelHolder
                               model: goForward
                               enableChannel: forwardButtonEnabled
                               useDefaultExtent: true
                             )
                            )
                          
                         )
                         extent: (Point 402 40)
                       )
                      )
                    
                   )
                 )
                )
              
             )
           )
          (LabelSpec
             label: 'Label'
             name: 'Label1'
             layout: (LayoutFrame 1 0 -25 1 -1 1 -1 1)
             level: -1
             translateLabel: true
             labelChannel: infoHolder
             adjust: left
           )
          )
        
       )
     )
! !

!AssistantApplication class methodsFor:'menu specs'!

mainMenu
    "This resource specification was automatically generated
     by the MenuEditor of ST/X."

    "Do not manually edit this!! If it is corrupted,
     the MenuEditor may not be able to read the specification."

    "
     MenuEditor new openOnClass:AssistantApplication andSelector:#mainMenu
     (Menu new fromLiteralArrayEncoding:(AssistantApplication mainMenu)) startUp
    "

    <resource: #menu>

    ^ 
     #(Menu
        (
         (MenuItem
            label: 'File'
            translateLabel: true
            submenu: 
           (Menu
              (
               (MenuItem
                  label: 'Exit'
                  itemValue: closeRequest
                  translateLabel: true
                )
               )
              nil
              nil
            )
          )
         (MenuItem
            label: 'MENU_Help'
            startGroup: conditionalRight
            translateLabel: true
            submenu: 
           (Menu
              (
               (MenuItem
                  label: 'Documentation'
                  itemValue: openDocumentation
                  translateLabel: true
                )
               (MenuItem
                  label: '-'
                )
               (MenuItem
                  label: 'About this Application...'
                  itemValue: openAboutThisApplication
                  translateLabel: true
                )
               )
              nil
              nil
            )
          )
         )
        nil
        nil
      )
! !

!AssistantApplication class methodsFor:'queries'!

isAbstract
    ^ self == AssistantApplication
! !

!AssistantApplication class methodsFor:'required protocol'!

assistantSpec
    "must return a sequenceable collection of assistantPageSpecs - one for each page"

    self subclassResponsibility
! !

!AssistantApplication methodsFor:'actions'!

canGoBackward
    |currentPageSpec previousPageSpec|

    "/ see if we are allowed to leave...
    currentPageSpec := self currentPageSpec.
    currentPageSpec canLeaveQuerySelector notNil ifTrue:[
        (self perform:currentPageSpec canLeaveQuerySelector) ifFalse:[^ false].
    ].

    "/ see if we are allowed to enter the next...
    previousPageSpec := self previousEnabledPageSpec.
    previousPageSpec isNil ifTrue:[^ false].

    previousPageSpec canEnterQuerySelector notNil ifTrue:[
        (self perform:previousPageSpec canEnterQuerySelector) ifFalse:[^ false].
    ].
    ^ true
!

canGoForward
    |currentPageSpec nextPageSpec|

    self currentPageIndex == self numberOfPages ifTrue:[^ false].

    "/ see if we are allowed to leave...
    currentPageSpec := self currentPageSpec.
    currentPageSpec canLeaveQuerySelector notNil ifTrue:[
        (self perform:currentPageSpec canLeaveQuerySelector) ifFalse:[^ false].
    ].

    "/ see if we are allowed to enter the next...
    nextPageSpec := self nextEnabledPageSpec.
    nextPageSpec isNil ifTrue:[^ false].

    nextPageSpec canEnterQuerySelector notNil ifTrue:[
        (self perform:nextPageSpec canEnterQuerySelector) ifFalse:[^ false].
    ].
    ^ true
!

doCancel
    self closeRequest
!

doFinish
    self closeRequest
!

goBackward
    (self canGoBackward) ifFalse:[^ self].
    self gotoPage:((self indexOfPreviousEnabledPageSpec) max:1)

    "Modified: / 20-07-2012 / 12:37:40 / cg"
!

goForward
    (self canGoForward) ifFalse:[^ self].
    self gotoPage:(self indexOfNextEnabledPageSpec)

    "Modified: / 20-07-2012 / 12:37:54 / cg"
!

gotoPage: pageIndex
    |currentPageSpec|

    currentPageSpec := self currentPageSpec.
    currentPageSpec leaveCallbackSelector notNil ifTrue:[
        self perform:currentPageSpec leaveCallbackSelector
    ].

    self currentPageIndexHolder value: pageIndex.

    currentPageSpec := self currentPageSpec.
    currentPageSpec enterCallbackSelector notNil ifTrue:[
        self perform:currentPageSpec enterCallbackSelector
    ].

    self updateButtonEnableState.

    "Created: / 20-07-2012 / 12:37:12 / cg"
! !

!AssistantApplication methodsFor:'aspects'!

assistantSpec
    ^ self class assistantSpec
!

backButtonEnabled
    <resource: #uiAspect>

    backButtonEnabled isNil ifTrue:[
        backButtonEnabled := false asValue.
    ].
    ^ backButtonEnabled.
!

backButtonLabelHolder
    <resource: #uiAspect>

    backButtonLabelHolder isNil ifTrue:[
        backButtonLabelHolder := self backButtonLabel asValue.
    ].
    ^ backButtonLabelHolder.
!

backButtonVisible
    <resource: #uiAspect>

    backButtonVisible isNil ifTrue:[
        backButtonVisible := true asValue.
    ].
    ^ backButtonVisible.
!

cancelButtonVisible
    <resource: #uiAspect>

    cancelButtonVisible isNil ifTrue:[
        cancelButtonVisible := true asValue.
    ].
    ^ cancelButtonVisible.

    "Created: / 06-09-2012 / 16:41:11 / cg"
!

currentPageIndexHolder
    <resource: #uiAspect>

    currentPageIndexHolder isNil ifTrue:[
        currentPageIndexHolder := 1 asValue.
        currentPageIndexHolder onChangeSend:#updateCanvas to:self
    ].
    ^ currentPageIndexHolder.
!

currentPageInfoHTMLHolder
    <resource: #uiAspect>

    currentPageInfoHTMLHolder isNil ifTrue:[
        currentPageInfoHTMLHolder := ValueHolder new.
    ].
    ^ currentPageInfoHTMLHolder.
!

currentPageSpecHolder
    <resource: #uiAspect>

    currentPageSpecHolder isNil ifTrue:[
        currentPageSpecHolder := nil asValue.
    ].
    ^ currentPageSpecHolder.
!

finishButtonEnabled
    <resource: #uiAspect>

    finishButtonEnabled isNil ifTrue:[
        finishButtonEnabled := false asValue.
    ].
    ^ finishButtonEnabled.
!

finishButtonVisible
    <resource: #uiAspect>

    finishButtonVisible isNil ifTrue:[
        finishButtonVisible := false asValue.
    ].
    ^ finishButtonVisible.
!

forwardButtonEnabled
    <resource: #uiAspect>

    forwardButtonEnabled isNil ifTrue:[
        forwardButtonEnabled := false asValue.
    ].
    ^ forwardButtonEnabled.
!

forwardButtonVisible
    <resource: #uiAspect>

    forwardButtonVisible isNil ifTrue:[
        forwardButtonVisible := true asValue.
    ].
    ^ forwardButtonVisible.
!

infoHolder
    "info message at the bottom"

    <resource: #uiAspect>

    infoHolder isNil ifTrue:[
        infoHolder := nil asValue.
    ].
    ^ infoHolder.

    "Modified: / 12-11-2010 / 12:33:01 / cg"
!

nextButtonLabelHolder
    <resource: #uiAspect>

    nextButtonLabelHolder isNil ifTrue:[
        nextButtonLabelHolder := self nextButtonLabel asValue.
    ].
    ^ nextButtonLabelHolder.
!

pageInfoHolder
    <resource: #uiAspect>

    pageInfoHolder isNil ifTrue:[
        pageInfoHolder := nil asValue.
    ].
    ^ pageInfoHolder.
!

pageLabelsInList
    pageLabelsInList isNil ifTrue:[
        pageLabelsInList := List new.
        pageLabelsInList contents:(self pageLabelsInListWithBullet).
    ].
    ^ pageLabelsInList
!

pageLabelsInListWithBullet
    |newList|

    newList := self pageLabels.
    newList := newList 
                with:(1 to:newList size) 
                collect:[:entry :index |
                    index == self currentPageIndex ifTrue:[
                        LabelAndTwoIcons new 
                            string:(entry allBold 
                                        withColor:(TextView defaultSelectionForegroundColor) 
                                        on:(TextView defaultSelectionBackgroundColor) );
                            icon:(self class rightArrowIcon);
                            image2:(self class leftArrowIcon)
                    ] ifFalse:[
                        (self isPageEnabledAtIndex:index) ifFalse:[
                            entry withColor:(Button defaultDisabledForegroundColor) "Color grey".
                        ] ifTrue:[
                            entry
                        ].
                    ].
                ].
    ^ newList
! !

!AssistantApplication methodsFor:'help'!

helpTextForKey:aKey
    <resource: #help>

    |text bindings nextSpec prevSpec|

    text := super helpTextForKey:aKey.
    text isNil ifTrue:[^ nil].
    
    nextSpec := self nextEnabledPageSpec.
    prevSpec := self previousEnabledPageSpec.

    bindings := Dictionary new.
    bindings 
        at:#'previousPageInfo' 
        put:(prevSpec notNil ifTrue:[ '"',prevSpec pageTitle,'"' ] ifFalse:['']).
    bindings 
        at:#'nextPageInfo'
        put:(nextSpec notNil ifTrue:[ '"',nextSpec pageTitle,'"' ] ifFalse:['']).

    ^ self resources string:text withArguments:bindings.

    "Modified: / 23-08-2018 / 21:02:45 / Claus Gittinger"
! !

!AssistantApplication methodsFor:'initialization & release'!

postBuildWith:aBuilder
    |maxCanvasExtent|

    super postBuildWith:aBuilder.
    self updateCanvas.

    maxCanvasExtent := (self assistantSpec 
                            collect:[:eachPageSpec | 
                                |windowSpecSelector specArray windowSpec|

                                windowSpecSelector := eachPageSpec windowSpecSelector.
                                specArray := self perform:windowSpecSelector ifNotUnderstood:[self class perform:windowSpecSelector].
                                windowSpec := specArray decodeAsLiteralArray.
                                windowSpec window bounds extent.
                            ]
                       ) max.

    self window extent:(maxCanvasExtent + (200 @ 40)).
    self builder window isModal ifFalse:[
        self cancelButtonVisible value:false
    ].

    "Modified: / 06-09-2012 / 16:42:42 / cg"
! !

!AssistantApplication methodsFor:'look'!

backButtonLabel
    ^ LabelAndIcon 
        label:(resources string:'Back')
        icon:(self backButtonEnabled value
                ifTrue:[ToolbarIconLibrary leftArrow24x24Icon]
                ifFalse:[ToolbarIconLibrary leftArrow24x24disabledIcon])
!

nextButtonLabel
    ^ LabelAndTwoIcons new 
        string:(resources string:'Next');
        image2:(self forwardButtonEnabled value
                ifTrue:[ToolbarIconLibrary rightArrow24x24Icon]
                ifFalse:[ToolbarIconLibrary rightArrow24x24disabledIcon]);
        yourself
!

pageLabels
    ^ self assistantSpec 
        collect:[:specEntry | resources string:specEntry pageTitle].
! !

!AssistantApplication methodsFor:'private'!

canFinish
    |pageIndex pageSpec|

    pageIndex := self currentPageIndexHolder value.
    pageSpec := self assistantSpec at:pageIndex.
    ^ pageSpec canLeaveQuerySelector isNil
    or:[ self perform:pageSpec canLeaveQuerySelector ]
!

currentPageIndex
    ^ self currentPageIndexHolder value
!

currentPageSpec
    ^ self assistantSpec at:(self currentPageIndex).
!

indexOfNextEnabledPageSpec
    |delta currentPageIndex|

    currentPageIndex := self currentPageIndex.
    delta := 1.
    [ 
        (currentPageIndex + delta) <= (self numberOfPages)
        and:[ (self isPageEnabledAtIndex:(currentPageIndex + delta)) not ]
    ] whileTrue:[
        delta := delta + 1.
    ].
    (currentPageIndex + delta) <= (self numberOfPages) ifTrue:[
        ^ (currentPageIndex + delta).
    ].
    ^ nil
!

indexOfPreviousEnabledPageSpec
    |delta currentPageIndex|

    currentPageIndex := self currentPageIndex.
    delta := 1.
    [ 
        (currentPageIndex - delta) > 0
        and:[ (self isPageEnabledAtIndex:(currentPageIndex - delta)) not ]
    ] whileTrue:[
        delta := delta + 1.
    ].
    (currentPageIndex - delta) > 0 ifTrue:[
        ^ (currentPageIndex - delta).
    ].
    ^ nil
!

isPageEnabledAtIndex:index
    |isEnabledSelector|

    isEnabledSelector := (self assistantSpec at:index) isEnabledQuerySelector.
    ^ isEnabledSelector isNil or:[ (self perform:isEnabledSelector) ]
!

nextEnabledPageSpec
    |index|

    index := self indexOfNextEnabledPageSpec.
    index isNil ifTrue:[^ nil].
    ^ self assistantSpec at:index.
!

nextPageSpec
    ^ self assistantSpec at:(self currentPageIndex + 1).
!

numberOfPages
    ^ self assistantSpec size
!

previousEnabledPageSpec
    |index|

    index := self indexOfPreviousEnabledPageSpec.
    index isNil ifTrue:[^ nil].
    ^ self assistantSpec at:index.
!

previousPageSpec
    ^ self assistantSpec at:(self currentPageIndex - 1).
! !

!AssistantApplication methodsFor:'update'!

updateButtonEnableState
    self backButtonEnabled value:(self canGoBackward).
    self forwardButtonEnabled value:(self canGoForward).
    self backButtonLabelHolder value:(self backButtonLabel).
    self nextButtonLabelHolder value:(self nextButtonLabel).
!

updateCanvas
    "update some valueHolders and especially the current canvas,
     after a step in either direction"

    |pageIndex pageSpec sel uiSpec|

    pageIndex := self currentPageIndex.
    pageSpec := self currentPageSpec.
    sel := pageSpec windowSpecSelector.
    uiSpec := self perform:sel ifNotUnderstood:[ self class perform:sel ].

    self pageLabelsInList contents:(self pageLabelsInListWithBullet).
    self currentPageSpecHolder value:uiSpec.

    self updateWindowLabelFor:pageSpec.

    self finishButtonVisible value:(pageIndex == self numberOfPages).
    self backButtonEnabled value:(pageIndex > 1).
    self forwardButtonEnabled value:(pageIndex < self numberOfPages).
    self finishButtonEnabled value:(pageIndex == self numberOfPages and:[ self canFinish ]).

    self backButtonLabelHolder value:(self backButtonLabel).
    self nextButtonLabelHolder value:(self nextButtonLabel).

    self pageInfoHolder value:(resources string:pageSpec infoText).

    "Modified: / 12-11-2010 / 12:32:09 / cg"
!

updateWindowLabelFor:aPageSpec
    self window label:(self class windowLabelTemplate bindWith:aPageSpec pageTitle).
! !

!AssistantApplication class methodsFor:'documentation'!

version
    ^ '$Header$'
!

version_CVS
    ^ '$Header$'
! !