WorkspaceApplication.st
author Claus Gittinger <cg@exept.de>
Mon, 14 Feb 2011 18:16:30 +0100
changeset 9774 5bde45b1c359
parent 9747 9d8ca93efdeb
child 9810 fd0cc2c4930d
permissions -rw-r--r--
automatically generated by browser

"
 COPYRIGHT (c) 2001 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:libtool' }"

MultiViewToolApplication subclass:#WorkspaceApplication
	instanceVariableNames:'autoDefineVariables syntaxHolder poolsConsideredInDoIts
		smalltalkMenuEnabledHolder clipBoardWatcherProcess
		fetchClipboardLines cursorLineHolder cursorColHolder
		modeLabelHolder'
	classVariableNames:'LastFilterBlockString LastProcessingBlockString LastTeaWaitTime
		DefaultToolBarVisible ClipBoardFetchingInstance LastLanguage'
	poolDictionaries:''
	category:'Interface-Smalltalk'
!

!WorkspaceApplication class methodsFor:'documentation'!

copyright
"
 COPYRIGHT (c) 2001 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
"
    A simple wrapper around a WorkSpace-View, adding a pullDown menu.

    [author:]
        Claus Gittinger
"
! !

!WorkspaceApplication class methodsFor:'defaults'!

defaultEditToolbarVisible
    ^ UserPreferences current editToolbarVisibleInWorkspace

    "Created: / 14-07-2007 / 16:42:50 / cg"
!

defaultInfoVisible
    ^ UserPreferences current infoVisibleInWorkspace

    "Created: / 14-07-2007 / 16:43:21 / cg"
!

defaultToolbarVisible
    ^ UserPreferences current toolbarVisibleInWorkspace

    "Created: / 14-07-2007 / 16:42:50 / cg"
!

webServiceLinkName
    ^ '/workspace'
! !

!WorkspaceApplication class methodsFor:'help specs'!

flyByHelpSpec
    <resource: #help>

    ^super flyByHelpSpec addPairsFrom:#(

#columnLabel
'The text-cursor''s column number'

#lineLabel
'The text-cursor''s line number. Double-Click to change'

#modeLabel
'The editing mode (Insert vs. Overwrite). Right-Click to change'

#editRedo
'Redo'

#doIndent
'Indent (Shift Right)'

#doUndent
'Undent (Shift Left)'

#languageSelection
'Syntax selection. Right-Click for Menu'

)

    "Modified: / 22-01-2011 / 11:54:14 / cg"
!

helpSpec
    <resource: #help>

    ^super helpSpec addPairsFrom:#(

#columnLabel
''

#lineLabel
''

#modeLabel
''

#languageSelection
''

)

    "Created: / 24-12-2010 / 02:10:12 / cg"
    "Modified: / 22-01-2011 / 11:54:40 / cg"
! !

!WorkspaceApplication class methodsFor:'interface specs'!

manageSnipletsDialogSpec
    "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:WorkspaceApplication andSelector:#manageSnipletsDialogSpec
     WorkspaceApplication new openInterface:#manageSnipletsDialogSpec
    "

    <resource: #canvas>

    ^ 
     #(FullSpec
        name: manageSnipletsDialogSpec
        window: 
       (WindowSpec
          label: 'Manage Sniplets'
          name: 'Manage Sniplets'
          min: (Point 10 10)
          bounds: (Rectangle 0 0 379 590)
        )
        component: 
       (SpecCollection
          collection: (
           (LabelSpec
              label: 'Sniplet:'
              name: 'Label1'
              layout: (LayoutFrame 0 0 0 0 0 1 30 0)
              translateLabel: true
              adjust: left
            )
           (VariableVerticalPanelSpec
              name: 'VariableVerticalPanel1'
              layout: (LayoutFrame 0 0 30 0 0 1 -80 1)
              component: 
             (SpecCollection
                collection: (
                 (SequenceViewSpec
                    name: 'List1'
                    model: selectedSniplet
                    hasHorizontalScrollBar: true
                    hasVerticalScrollBar: true
                    useIndex: true
                    sequenceList: listOfSniplets
                  )
                 (TextEditorSpec
                    name: 'TextEditor1'
                    model: selectedSnipletsText
                    hasHorizontalScrollBar: true
                    hasVerticalScrollBar: true
                    hasKeyboardFocusInitially: false
                    viewClassName: ''
                  )
                 )
               
              )
              handles: (Any 0.5 1.0)
            )
           (HorizontalPanelViewSpec
              name: 'ButtonPanel'
              layout: (LayoutFrame 0 0 -70 1 0 1 -40 1)
              horizontalLayout: center
              verticalLayout: center
              horizontalSpace: 3
              verticalSpace: 3
              component: 
             (SpecCollection
                collection: (
                 (ActionButtonSpec
                    label: 'Save Changes'
                    name: 'Button4'
                    translateLabel: true
                    model: saveSelectedSniplet
                    enableChannel: saveEnabled
                    extent: (Point 125 22)
                  )
                 (ActionButtonSpec
                    label: 'Remove'
                    name: 'Button2'
                    translateLabel: true
                    model: removeSelectedSniplet
                    enableChannel: removeEnabled
                    extent: (Point 125 22)
                  )
                 (ActionButtonSpec
                    label: 'Paste'
                    name: 'Button3'
                    translateLabel: true
                    model: pasteSelectedSniplet
                    enableChannel: pasteEnabled
                    extent: (Point 125 22)
                  )
                 )
               
              )
            )
           (DividerSpec
              name: 'Separator1'
              layout: (LayoutFrame 0 0.0 557 0 0 1.0 561 0)
            )
           (HorizontalPanelViewSpec
              name: 'CloseButtonPanel'
              layout: (LayoutFrame 0 0 -30 1 0 1 0 1)
              horizontalLayout: fitSpace
              verticalLayout: center
              horizontalSpace: 3
              verticalSpace: 3
              reverseOrderIfOKAtLeft: true
              component: 
             (SpecCollection
                collection: (
                 (ActionButtonSpec
                    label: 'Close'
                    name: 'Button1'
                    translateLabel: true
                    model: cancel
                    extent: (Point 373 22)
                  )
                 )
               
              )
            )
           )
         
        )
      )
!

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:WorkspaceApplication andSelector:#windowSpec
     WorkspaceApplication new openInterface:#windowSpec
     WorkspaceApplication open
    "

    <resource: #canvas>

    ^ 
     #(FullSpec
        name: windowSpec
        window: 
       (WindowSpec
          label: 'Workspace'
          name: 'Workspace'
          min: (Point 10 10)
          bounds: (Rectangle 0 0 432 241)
          menu: mainMenu
        )
        component: 
       (SpecCollection
          collection: (
           (ViewSpec
              name: 'ToolBar'
              layout: (LayoutFrame 0 0 0 0 0 1 32 0)
              visibilityChannel: toolBarVisibleHolder
              component: 
             (SpecCollection
                collection: (
                 (ActionButtonSpec
                    label: 'hideToolBarIcon'
                    name: 'HideToolBarButton'
                    layout: (LayoutFrame 0 0 0 0 13 0 0 1)
                    activeHelpKey: hideToolBar
                    hasCharacterOrientedLabel: false
                    translateLabel: true
                    model: hideToolbar
                    postBuildCallback: hideToolBarButtonCreated:
                  )
                 (MenuPanelSpec
                    name: 'ToolBarMenu'
                    layout: (LayoutFrame 13 0.0 0 0.0 0 1.0 0 1.0)
                    visibilityChannel: toolBarVisibleHolder
                    menu: toolBarMenu
                    textDefault: true
                  )
                 )
               
              )
            )
           (ViewSpec
              name: 'EditToolBar'
              layout: (LayoutFrame 0 0 32 0 0 1 64 0)
              visibilityChannel: editToolBarVisibleHolder
              component: 
             (SpecCollection
                collection: (
                 (ActionButtonSpec
                    label: 'hideToolBarIcon'
                    name: 'HideEditToolBarButton'
                    layout: (LayoutFrame 0 0 0 0 13 0 0 1)
                    activeHelpKey: hideEditToolBar
                    hasCharacterOrientedLabel: false
                    translateLabel: true
                    model: hideEditToolbar
                    postBuildCallback: hideToolBarButtonCreated:
                  )
                 (MenuPanelSpec
                    name: 'EditToolBar1'
                    layout: (LayoutFrame 13 0.0 0 0.0 0 1.0 0 1.0)
                    visibilityChannel: editToolBarVisibleHolder
                    menu: editToolBarMenu
                    textDefault: true
                  )
                 )
               
              )
            )
           (NoteBookViewSpec
              name: 'NoteBook'
              layout: (LayoutFrame 0 0.0 0 0.0 0 1.0 -26 1.0)
              model: selectedWorkspaceIndexHolder
              menu: tabList
              useIndex: true
              accessTabMenuAction: tabMenuAt:
              destroyTabAction: destroyTab:
              canvas: workspaceHolder
              canvasInset: 0
              keepCanvasAlive: true
              tabLevel: 1
            )
           (UISubSpecification
              name: 'infoBarSubSpec'
              layout: (LayoutFrame 0 0.0 -26 1 0 1.0 0 1.0)
              visibilityChannel: infoVisibleHolder
              majorKey: WorkspaceApplication
              minorKey: windowSpecForInfoBar
            )
           )
         
        )
      )
!

windowSpecForInfoBar
    "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:WorkspaceApplication andSelector:#windowSpecForInfoBar
     WorkspaceApplication new openInterface:#windowSpecForInfoBar
    "

    <resource: #canvas>

    ^ 
     #(FullSpec
        name: windowSpecForInfoBar
        window: 
       (WindowSpec
          label: 'Info Bar'
          name: 'Info Bar'
          min: (Point 400 320)
          max: (Point 1152 900)
          bounds: (Rectangle 0 0 500 30)
        )
        component: 
       (SpecCollection
          collection: (
           (ViewSpec
              name: 'infoView'
              layout: (LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0)
              component: 
             (SpecCollection
                collection: (
                 (LabelSpec
                    name: 'infoLabel'
                    layout: (LayoutFrame 0 0.0 0 0.0 -162 1.0 0 1.0)
                    level: -1
                    labelChannel: infoLabelHolder
                    resizeForLabel: false
                    adjust: left
                  )
                 (LabelSpec
                    name: 'LanguageLabel'
                    layout: (LayoutFrame -160 1.0 0 0.0 -60 1.0 0 1.0)
                    activeHelpKey: languageSelection
                    level: -1
                    labelChannel: languageInfoLabelHolder
                    resizeForLabel: false
                    adjust: left
                    menu: languageInfoLabelMenu
                  )
                 (LabelSpec
                    name: 'ModeLabel'
                    layout: (LayoutFrame -60 1 0 0.0 -50 1 0 1.0)
                    activeHelpKey: modeLabel
                    level: -1
                    translateLabel: true
                    labelChannel: modeLabelHolder
                    postBuildCallback: postBuildEditModeInfoLabel:
                  )
                 (LabelSpec
                    name: 'CursorLineLabel'
                    layout: (LayoutFrame -50 1 0 0.0 -20 1 0 1.0)
                    activeHelpKey: lineLabel
                    level: -1
                    translateLabel: true
                    labelChannel: cursorLineLabelHolder
                    adjust: right
                  )
                 (LabelSpec
                    name: 'CursorColLabel'
                    layout: (LayoutFrame -20 1 0 0.0 0 1.0 0 1.0)
                    activeHelpKey: columnLabel
                    level: -1
                    translateLabel: true
                    labelChannel: cursorColLabelHolder
                    adjust: right
                  )
                 )
               
              )
            )
           )
         
        )
      )
! !

!WorkspaceApplication class methodsFor:'menu specs'!

bufferMenu
    "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:WorkspaceApplication andSelector:#bufferMenu
     (Menu new fromLiteralArrayEncoding:(WorkspaceApplication bufferMenu)) startUp
    "

    <resource: #menu>

    ^ 
     #(Menu
        (
         (MenuItem
            label: 'Add Buffer'
            itemValue: addWorkspace
            translateLabel: true
          )
         (MenuItem
            label: '-'
            isVisible: thisIsASmalltalkWorkspace
          )
         (MenuItem
            label: 'Add Buffer on MyWorkspace'
            itemValue: addMyWorkspace
            translateLabel: true
            isVisible: thisIsASmalltalkWorkspace
          )
         (MenuItem
            enabled: anyWorkspaceVariableIsDefined
            label: 'Add Buffer on Workspace Variables'
            itemValue: addWorkspaceVariableInspector
            translateLabel: true
            isVisible: thisIsASmalltalkWorkspace
          )
         (MenuItem
            label: 'Add Buffer on Global Variables'
            itemValue: addGlobalVariableInspector
            translateLabel: true
            isVisible: thisIsASmalltalkWorkspace
          )
         (MenuItem
            label: 'Add Buffer on Namespace...'
            itemValue: addNamespaceInspector
            translateLabel: true
            isVisible: thisIsASmalltalkWorkspace
          )
         (MenuItem
            label: 'Add Buffer on SharedPool...'
            itemValue: addSharedPoolInspector
            translateLabel: true
            isVisible: thisIsASmalltalkWorkspace
          )
         (MenuItem
            label: 'Add Buffer on Class Variables'
            itemValue: addClassVariableInspector
            translateLabel: true
            isVisible: thisIsASmalltalkWorkspace
          )
         (MenuItem
            label: '-'
            isVisible: thisIsASmalltalkWorkspace
          )
         (MenuItem
            label: 'Add Evaluation Buffer'
            itemValue: addEvaluationWorkspace
            translateLabel: true
            isVisible: thisIsASmalltalkWorkspace
          )
         (MenuItem
            label: '-'
          )
         (MenuItem
            label: 'Tea Timer'
            itemValue: addTeaTimer
            translateLabel: true
          )
         (MenuItem
            label: 'Stop Watch'
            itemValue: addStopWatch
            translateLabel: true
          )
         (MenuItem
            label: '-'
          )
         (MenuItem
            label: 'Rename...'
            itemValue: renameWorkspace
            translateLabel: true
          )
         (MenuItem
            label: '-'
          )
         (MenuItem
            enabled: canRemoveWorkspace
            label: 'Remove Buffer'
            itemValue: removeWorkspace
            translateLabel: true
          )
         )
        nil
        nil
      )
!

editMenu
    "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:WorkspaceApplication andSelector:#editMenu
     (Menu new fromLiteralArrayEncoding:(WorkspaceApplication editMenu)) startUp
    "

    <resource: #menu>

    ^ 
     #(Menu
        (
         (MenuItem
            enabled: hasSelectionInActiveWorkspace
            label: 'Cut'
            itemValue: cutSelection
            translateLabel: true
          )
         (MenuItem
            enabled: hasSelectionInActiveWorkspace
            label: 'Copy'
            itemValue: copySelection
            translateLabel: true
          )
         (MenuItem
            label: 'Paste'
            itemValue: paste
            translateLabel: true
          )
         (MenuItem
            enabled: hasHistory
            label: 'Paste Last'
            itemValue: pasteLastDoIt
            translateLabel: true
            isVisible: thisIsASmalltalkWorkspace
            submenuChannel: pasteRecentDoItMenu
          )
         (MenuItem
            label: '-'
          )
         (MenuItem
            label: 'Copy as Sniplet...'
            itemValue: addSelectionToSniplets
            translateLabel: true
          )
         (MenuItem
            label: 'Paste Sniplet...'
            itemValue: pasteSniplet
            translateLabel: true
          )
         (MenuItem
            label: 'Manage Sniplets...'
            itemValue: manageSniplets
            translateLabel: true
          )
         (MenuItem
            label: '-'
          )
         (MenuItem
            label: 'Select All'
            itemValue: selectAll
            translateLabel: true
          )
         (MenuItem
            label: '-'
            isVisible: thisIsASmalltalkWorkspace
          )
         (MenuItem
            label: 'Filter Text...'
            itemValue: filterText
            translateLabel: true
            isVisible: thisIsASmalltalkWorkspace
          )
         (MenuItem
            label: 'Process Text...'
            itemValue: processText
            translateLabel: true
            isVisible: thisIsASmalltalkWorkspace
          )
         (MenuItem
            label: '-'
          )
         (MenuItem
            label: 'Services'
            translateLabel: true
            submenu: 
           (Menu
              (
               (MenuItem
                  label: 'Autofetch Selection'
                  itemValue: autoFetchSelection:
                  translateLabel: true
                  indication: autoFetchSelection
                )
               (MenuItem
                  label: 'Autofetch Selection (Lines)'
                  translateLabel: true
                  indication: autoFetchSelectionLines
                )
               (MenuItem
                  label: '-'
                  isVisible: thisIsASmalltalkWorkspace
                )
               (MenuItem
                  enabled: hasSelectionInActiveWorkspace
                  label: 'Google Spell'
                  itemValue: googleSpellingSuggestion
                  translateLabel: true
                  isVisible: thisIsASmalltalkWorkspace
                )
               (MenuItem
                  label: 'Translate (babelFish)'
                  translateLabel: true
                  isVisible: thisIsASmalltalkWorkspace
                  submenu: 
                 (Menu
                    (
                     (MenuItem
                        enabled: hasSelectionInActiveWorkspace
                        label: 'English -> German'
                        itemValue: babelFishTranslate:
                        translateLabel: true
                        argument: 'en_de'
                      )
                     (MenuItem
                        enabled: hasSelectionInActiveWorkspace
                        label: 'English -> French'
                        itemValue: babelFishTranslate:
                        translateLabel: true
                        argument: 'en_fr'
                      )
                     (MenuItem
                        enabled: hasSelectionInActiveWorkspace
                        label: 'English -> Spanish'
                        itemValue: babelFishTranslate:
                        translateLabel: true
                        argument: 'en_es'
                      )
                     (MenuItem
                        enabled: hasSelectionInActiveWorkspace
                        label: 'English -> Portuguese'
                        itemValue: babelFishTranslate:
                        translateLabel: true
                        argument: 'en_pt'
                      )
                     (MenuItem
                        label: '-'
                      )
                     (MenuItem
                        enabled: hasSelectionInActiveWorkspace
                        label: 'German -> English'
                        itemValue: babelFishTranslate:
                        translateLabel: true
                        argument: 'de_en'
                      )
                     (MenuItem
                        enabled: hasSelectionInActiveWorkspace
                        label: 'French -> English'
                        itemValue: babelFishTranslate:
                        translateLabel: true
                        argument: 'fr_en'
                      )
                     (MenuItem
                        enabled: hasSelectionInActiveWorkspace
                        label: 'Spanish -> English'
                        itemValue: babelFishTranslate:
                        translateLabel: true
                        argument: 'es_en'
                      )
                     (MenuItem
                        enabled: hasSelectionInActiveWorkspace
                        label: 'Portuguese -> English'
                        itemValue: babelFishTranslate:
                        translateLabel: true
                        argument: 'pt_en'
                      )
                     (MenuItem
                        enabled: hasSelectionInActiveWorkspace
                        label: 'Russian -> English'
                        itemValue: babelFishTranslate:
                        translateLabel: true
                        argument: 'ru_en'
                      )
                     )
                    nil
                    nil
                  )
                )
               )
              nil
              nil
            )
          )
         )
        nil
        nil
      )
!

editModeInfoLabelMenu
    "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:Tools::NewSystemBrowser andSelector:#editModeInfoLabelMenu
     (Menu new fromLiteralArrayEncoding:(Tools::NewSystemBrowser editModeInfoLabelMenu)) startUp
    "

    <resource: #menu>

    ^ 
     #(Menu
        (
         (MenuItem
            label: 'Insert'
            itemValue: editModeInsert
            translateLabel: true
          )
         (MenuItem
            label: 'Overwrite'
            itemValue: editModeOverwrite
            translateLabel: true
          )
         (MenuItem
            label: 'Insert Selecting'
            itemValue: editModeInsertAndSelect
            translateLabel: true
          )
         )
        nil
        nil
      )

    "Created: / 22-01-2011 / 11:50:05 / cg"
!

editToolBarMenu
    "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:WorkspaceApplication andSelector:#editToolBarMenu
     (Menu new fromLiteralArrayEncoding:(WorkspaceApplication editToolBarMenu)) startUp
    "

    <resource: #menu>

    ^ 
     #(Menu
        (
         (MenuItem
            activeHelpKey: editCut
            label: 'Cut'
            itemValue: cutSelection
            translateLabel: true
            labelImage: (ResourceRetriever ToolbarIconLibrary cut16x16Icon)
            isButton: true
          )
         (MenuItem
            activeHelpKey: editCopy
            label: 'Copy'
            itemValue: copySelection
            translateLabel: true
            labelImage: (ResourceRetriever ToolbarIconLibrary copy16x16Icon)
            isButton: true
          )
         (MenuItem
            activeHelpKey: editPaste
            label: 'Paste'
            itemValue: paste
            translateLabel: true
            labelImage: (ResourceRetriever ToolbarIconLibrary paste16x16Icon)
            isButton: true
          )
         (MenuItem
            label: '-'
          )
         (MenuItem
            activeHelpKey: editUndo
            label: 'Undo'
            itemValue: undo
            translateLabel: true
            labelImage: (ResourceRetriever ToolbarIconLibrary undo16x16Icon)
            isButton: true
          )
         (MenuItem
            activeHelpKey: editRedo
            label: 'Redo'
            itemValue: redo
            translateLabel: true
            labelImage: (ResourceRetriever ToolbarIconLibrary redo16x16Icon)
            isButton: true
          )
         (MenuItem
            label: '-'
          )
         (MenuItem
            activeHelpKey: editSearch
            label: 'Search'
            itemValue: search
            translateLabel: true
            labelImage: (ResourceRetriever ToolbarIconLibrary search16x16Icon)
            isButton: true
          )
         (MenuItem
            label: '-'
          )
         (MenuItem
            activeHelpKey: doUndent
            label: 'Undent'
            itemValue: undent
            translateLabel: true
            isButton: true
            labelImage: (ResourceRetriever ToolbarIconLibrary undent16x16Icon)
          )
         (MenuItem
            activeHelpKey: doIndent
            label: 'Indent'
            itemValue: indent
            translateLabel: true
            isButton: true
            labelImage: (ResourceRetriever ToolbarIconLibrary indent16x16Icon)
          )
         )
        nil
        nil
      )
!

executionMenu
    "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:WorkspaceApplication andSelector:#executionMenu
     (Menu new fromLiteralArrayEncoding:(WorkspaceApplication executionMenu)) startUp
    "

    <resource: #menu>

    ^ 
     #(Menu
        (
         (MenuItem
            enabled: hasHistory
            label: 'Redo Last'
            itemValue: redoLastDoIt
            translateLabel: true
            submenuChannel: redoRecentDoItMenu
          )
         (MenuItem
            label: '-'
          )
         (MenuItem
            enabled: hasSelectionInActiveWorkspace
            label: 'DoIt'
            itemValue: doIt
            translateLabel: true
          )
         (MenuItem
            enabled: hasSelectionInActiveWorkspace
            label: 'PrintIt'
            itemValue: printIt
            translateLabel: true
          )
         (MenuItem
            enabled: hasSelectionInActiveWorkspace
            label: 'InspectIt'
            itemValue: inspectIt
            translateLabel: true
          )
         (MenuItem
            label: '-'
          )
         (MenuItem
            enabled: hasSelectionInActiveWorkspace
            label: 'Browse Class'
            itemValue: browseIt
            translateLabel: true
          )
         (MenuItem
            enabled: hasSelectionInActiveWorkspace
            label: 'Browse Implementors of It'
            itemValue: browseImplementorsOfIt
            translateLabel: true
          )
         (MenuItem
            enabled: hasSelectionInActiveWorkspace
            label: 'Browse References to It'
            itemValue: browseReferencesToIt
            translateLabel: true
          )
         (MenuItem
            label: '-'
          )
         (MenuItem
            enabled: hasSelectionInActiveWorkspace
            label: 'TimeIt'
            itemValue: timeIt
            translateLabel: true
          )
         (MenuItem
            enabled: hasSelectionInActiveWorkspace
            label: 'SpyOnIt'
            itemValue: spyOnIt
            translateLabel: true
          )
         )
        nil
        nil
      )
!

fileMenu
    "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:WorkspaceApplication andSelector:#fileMenu
     (Menu new fromLiteralArrayEncoding:(WorkspaceApplication fileMenu)) startUp
    "

    <resource: #menu>

    ^ 
     #(Menu
        (
         (MenuItem
            label: 'New Workspace'
            itemValue: newWorkspace
            translateLabel: true
          )
         (MenuItem
            label: 'New SystemWorkspace'
            itemValue: newSystemWorkspace
            translateLabel: true
            isVisible: thisIsASmalltalkWorkspace
          )
         (MenuItem
            label: 'New EvaluationWorkspace'
            itemValue: newEvaluationWorkspace
            translateLabel: true
            isVisible: thisIsASmalltalkWorkspace
          )
         (MenuItem
            label: '-'
          )
         (MenuItem
            label: 'Load File...'
            itemValue: menuLoad
            translateLabel: true
          )
         (MenuItem
            label: '-'
          )
         (MenuItem
            label: 'Save As...'
            itemValue: menuSaveAs
            translateLabel: true
          )
         (MenuItem
            enabled: hasMultipleBuffersHolder
            label: 'Save all As...'
            itemValue: menuSaveAllAs
            translateLabel: true
          )
         (MenuItem
            label: '-'
          )
         (MenuItem
            enabled: hasTextInActiveWorkspace
            label: 'Print...'
            itemValue: menuPrint
            translateLabel: true
          )
         (MenuItem
            label: '-'
          )
         (MenuItem
            label: 'Exit'
            itemValue: closeRequest
            translateLabel: true
          )
         )
        nil
        nil
      )
!

helpMenu
    "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:WorkspaceApplication andSelector:#helpMenu
     (Menu new fromLiteralArrayEncoding:(WorkspaceApplication helpMenu)) startUp
    "

    <resource: #menu>

    ^ 
     #(Menu
        (
         (MenuItem
            label: 'Documentation'
            itemValue: openDocumentation
            translateLabel: true
          )
         (MenuItem
            label: 'Documentation on Smalltalk/X'
            itemValue: openSTXDocumentation
            translateLabel: true
          )
         (MenuItem
            label: '-'
          )
         (MenuItem
            label: 'About this Application...'
            itemValue: openAboutThisApplication
            translateLabel: true
          )
         )
        nil
        nil
      )
!

languageInfoLabelMenu
    "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:WorkspaceApplication andSelector:#workspaceMenu
     (Menu new fromLiteralArrayEncoding:(WorkspaceApplication workspaceMenu)) startUp
    "

    <resource: #menu>

    ^ 
     #(Menu
                    (
"/                     (MenuItem
"/                        label: 'Smalltalk'
"/                        translateLabel: true
"/                        choice: syntaxHolder
"/                        choiceValue: Smalltalk
"/                      )
"/                     (MenuItem
"/                        label: 'JavaScript'
"/                        translateLabel: true
"/                        choice: syntaxHolder
"/                        choiceValue: JavaScript
"/                      )
                     (MenuItem
                        label: 'Language List Slice'
                        translateLabel: true
                        submenuChannel: languageListMenuSlice
                        isMenuSlice: true
                      )
                     )
                    nil
                    nil
                  )

    "Created: / 24-12-2010 / 02:03:59 / cg"
!

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:WorkspaceApplication andSelector:#mainMenu
     (Menu new fromLiteralArrayEncoding:(WorkspaceApplication mainMenu)) startUp
    "

    <resource: #menu>

    ^ 
     #(Menu
        (
         (MenuItem
            label: 'File'
            translateLabel: true
            submenuChannel: fileMenu
            keepLinkedMenu: true
          )
         (MenuItem
            label: 'Buffers'
            translateLabel: true
            submenuChannel: bufferMenu
            keepLinkedMenu: true
          )
         (MenuItem
            label: 'Edit'
            translateLabel: true
            submenuChannel: editMenu
            keepLinkedMenu: true
          )
         (MenuItem
            label: 'View'
            translateLabel: true
            submenuChannel: viewMenu
            keepLinkedMenu: true
          )
         (MenuItem
            label: 'Execute'
            translateLabel: true
            isVisible: executeMenuVisible 
            submenuChannel: executionMenu
            keepLinkedMenu: true
          )
         (MenuItem
            label: 'Workspace'
            translateLabel: true
            isVisible: thisIsASmalltalkWorkspace
            submenuChannel: workspaceMenu
            keepLinkedMenu: true
          )
         (MenuItem
            enabled: smalltalkMenuEnabledHolder
            label: 'Smalltalk'
            translateLabel: true
            isVisible: thisIsASmalltalkWorkspace
            submenuChannel: smalltalkMenu
            keepLinkedMenu: true
          )
         (MenuItem
            label: 'MENU_Help'
            translateLabel: true
            submenuChannel: helpMenu
            keepLinkedMenu: true
          )
         )
        nil
        nil
      )
!

smalltalkMenu
    "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:WorkspaceApplication andSelector:#smalltalkMenu
     (Menu new fromLiteralArrayEncoding:(WorkspaceApplication smalltalkMenu)) startUp
    "

    <resource: #menu>

    ^ 
     #(Menu
        (
         (MenuItem
            label: 'FileIn Text'
            itemValue: fileInText
            translateLabel: true
          )
         (MenuItem
            label: 'ChangeList on Text'
            itemValue: changesBrowserOnText
            translateLabel: true
          )
         (MenuItem
            label: '-'
          )
         (MenuItem
            label: 'Add Global Variable...'
            itemValue: addGlobalVariable
            translateLabel: true
          )
         (MenuItem
            label: 'Remove Global Variable...'
            itemValue: removeGlobalVariable
            translateLabel: true
          )
         (MenuItem
            label: '-'
          )
         (MenuItem
            label: 'Add SharedPool...'
            itemValue: addSharedPool
            translateLabel: true
          )
         (MenuItem
            label: 'Remove SharedPool...'
            itemValue: removeSharedPool
            translateLabel: true
          )
         )
        nil
        nil
      )
!

toolBarMenu
    "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:WorkspaceApplication andSelector:#toolBarMenu
     (Menu new fromLiteralArrayEncoding:(WorkspaceApplication toolBarMenu)) startUp
    "

    <resource: #menu>

    ^ 
     #(Menu
        (
         (MenuItem
            label: ''
          )
         (MenuItem
            label: 'Add Buffer'
            itemValue: addWorkspace
            translateLabel: true
            isButton: true
            labelImage: (ResourceRetriever ToolbarIconLibrary addBufferIcon)
          )
         (MenuItem
            label: '-'
          )
         (MenuItem
            label: 'Save Text As...'
            itemValue: menuSaveAs
            translateLabel: true
            isButton: true
            labelImage: (ResourceRetriever ToolbarIconLibrary saveToFileAsIcon)
          )
         (MenuItem
            label: '-'
            isVisible: doItMenuButtonVisibile
          )
         (MenuItem
            label: 'DoIt'
            activeHelpKey: help_doIt
            itemValue: doIt
            translateLabel: true
            isButton: true
            isVisible: doItMenuButtonVisibile
            labelImage: (ResourceRetriever ToolbarIconLibrary doItIcon)
          )
         (MenuItem
            label: 'PrintIt'
            activeHelpKey: help_printIt
            itemValue: printIt
            translateLabel: true
            isButton: true
            isVisible: printItMenuButtonVisibile
            labelImage: (ResourceRetriever ToolbarIconLibrary printItIcon)
          )
         (MenuItem
            label: 'InspectIt'
            activeHelpKey: help_inspectIt
            itemValue: inspectIt
            translateLabel: true
            isButton: true
            isVisible: inspectItMenuButtonVisibile
            labelImage: (ResourceRetriever ToolbarIconLibrary inspectItIcon)
          )
         (MenuItem
            label: 'BrowseIt'
            activeHelpKey: help_browseIt
            itemValue: browseIt
            translateLabel: true
            isButton: true
            isVisible: browseItMenuButtonVisibile
            labelImage: (ResourceRetriever ToolbarIconLibrary browseItIcon)
          )
         )
        nil
        nil
      )
!

workspaceMenu
    "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:WorkspaceApplication andSelector:#workspaceMenu
     (Menu new fromLiteralArrayEncoding:(WorkspaceApplication workspaceMenu)) startUp
    "

    <resource: #menu>

    ^ 
     #(Menu
        (
         (MenuItem
            label: 'Add Workspace Variable...'
            itemValue: addWorkspaceVariable
            translateLabel: true
          )
         (MenuItem
            enabled: anyWorkspaceVariableIsDefined
            label: 'Remove Workspace Variable...'
            itemValue: removeWorkspaceVariable
            translateLabel: true
          )
         (MenuItem
            enabled: anyWorkspaceVariableIsDefined
            label: 'Remove all Workspace Variables...'
            itemValue: removeAllWorkspaceVariables
            translateLabel: true
          )
         (MenuItem
            label: '-'
          )
         (MenuItem
            enabled: anyWorkspaceVariableIsDefined
            label: 'Inspect Workspace Variables'
            itemValue: inspectWorkspaceVariables
            translateLabel: true
          )
         (MenuItem
            label: '-'
          )
         (MenuItem
            label: 'Settings'
            translateLabel: true
            submenu: 
           (Menu
              (
               (MenuItem
                  label: 'Autodefine as Workspace Variable'
                  translateLabel: true
                  hideMenuOnActivated: false
                  choice: autoDefineVariables
                  choiceValue: workspace
                )
               (MenuItem
                  label: 'Autodefine as DoIt Variable'
                  translateLabel: true
                  hideMenuOnActivated: false
                  choice: autoDefineVariables
                  choiceValue: doIt
                )
               (MenuItem
                  label: 'Autodefine off'
                  translateLabel: true
                  hideMenuOnActivated: false
                  choice: autoDefineVariables
                )
               (MenuItem
                  label: '-'
                )
               (MenuItem
                  label: 'Syntax'
                  translateLabel: true
                  submenu: 
                 (Menu
                    (
"/                     (MenuItem
"/                        label: 'Smalltalk'
"/                        translateLabel: true
"/                        choice: syntaxHolder
"/                        choiceValue: Smalltalk
"/                      )
"/                     (MenuItem
"/                        label: 'JavaScript'
"/                        translateLabel: true
"/                        choice: syntaxHolder
"/                        choiceValue: JavaScript
"/                      )
                     (MenuItem
                        label: 'Language List Slice'
                        translateLabel: true
                        submenuChannel: languageListMenuSlice
                        isMenuSlice: true
                      )
                     )
                    nil
                    nil
                  )
                )
               )
              nil
              nil
            )
          )
         )
        nil
        nil
      )
! !

!WorkspaceApplication class methodsFor:'special startup'!

openEvaluationWorkspace
    |wsApp path needRemove font|

    needRemove := true.

    wsApp := self new.
    wsApp allButOpen.
    wsApp window extent:400@500.

    wsApp addEvaluationWorkspace.
    wsApp removeWorkspace:1.
    wsApp renameWorkspace:1 to:'Evaluator'.

    wsApp openWindow.
    wsApp selectedWorkspaceIndexHolder value:1.
    ^ wsApp

    "
     self openEvaluationWorkspace
    "

    "Created: / 13-10-2006 / 12:14:13 / cg"
    "Modified: / 25-09-2007 / 21:00:45 / cg"
!

openForSinglePageDoing:aBlock
    |wsApp needRemove|

    needRemove := true.

    wsApp := self new.
    wsApp allButOpen.

    (wsApp builder componentAt:'NoteBook') destroyTabAction:nil.

    wsApp window height:500.

    aBlock value:wsApp.
    wsApp removeWorkspace:1.  "/ the original Workspace
    "/ wsApp renameWorkspace:1 to:'LICENCE README'.

    wsApp openWindow.
    wsApp selectedWorkspaceIndexHolder value:1.
    ^ wsApp

    "
     self openWithGlobalsInspector
    "
!

openMyWorkspace
    self openOnFile:'MyWorkspace.wsp'

    "
     self openMyWorkspace.
    "
!

openOnFile:aFilename
    "launch a new workspace on the contents of some file"

    |ws|

    ws := self openWith:nil.

    "/ let the ws load the file - instead of the caller.
    "/ so the error dialog is shown in its context, 
    "/ and the caller (Launcher) is not blocked.
    ws enqueueDelayedAction:[ws loadFile:aFilename].
"/    ws loadFile:aFilename.
    ^ ws

    "
     WorkspaceApplication openOnFile:'Makefile'
    "
!

openSystemWorkspace
    |wsApp path needRemove font|

    needRemove := true.

    wsApp := self new.
    wsApp allButOpen.

    (wsApp builder componentAt:'NoteBook') destroyTabAction:nil.

    wsApp window extent:640@400.

    path := (Smalltalk getSystemFileName:'README') ?  '../../README'.
    path := path asFilename.
    path isReadable ifTrue:[
        wsApp addWindow:(HVScrollableView for:Workspace) named:'README' asFirst:false.
        wsApp loadFile:path.
        wsApp removeWorkspace:1.  "/ the original Workspace
        wsApp renameWorkspace:1 to:'LICENCE README'.
        needRemove := false.
    ].

"/    path := (Smalltalk getSystemFileName:'doc/online/english/LICENCE_STX.html') ?  '../../doc/online/english/LICENCE_STX.html'.
"/    path asFilename exists ifTrue:[
"/        wsApp addWindow:(licenceView := HVScrollableView for:HTMLDocumentView) named:'License' asFirst:false.
"/        licenceView homeDocument:'../../doc/online/english/LICENCE_STX.html'.
"/        licenceView updateLabelFlag:false.
"/        needRemove ifTrue:[wsApp removeWorkspace:1].  "/ the original Workspace
"/        needRemove := false.
"/    ].

    wsApp graphicsDevice platformName = 'X11' ifTrue:[
        font := Font family:'unifont' face:'medium' style:'roman' size:16 encoding:'iso10646-1'.
        font := font onDevice:wsApp graphicsDevice ifAbsent:nil.
        font isNil ifTrue:[    
            font := Font family:'arial' face:'medium' style:'roman' size:12 encoding:'iso10646-1'.
            font := font onDevice:wsApp graphicsDevice ifAbsent:nil.
        ].
    ] ifFalse:[
        "/ font := Font family:'Arial Unicode MS' face:'medium' style:'roman' size:10 encoding:'ms-ansi'.
        font := Font family:'Arial' face:'medium' style:'roman' size:10 encoding:'ms-ansi'.
        font := font onDevice:wsApp graphicsDevice ifAbsent:nil.
    ].

    #(  "/ file                     resourceKey             title                       forcedEncoding  type
        ('Hello_utf8.wsp'           HELLO_UTF_FILE          'Hello'                     #'utf8'         #text)
        ('Welcome.wsp'              WELCOME_FILE            'This Release'              nil             #text)
"/        ('Setup.wsp'                SETUP_FILE              'Setup'                     nil             #text)
        ('Keyboard.wsp'             KEYBOARD_FILE           'Keyboard'                  nil             #text)
"/        ('GettingStarted.wsp'       GETTING_STARTED_FILE    'Getting Started'           nil             #text)
        ('../../doc/online/english/GettingStarted.html'   GETTING_STARTED_TML_FILE  'Getting Started'           nil             #html)
        ('../../doc/books/JoyOfST/IntroToST.html'         INTRO_TO_ST_FILE          'Smalltalk Introduction'    nil             #html)
    "/ if these are present, show them.
        ('Private.wsp'              PRIVATE_FILE            'Private Workspace'         nil             #text)
        ('MyWorkspace.wsp'          MYWORKSPACE_FILE        'My Workspace'              nil             #text)
    ) do:[:tuple |
        |file resKey title forcedEncoding type pane encoding htmlView|

        file := tuple at:1.
        resKey := tuple at:2.
        file := self classResources string:resKey default:file.

        title := tuple at:3.
        forcedEncoding := tuple at:4.
        type := tuple at:5.

        path := Smalltalk getSystemFileName:file.
        (path notNil and:[path asFilename isReadable]) ifTrue:[
            type == #html ifTrue:[
                wsApp addWindow:(htmlView := HVScrollableView for:HTMLDocumentView) named:title asFirst:false.
                htmlView homeDocument:path.
                htmlView updateTopViewsTitleFlag:false.
            ] ifFalse:[
                wsApp addWindow:(pane := HVScrollableView for:Workspace) named:title asFirst:false.
                forcedEncoding notNil ifTrue:[
                    encoding := forcedEncoding.
                    font notNil ifTrue:[
                        pane font:font.
                    ]
                ] ifFalse:[
                    encoding := CharacterEncoder guessEncodingOfFile:path.
                    (encoding == #'iso8859-1' or:[encoding == #'ascii']) ifTrue:[
                        encoding := nil
                    ].
                ].
                wsApp loadFile:path encoding:encoding label:title.
            ].
            needRemove ifTrue:[wsApp removeWorkspace:1].  "/ the original Workspace
            needRemove := false.
        ].
    ].
    wsApp openWindow.
    wsApp selectedWorkspaceIndexHolder value:2.
    ^ wsApp

    "
     |ws b|
     ws := self openSystemWorkspace.
     ws addMyWorkspace.
     ws selectedWorkspaceIndexHolder value:(ws workspaces size).
     ws selectedWorkspace contents:'Tools::NewSystemBrowser open'; selectAll.
     ws selectedWorkspace 
        add:(b := Button label:'DoIt' action:[ws doIt. b destroy])
    "
    "
     |ws b|
     ws := self new.
     ws open. 
     ws selectedWorkspace contents:'Tools::NewSystemBrowser open'; selectAll.
    "

    "Modified: / 25-09-2007 / 21:04:50 / cg"
!

openWith:initialText
    "launch a new workspace with some initial contents"

    ^ self openWith:initialText selected:false

    "
     WorkspaceApplication openWith:'Transcript showCR:''hello world'''
    "
!

openWith:initialText selected:selectedBoolean
    "launch a new workspace with some initial contents"

    |workspace|

    workspace := self new.
    workspace open.
    workspace selectedWorkspace contents:initialText selected:selectedBoolean.
    ^ workspace

    "
     WorkspaceApplication openWith:'Transcript showCR:''hello world'''
    "
!

openWithGlobalsInspector
    "open a workspaceApp with a single initial pane, showing global variables.
     Same as Smalltalk inspect, but looks nicer..."

    ^ self openForSinglePageDoing:[:wsApp | wsApp addNamespaceInspectorFor:Smalltalk]

    "
     self openWithGlobalsInspector
    "
!

openWithWorkspaceVariableInspector
    "open a workspaceApp with a single initial pane, showing workspace variables.
     Same as Workspace workspaceVariables inspect, but looks nicer..."

    ^ self openForSinglePageDoing:[:wsApp | wsApp addWorkspaceVariableInspector]

    "
     self openWithWorkspaceVariableInspector
    "
! !

!WorkspaceApplication methodsFor:'aspects'!

autoDefineVariables
    autoDefineVariables isNil ifTrue:[
        autoDefineVariables := ValueHolder new.
        (UserPreferences current autoDefineWorkspaceVariables) ifTrue:[
            autoDefineVariables value:#workspace.
        ] ifFalse:[
            autoDefineVariables value:#doIt.
        ].
        autoDefineVariables onChangeSend:#autoDefineVariablesChanged to:self.
    ].
    ^ autoDefineVariables.
!

browseItMenuButtonVisibile
    ^ self thisIsASmalltalkWorkspace
!

cursorColHolder
    cursorColHolder isNil ifTrue:[
        cursorColHolder := IndirectValue for:(1 asValue)
    ].
    ^ cursorColHolder

    "Created: / 22-01-2011 / 11:36:00 / cg"
!

cursorColLabelHolder
    ^ BlockValue 
            with:[:v | v isNil ifTrue:[''] ifFalse:[v printString]]
            argument:self cursorColHolder.

    "Created: / 22-01-2011 / 11:36:08 / cg"
!

cursorLineHolder
    cursorLineHolder isNil ifTrue:[
        cursorLineHolder := IndirectValue for:(1 asValue)
    ].
    ^ cursorLineHolder

    "Created: / 22-01-2011 / 11:35:22 / cg"
!

cursorLineLabelHolder
    ^ BlockValue 
            with:[:v | v isNil ifTrue:[''] ifFalse:[v printString]]
            argument:self cursorLineHolder.

    "Modified: / 22-01-2011 / 11:42:56 / cg"
!

doItMenuButtonVisibile
    ^ self thisIsASmalltalkWorkspace
!

hasHistory
    ^ Workspace doItHistory size > 0.
!

hasInfoLabel
    ^ true
!

inspectItMenuButtonVisibile
    ^ self thisIsASmalltalkWorkspace
!

languageInfoLabelHolder
    ^ BlockValue
        with:[:syntax | 'Syntax: ',syntax name ]
        argument:self syntaxHolder
!

modeLabelHolder
    modeLabelHolder isNil ifTrue:[
        modeLabelHolder := IndirectValue for:('I' asValue)
    ].
    ^ modeLabelHolder

    "Created: / 22-01-2011 / 11:37:25 / cg"
!

printItMenuButtonVisibile
    ^ self thisIsASmalltalkWorkspace
!

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

syntaxHolder
    syntaxHolder isNil ifTrue:[
        syntaxHolder := self defaultEvaluatorSyntax asValue.
        syntaxHolder onChangeSend:#setCompilerForSyntax to:self
    ].
    ^ syntaxHolder
! !

!WorkspaceApplication methodsFor:'aspects-queries'!

anyWorkspaceVariableIsDefined
    ^ Workspace anyWorkspaceVariableIsDefined

    "Modified: / 20-04-2005 / 11:57:59 / cg"
! !

!WorkspaceApplication methodsFor:'autofetch selection'!

autoFetchSelection
    ^ clipBoardWatcherProcess notNil

    "Created: / 16-11-2010 / 14:55:39 / cg"
!

autoFetchSelection:aBoolean
    Display platformName = 'WIN32' ifTrue:[
        aBoolean ifTrue:[
            self startClipboardWatcher
        ] ifFalse:[
            self stopClipboardWatcher
        ].
        ^ self.
    ].

    aBoolean ifTrue:[
        self window windowGroup addPreEventHook:self.
        device addSelectionHandler:self
    ] ifFalse:[
        self window windowGroup removePreEventHook:self.
        device removeSelectionHandler:self
    ].

    "Created: / 16-11-2010 / 14:34:15 / cg"
!

autoFetchSelectionLines
    fetchClipboardLines isNil ifTrue:[
        fetchClipboardLines := true asValue
    ].
    ^ fetchClipboardLines

    "Created: / 04-02-2011 / 17:52:34 / cg"
!

itemFromClipboard
    |text|

    text := self window getClipboardText.
    (text notNil and:[text isString]) ifTrue:[
        self autoFetchSelectionLines value ifTrue:[
            text := text , Character cr
        ].
        self paste:text.
    ].

    "Created: / 16-11-2010 / 14:44:26 / cg"
    "Modified: / 04-02-2011 / 17:53:46 / cg"
!

startClipboardWatcher
    clipBoardWatcherProcess isNil ifTrue:[
        ClipBoardFetchingInstance notNil ifTrue:[
            ClipBoardFetchingInstance stopClipboardWatcher
        ].
        clipBoardWatcherProcess := 
            [
                [true] whileTrue:[
                    self waitForClipBoardToChange.
                ].
            ] newProcess.

        clipBoardWatcherProcess resume.
        ClipBoardFetchingInstance := self.
    ].

    "Created: / 16-11-2010 / 14:35:55 / cg"
!

stopClipboardWatcher
    |p|

    (p := clipBoardWatcherProcess) notNil ifTrue:[
        ClipBoardFetchingInstance := nil.
        clipBoardWatcherProcess := nil.
        p terminate
    ].

    "Created: / 16-11-2010 / 14:36:12 / cg"
!

waitForClipBoardToChange
    |prev|

    prev := self window getClipboardText.
    [ 
        Delay waitForSeconds:0.2.
        self window getClipboardText = prev
    ] whileTrue.
    self itemFromClipboard.

    "Created: / 16-11-2010 / 14:44:05 / cg"
! !

!WorkspaceApplication methodsFor:'defaults'!

defaultEvaluatorSyntax
    LastLanguage notNil ifTrue:[^ LastLanguage].
    ^ SmalltalkLanguage instance.

    "Modified: / 01-12-2010 / 12:21:41 / cg"
!

defaultFileNameForLoad
   ^ 'file.wsp'

    "Created: / 25-10-2006 / 14:56:10 / cg"
!

defaultFileNameForSave
    |ws|

    ws := self selectedWorkspace scrolledView.
    ws isTextView ifFalse:[
        "/ eval-ws
        ^ super defaultFileNameForSave
    ].
    ^ ws defaultFileNameForFileDialog ? super defaultFileNameForSave

    "Modified: / 22-01-2011 / 12:01:27 / cg"
!

defaultFileNameForSaveAll
   ^ 'file.wsp'

    "Created: / 25-10-2006 / 14:56:04 / cg"
!

defaultPatternLoad
   ^ '*.wsp; *.txt; *.rc'

    "Created: / 25-10-2006 / 14:57:25 / cg"
!

executeMenuVisible 
    ^ self thisIsASmalltalkWorkspace
!

thisIsASmalltalkWorkspace
    "can be redefined in a subclass to disable smalltalk-specific menu items
     (expecco uses workspaces as scratchpads)"

    ^ true
! !

!WorkspaceApplication methodsFor:'drag & drop'!

droppedFile:aFilename in:aComponent
    "this is a notification from my textView component"

    self 
        renameWorkspace:(self selectedWorkspaceIndexHolder value)
        to:aFilename asFilename baseName
! !

!WorkspaceApplication methodsFor:'initialization & release'!

closeRequest
    "asks for permission before closing"

    (self askIfAnyModified:'Text was not saved. Close anyway ?' yesButton:'Close') ifFalse:[
        ^ self
    ].

    ^ super closeRequest
!

postBuildEditModeInfoLabel:aLabel
    aLabel menuHolder:self; menuMessage:#editModeInfoLabelMenu.

    "Created: / 22-01-2011 / 11:32:57 / cg"
!

postBuildWith:aBuilder
    super postBuildWith:aBuilder.
    self setCompilerForSyntax.

    self infoVisibilityChanged.         "/ force geometry update
    self autoDefineVariablesChanged.    "/ force workspaceView update
!

postOpenWith:aBuilder
    self windowGroup addPreEventHook:self.
    super postOpenWith:aBuilder.

    "Created: / 22-01-2011 / 12:09:20 / cg"
    "Modified: / 08-02-2011 / 21:33:49 / cg"
!

processEvent:anEvent
    "filter double click in line-label.
     Return true, if I have eaten the event"

    anEvent isButtonMultiPressEvent ifTrue:[
        anEvent view name = 'CursorLineLabel' ifTrue:[
            self selectedWorkspace scrolledView gotoLine.
            ^ true
        ].
    ].
    ^ false

    "Created: / 22-01-2011 / 12:10:01 / cg"
! !

!WorkspaceApplication methodsFor:'menu-actions'!

askForFilterBlock:message template:template rememberIn:nameOfClassVar
    |filterBlockString filterBlock dialog textHolder classVarValue|

    classVarValue := self class classVarAt:nameOfClassVar ifAbsent:nil.
    classVarValue isNil ifTrue:[
        self class classVarAt:nameOfClassVar put:template. 
        classVarValue := template.
    ].

    textHolder := ValueHolder new.
    dialog := Dialog 
                 forRequestText:(resources string:message)
                 lines:25 
                 columns:70
                 initialAnswer:classVarValue
                 model:textHolder.
    dialog addButton:(Button label:'Template' action:[textHolder value:template. textHolder changed:#value.]).
    dialog open.
    dialog accepted ifFalse:[^ nil].

    filterBlockString := textHolder value.
    self class classVarAt:nameOfClassVar put:filterBlockString. 

    filterBlock := Parser evaluate:filterBlockString.
    filterBlock isBlock ifFalse:[
        self error:'bad input for filterBlock' mayProceed:true.
        ^ nil
    ].

    ^ filterBlock
!

autoDefineVariablesChanged
    |autoDefine|

    autoDefine := autoDefineVariables value.
    UserPreferences current autoDefineWorkspaceVariables:(autoDefine == #workspace).
    workspaces do:[:each |
        each autoDefineVariables:autoDefine
    ].
!

basicInspectIt
    self inspectIt:true
!

browseImplementorsOfIt
    self selectedWorkspacesTextView browseImplementorsOfIt
!

browseIt
    self selectedWorkspacesTextView browseIt
!

browseReferencesToIt
    self selectedWorkspacesTextView browseReferencesToIt
!

clearHistory
    Workspace clearDoItHistory
!

doIt
    self selectedWorkspacesTextView doIt
!

inspectIt
    self inspectIt:false
!

inspectIt:isBasicInspector
    |ws|

    ws := self selectedWorkspacesTextView.
    ws
        do:(ws selection) 
        withValueDo:[:result | 
                        self addInspectorOn:result basic:isBasicInspector suppressPseudoSlots:false
                    ]

"/    self selectedWorkspace inspectIt
!

inspectWorkspaceVariables
    |wsvars|

    wsvars := Workspace workspaceVariables.
    wsvars size == 0 ifTrue:[
        Dialog information:'No Workspace Variables are defined'.
        ^ self
    ].
    wsvars inspect
!

manageSniplets
    |bindings listOfSniplets removeAction pasteAction
     hasSelectionHolder removeEnabledHolder pasteEnabledHolder
     selectedSnipletHolder selectedSnipletsTextHolder selectedSnipletsName
     snipletsDictionary saveEnabledHolder saveAction |

    snipletsDictionary := Workspace sniplets.
    snipletsDictionary isEmptyOrNil ifTrue:[
        Dialog information:(resources string:'No Sniplets to Manage').
        ^ self.
    ].

    listOfSniplets := List withAll:(snipletsDictionary keys asOrderedCollection sort).
    selectedSnipletsTextHolder := '' asValue.

    selectedSnipletHolder := nil asValue.
    selectedSnipletHolder onChangeEvaluate:[
        (selectedSnipletHolder value) isNil ifTrue:[
            selectedSnipletsName := nil.
            selectedSnipletsTextHolder value:''.
        ] ifFalse:[
            selectedSnipletsName := listOfSniplets at:(selectedSnipletHolder value).
            selectedSnipletsTextHolder value:(snipletsDictionary at:selectedSnipletsName).
        ].
    ].

    hasSelectionHolder := BlockValue with:[:m | m value notNil] argument:selectedSnipletHolder.
    removeEnabledHolder := hasSelectionHolder.
    pasteEnabledHolder := hasSelectionHolder.
    saveEnabledHolder := BlockValue with:[:m :textHolder| 
        m value notNil
            and:[(snipletsDictionary at:(listOfSniplets at:(selectedSnipletHolder value))) ~= textHolder value]
    ] argument: selectedSnipletHolder argument: selectedSnipletsTextHolder.

    removeAction := [
        snipletsDictionary removeKey:selectedSnipletsName.
        listOfSniplets remove:selectedSnipletsName.
    ].

    pasteAction := [
        |text|
        text := snipletsDictionary at:selectedSnipletsName.
        self paste:text
    ].
    saveAction := [
        |originalText newText|
        originalText := snipletsDictionary at:selectedSnipletsName.
        newText := selectedSnipletsTextHolder value.
        originalText ~= newText ifTrue:[
            snipletsDictionary at: selectedSnipletsName put: newText.
        ].
        saveEnabledHolder recomputeValue.
    ].

    bindings := IdentityDictionary new.
    bindings at:#listOfSniplets put:listOfSniplets.
    bindings at:#selectedSniplet put:selectedSnipletHolder asValue.
    bindings at:#selectedSnipletsText put:selectedSnipletsTextHolder.
    bindings at:#removeSelectedSniplet put:removeAction.
    bindings at:#pasteSelectedSniplet put:pasteAction.
    bindings at:#saveSelectedSniplet put:saveAction.
    bindings at:#removeEnabled put:removeEnabledHolder.
    bindings at:#pasteEnabled put:pasteEnabledHolder.
    bindings at:#saveEnabled put:saveEnabledHolder.

    self openDialogInterface:#manageSnipletsDialogSpec withBindings:bindings
!

newEvaluationWorkspace
    self class openEvaluationWorkspace

    "Created: / 13-10-2006 / 12:19:47 / cg"
!

newSystemWorkspace
    self class openSystemWorkspace
!

openDocumentation
    "opens the documentation file"

    self openHTMLDocument: 'tools/misc/TOP.html#WORKSPACE'
!

pasteAndExecute:aString
    self paste:aString.
    self printIt
!

pasteSniplet
    |allSniplets snipletToPaste snipletsDictionary|

    snipletsDictionary := Workspace sniplets.
    snipletsDictionary isEmptyOrNil ifTrue:[
        Dialog information:(resources string:'No Sniplets to Paste').
        ^ self.
    ].
    allSniplets := snipletsDictionary keys asOrderedCollection sort.

    snipletToPaste := Dialog 
                choose:(resources string:'Paste Sniplet:')
                fromList:allSniplets
                lines:10.
    snipletToPaste isNil ifTrue:[
        ^ self
    ].
    self paste:(snipletsDictionary at:snipletToPaste) withCRs.

    "Modified: / 29-10-2010 / 10:21:29 / cg"
!

printIt
    self selectedWorkspacesTextView printIt
!

processText
    |template filterBlock newList oldList answer nChanged changedLines flags|

    template :=
'"/ general text processor;
"/ the following block should evaluate to a new line, 
"/ given the original line as argument.
"/ Beginner warning: Smalltalk know-how is useful here.

[:line |
     "/ any processing on line.
     "/ Notice, that line might be a Text object (i.e. non-string),
     "/ 
     "/ Useful operations on the line are:
     "/     - '' .... '' ,                      concatenation of any prefix/suffix
     "/     - leftPaddedTo:size                 padding
     "/     - rightPaddedTo:size                padding
     "/     - copyTo:(size min:N)               
     "/     - asUppercase 
     "/     - asLowercase
     "/     - withoutSeparators                 remove whiteSpace
     "/     - asCollectionOfWords               words

     "/ makes everything bold
     "/
     "/ line allBold

     "/ first word only
     "/
     "/ line withoutSeparators asCollectionOfWords first

     "/ dummy filter (keeps all lines as-is)
     "/
     line
]
'.
    filterBlock := self askForFilterBlock:'Processing block:'
                        template:template
                        rememberIn:#LastProcessingBlockString.
    filterBlock isNil ifTrue:[^ self].

    oldList := self selectedWorkspacesTextView list.
    oldList := oldList collect:[:lineOrNil | lineOrNil ? ''].
    newList := oldList collect:[:line | |newLine|
                newLine := line.
                Error handle:[:ex |
                ] do:[
                    newLine := filterBlock value:line
                ].
                newLine
               ].
    newList := newList collect:[:line | (line isString and:[line size == 0]) ifTrue:[nil] ifFalse:[line]].

    flags := (1 to:oldList size) collect:[:i | (oldList at:i) ~= (newList at:i)].
    flags := flags select:[:flag | flag].
    nChanged := flags size.
    nChanged == 0 ifTrue:[
        self information:'No lines were changed.'.
        ^ self
    ].

    answer := Dialog confirmWithCancel:(resources 
                        string:'%1 lines changed. Change text ?'
                        with:nChanged)
                labels:#( 'Cancel' 'No, Show Changed' 'Yes').
    answer isNil ifTrue:[^ self].
    answer ifFalse:[
        changedLines := (1 to:oldList size) select:[:i | (oldList at:i) ~= (newList at:i)].
        changedLines := changedLines collect:[:i | (newList at:i)].
        TextBox openOn:(changedLines asStringCollection) title:'Changed lines'.
        ^ self.
    ].

    self selectedWorkspacesTextView list:newList.
!

redoLastDoIt
    |s|

    s := self lastDoItsString.
    s notNil ifTrue:[
        self pasteAndExecute:s
    ]
!

removeAllWorkspaceVariables
    (Dialog confirm:(resources string:'Do you really want to remove all Workspace Variables ?'))
    ifTrue:[
        Workspace removeAllWorkspaceVariables
   ].
!

removeGlobalVariable
    |name nameKey selection value|

    selection := self selectedWorkspacesTextView selection ? ''.

    name := Dialog 
                request:'Remove Global Variable:'
                initialAnswer:(selection asString string)
                okLabel:'Remove'
                title:'Remove Global'.

    name size == 0 ifTrue:[^ self].
    nameKey := name asSymbolIfInterned.
    nameKey isNil ifTrue:[^ self].

    (Smalltalk includesKey:nameKey) ifFalse:[
        self warn:('No such Global Binding: ''%1''.' bindWith:name).
        ^ self.
    ].

    value := Smalltalk at:nameKey.
    value notNil ifTrue:[
        (self confirm:('Global ''%1'' is currently bound to %2\\Remove Binding ?' bindWith:name with:value) withCRs)
        ifFalse:[
            ^ self.
        ].
    ].
    Smalltalk at:nameKey put:nil.
    Smalltalk removeKey:nameKey
!

removeSharedPool
    |poolToRemove|

    poolsConsideredInDoIts isEmptyOrNil ifTrue:[
        Dialog information:'No pools have been added yet'.
        ^ self.
    ].

    poolToRemove := Dialog 
                choose:'Pool to Remove (No longer known in doIt-Evaluations):'
                fromList:(poolsConsideredInDoIts asOrderedCollection sort)
                lines:10.

    poolToRemove isNil ifTrue:[
        ^ self
    ].
    poolsConsideredInDoIts remove:poolToRemove.
    workspaces do:[:ws |
        ws poolsConsideredInDoits:poolsConsideredInDoIts.
    ].

    "Modified: / 24-11-2006 / 12:44:16 / cg"
!

removeWorkspaceVariable
    |name selection wsVarNames|

    wsVarNames := Workspace workspaceVariableNames.
    wsVarNames isEmpty ifTrue:[
        Dialog information:'No Workspace Variables are defined'.
        ^ self
    ].

    selection := self selectedWorkspacesTextView selection ? ''.

    name := Dialog 
                request:'Variable to remove:'
                initialAnswer:(selection asString string)
                okLabel:'Remove'
                title:'Enter Variable Name'
                list:(wsVarNames asOrderedCollection sort).      
    name isEmptyOrNil ifTrue:[
        ^ self
    ].
    Workspace removeWorkspaceVariable:name.

    "Modified: / 20-04-2005 / 11:56:28 / cg"
!

setCompilerForSyntax
    self setCompilerForSyntaxIn:self selectedWorkspace.

    "Modified: / 08-02-2011 / 21:39:51 / cg"
!

setCompilerForSyntaxIn:aWorkspace
    |language|

    language := self syntaxHolder value.
    language isSymbol ifTrue:[
        language := ProgrammingLanguage named:language  
    ].
    aWorkspace compilerClass:(language compilerClass "self compilerClassForSyntaxName:syntax").
    self smalltalkMenuEnabledHolder value:(language isSmalltalk).
    LastLanguage := language.

    "Created: / 08-02-2011 / 21:32:39 / cg"
!

spyOnIt
    self selectedWorkspacesTextView spyOnIt
!

timeIt
    self selectedWorkspacesTextView timeIt
! !

!WorkspaceApplication methodsFor:'menu-actions-adding'!

addClassVariableInspector
    |v|

    ClassVariablesInspectorView isNil ifTrue:[
        self error:'Missing class: "ClassVariablesInspectorView"'.
        ^ self.
    ].
    v := self addInspectorOn:Smalltalk inspectorClass:ClassVariablesInspectorView suppressPseudoSlots:true.

    v fieldListLabel:'Name'.
    self renameWorkspace:(self selectedWorkspaceIndexHolder value) to:'Class Variables'.

    "Modified: / 22-10-2006 / 11:28:14 / cg"
!

addEvaluationWorkspace
    ^ self addWindow:(self createEvaluationWorkspace) named:'Eval%1'

    "Modified: / 13-10-2006 / 12:16:35 / cg"
!

addGlobalVariable
    |name nameKey selection|

    selection := self selectedWorkspacesTextView selection ? ''.

    name := Dialog 
                request:'Name of new Global Variable:'
                initialAnswer:(selection asString string)
                okLabel:'Add'
                title:'Enter Variable Name'.
    name size == 0 ifTrue:[
        ^ self
    ].
    nameKey := name asSymbol.

    (Smalltalk includesKey:nameKey) ifTrue:[
        self warn:'Global named ''' , name , ''' already exists.'.
        ^ self.
    ].
    Smalltalk at:nameKey put:nil.
!

addGlobalVariableInspector
    ^ self addNamespaceInspectorFor:Smalltalk

    "Modified: / 29-05-2007 / 19:08:58 / cg"
!

addInspectorOn:aValue basic:isBasicInspector suppressPseudoSlots:suppressPseudoSlots
    |inspectorClass|

    isBasicInspector ifFalse:[
        inspectorClass := aValue inspectorClass.
    ].
    inspectorClass isNil ifTrue:[
        inspectorClass := InspectorView
    ].

    ^ self
        addInspectorOn:aValue 
        inspectorClass:inspectorClass 
        suppressPseudoSlots:suppressPseudoSlots
!

addInspectorOn:aValue inspectorClass:inspectorClass suppressPseudoSlots:suppressPseudoSlots
    |view resultString|

    view := inspectorClass new.
    view suppressPseudoSlots:suppressPseudoSlots.
    view inspect:aValue.
    "/ v allowFollow:true.
    aValue isBehavior ifTrue:[
        resultString := aValue name
    ] ifFalse:[
        resultString := aValue classNameWithArticle
    ].
    self addWindow:view named:('Inspecting: ' , resultString).
    ^ view
!

addMyWorkspace
    |pane f|

    self addWindow:(pane := HVScrollableView for:Workspace) named:'My Workspace' asFirst:false.
    'MyWorkspace.wsp' asFilename exists ifTrue:[
        self loadFile:'MyWorkspace.wsp' label:'My Workspace'.
    ] ifFalse:[
        (f := Filename homeDirectory construct:'MyWorkspace.wsp') exists ifTrue:[
            self loadFile:f label:'My Workspace'.
        ] ifFalse:[
            pane defaultFileNameForFileDialog:'MyWorkspace.wsp'.
        ].
    ].

    "Modified: / 15-03-2007 / 11:54:17 / cg"
!

addNamespaceInspector
    |ns|

    ns := Dialog requestNameSpace:'Namespace' initialAnswer:nil.
    ns isEmptyOrNil ifTrue:[^ self].
    ^ self addNamespaceInspectorFor:(Smalltalk at:ns asSymbol)

    "Created: / 29-05-2007 / 19:10:50 / cg"
!

addNamespaceInspectorFor:aNameSpaceOrSharedPool
    |v label|

    SmalltalkInspectorView isNil ifTrue:[
        self error:'Missing class: "SmalltalkInspectorView"'.
        ^ nil.
    ].

    v := self 
            addInspectorOn:aNameSpaceOrSharedPool 
            inspectorClass:SmalltalkInspectorView 
            suppressPseudoSlots:true.

    v fieldListLabel:'Name'.
    aNameSpaceOrSharedPool == Smalltalk ifTrue:[
        label := 'Smalltalk (Globals)'
    ] ifFalse:[
        aNameSpaceOrSharedPool isSharedPool ifTrue:[
            label := aNameSpaceOrSharedPool name,' (SharedPool)'
        ] ifFalse:[
            label := aNameSpaceOrSharedPool name,' (Namespace)'
        ].
    ].

    self 
        renameWorkspace:(self selectedWorkspaceIndexHolder value) 
        to:label.
    ^ v

    "Created: / 29-05-2007 / 19:08:45 / cg"
!

addSelectionToSniplets
    |selection snipletsBaseName snipletsName nr snipletsDictionary|

    selection := (self selectedWorkspacesTextView selection ? '') asString.
    selection isEmpty ifTrue:[
        Dialog information:(resources string:'Nothing Selected').
        ^ self
    ].

    snipletsBaseName := Dialog request:(resources string:'Name of Sniplet:').
    snipletsBaseName isNil ifTrue:[
        ^ self
    ].
    snipletsBaseName isEmpty ifTrue:[
        snipletsBaseName := Time now asString.
    ].
    snipletsDictionary := Workspace sniplets.

    snipletsName := snipletsBaseName.
    (snipletsDictionary includesKey:snipletsName) ifTrue:[
        (Dialog confirm:(resources string:'Replace existing sniplet named "%1" ?' with:snipletsName))
        ifFalse:[
            [snipletsDictionary includesKey:snipletsName] whileTrue:[
                nr := (nr ? 1) + 1.
                snipletsName := (snipletsBaseName,'(%1)') bindWith:nr
            ].
        ]
    ].
    snipletsDictionary at:snipletsName put:selection

    "Modified: / 24-11-2006 / 12:44:16 / cg"
!

addSharedPool
    |allPools poolToAdd|

    allPools := SharedPool allSubclasses collect:[:p | p name].
    allPools removeAll:(poolsConsideredInDoIts ? #()).
    allPools sort.

    poolToAdd := Dialog 
                choose:'Select a SharedPool to Add (To be known in doIt-Evaluations):'
                fromList:allPools
                lines:15.
    poolToAdd isNil ifTrue:[
        ^ self
    ].
    poolsConsideredInDoIts isNil ifTrue:[
        poolsConsideredInDoIts := (Set new).
    ].
    poolsConsideredInDoIts add:poolToAdd.
    workspaces do:[:ws |
        ws poolsConsideredInDoIts:poolsConsideredInDoIts.
    ].

    "Modified: / 24-11-2006 / 12:44:16 / cg"
!

addSharedPoolInspector
    |pool|

    pool := Dialog requestSharedPool:'SharedPool' title:nil initialAnswer:nil.
    pool isEmptyOrNil ifTrue:[^ self].
    ^ self addNamespaceInspectorFor:(Smalltalk at:pool asSymbol)

    "Created: / 29-05-2007 / 19:10:50 / cg"
!

addStopWatch
    |v clock|

    v := View new.
    v viewBackground:Color white.
    clock := ClockView in:v.
    clock beStopWatch.

    clock 
        origin:[ 
            |ext|

            ext := (v height) min:(v width).
            (v extent - ext) // 2
        ]
        extent:[        
            |ext|

            ext := (v height) min:(v width).
            ext @ ext
        ].

    self addWindow:v named:'StopWatch%1'.
!

addTeaTimer
    |l dt tEnd dur answer confirmed confirmButton|

    dt := LastTeaWaitTime ? (3*60).
    answer := Dialog 
                request:'Delta-Time (seconds), Duration (n s/m/h) or End-Time (hh:mm:ss):' 
                initialAnswer:(TimeDuration seconds:dt) printString.
    answer isEmptyOrNil ifTrue:[^ self].

    "/ allow 3 formats:
    "/  hh:mm:ss       -> endTime
    "/  nnn s          -> x seconds
    "/  nnn m          -> x minutes
    "/  nnn h          -> x hours
    "/  nnn            -> seconds

    tEnd := Time readFromString:answer onError:nil.
    tEnd isNil ifTrue:[
        dur := TimeDuration readFromString:answer onError:nil.
        dur isNil ifTrue:[
            dt := Number readFromString:answer onError:[^ self].
            LastTeaWaitTime := dt.
            tEnd := Timestamp now addSeconds:dt.
        ] ifFalse:[
            dt := dur asSeconds.
            tEnd := Timestamp now + dur.
        ].                
    ] ifFalse:[
        tEnd < Time now ifTrue:[
            (Dialog confirm:'Tomorrow ?') ifFalse:[^ self].
            tEnd := tEnd asTimestamp addDays:1.
            dt := tEnd - Timestamp now.
        ] ifFalse:[
            dt := tEnd - Time now.
            tEnd := tEnd asTimestamp.
        ].
    ].

    l := Label new.
    l sizeFixed:true.
    l label:'Waiting... [',(TimeDuration seconds:dt) printString,']'.
    l viewBackground:Color red.
    confirmButton := (Button label:'OK') action:[ confirmed := true. confirmButton beInvisible. ].
    confirmButton beInvisible.
    l add:confirmButton.
    self addWindow:l named:'TeaTimer%1'.

    [
        Error handle:[ self halt.
            #intentionallyLeftBlank
        ] do:[
            |remaining wg|

            confirmed := false.
            [AbsoluteTime now < tEnd ] whileTrue:[
                remaining := tEnd - AbsoluteTime now.
                l label:'Waiting... [',(TimeDuration seconds:remaining) printString,']'.
                Delay waitForSeconds:1.
            ].

            l label:'TEA is ready !!'.
            "/ could have been removed in the meantime....
            (wg := confirmButton windowGroup) notNil ifTrue:[
                confirmButton beVisible.
                wg repairDamage.

                [ confirmed ] whileFalse:[
                    3 timesRepeat:[ l beep. Delay waitForSeconds:0.4 ].
                    Delay waitForSeconds:5.
                ].

                l viewBackground:Color green.
                l topView raiseDeiconified.
            ].
        ]
    ] fork.

    "Modified: / 16-11-2010 / 14:54:05 / cg"
!

addWorkspaceVariable
    |name selectedWorkspacesTextView selection|

    selectedWorkspacesTextView := self selectedWorkspacesTextView.
    selectedWorkspacesTextView notNil ifTrue:[
        selection := selectedWorkspacesTextView selection.
    ].

    name := Dialog 
                request:'Name of new Workspace Variable:'
                initialAnswer:(selection ? '') asString string
                okLabel:'Add'
                title:'Enter Variable Name'.
    name size == 0 ifTrue:[
        ^ self
    ].
    Workspace addWorkspaceVariable:name.

    "Modified: / 24-11-2006 / 12:44:16 / cg"
!

addWorkspaceVariableInspector
    |v|

    v := self addInspectorOn:(Workspace workspaceVariables) basic:false suppressPseudoSlots:true.
    v dereferenceValueHolders:true.
    v fieldListLabel:'Name'.
    self renameWorkspace:(self selectedWorkspaceIndexHolder value) to:'Workspace Variables'.
! !

!WorkspaceApplication methodsFor:'menu-actions-editing'!

babelFishTranslate:fromToModeString
    "translate the selected text and paste it after the selection"

    SOAP::BabelFishClient isNil ifTrue:[
        Dialog information:'Sorry the SOAP-BabelFish translation-client is not available'.
        ^ self.
    ].
    self selectedWorkspace babelFishTranslate:fromToModeString

    "Modified: / 01-12-2010 / 12:24:34 / cg"
!

changesBrowserOnText
    ChangeSetBrowser
        openOn:(ChangeSet fromStream:self selectedWorkspacesTextView contentsAsString readStream)

    "Created: / 27-08-2007 / 10:57:30 / cg"
!

editModeInsert
    self selectedWorkspace editModeInsert

    "Created: / 22-01-2011 / 11:51:12 / cg"
!

editModeInsertAndSelect
    self selectedWorkspace editModeInsertAndSelect

    "Created: / 22-01-2011 / 11:52:52 / cg"
!

editModeOverwrite
    self selectedWorkspace editModeOverwrite

    "Created: / 22-01-2011 / 11:52:15 / cg"
!

fileInText
    self selectedWorkspacesTextView contentsAsString readStream fileIn
!

filterText
    |template filterBlock newList oldList answer nDeleted deletedLines|

    template :=
'"/ general text filter;
"/ the following block should evaluate to true for all lines
"/ you want to keep - lines for which the block returns false will be removed.
"/ Beginner warning: Smalltalk know-how is useful here.

[:line |
     "/ any condition on line.
     "/ Notice, that line might be a Text object (i.e. non-string),
     "/ so you may want to use line string.
     "/ 
     "/ Useful queries on the line are:
     "/     - size                   the length of the line
     "/     - hasChangeOfEmphasis    any bold, italic etc.
     "/     - startsWith:someString
     "/     - endsWith:someString

     "/ example filter (removes all empty lines)
     "/
     "/ line size > 0

     "/ example filter (removes all lines which do not end with some suffix)
     "/
     "/ (line asLowercase endsWith:''foo'') not

     "/ dummy filter (keeps all lines)
     "/
     true
]
'.

    filterBlock := self askForFilterBlock:'Filter block:'
                        template:template
                        rememberIn:#LastFilterBlockString.
    filterBlock isNil ifTrue:[^ self].

    oldList := self selectedWorkspacesTextView list.
    oldList := oldList collect:[:lineOrNil | lineOrNil ? ''].
    newList := oldList select:filterBlock.
    newList := newList collect:[:line | (line isString and:[line size == 0]) ifTrue:[nil] ifFalse:[line]].
    nDeleted := oldList size - newList size.
    nDeleted == 0 ifTrue:[
        self information:'No lines were deleted.'.
        ^ self
    ].

    answer := Dialog confirmWithCancel:(resources 
                        string:'%1 lines remain (%2 deleted). Change text ?'
                        with:newList size
                        with:nDeleted)
                labels:#( 'Cancel' 'No, Show Deleted' 'Yes').
    answer isNil ifTrue:[^ self].
    answer ifFalse:[
        deletedLines := oldList reject:filterBlock.
        TextBox openOn:(deletedLines asStringCollection) title:'Filtered lines'.
        ^ self.
    ].

    self selectedWorkspacesTextView list:newList.
!

googleSpellingSuggestion
    self selectedWorkspacesTextView googleSpellingSuggestion
!

indent
    |macro|

    macro := (UserPreferences current functionKeySequences at:#IndentBy4).
    self selectedWorkspacesTextView
        undoableDo:[ self selectedWorkspacesTextView executeKeyboardMacro:macro ]
        info:'Indent'.
!

pasteLastDoIt
    |s|

    s := self lastDoItsString.
    s notNil ifTrue:[
        self paste:s
    ]
!

undent
    |macro|

    macro := (UserPreferences current functionKeySequences at:#UndentBy4).
    self selectedWorkspacesTextView
        undoableDo:[ self selectedWorkspacesTextView executeKeyboardMacro:macro ]
        info:'Undent'.
! !

!WorkspaceApplication methodsFor:'menu-dynamic'!

editModeInfoLabelMenu
    ^ self class editModeInfoLabelMenu

    "Created: / 22-01-2011 / 11:50:35 / cg"
!

languageListMenuSlice
    |m allLanguages|

    allLanguages := OrderedCollection new.
    ProgrammingLanguage allDo:[:eachLanguage | 
        eachLanguage isSmalltalk ifFalse:[
            allLanguages add:eachLanguage
        ]
    ].
    allLanguages sort:[:a :b | a name < b name].

    m := Menu new.
    m addItem:(MenuItem 
                label:'Smalltalk' 
                choice:#syntaxHolder
                choiceValue:SmalltalkLanguage instance).

    allLanguages notEmpty ifTrue:[
        m addItem:(MenuItem separator).

        allLanguages do:[:eachLanguage |
            m addItem:(MenuItem 
                        label:(eachLanguage name) 
                        choice:#syntaxHolder
                        choiceValue:eachLanguage).
        ].
    ].
    ^ m
!

makeRecentDoItsMenuFor:aSelector
    |doIts m cmdLabelLen|

    cmdLabelLen := 40.

    doIts := Workspace doItHistory.
    doIts size > 0 ifTrue:[
        m := Menu new.
        doIts do:[:doItEntry |
            |lines label item|

            lines := doItEntry withoutLeadingSeparators asStringCollection.
            label := lines first.
            (label size > cmdLabelLen) ifTrue:[
                label := (label contractTo:cmdLabelLen)
            ]. 
            (lines size > 1) ifTrue:[
                label := label , ' [...]'
            ].
            label := '''' , label , ''''.

            item := MenuItem label:label.
            m addItem:item.
            item value:aSelector.
            item argument:doItEntry.
        ].
        m addItem: (MenuItem separator).
        m addItem: (MenuItem new 
                    label: (resources string:'Clear History'); 
                    value: #clearHistory; 
                    activeHelpKey: #historyEmptyMenu;
                    translateLabel:true).
   ].
   ^ m
!

pasteRecentDoItMenu
    <resource: #programMenu >

    ^ self recentDoItsMenuFor:#'paste:'
!

recentDoItsMenuFor:aSelector
    <resource: #programMenu >

    ^ [
        self makeRecentDoItsMenuFor:aSelector
    ].
!

redoRecentDoItMenu
    <resource: #programMenu >

    ^ self recentDoItsMenuFor:#'pasteAndExecute:'
! !

!WorkspaceApplication methodsFor:'private'!

askIfAnyModified:question yesButton:yesButtonText
    (workspaces contains:[:aView | self isModifiedWorkspace:aView]) ifFalse:[^ true].

    (Dialog 
        confirm:(resources stringWithCRs:question)
        yesLabel:(resources string:yesButtonText)
        noLabel:(resources string:'Cancel'))
    ifTrue:[
        "/ reset modified flag so question is asked only once
        workspaces 
            select:[:aView | (self isModifiedWorkspace:aView)]
            thenDo:[:eachModifiedTextView |
                        eachModifiedTextView 
                                perform:#modified: with:false
                                ifNotUnderstood:[].
                    ].
        ^ true
    ].
    ^ false
!

compilerClassForSyntaxName:syntax
    syntax == #Smalltalk ifTrue:[
        ^ Compiler
    ].
    syntax == #JavaScript ifTrue:[
        ^ JavaScriptCompiler
    ].
    ^ Compiler
!

createEvaluationWorkspace
    |ws l b box resultView environmentView panel workspaceVariables timeLabel|

    workspaceVariables := Workspace workspaceVariables.

    panel := VariableVerticalPanel new.
    panel showHandle:true.

      box := View new.
      l := Label new.
      l label:(resources string:'Eval:').
      l layout:((0.0@0.0 corner:0.5@0.0) asLayout bottomOffset:22).
      l adjust:#left.
      box add:l.

      ws := HVScrollableView for:Workspace.
      ws scrolledView name:#'Workspace'.  
      ws autoDefineVariables:#workspace.
      ws layout:((0.0@0.0 corner:1.0@1.0) asLayout topOffset:22; bottomOffset:-22).
      box add:ws.

      b := Button new.
      b label:'DoIt'.
      b layout:((0.25@1.0 corner:0.5@1.0) asLayout topOffset:-22).
      b adjust:#left.
      b action:[ws doIt].
      box add:b.

      b := Button new.
      b label:'InspectIt'.
      b layout:((0.5@1.0 corner:0.75@1.0) asLayout topOffset:-22).
      b adjust:#left.
      b action:[ws inspectIt].
      box add:b.

      b := Button new.
      b label:'BrowseIt'.
      b layout:((0.75@1.0 corner:1.0@1.0) asLayout topOffset:-22).
      b adjust:#left.
      b action:[ws browseIt].
      box add:b.

    panel add:box.

      box := View new.
      box add:(Label new label:(resources string:'Value:'); adjust:#left; layout:((0.0@0.0 corner:0.5@0.0) asLayout bottomOffset:22)).
      box add:(timeLabel := Label new label:''; adjust:#right; layout:((0.5@0.0 corner:1.0@0.0) asLayout bottomOffset:22)).
      resultView := HVScrollableView for:TextCollector.
      box add:(resultView layout:((0@0 corner:1.0@1.0) asLayout topOffset:22); yourself).

    panel add:box.

      box := View new.
      box add:(Label new label:(resources string:'Environment:'); adjust:#left; layout:((0.0@0.0 corner:1.0@0.0) asLayout bottomOffset:22)).
      environmentView := DictionaryInspectorView new.
      environmentView suppressPseudoSlots:true.
      environmentView inspect:workspaceVariables.
      environmentView dereferenceValueHolders:true.
      environmentView fieldListLabel:'Variable'.
      box add:(environmentView layout:((0@0 corner:1.0@1.0) asLayout topOffset:22); yourself).

    panel add:box.

"/     self renameWorkspace:(self selectedWorkspaceIndexHolder value) to:'Eval'.

    ws doItAction:[:theCode |
        |t result resultString|

        t := TimeDuration toRun:[
            result := ws executeDoIt:theCode.
        ].
        timeLabel label:(resources string:'Exec. Time: %1' with:t printString).

        resultString := [
                            result storeString
                        ] on:Error do:[
                            result printString
                        ].  
                        
        resultView showCR:resultString.
        9 to:1 by:-1 do:[:h|
            (workspaceVariables includesKey:('_%1' bindWith:h-1)) ifTrue:[
                workspaceVariables 
                        at:('_%1' bindWith:h)
                        put:(workspaceVariables at:('_%1' bindWith:h-1)).
            ].
        ].
        workspaceVariables at:'_0' put:(ValueHolder with:result).
        environmentView doUpdate.
        result.
    ].
    panel relativeCorners:#(0.4 0.6 1.0).
    ^ panel

    "Modified: / 24-11-2006 / 11:06:33 / cg"
!

createWorkspace
    |ws|

    ws := (HVScrollableView for:Workspace).
    ws autoDefineVariables:autoDefineVariables.
    ws poolsConsideredInDoIts:poolsConsideredInDoIts.

    self setCompilerForSyntaxIn:ws.
    ^ ws

    "Modified: / 08-02-2011 / 21:34:22 / cg"
!

isModifiedWorkspace:aView
    |view|

    view := self workspaceViewOfView:aView.

    (view isNil
    or:[view modified not 
    or:[view contentsWasSaved
    or:[view contents withoutSeparators isEmpty]]]) ifTrue:[
        ^ false
    ].
    ^ true
!

lastDoItsString
    |history|

    history := Workspace doItHistory.
    history size > 0 ifFalse:[
        self selectedWorkspacesTextView flash.
        ^ nil
    ].
    ^ history first
!

syntaxNameForCompilerClass:aClass
    aClass == Compiler ifTrue:[
        ^ #Smalltalk
    ].
    aClass == JavaScriptCompiler ifTrue:[
        ^ #JavaScript
    ].
    ^ #Smalltalk
!

workspaceSelectionChanged
    "attach line, col and mode holders to the current workspace window"

    |compilerClass selectedWorkspace|

    super workspaceSelectionChanged.

    selectedWorkspace := self selectedWorkspace.
    (selectedWorkspace notNil and:[selectedWorkspace isScrollWrapper]) ifTrue:[  
        selectedWorkspace := selectedWorkspace scrolledView
    ].

    compilerClass := (selectedWorkspace isKindOf:Workspace) not
                        ifTrue:[Compiler] 
                        ifFalse:[selectedWorkspace compilerClass].

    self syntaxHolder setValue:(self syntaxNameForCompilerClass:compilerClass).

    (selectedWorkspace notNil and:[ selectedWorkspace scrolledView isTextView ]) ifTrue:[
        self cursorLineHolder valueHolder:( selectedWorkspace perform:#cursorLineHolder ifNotUnderstood:nil ).
        self cursorColHolder valueHolder:( selectedWorkspace perform:#cursorColHolder ifNotUnderstood:nil ).
        self modeLabelHolder valueHolder:( selectedWorkspace perform:#modeLabelHolder ifNotUnderstood:nil ).
    ] ifFalse:[
        self cursorLineHolder valueHolder:nil.
        self cursorColHolder valueHolder:nil.
        self modeLabelHolder valueHolder:nil.
    ].

    "Modified: / 08-02-2011 / 21:45:29 / cg"
! !

!WorkspaceApplication methodsFor:'user actions'!

infoVisibilityChanged
    super infoVisibilityChanged.
    UserPreferences current infoVisibleInWorkspace:(self infoVisibleHolder value)

    "Created: / 14-07-2007 / 16:46:58 / cg"
!

toolBarVisibilityChanged
    super toolBarVisibilityChanged.
    UserPreferences current toolbarVisibleInWorkspace:(self toolBarVisibleHolder value).
    UserPreferences current editToolbarVisibleInWorkspace:(self editToolBarVisibleHolder value).

    "Created: / 14-07-2007 / 16:45:31 / cg"
! !

!WorkspaceApplication class methodsFor:'documentation'!

version
    ^ '$Header: /cvs/stx/stx/libtool/WorkspaceApplication.st,v 1.202 2011-02-08 20:45:56 cg Exp $'
!

version_CVS
    ^ '$Header: /cvs/stx/stx/libtool/WorkspaceApplication.st,v 1.202 2011-02-08 20:45:56 cg Exp $'
! !