Tools__ProjectBuilderAssistantApplication.st
author Claus Gittinger <cg@exept.de>
Tue, 20 Oct 2009 22:39:09 +0200
changeset 2640 3e62b7459698
parent 2636 c338c198484d
child 2645 8c2aab033e84
permissions -rw-r--r--
automatically generated by browser

"{ Package: 'stx:libtool2' }"

"{ NameSpace: Tools }"

AssistantApplication subclass:#ProjectBuilderAssistantApplication
	instanceVariableNames:'packageToBuildHolder projectType selectedProjectIndexHolder
		selectedProjectDefinition listOfMatchingProjects
		selectedProjectsComment newProjectsName hideSTXProjects
		startMakeButtonEnabled stopMakeButtonVisible makeOutputHolder
		newApplicationsName selectedApplicationIndexHolder
		selectedApplication listOfApplicationsInProject
		selectedApplicationsComment buildDirectoryHolder makeProcess
		listOfClassesInProject'
	classVariableNames:''
	poolDictionaries:''
	category:'System-Support-Projects'
!


!ProjectBuilderAssistantApplication class methodsFor:'interface specs'!

_1_projectTypeSelectionSpec
    "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:ProjectBuilderAssistantApplication andSelector:#_1_projectTypeSelectionSpec
     ProjectBuilderAssistantApplication new openInterface:#_1_projectTypeSelectionSpec
    "

    <resource: #canvas>

    ^ 
     #(FullSpec
        name: #'_1_projectTypeSelectionSpec'
        window: 
       (WindowSpec
          label: 'Project Selection'
          name: 'Project Selection'
          min: (Point 0 0)
          bounds: (Rectangle 0 0 626 394)
        )
        component: 
       (SpecCollection
          collection: (
           (FramedBoxSpec
              label: 'Project Type Filter'
              name: 'FramedBox1'
              layout: (LayoutFrame 0 0.0 0 0 4 1.0 105 0)
              labelPosition: topLeft
              translateLabel: true
              component: 
             (SpecCollection
                collection: (
                 (VerticalPanelViewSpec
                    name: 'VerticalPanel1'
                    layout: (LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0)
                    horizontalLayout: leftSpace
                    verticalLayout: topSpace
                    horizontalSpace: 3
                    verticalSpace: 3
                    component: 
                   (SpecCollection
                      collection: (
                       (ViewSpec
                          name: 'Box1'
                          extent: (Point 10 10)
                        )
                       (RadioButtonSpec
                          label: 'GUI Application'
                          name: 'RadioButton1'
                          translateLabel: true
                          model: projectType
                          isTriggerOnDown: true
                          onCallBackSelector: projectTypeChanged
                          select: guiApplicationType
                          extent: (Point 136 22)
                        )
                       (RadioButtonSpec
                          label: 'Non-GUI Application'
                          name: 'RadioButton2'
                          translateLabel: true
                          model: projectType
                          isTriggerOnDown: true
                          onCallBackSelector: projectTypeChanged
                          select: nonGuiApplicationType
                          extent: (Point 136 22)
                        )
                       (RadioButtonSpec
                          label: 'Class Library'
                          name: 'RadioButton3'
                          translateLabel: true
                          model: projectType
                          isTriggerOnDown: true
                          onCallBackSelector: projectTypeChanged
                          select: libraryType
                          extent: (Point 136 22)
                        )
                       )
                     
                    )
                  )
                 )
               
              )
            )
           (FramedBoxSpec
              label: 'Existing Projects'
              name: 'FramedBox2'
              layout: (LayoutFrame 0 0.0 105 0 4 1.0 397 0)
              labelPosition: topLeft
              translateLabel: true
              component: 
             (SpecCollection
                collection: (
                 (VariableHorizontalPanelSpec
                    name: 'VariableHorizontalPanel1'
                    layout: (LayoutFrame 0 0 4 0 0 1 -26 1)
                    component: 
                   (SpecCollection
                      collection: (
                       (SequenceViewSpec
                          name: 'List1'
                          model: selectedProjectIndexHolder
                          hasHorizontalScrollBar: true
                          hasVerticalScrollBar: true
                          useIndex: true
                          sequenceList: listOfMatchingProjects
                        )
                       (TextEditorSpec
                          name: 'TextEditor1'
                          model: selectedProjectsComment
                          hasHorizontalScrollBar: true
                          hasVerticalScrollBar: true
                          isReadOnly: true
                          hasKeyboardFocusInitially: false
                        )
                       )
                     
                    )
                    handles: (Any 0.34560327198364 1.0)
                  )
                 (CheckBoxSpec
                    label: 'Hide ST/X Base Packages'
                    name: 'CheckBox1'
                    layout: (LayoutFrame -1 0 -18 1 275 0 4 1)
                    model: hideSTXProjects
                    translateLabel: true
                  )
                 )
               
              )
            )
           )
         
        )
      )
!

_2_projectSelectionSpec
    "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:ProjectBuilderAssistantApplication andSelector:#_2_projectSelectionSpec
     ProjectBuilderAssistantApplication new openInterface:#_2_projectSelectionSpec
    "

    <resource: #canvas>

    ^ 
     #(FullSpec
        name: #'_2_projectSelectionSpec'
        window: 
       (WindowSpec
          label: 'Project Selection'
          name: 'Project Selection'
          min: (Point 0 0)
          bounds: (Rectangle 0 0 521 453)
        )
        component: 
       (SpecCollection
          collection: (
           (FramedBoxSpec
              label: 'New Project'
              name: 'FramedBox3'
              layout: (LayoutFrame 0 0.0 5 0 4 1.0 72 0)
              labelPosition: topLeft
              translateLabel: true
              component: 
             (SpecCollection
                collection: (
                 (InputFieldSpec
                    name: 'EntryField1'
                    layout: (LayoutFrame 1 0 6 0 210 0 28 0)
                    model: newProjectsName
                    acceptOnReturn: true
                    acceptOnTab: true
                    acceptOnPointerLeave: true
                    emptyFieldReplacementText: 'module:directory'
                  )
                 (ActionButtonSpec
                    label: 'Create'
                    name: 'Button1'
                    layout: (LayoutFrame 216 0 6 0 341 0 28 0)
                    translateLabel: true
                    model: createNewProject
                  )
                 )
               
              )
            )
           (FramedBoxSpec
              label: 'Existing Projects'
              name: 'FramedBox4'
              layout: (LayoutFrame 0 0.0 70 0 4 1.0 362 0)
              labelPosition: topLeft
              translateLabel: true
              component: 
             (SpecCollection
                collection: (
                 (VariableHorizontalPanelSpec
                    name: 'VariableHorizontalPanel2'
                    layout: (LayoutFrame 0 0 4 0 0 1 -26 1)
                    component: 
                   (SpecCollection
                      collection: (
                       (SequenceViewSpec
                          name: 'List2'
                          model: selectedProjectIndexHolder
                          hasHorizontalScrollBar: true
                          hasVerticalScrollBar: true
                          useIndex: true
                          sequenceList: listOfMatchingProjects
                        )
                       (TextEditorSpec
                          name: 'TextEditor2'
                          model: selectedProjectsComment
                          hasHorizontalScrollBar: true
                          hasVerticalScrollBar: true
                          isReadOnly: true
                          hasKeyboardFocusInitially: false
                          viewClassName: 'TextView'
                        )
                       )
                     
                    )
                    handles: (Any 0.34560327198364 1.0)
                  )
                 (CheckBoxSpec
                    label: 'Hide ST/X Base Packages'
                    name: 'CheckBox1'
                    layout: (LayoutFrame -1 0 -17 1 275 0 5 1)
                    model: hideSTXProjects
                    translateLabel: true
                  )
                 )
               
              )
            )
           (ActionButtonSpec
              label: 'Browse Selected Project'
              name: 'Button3'
              layout: (LayoutFrame 9 0 363 0 189 0 385 0)
              translateLabel: true
              model: doBrowseProject
            )
           )
         
        )
      )
!

_3_applicationSelectionSpec
    "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:ProjectBuilderAssistantApplication andSelector:#_3_applicationSelectionSpec
     ProjectBuilderAssistantApplication new openInterface:#_3_applicationSelectionSpec
    "

    <resource: #canvas>

    ^ 
     #(FullSpec
        name: #'_3_applicationSelectionSpec'
        window: 
       (WindowSpec
          label: 'Application Selection'
          name: 'Application Selection'
          min: (Point 0 0)
          bounds: (Rectangle 0 0 521 408)
        )
        component: 
       (SpecCollection
          collection: (
           (FramedBoxSpec
              label: 'New Application'
              name: 'FramedBox3'
              layout: (LayoutFrame 0 0.0 5 0 4 1.0 105 0)
              labelPosition: topLeft
              translateLabel: true
              component: 
             (SpecCollection
                collection: (
                 (InputFieldSpec
                    name: 'EntryField1'
                    layout: (LayoutFrame 1 0 6 0 210 0 28 0)
                    model: newApplicationsName
                    acceptOnReturn: true
                    acceptOnTab: true
                    acceptOnPointerLeave: true
                    emptyFieldReplacementText: 'MyApplication'
                  )
                 (ActionButtonSpec
                    label: 'Create'
                    name: 'Button1'
                    layout: (LayoutFrame 216 0 6 0 341 0 28 0)
                    translateLabel: true
                    model: createNewApplication
                  )
                 )
               
              )
            )
           (FramedBoxSpec
              label: 'Existing Applications'
              name: 'FramedBox4'
              layout: (LayoutFrame 0 0.0 105 0 4 1.0 362 0)
              labelPosition: topLeft
              translateLabel: true
              component: 
             (SpecCollection
                collection: (
                 (VariableHorizontalPanelSpec
                    name: 'VariableHorizontalPanel2'
                    layout: (LayoutFrame 0 0 4 0 0 1 0 1)
                    component: 
                   (SpecCollection
                      collection: (
                       (SequenceViewSpec
                          name: 'List2'
                          model: selectedApplicationIndexHolder
                          hasHorizontalScrollBar: true
                          hasVerticalScrollBar: true
                          useIndex: true
                          sequenceList: listOfApplicationsInProject
                        )
                       (TextEditorSpec
                          name: 'TextEditor2'
                          model: selectedApplicationsComment
                          hasHorizontalScrollBar: true
                          hasVerticalScrollBar: true
                          isReadOnly: true
                          hasKeyboardFocusInitially: false
                          viewClassName: 'TextView'
                        )
                       )
                     
                    )
                    handles: (Any 0.34560327198364 1.0)
                  )
                 )
               
              )
            )
           (ActionButtonSpec
              label: 'Browse Selected Application'
              name: 'Button3'
              layout: (LayoutFrame 9 0 363 0 189 0 385 0)
              translateLabel: true
              model: doBrowseApplication
            )
           )
         
        )
      )
!

_4_specifyIncludedClasses
    "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:ProjectBuilderAssistantApplication andSelector:#_4_specifyIncludedClasses
     ProjectBuilderAssistantApplication new openInterface:#_4_specifyIncludedClasses
    "

    <resource: #canvas>

    ^ 
     #(FullSpec
        name: #'_4_specifyIncludedClasses'
        window: 
       (WindowSpec
          label: 'Project Selection'
          name: 'Project Selection'
          min: (Point 0 0)
          bounds: (Rectangle 0 0 521 400)
        )
        component: 
       (SpecCollection
          collection: (
           (FramedBoxSpec
              label: 'Project Contents'
              name: 'FramedBox3'
              layout: (LayoutFrame 0 0.0 5 0 4 1.0 362 0)
              labelPosition: topLeft
              translateLabel: true
              component: 
             (SpecCollection
                collection: (
                 (SequenceViewSpec
                    name: 'List1'
                    layout: (LayoutFrame 0 0 0 0 0 1 0 1)
                    initiallyDisabled: true
                    hasHorizontalScrollBar: true
                    hasVerticalScrollBar: true
                    useIndex: false
                    sequenceList: listOfClassesInProject
                  )
                 )
               
              )
            )
           (ActionButtonSpec
              label: 'Browse Project Definition'
              name: 'Button3'
              layout: (LayoutFrame 9 0 363 0 189 0 385 0)
              translateLabel: true
              model: doBrowseProject
            )
           (ActionButtonSpec
              label: 'Update Contents (Scan)'
              name: 'Button4'
              layout: (LayoutFrame 293 0 363 0 473 0 385 0)
              translateLabel: true
              model: doUpdateProjectContents
            )
           )
         
        )
      )
!

_5_specifyBuildDirectorySpec
    "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:ProjectBuilderAssistantApplication andSelector:#_5_specifyBuildDirectorySpec
     ProjectBuilderAssistantApplication new openInterface:#_5_specifyBuildDirectorySpec
    "

    <resource: #canvas>

    ^ 
     #(FullSpec
        name: #'_5_specifyBuildDirectorySpec'
        window: 
       (WindowSpec
          label: 'Project Selection'
          name: 'Project Selection'
          min: (Point 0 0)
          bounds: (Rectangle 0 0 521 104)
        )
        component: 
       (SpecCollection
          collection: (
           (FramedBoxSpec
              label: 'Build Directory'
              name: 'FramedBox3'
              layout: (LayoutFrame 0 0.0 5 0 4 1.0 79 0)
              labelPosition: topLeft
              translateLabel: true
              component: 
             (SpecCollection
                collection: (
                 (FilenameInputFieldSpec
                    name: 'FilenameEntryField1'
                    layout: (LayoutFrame 0 0.0 10 0 0 1.0 32 0)
                    model: buildDirectoryHolder
                    acceptOnPointerLeave: true
                    viewClassName: FilenameWidgetWithHistory
                  )
                 )
               
              )
            )
           )
         
        )
      )
!

_6_buildSpec
    "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:ProjectBuilderAssistantApplication andSelector:#_6_buildSpec
     ProjectBuilderAssistantApplication new openInterface:#_6_buildSpec
    "

    <resource: #canvas>

    ^ 
     #(FullSpec
        name: #'_6_buildSpec'
        window: 
       (WindowSpec
          label: 'Project Selection'
          name: 'Project Selection'
          min: (Point 0 0)
          bounds: (Rectangle 0 0 521 472)
        )
        component: 
       (SpecCollection
          collection: (
           (FramedBoxSpec
              label: 'Make Output'
              name: 'FramedBox3'
              layout: (LayoutFrame 0 0.0 5 0 4 1.0 -46 1)
              labelPosition: topLeft
              translateLabel: true
              component: 
             (SpecCollection
                collection: (
                 (TextEditorSpec
                    name: 'TextEditor3'
                    layout: (LayoutFrame 0 0 0 0 0 1 0 1)
                    model: makeOutputHolder
                    hasHorizontalScrollBar: true
                    hasVerticalScrollBar: true
                    hasKeyboardFocusInitially: false
                    viewClassName: 'TextCollector'
                  )
                 )
               
              )
            )
           (ActionButtonSpec
              label: 'Start Make'
              name: 'Button3'
              layout: (LayoutFrame 9 0 -42 1 116 0 -20 1)
              translateLabel: true
              model: doStartMake
              enableChannel: startMakeButtonEnabled
            )
           (ActionButtonSpec
              label: 'Stop Make'
              name: 'Button4'
              layout: (LayoutFrame 131 0 -42 1 238 0 -20 1)
              visibilityChannel: stopMakeButtonVisible
              translateLabel: true
              model: doStopMake
            )
           )
         
        )
      )
!

_7_deploySpec
    "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:ProjectBuilderAssistantApplication andSelector:#_7_deploySpec
     ProjectBuilderAssistantApplication new openInterface:#_7_deploySpec
    "

    <resource: #canvas>

    ^ 
     #(FullSpec
        name: #'_7_deploySpec'
        window: 
       (WindowSpec
          label: 'Project Selection'
          name: 'Project Selection'
          min: (Point 0 0)
          bounds: (Rectangle 0 0 521 472)
        )
        component: 
       (SpecCollection
          collection: (
           (FramedBoxSpec
              label: 'New Project'
              name: 'FramedBox3'
              layout: (LayoutFrame 0 0.0 5 0 4 1.0 105 0)
              labelPosition: topLeft
              translateLabel: true
              component: 
             (SpecCollection
                collection: (
                 (InputFieldSpec
                    name: 'EntryField1'
                    layout: (LayoutFrame 1 0 6 0 210 0 28 0)
                    model: newProjectsName
                    acceptOnReturn: true
                    acceptOnTab: true
                    acceptOnPointerLeave: true
                    emptyFieldReplacementText: 'module:directory'
                  )
                 (ActionButtonSpec
                    label: 'Create'
                    name: 'Button1'
                    layout: (LayoutFrame 216 0 6 0 341 0 28 0)
                    translateLabel: true
                    model: createNewProject
                  )
                 )
               
              )
            )
           (FramedBoxSpec
              label: 'Existing Projects'
              name: 'FramedBox4'
              layout: (LayoutFrame 0 0.0 105 0 4 1.0 397 0)
              labelPosition: topLeft
              translateLabel: true
              component: 
             (SpecCollection
                collection: (
                 (VariableHorizontalPanelSpec
                    name: 'VariableHorizontalPanel2'
                    layout: (LayoutFrame 0 0 4 0 0 1 -26 1)
                    component: 
                   (SpecCollection
                      collection: (
                       (SequenceViewSpec
                          name: 'List2'
                          model: selectedProjectIndexHolder
                          hasHorizontalScrollBar: true
                          hasVerticalScrollBar: true
                          useIndex: true
                          sequenceList: listOfMatchingProjects
                        )
                       (TextEditorSpec
                          name: 'TextEditor2'
                          model: selectedProjectsComment
                          hasHorizontalScrollBar: true
                          hasVerticalScrollBar: true
                          isReadOnly: true
                          hasKeyboardFocusInitially: false
                        )
                       )
                     
                    )
                    handles: (Any 0.34560327198364 1.0)
                  )
                 (CheckBoxSpec
                    label: 'Hide ST/X Base Packages'
                    name: 'CheckBox1'
                    layout: (LayoutFrame -1 0 241 0 275 0 263 0)
                    model: hideSTXProjects
                    translateLabel: true
                  )
                 )
               
              )
            )
           (ActionButtonSpec
              label: 'Browse Selected Project'
              name: 'Button3'
              layout: (LayoutFrame 9 0 410 0 189 0 432 0)
              translateLabel: true
              model: doBrowseProject
            )
           )
         
        )
      )
! !

!ProjectBuilderAssistantApplication methodsFor:'actions'!

buildDirectoryChanged
    self updateButtonEnableState.
!

createNewApplication
    <resource: #uiCallback>

    |newAppName newAppClass|

    newAppName := self newApplicationsName value.
    newAppName isEmptyOrNil ifTrue:[
        Dialog warn:'Please enter the name of the Application-Class first.'.
        ^ self
    ].

    Class packageQuerySignal answer:(selectedProjectDefinition package)
    do:[
        newAppClass := ApplicationModel
                        subclass:newAppName asSymbol
                        instanceVariableNames:''
                        classVariableNames:''
                        poolDictionaries:''
                        category:'Applications'.
        CodeGeneratorTool createApplicationCodeFor:newAppClass.
    ].
    self updateListOfApplicationsInProject
!

createNewProject
    <resource: #uiCallback>

    |newProjectID projectDefinitionType projectDefinitionClass projectClasses|

    newProjectID := self newProjectsName value.
    newProjectID isEmptyOrNil ifTrue:[
        Dialog warn:'Please enter a packageID first.'.
        ^ self
    ].

    projectDefinitionType := ProjectDefinition perform:(self projectType value).


    projectDefinitionClass := ProjectDefinition
                                definitionClassForPackage:newProjectID
                                projectType: projectDefinitionType
                                createIfAbsent:true.

    projectDefinitionClass compileDescriptionMethods.
    self updateListOfMatchingProjects.

    self selectedProjectIndexHolder value:( self listOfMatchingProjects value indexOf:projectDefinitionClass).

    projectClasses := projectDefinitionClass allClassNames 
                            collect:[:nm |Smalltalk classNamed:nm].

    projectDefinitionClass isGUIApplication ifTrue:[
        "/ see if it has an AppModel class
        (projectClasses contains:[:cls | cls isVisualStartable]) ifFalse:[
            (Dialog confirm:'Create an Application Class ?') ifTrue:[
self halt.
            ].
        ].
    ].

"/    projectDefinitionClass isLibrary ifFalse:[
"/        "/ see if it has a Startup class
"/        (projectClasses contains:[:cls | cls isStartable]) ifFalse:[
"/        ].
"/    ].
!

doAddClassToProject
    <resource: #uiCallback>

    Transcript showCR:self class name, ': action for doAddClassToProject ...'.
    self halt.
!

doBrowseApplication
    <resource: #uiCallback>

    |appClass|

    appClass := self listOfApplicationsInProject value at:(self selectedApplicationIndexHolder value).
    UserPreferences systemBrowserClass openInClass:appClass.
!

doBrowseProject
    <resource: #uiCallback>

    UserPreferences systemBrowserClass openOnPackage:selectedProjectDefinition package.
!

doStartMake
    <resource: #uiCallback>

    self stopMakeButtonVisible value:true.
    self startMakeButtonEnabled value:false.

    makeProcess := 
            [
                [
                    self runBuildProcess
                ] ensure:[
                    self stopMakeButtonVisible value:false.
                    self startMakeButtonEnabled value:true.
                ].
            ] newProcess.

    makeProcess priority:4.
    makeProcess priorityRange:(4 to:8).
    makeProcess resume.
!

doUpdateProjectContents
    self updatePackageContentsMethods
!

projectTypeChanged
    <resource: #uiCallback>

    self updateListOfMatchingProjects
!

runBuildProcess
    <resource: #uiCallback>

    Delay waitForSeconds:10
!

selectedApplicationChanged
    self selectedApplicationIndexHolder value isNil ifTrue:[
        selectedApplication := nil.
    ] ifFalse:[
        selectedApplication := self listOfApplicationsInProject value at:(self selectedApplicationIndexHolder value).
    ].
    self updateApplicationComment.
    self updateButtonEnableState.
!

selectedProjectChanged
    self selectedProjectIndexHolder value isNil ifTrue:[
        selectedProjectDefinition := nil.
    ] ifFalse:[
        selectedProjectDefinition := self listOfMatchingProjects value at:(self selectedProjectIndexHolder value).
    ].
    self updateComment.
    self updateListOfApplicationsInProject.
    self updateButtonEnableState.
!

updatePackageContentsMethods
    <resource: #uiCallback>

    Class packageQuerySignal answer:(selectedProjectDefinition package)
    do:[
        selectedProjectDefinition 
            forEachContentsMethodsCodeToCompileDo:[:code :category |
                    CodeGeneratorTool
                        compile:code
                        forClass:selectedProjectDefinition theMetaclass
                        inCategory:category.
                ]
            ignoreOldDefinition:true
    ].
! !

!ProjectBuilderAssistantApplication methodsFor:'aspects'!

buildDirectoryHolder
    <resource: #uiAspect>

    |buildDirectory|

    buildDirectoryHolder isNil ifTrue:[
        buildDirectoryHolder := nil asValue.
        buildDirectoryHolder onChangeSend:#buildDirectoryChanged to:self.
    ].
    buildDirectoryHolder value isEmptyOrNil ifTrue:[
        buildDirectory := Tools::ProjectBuilder previousBuildDirectory.
        buildDirectory isNil ifTrue:[
            buildDirectory := UserPreferences current buildDirectory.
            buildDirectory isNil ifTrue:[
                buildDirectory := Filename tempDirectory construct:'stx_build'.
            ].
        ].
        buildDirectoryHolder value: buildDirectory.
    ].
    ^ buildDirectoryHolder.
!

hasBuildDirectorySpecified
    ^ self buildDirectoryHolder value notEmptyOrNil
!

hasProjectSelected
    ^ self selectedProjectIndexHolder value notNil
!

hideSTXProjects
    <resource: #uiAspect>

    hideSTXProjects isNil ifTrue:[
        hideSTXProjects := true asValue.
        hideSTXProjects onChangeSend:#updateListOfMatchingProjects to:self.
    ].
    ^ hideSTXProjects.
!

listOfApplicationsInProject
    <resource: #uiAspect>

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

listOfClassesInProject
    <resource: #uiAspect>

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

listOfMatchingProjects
    <resource: #uiAspect>

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

makeOutputHolder
    <resource: #uiAspect>

    "automatically generated by UIPainter ..."

    "*** the code below creates a default model when invoked."
    "*** (which may not be the one you wanted)"
    "*** Please change as required and accept it in the browser."
    "*** (and replace this comment by something more useful ;-)"

    makeOutputHolder isNil ifTrue:[
        makeOutputHolder := '' asValue.
"/ if your app needs to be notified of changes, uncomment one of the lines below:
"/       makeOutputHolder addDependent:self.
"/       makeOutputHolder onChangeSend:#makeOutputHolderChanged to:self.
    ].
    ^ makeOutputHolder.
!

newApplicationsName
    <resource: #uiAspect>

    "automatically generated by UIPainter ..."

    "*** the code below creates a default model when invoked."
    "*** (which may not be the one you wanted)"
    "*** Please change as required and accept it in the browser."
    "*** (and replace this comment by something more useful ;-)"

    newApplicationsName isNil ifTrue:[
        newApplicationsName := ValueHolder new.
"/ if your app needs to be notified of changes, uncomment one of the lines below:
"/       newApplicationsName addDependent:self.
"/       newApplicationsName onChangeSend:#newApplicationsNameChanged to:self.
    ].
    ^ newApplicationsName.
!

newProjectsName
    <resource: #uiAspect>

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

projectType
    <resource: #uiAspect>

    projectType isNil ifTrue:[
        projectType := RadioButtonGroup new.
        projectType value:#guiApplicationType.
    ].
    ^ projectType.
!

projectTypeIsNotLibrary
    ^ self projectType value ~~ #libraryType
!

selectedApplication
    <resource: #uiAspect>

    selectedApplication isNil ifTrue:[
        selectedApplication := ValueHolder new.
        selectedApplication onChangeSend:#selectedApplicationChanged to:self.
    ].
    ^ selectedApplication.
!

selectedApplicationIndexHolder
    <resource: #uiAspect>

    selectedApplicationIndexHolder isNil ifTrue:[
        selectedApplicationIndexHolder := ValueHolder new.
        selectedApplicationIndexHolder onChangeSend:#selectedApplicationChanged to:self.
    ].
    ^ selectedApplicationIndexHolder.
!

selectedApplicationsComment
    <resource: #uiAspect>

    "automatically generated by UIPainter ..."

    "*** the code below creates a default model when invoked."
    "*** (which may not be the one you wanted)"
    "*** Please change as required and accept it in the browser."
    "*** (and replace this comment by something more useful ;-)"

    selectedApplicationsComment isNil ifTrue:[
        selectedApplicationsComment := '' asValue.
"/ if your app needs to be notified of changes, uncomment one of the lines below:
"/       selectedApplicationsComment addDependent:self.
"/       selectedApplicationsComment onChangeSend:#selectedApplicationsCommentChanged to:self.
    ].
    ^ selectedApplicationsComment.
!

selectedProjectDefinition
    <resource: #uiAspect>

    ^ selectedProjectDefinition.
!

selectedProjectIndexHolder
    <resource: #uiAspect>

    selectedProjectIndexHolder isNil ifTrue:[
        selectedProjectIndexHolder := ValueHolder new.
        selectedProjectIndexHolder onChangeSend:#selectedProjectChanged to:self.
    ].
    ^ selectedProjectIndexHolder.
!

selectedProjectsComment
    <resource: #uiAspect>

    selectedProjectsComment isNil ifTrue:[
        selectedProjectsComment := '' asValue.
    ].
    ^ selectedProjectsComment.
!

startMakeButtonEnabled
    <resource: #uiAspect>

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

stopMakeButtonVisible
    <resource: #uiAspect>

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

!ProjectBuilderAssistantApplication methodsFor:'initialization & release'!

postBuildWith:aBuilder
    super postBuildWith:aBuilder.
    self updateListOfMatchingProjects.

    Smalltalk addDependent:self.
!

release
    Smalltalk removeDependent:self.
    super release
! !

!ProjectBuilderAssistantApplication methodsFor:'private'!

commentFromClass:aClass
    |docMethod comment indents minIndent maxLineLength|

    docMethod := aClass class compiledMethodAt:#documentation.
    docMethod notNil ifTrue:[
        comment := docMethod comment.
        comment := comment asStringCollection 
                        collect:[:line | line withoutTrailingSeparators].
        [comment notEmpty and:[comment first isBlank]] whileTrue:[ comment removeFirst ].
        maxLineLength := (comment collect:[:line | line size]) max.
        indents := comment collect:[:line | 
                                        line isEmptyOrNil
                                            ifTrue:[maxLineLength]
                                            ifFalse:[ line findFirst:[:ch | ch isSeparator not]]].
        (minIndent := indents min) > 1 ifTrue:[
            comment := comment collect:[:line | line copyFrom:minIndent].
        ].
        comment := comment asString.
    ].
    ^ comment
! !

!ProjectBuilderAssistantApplication methodsFor:'specs'!

assistantSpec
    ^ #(Array
        ( AssistantPageSpec
            pageTitle: 'Project Type Selection'
            windowSpecSelector: _1_projectTypeSelectionSpec
        )

        (AssistantPageSpec
            pageTitle: 'Project Selection'
            windowSpecSelector: _2_projectSelectionSpec
        )

        (AssistantPageSpec
            pageTitle: 'Application Selection'
            windowSpecSelector: _3_applicationSelectionSpec
            isEnabledQuerySelector: #projectTypeIsNotLibrary
            canEnterQuerySelector: #hasProjectSelected
        )

        (AssistantPageSpec
            pageTitle: 'Specify Contents'
            windowSpecSelector: _4_specifyIncludedClasses
            enterCallbackSelector: updateListOfClassesInProject
        )

        (AssistantPageSpec
            pageTitle: 'Specify Build Directory'
            windowSpecSelector: _5_specifyBuildDirectorySpec
        )

        (AssistantPageSpec
            pageTitle: 'Build'
            windowSpecSelector: _6_buildSpec
            canEnterQuerySelector: #hasBuildDirectorySpecified
        )

        (AssistantPageSpec
            pageTitle: 'Deploy'
            windowSpecSelector: _7_deploySpec
        )
    ) decodeAsLiteralArray.
! !

!ProjectBuilderAssistantApplication methodsFor:'update'!

update:something with:anArgument from:changedObject
    changedObject == Smalltalk ifTrue:[
        (something == #newClass
        or:[something == #classRemove
        or:[something == #projectOrganization]]) ifTrue:[
            self updateListOfMatchingProjects.
            ^ self.
        ].
        ^ self.
    ].
    super update:something with:anArgument from:changedObject
!

updateApplicationComment
    |comment|

    self selectedApplicationIndexHolder value notNil ifTrue:[
        comment := self commentFromClass:selectedApplication.
        comment isNil ifTrue:[
            comment := 'Application has no comment' allItalic colorizeAllWith:Color lightGrey.
        ].
    ] ifFalse:[
        comment := 'Please select an Application' allItalic colorizeAllWith:Color lightGrey.
    ].
    self selectedApplicationsComment value:comment.
!

updateComment
    |comment|

    self selectedProjectIndexHolder value notNil ifTrue:[
        comment := self commentFromClass:selectedProjectDefinition.
        comment isNil ifTrue:[
            comment := 'Project has no comment' allItalic colorizeAllWith:Color lightGrey.
        ].
    ] ifFalse:[
        comment := 'Please select a Project' allItalic colorizeAllWith:Color lightGrey.
    ].
    self selectedProjectsComment value:comment.
!

updateListOfApplicationsInProject
    |applicationClasses package|

    self selectedApplicationIndexHolder value:nil.
    selectedProjectDefinition isNil ifTrue:[
        applicationClasses := #()
    ] ifFalse:[
        package := selectedProjectDefinition package.

        applicationClasses := Smalltalk allClasses
                                    select:[:cls |
                                        (cls package = package
                                        and:[ cls isSubclassOf:ApplicationModel ])
                                    ].
        applicationClasses := applicationClasses asOrderedCollection.
        applicationClasses sort:[:a :b | a name < b name].
    ].
    self listOfApplicationsInProject value:applicationClasses
!

updateListOfClassesInProject
    self listOfClassesInProject value:(selectedProjectDefinition classNames).
!

updateListOfMatchingProjects
    |matching projectType idx|

    projectType := self projectType value.
    matching := ProjectDefinition allSubclasses
                    select:[:defClass |
                        |match|

                        match := false.
                        defClass isAbstract ifFalse:[
                            (self hideSTXProjects value not
                            or:[ defClass package asPackageId module ~= 'stx' ])
                            ifTrue:[
                                projectType == #libraryType ifTrue:[
                                    match := defClass isLibraryDefinition
                                ] ifFalse:[
                                    projectType == #guiApplicationType ifTrue:[
                                        match := defClass isGUIApplication
                                    ] ifFalse:[
                                        projectType == #nonGuiApplicationType ifTrue:[
                                            match := defClass isConsoleApplication
                                        ] ifFalse:[
                                            self error.
                                        ].
                                    ].
                                ].
                            ].
                        ].
                   ].
    matching sort:[:a :b | a name < b name].
    self listOfMatchingProjects value:matching.

    idx := matching indexOf:selectedProjectDefinition.
    idx == 0 ifTrue:[
        self selectedProjectIndexHolder value:nil.
    ] ifFalse:[
        self selectedProjectIndexHolder value:idx.
    ].
! !

!ProjectBuilderAssistantApplication class methodsFor:'documentation'!

version_CVS
    ^ '$Header$'
! !