FileBrowserV2.st
author Claus Gittinger <cg@exept.de>
Tue, 31 May 2005 12:07:27 +0200
changeset 6307 8e5863ecd881
parent 6241 9cc17d183247
child 6334 89e055168f51
permissions -rw-r--r--
*** empty log message ***

"
 COPYRIGHT (c) 2002 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' }"

AbstractFileBrowser subclass:#FileBrowserV2
	instanceVariableNames:'fileEntryFieldHolder pathEntryField previewProcess
		listOfDeviceDrives selectedDeviceDrive imgView'
	classVariableNames:''
	poolDictionaries:''
	category:'Interface-Tools-File'
!

!FileBrowserV2 class methodsFor:'documentation'!

copyright
"
 COPYRIGHT (c) 2002 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
"
    FileBrowserV2 is based on Filebrowser

    WARNING: files edited with FileBrowser will have leading spaces (multiple-8)
             being replaced by tabs. If tabs are to be preserved at other
             positions (for example, sendmail-config files) they will be
             corrupt after being written.

    [instance variables]:

        checkDelta      <Integer>       number of seconds of check interval
                                        (looks ever so often if shown directory
                                         has changed). You may make this number
                                        higher, if your network-times are
                                        incorrect and thus, the filebrowser
                                        checks too often.

        compressTabs    <Boolean>       if true, leading spaces will be
                                        replaced by tabs when saving text

    some of the defaults (long/short list etc.) can be set by the resource file;
    see FileBrowser>>initialize for more details..

    [author:]
        Christian Penk

    [start with:]
        FileBrowserV2 open
"
!

toDo

"
    - the tab for the directory description text editor not changed if the 
      directory description change to a normal text editor
    - FileDialog should get a file history
    - change comment characters on change text file in TextEditor
    - directorycontentsItem isDirectory failed if it is a symbolic link
    - on sort order change in directory contents browser the columnspec shouldnt not reloaded
    - in windows directory up on top of a volume goes to default directory
    - check all windowspecs with different font types
    - multiple select with mouse moving is flickering (see bestFilename in FilenameEditField)
    - too many system calls on update cycle
    - stop monitoring task for DirectoryTreebrowser and DirectoryContentsBrowser
"
! !

!FileBrowserV2 class methodsFor:'instance creation'!

on:aDirectoryPath
    "return a new FileBrowserV2 in a pathname"

    |instance files|
    instance := self new createBuilder.
    aDirectoryPath isCollection ifTrue:[
        files := aDirectoryPath
    ] ifFalse:[
        files := Array with:aDirectoryPath.
    ].
    instance currentFileNameHolder value:files.
    ^ instance
!

open
    "start a new FileBrowserV2"

    | instance |
    instance := self new.
    instance open.
    ^ instance

    "
     FileBrowserV2 openOn:(OrderedCollection with:(Filename currentDirectory asAbsoluteFilename)) withExtent:800@600
    "
!

openOn:aDirectoryPath 
    "start a new FileBrowserV2 in a pathname"

    | instance|
    instance := self on:aDirectoryPath asFilename.
    instance open.
    ^ instance.
    
    "
     FileBrowserV2 openOn:(OrderedCollection with:(Filename currentDirectory asAbsoluteFilename))
    "
!

openOn:aDirectoryPath withExtent:extent
    "start a new FileBrowserV2 in a pathname"

    | instance builder|
    instance := self on:aDirectoryPath.
    builder := instance open.
    builder window extent:extent.
    ^ instance

    "
     FileBrowserV2 openOn:(OrderedCollection with:(Filename currentDirectory asAbsoluteFilename)) withExtent:800@600
    "
!

openOnFileNamed:aFilename
    "start a new FileBrowserV2 on a aFilename.
     The browser looks for an appropriate viewer and uses that if one is found;
     otherwise, the file is opened for text editing."

    ^ self openOnFileNamed:aFilename editing:true

    "
     FileBrowserV2 openOnFileNamed:'Makefile'
    "
!

openOnFileNamed:aFilename editing:editing
    "start a new FileBrowserV2 on a aFilename;
     If editing is true, the browser opens the document as text to be edited;
     if false, it looks for an appropriate viewer and uses that if one is found."

    |f browser|

    f := aFilename asFilename asAbsoluteFilename.
    f isDirectory ifTrue:[
        ^ self openOn:aFilename
    ].

    browser := self on:(f directory).
    browser currentFileNameHolder setValue:(Array with:f).
    browser open.
    editing ifTrue:[
        browser openTextEditorForFile:f.
    ] ifFalse:[
        browser openApplForFile:f.
    ].

    "
     FileBrowserV2 openOnFileNamed:'Makefile'
    "
!

openWithAspects:someAspects withExtent:extent
    "start a new FileBrowserV2 in a pathname"

    |dir clone|

    dir := someAspects at:#currentFileNameHolder ifAbsent:nil.
    clone := self openOn:(dir value) withExtent:extent.
! !

!FileBrowserV2 class methodsFor:'class initialization'!

applicationIcon
    ^ NewLauncher startNewFileBrowserIcon
!

initialize
    "/ self installInLauncher.            - now done in phase 2
    ObjectMemory addDependent:self.
!

installInLauncher
    "add myself to the launcher menu and toolBar"

    |menuItem icon action currentLauncher|

    FileBrowserV2 isNil ifTrue:[^ self].

    action := [FileBrowserV2 open].

    icon := [self applicationIcon]. "/ self defaultIcon magnifiedTo:28@28.

    menuItem := MenuItem new 
                    translateLabel: true;
                    value: action;
                    isButton: false;
                    label:'File Browser' icon:icon;
                    nameKey: #fileBrowserV2;
                    activeHelpKey: #fileBrowserV2;
                    submenuChannel: #menuFileHistory;
                    showBusyCursorWhilePerforming:true.

    NewLauncher 
        addMenuItem:menuItem 
        from:self
        in:'menu.file' 
        position:#( #before #fileBrowser) 
        space:true.

    menuItem := MenuItem new 
                    translateLabel: true;
                    value: action;
                    isButton: true;
                    "label:'File Browser'" icon:icon;
                    nameKey: #fileBrowserV2;
                    activeHelpKey: #fileBrowserV2;
                    submenuChannel: #menuFileHistory;
                    showBusyCursorWhilePerforming:true.

    NewLauncher 
        addMenuItem:menuItem 
        from:self
        in:'toolbar' 
        position:#( #before #fileBrowser) 
        space:false.

    currentLauncher := NewLauncher current.
    currentLauncher notNil ifTrue:[
        currentLauncher fileBrowserItemVisible value:false
    ].
    NewLauncher addSettingsApplicationByClass:#'FileBrowserV2SettingsAppl' 
                withName:'Tools/FileBrowserV2' 
                icon:nil.

    "
     self installInLauncher
     self removeFromLauncher
    "
!

removeFromLauncher
    "/
    "/ remove myself from the launcher menu
    "/

    |currentLauncher|

    NewLauncher isNil ifTrue:[^ self].
    NewLauncher removeUserTool:#fileBrowserV2.
    currentLauncher := NewLauncher current.
    currentLauncher notNil ifTrue:[
        currentLauncher fileBrowserItemVisible value:false
    ].
    NewLauncher removeSettingsApplicationByClass:#'FileBrowserV2SettingsAppl'.

    "
     self removeFromLauncher
    "
!

update:something with:aParameter from:changedObject
    something == #initialized ifTrue:[
        changedObject == ObjectMemory ifTrue:[
            self installInLauncher.
            ObjectMemory removeDependent:self.
        ]
    ].
! !

!FileBrowserV2 class methodsFor:'defaults'!

entryFieldEndStringForMultipleSelection

    ^ ('[*]')
! !

!FileBrowserV2 class methodsFor:'help specs'!

helpSpec
    "This resource specification was automatically generated
     by the UIHelpTool of ST/X."

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

    "
     UIHelpTool openOnClass:FileBrowserV2    
    "

    <resource: #help>

    ^ super helpSpec addPairsFrom:#(

#editFile
''

#fileIn
''

#searchFile
''

#toggleDetails
''

)
! !

!FileBrowserV2 class methodsFor:'icon'!

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

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

    "
     self defaultIcon inspect
     ImageEditor openOnClass:self andSelector:#defaultIcon
    "

    <resource: #image>

    ^Icon
        constantNamed:#'FileBrowserV2 class defaultIcon'
        ifAbsentPut:[(Depth4Image new) width: 28; height: 28; photometric:(#palette); bitsPerSample:(#(4 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'
@@@@@@@@@@@@@@@@@@@@CLA&Y&Y&Y&X@@ADP@@@L0F@@@@@@A @ADAD@@@3@XN;.;.8F@ADPDQ@@CLA ;.@@@@@@D@@@D@@L0FC.8O[6=/@QDADP@@3@X@; 
[6=/[0DPDP@@CLA DNC6<@@F<ADP@@@L0F@A@F= [0= @@@@@@3@X@@P=/[6=/@@@@@@CLA @@A/[6=/X@@@@@@L0FC0@O[6=/[0@@@@@@3@XF<@@@@@@@@@
@@@@CLA = @@@@@@@@@@@@@L0FA/[6=/A @@@@@@@@3@XO[6=/XF@@@@@@@@CLA @@@@@@X@@@@@@@@L0FY&Y&Y&Y @@@@@@@@C@Y&Y&Y&Y&@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@N@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@C @b') ; colorMapFromArray:#[0 0 0 255 255 255 255 0 0 0 255 0 0 0 255 0 255 255 255 255 0 255 0 255 127 0 0 0 127 0 0 0 127 0 127 127 127 127 0 127 0 127 127 127 127 170 170 170]; mask:((Depth1Image new) width: 28; height: 28; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'
O??# C??9<@??>? O???<C????@????0O???8C???<@???>@O??<@C???@@???0@O??<@C??8@@??>@@O?? @C??8@@??>@@G?? @@??8@@@@@@@G.P=0AAD
HP@PQBD@GDP8 AADHD@PQBA@DN^=0@@a') ; yourself); yourself]
!

hideFilenameEntryFieldIcon
    <resource: #programImage>

    ^ ToolbarIconLibrary hideToolbarIconH14
!

hideToolBarIcon
    <resource: #programImage>

    ^ ToolbarIconLibrary hideToolbarIconH26
! !

!FileBrowserV2 class methodsFor:'interface specs'!

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

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

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

    <resource: #canvas>

    ^ 
     #(FullSpec
        name: windowSpec
        window: 
       (WindowSpec
          label: FileBrowser
          name: FileBrowser
          min: (Point 10 10)
          bounds: (Rectangle 0 0 800 600)
          menu: mainMenu
          icon: applicationIcon
        )
        component: 
       (SpecCollection
          collection: (
           (ViewSpec
              name: 'ToolbarBox'
              layout: (LayoutFrame 0 0 0 0 0 1 30 0)
              level: 0
              visibilityChannel: toolBarVisibleHolder
              component: 
             (SpecCollection
                collection: (
                 (ActionButtonSpec
                    label: 'hideToolBarIcon'
                    name: 'HideToolBarButton'
                    layout: (LayoutFrame 0 0 0 0 13 0 30 0)
                    activeHelpKey: hideToolBar
                    hasCharacterOrientedLabel: false
                    translateLabel: true
                    model: hideToolbar
                    postBuildCallback: hideToolBarButtonCreated:
                  )
                 (MenuPanelSpec
                    name: 'ToolBar'
                    layout: (LayoutFrame 13 0 0 0 0 1 32 0)
                    menu: toolBarMainMenu
                    textDefault: true
                  )
                 )
               
              )
            )
           (ViewSpec
              name: 'FilenameEntryFieldBox'
              layout: (LayoutFrame 0 0 32 0 0 1 57 0)
              level: 0
              visibilityChannel: filenameEntryFieldVisibleHolder
              component: 
             (SpecCollection
                collection: (
                 (ActionButtonSpec
                    label: 'hideFilenameEntryFieldIcon'
                    name: 'HideFilenameEntryFieldButton'
                    layout: (LayoutFrame 0 0 0 0 13 0 0 1)
                    activeHelpKey: hideFilenameEntryField
                    hasCharacterOrientedLabel: false
                    translateLabel: true
                    model: hideFilenameEntryField
                    postBuildCallback: hideFilenameEntryFieldButtonCreated:
                  )
                 (HorizontalPanelViewSpec
                    name: 'HorizontalPanel1'
                    layout: (LayoutFrame 13 0.0 0 0.0 0 1.0 0 1.0)
                    level: 1
                    horizontalLayout: leftFit
                    verticalLayout: fit
                    horizontalSpace: 3
                    verticalSpace: 3
                    component: 
                   (SpecCollection
                      collection: (
                       (ComboListSpec
                          name: 'ComboList1'
                          visibilityChannel: driveSelectorVisible
                          model: selectedDeviceDrive
                          comboList: listOfDeviceDrives
                          useIndex: false
                          hidePullDownMenuButton: false
                          extent: (Point 53 23)
                        )
                       (VariableHorizontalPanelSpec
                          name: 'VariableHorizontalPanel1'
                          level: 0
                          showHandle: true
                          component: 
                         (SpecCollection
                            collection: (
                             (NonScrollableArbitraryComponentSpec
                                name: 'NonScrollableArbitraryComponent1'
                                component: FilenameEditFieldV2
                                postBuildCallback: postBuildEditField:
                              )
                             (ViewSpec
                                name: 'FilterBox'
                                component: 
                               (SpecCollection
                                  collection: (
                                   (LabelSpec
                                      label: 'Filter:'
                                      name: 'Filter'
                                      layout: (LayoutFrame 0 0 0 0 40 0 0 1)
                                      translateLabel: true
                                      adjust: left
                                      postBuildCallback: postBuildPathViewBox:
                                    )
                                   (ComboBoxSpec
                                      name: 'FilterSelectionBox'
                                      layout: (LayoutFrame 40 0 0 0 0 1 0 1)
                                      model: filterModel
                                      immediateAccept: true
                                      acceptOnPointerLeave: false
                                      comboList: filterListModel
                                    )
                                   )
                                 
                                )
                                postBuildCallback: postBuildPathViewBox:
                              )
                             )
                           
                          )
                          handles: (Any 0.774936 1.0)
                          postBuildCallback: postBuildPathViewBox:
                          useDefaultExtent: true
                        )
                       )
                     
                    )
                    postBuildCallback: postBuildPathViewBox:
                  )
                 )
               
              )
            )
           (#'FileBrowserV2UISpecifications::PanelSpec'
              name: 'BrowserBox'
              layout: (LayoutFrame 0 0.0 57 0.0 0 1.0 -20 1.0)
              level: 0
              showHandle: true
              snapMode: both
              whichView: last
              orientation: vertical
              visibility: viewNoteBookApplicationHolder
              component: 
             (SpecCollection
                collection: (
                 (#'FileBrowserV2UISpecifications::PanelSpec'
                    name: 'HorizontalPanel'
                    level: 0
                    snapMode: both
                    whichView: first
                    orientation: horizontal
                    visibility: showDirectoryTree
                    component: 
                   (SpecCollection
                      collection: (
                       (SubCanvasSpec
                          name: 'DirectoryTreeBrowser'
                          hasHorizontalScrollBar: false
                          hasVerticalScrollBar: false
                          majorKey: DirectoryTreeBrowser
                          createNewApplication: true
                          createNewBuilder: true
                          postBuildCallback: postBuildDirectoryTree:
                        )
                       (SubCanvasSpec
                          name: 'DirectoryContentsBrowser'
                          hasHorizontalScrollBar: false
                          hasVerticalScrollBar: false
                          majorKey: DirectoryContentsBrowser
                          createNewApplication: true
                          createNewBuilder: true
                        )
                       )
                     
                    )
                    handles: (Any 0.225 1.0)
                  )
                 (SubCanvasSpec
                    name: 'FileApplicationNoteBook'
                    tabable: false
                    hasHorizontalScrollBar: false
                    hasVerticalScrollBar: false
                    majorKey: FileApplicationNoteBook
                    createNewApplication: true
                    createNewBuilder: true
                  )
                 )
               
              )
              handles: (Any 0.5 1.0)
            )
           (ViewSpec
              name: 'Box2'
              layout: (LayoutFrame 0 0 -20 1 0 1 0 1)
              level: 0
              component: 
             (SpecCollection
                collection: (
                 (LabelSpec
                    label: 'NotifyLabel'
                    name: 'NotifyLabel'
                    layout: (LayoutFrame 0 0 1 0.0 -220 1 1 1.0)
                    level: -1
                    translateLabel: true
                    labelChannel: notifyChannel
                    adjust: left
                  )
                 (LabelSpec
                    label: 'encoding'
                    name: 'EncodingLabel'
                    layout: (LayoutFrame -307 1 2 0.0 -221 1 0 1.0)
                    level: 0
                    labelChannel: fileEncodingHolder
                    adjust: right
                    menu: encodingMenu
                  )
                 (LabelSpec
                    label: 'Shown Files'
                    name: 'ShownFilesLabel'
                    layout: (LayoutFrame -220 1 1 0.0 -60 1 1 1.0)
                    level: -1
                    translateLabel: true
                    labelChannel: shownFiles
                    adjust: right
                  )
                 (ViewSpec
                    name: 'ProgressIndicatorBox'
                    layout: (LayoutFrame -220 1 1 0.0 -60 1 1 1.0)
                    level: -1
                    visibilityChannel: activityVisibilityChannel
                    component: 
                   (SpecCollection
                      collection: (
                       (ProgressIndicatorSpec
                          name: 'ProgressIndicator1'
                          layout: (LayoutFrame 5 0.0 -7 0.5 -5 1.0 7 0.5)
                          backgroundColor: (Color 0.0 66.666666666667 66.666666666667)
                          isActivityIndicator: true
                        )
                       )
                     
                    )
                  )
                 (LabelSpec
                    label: 'M'
                    name: 'ModeLabel'
                    layout: (LayoutFrame -60 1 1 0.0 -50 1 1 1.0)
                    level: -1
                    translateLabel: true
                    labelChannel: modeLabelHolder
                    adjust: right
                  )
                 (LabelSpec
                    label: 'L'
                    name: 'LineLabel'
                    layout: (LayoutFrame -50 1 1 0.0 -20 1 1 1.0)
                    level: -1
                    translateLabel: true
                    labelChannel: cursorLineLabelHolder
                    adjust: right
                  )
                 (LabelSpec
                    label: 'C'
                    name: 'ColLabel'
                    layout: (LayoutFrame -20 1 1 0.0 0 1 1 1.0)
                    level: -1
                    translateLabel: true
                    labelChannel: cursorColLabelHolder
                    adjust: right
                  )
                 )
               
              )
            )
           (LabelSpec
              label: 'Preview'
              name: 'PreviewLabel'
              layout: (LayoutFrame 0 0.5 39 0 100 0.5 61 0)
              level: 0
              borderWidth: 1
              visibilityChannel: previewVisibleHolder
              backgroundColor: (Color 86.999313344015 86.999313344015 86.999313344015)
              translateLabel: true
            )
           (ArbitraryComponentSpec
              name: 'Preview'
              layout: (LayoutFrame 0 0.5 63 0 -147 1 -319 1)
              level: 1
              visibilityChannel: previewVisibleHolder
              hasBorder: false
              component: ImageView
            )
           )
         
        )
      )
! !

!FileBrowserV2 class methodsFor:'menu specs'!

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

    <resource: #menu>

    ^ 
     #(Menu
        (
         (MenuItem
            label: 'Encoding...'
            itemValue: fileEncodingDialog
            translateLabel: true
          )
         )
        nil
        nil
      )
!

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

    <resource: #menu>

    ^ 
     #(Menu
        (
         (MenuItem
            label: 'Browser'
            translateLabel: true
            submenuChannel: browserMenu
            keepLinkedMenu: true
          )
         (MenuItem
            label: 'Directory'
            translateLabel: true
            submenuChannel: directoryMenu
            keepLinkedMenu: true
          )
         (MenuItem
            label: 'File'
            translateLabel: true
            submenuChannel: fileMenu
            keepLinkedMenu: true
          )
         (MenuItem
            label: 'Edit'
            translateLabel: true
            submenuChannel: editMenu
            keepLinkedMenu: true
          )
         (MenuItem
            label: 'View'
            translateLabel: true
            submenu: 
           (Menu
              (
               (MenuItem
                  label: 'Details'
                  translateLabel: true
                  submenuChannel: viewInContentsBrowserMenu
                )
               (MenuItem
                  label: 'Sort'
                  translateLabel: true
                  submenuChannel: sortMenu
                )
               (MenuItem
                  label: 'Show'
                  translateLabel: true
                  submenuChannel: showMenuSpec
                )
               (MenuItem
                  label: '-'
                )
               (MenuItem
                  label: 'Toolbar'
                  translateLabel: true
                  hideMenuOnActivated: false
                  indication: toolBarVisibleHolder
                )
               (MenuItem
                  label: 'Path Entry && Filter'
                  translateLabel: true
                  hideMenuOnActivated: false
                  indication: filenameEntryFieldVisibleHolder
                )
               (MenuItem
                  label: 'Preview'
                  translateLabel: true
                  hideMenuOnActivated: false
                  indication: previewVisibleHolder
                )
               (MenuItem
                  label: '-'
                )
               (MenuItem
                  label: 'Update'
                  itemValue: updateCurrentDirectory
                  translateLabel: true
                )
               )
              nil
              nil
            )
          )
         (MenuItem
            label: 'Tools'
            translateLabel: true
            submenuChannel: toolsMenuSpec
            keepLinkedMenu: true
          )
         (MenuItem
            label: 'CVS'
            translateLabel: true
            submenuChannel: cvsMenu
            keepLinkedMenu: true
          )
         (MenuItem
            label: 'Help'
            translateLabel: true
            startGroup: right
            submenu: 
           (Menu
              (
               (MenuItem
                  label: 'FileBrowser Documentation'
                  itemValue: openHTMLDocument:
                  translateLabel: true
                  argument: 'tools/fbrowserV2/TOP.html'
                )
               (MenuItem
                  label: '-'
                )
               (MenuItem
                  label: 'About FileBrowser...'
                  itemValue: openAboutThisApplication
                  translateLabel: true
                )
               )
              nil
              nil
            )
          )
         )
        nil
        nil
      )

    "Modified: / 17-03-2004 / 13:19:04 / cg"
!

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

    <resource: #menu>

    ^ 
     #(#Menu
        #(
         #(#MenuItem
            #label: 'Close Preview'
            #itemValue: #closePreview
            #translateLabel: true
          )
         )
        nil
        nil
      )
!

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

    <resource: #menu>

    ^ 
     #(Menu
        (
         (MenuItem
            activeHelpKey: directoryUp
            enabled: enableDirectoryUp
            label: 'DirectoryUp'
            itemValue: doGoDirectoryUp
            translateLabel: true
            isButton: true
            labelImage: (ResourceRetriever ToolbarIconLibrary directoryUpIcon)
          )
         (MenuItem
            activeHelpKey: directoryBack
            enabled: enableBack
            label: 'Back'
            itemValue: doBack
            translateLabel: true
            isButton: true
            submenuChannel: menuDirHistoryBack
            labelImage: (ResourceRetriever ToolbarIconLibrary historyBackIcon)
          )
         (MenuItem
            label: ''
          )
         (MenuItem
            activeHelpKey: directoryForward
            enabled: enableForward
            label: 'Forward'
            itemValue: doForward
            translateLabel: true
            isButton: true
            submenuChannel: menuDirHistoryForward
            labelImage: (ResourceRetriever ToolbarIconLibrary historyForwardIcon)
          )
         (MenuItem
            label: ''
          )
         (MenuItem
            activeHelpKey: fileHome
            enabled: enableHome
            label: 'Home'
            itemValue: doGotoHomeDirectory
            translateLabel: true
            isButton: true
            labelImage: (ResourceRetriever ToolbarIconLibrary homeIcon)
          )
         (MenuItem
            activeHelpKey: fileGotoDefault
            enabled: enableGotoDefault
            label: 'ST/X Default'
            itemValue: doGotoDefaultDirectory
            translateLabel: true
            isButton: true
            labelImage: (ResourceRetriever ToolbarIconLibrary stxHomeIcon)
          )
         (MenuItem
            activeHelpKey: fileGotoBookmark
            label: 'Bookmarks'
            translateLabel: true
            isButton: true
            submenuChannel: gotoBookmarksMenuSpec
            labelImage: (ResourceRetriever ToolbarIconLibrary directoryBookmarksIcon)
          )
         (MenuItem
            label: ''
          )
         (MenuItem
            activeHelpKey: fileHistory
            enabled: enableFileHistory
            label: 'File History'
            translateLabel: true
            isButton: true
            submenuChannel: menuFileHistory
            labelImage: (ResourceRetriever ToolbarIconLibrary historyIcon)
          )
         (MenuItem
            label: '-'
          )
         (MenuItem
            activeHelpKey: cutFile
            enabled: hasSelection
            label: 'Cut'
            itemValue: cutFiles
            translateLabel: true
            isButton: true
            labelImage: (ResourceRetriever ToolbarIconLibrary cutFileIcon)
          )
         (MenuItem
            activeHelpKey: copyFile
            enabled: hasSelection
            label: 'Copy'
            itemValue: copyFiles
            translateLabel: true
            isButton: true
            labelImage: (ResourceRetriever ToolbarIconLibrary copyFileIcon)
          )
         (MenuItem
            activeHelpKey: pasteFile
            enabled: canPaste
            label: 'Paste'
            itemValue: pasteFiles
            translateLabel: true
            isButton: true
            labelImage: (ResourceRetriever ToolbarIconLibrary pasteFileIcon)
          )
         (MenuItem
            activeHelpKey: deleteFile
            enabled: hasSelection
            label: 'Delete'
            itemValue: deleteFiles
            translateLabel: true
            isButton: true
            labelImage: (ResourceRetriever ToolbarIconLibrary deleteFileIcon)
          )
         (MenuItem
            label: '-'
          )
         (MenuItem
            activeHelpKey: fileIn
            label: 'File In'
            itemValue: fileFileIn
            translateLabel: true
            isButton: true
            labelImage: (ResourceRetriever ToolbarIconLibrary fileInIcon)
          )
         (MenuItem
            activeHelpKey: openChangeBrowser
            enabled: hasFileSelection
            label: 'Changes Browser'
            itemValue: openChangesBrowser
            translateLabel: true
            isButton: true
            labelImage: (ResourceRetriever ToolbarIconLibrary startChangesBrowserIcon)
          )
         (MenuItem
            label: '-'
          )
         (MenuItem
            activeHelpKey: editFile
            label: 'Edit File'
            itemValue: doShowFileContents
            translateLabel: true
            isButton: true
            labelImage: (ResourceRetriever ToolbarIconLibrary editFileIcon)
          )
         (MenuItem
            activeHelpKey: searchFile
            label: 'Search File'
            itemValue: doOpenSearchFile
            translateLabel: true
            isButton: true
            labelImage: (ResourceRetriever ToolbarIconLibrary searchFileIcon)
          )
         (MenuItem
            activeHelpKey: addTerminal
            label: 'VT100'
            itemValue: doAddTerminal
            translateLabel: true
            isButton: true
            labelImage: (ResourceRetriever ToolbarIconLibrary shellTerminalIcon)
          )
         (MenuItem
            activeHelpKey: make
            enabled: canMake
            label: 'Make'
            itemValue: doMake
            translateLabel: true
            isButton: true
            labelImage: (ResourceRetriever ToolbarIconLibrary makeIcon)
          )
         (MenuItem
            activeHelpKey: viewDetails
            label: 'viewDetails'
            translateLabel: true
            isButton: true
            startGroup: right
            hideMenuOnActivated: false
            indication: viewDetails
            labelImage: (ResourceRetriever ToolbarIconLibrary viewDetailsIcon)
          )
         (MenuItem
            activeHelpKey: viewDetails
            label: 'viewDetails'
            translateLabel: true
            isButton: true
            startGroup: right
            isVisible: false
            indication: viewDetails
            submenuChannel: viewDetailsMenuSpec
            labelImage: (ResourceRetriever ToolbarIconLibrary viewDetailsIcon)
          )
         (MenuItem
            activeHelpKey: selectDetails
            label: ''
            isButton: true
            startGroup: right
            submenuChannel: viewDetailsMenuSpec
            labelImage: (ResourceRetriever ToolbarIconLibrary empty1x20Icon)
          )
         )
        nil
        nil
      )
! !

!FileBrowserV2 methodsFor:'actions'!

changeFileBrowserTitleTo:aString

    |string|

    string := 'FileBrowser ', aString.
    self window label:string.
!

doSpawn

    self saveRuntimeAspectValues.
    self class openWithAspects:aspects withExtent:self builder window extent.
!

hideFilenameEntryField
    self filenameEntryFieldVisibleHolder value:false.
!

hideToolbar
    self toolBarVisibleHolder value:false.
!

toggleFileDetailsFor:anItem
    |viewDetails|

    viewDetails := self viewDetails value not.
    self viewDetails value:viewDetails.

    viewDetails ifTrue:[
        anItem activeHelpKey:#hideFileDetails.
        anItem label:(ToolbarIconLibrary viewNoDetailsIcon).
    ] ifFalse:[
        anItem activeHelpKey:#showFileDetails.
        anItem label:(ToolbarIconLibrary viewDetailsIcon).
    ].
! !

!FileBrowserV2 methodsFor:'aspects'!

cursorColLabelHolder
    ^ self 
        aspectFor:#cursorColLabelHolder 
        ifAbsent:[
            self 
                applicationNamed:#FileApplicationNoteBook
                ifPresentDo:[:appl | appl cursorColLabelHolder].
        ]
!

cursorLineLabelHolder
    ^ self 
        aspectFor:#cursorLineLabelHolder
        ifAbsent:[
            self 
                applicationNamed:#FileApplicationNoteBook
                ifPresentDo:[:appl | appl cursorLineLabelHolder].
        ]
!

fileEntryFieldHolder

    fileEntryFieldHolder isNil ifTrue:[
        fileEntryFieldHolder := ValueHolder new.
        fileEntryFieldHolder addDependent:self.
    ].
    ^ fileEntryFieldHolder.
!

listOfDeviceDrives

    listOfDeviceDrives isNil ifTrue:[
        listOfDeviceDrives := Filename volumes.
    ].
    ^ listOfDeviceDrives
!

modeLabelHolder
    ^ self 
        aspectFor:#modeLabelHolder 
        ifAbsent:[
            self 
                applicationNamed:#FileApplicationNoteBook
                ifPresentDo:[:appl | appl modeLabelHolder].
        ]
!

selectedDeviceDrive

    selectedDeviceDrive isNil ifTrue:[
        selectedDeviceDrive := self listOfDeviceDrives first asValue.
        selectedDeviceDrive addDependent:self.
    ].
    ^ selectedDeviceDrive
! !

!FileBrowserV2 methodsFor:'aspects-visibility'!

driveSelectorVisible
    ^ self systemIsDOS
!

filenameEntryFieldVisibleHolder
    " aspect for show FileEntryField "

    ^ self aspectFor:#filenameEntryFieldVisibleHolder ifAbsent:[true asValue]
!

previewVisibleHolder
    " aspect for show preview"

    ^ self aspectFor:#previewVisibleHolder ifAbsent:[false asValue]
!

toolBarVisibleHolder
    " aspect for show toolbar"

    ^ self aspectFor:#toolBarVisibleHolder ifAbsent:[true asValue]
! !

!FileBrowserV2 methodsFor:'change & update'!

currentFileNameHolderChanged
    |newEntryValue nSelected files volume|

    files := self currentFileNameHolder value.
    nSelected := files size.

    nSelected == 0 ifTrue:[
        newEntryValue := ''.
    ] ifFalse:[
        nSelected == 1 ifTrue:[
            newEntryValue := files first.
        ] ifFalse:[
            newEntryValue := self commonPrefixOfSelectedFiles.
        ].
    ].
    self fileEntryFieldHolder value:(newEntryValue asString) withoutNotifying:self.

    OperatingSystem supportsVolumes ifTrue:[
        volume := (nSelected >= 1) 
                    ifTrue:[files first volume] 
                    ifFalse:nil.    
        self selectedDeviceDrive value:volume.
    ].
    self updatePreview.
!

fileEntryFieldHolderChanged
    |fileName fileNameString answer dir|

    fileNameString := fileEntryFieldHolder value withoutSeparators.
    fileName := fileNameString asFilename.
    fileNameString isEmpty ifTrue:[ 
        pathEntryField flash.
        ^ self
    ].

    (fileName exists) ifFalse:[ 
        pathEntryField flash.

        dir := fileName directory.
        dir exists ifTrue:[
            self currentFileNameHolder 
                value:(OrderedCollection with:dir)
                withoutNotifying:self.
        ].
        fileName baseName includesMatchCharacters ifTrue:[
            self fileEntryFieldHolder value:(fileName directoryName) withoutNotifying:self.
            self filterModel value:fileName baseName.
        ].

"/        answer := OptionBox 
"/           request:(resources string:'No file or directory named "%1" exists.\\Create ?' with:fileNameString allBold) withCRs
"/           buttonLabels:#('Create as File' 'Create as Directory' 'Cancel')
"/           values:#(createFile createDirectory nil)
"/           default:nil.
"/
        answer isNil ifTrue:[
            ^ self.
        ].

        [
            answer == #createFile ifTrue:[
                fileName directory recursiveMakeDirectory.
                fileName createAsEmptyFile.
            ] ifFalse:[
                answer == #createDirectory ifTrue:[
                    fileName recursiveMakeDirectory.
                ]
            ].
        ] on:OperatingSystem accessDeniedErrorSignal do:[:ex |
            Dialog warn:'Error: ' , ex description.
        ].
        ^ self
    ].
    self setCurrentFileName:fileName.
!

selectedDeviceDriveChanged

    | newDrive curSel newFile|

    newDrive := self selectedDeviceDrive value.
    curSel := self currentFileNameHolder value.
    curSel notEmpty ifTrue:[
        curSel first volume = newDrive ifTrue:[ ^self].
    ].
    newDrive notNil ifTrue:[
        newFile := newDrive asFilename.

        newFile isReadable ifTrue:[
            self gotoFile:newFile.
            ^self.
        ].
    ].
    curSel notEmpty ifTrue:[
        self selectedDeviceDrive value:(curSel first volume).
    ] ifFalse:[
        self selectedDeviceDrive value:'C:'.
    ].
!

selectedImage
    |files selectedFile mime img|

    files := self currentSelectedFiles.
    files size >= 1 ifFalse:[
        ^ nil
    ].
    selectedFile := files last.    

    mime := MIMETypes mimeTypeForFilename:selectedFile.
    (mime notNil and:[mime startsWith:'image/']) ifTrue:[
        img := Image fromFile:selectedFile.
        ^ img
    ].

    ^ nil.
!

showImagePreview:image
    |imgView|

    imgView := builder componentAt:#Preview.

    imgView adjust:#fitBig.
    imgView image:image.
!

showPreview
    |shownImage lbl previewLabel|

    shownImage := self selectedImage.
    lbl := shownImage isNil ifTrue:'Preview' ifFalse:[ shownImage fileName asFilename baseName ].

    previewLabel := builder componentAt:#PreviewLabel.
    previewLabel label:lbl; forceResizeHorizontally.     
    self enqueueMessage:#'showImagePreview:' for:self arguments:(Array with:shownImage).        
!

update:something with:aParameter from:changedObject


    changedObject == self selectedDeviceDrive ifTrue:[
        self selectedDeviceDriveChanged.
        ^ self.
    ].
    changedObject == self fileEntryFieldHolder ifTrue:[
        self fileEntryFieldHolderChanged.
        ^ self.
    ].
    changedObject == self currentFileNameHolder ifTrue:[
        super update:something with:aParameter from:changedObject.
        self currentFileNameHolderChanged.
        ^ self.
    ].
    (changedObject == self previewVisibleHolder) ifTrue:[
        self updatePreview.
        ^ self.
    ].
    (changedObject == self toolBarVisibleHolder 
    or:[changedObject == self filenameEntryFieldVisibleHolder]) ifTrue:[
        self updateToolVisibility.
        ^ self.
    ].
    (changedObject == self sortBlockProperty or:[changedObject == self sortDirectoriesBeforeFiles]) ifTrue:[
        self sortFileListsBy:(self sortBlockProperty value) withReverse:false.
        ^ self.
    ].             

    ^ super update:something with:aParameter from:changedObject.
!

updatePreview
    |previewLabel shownImage plug|

    self previewVisibleHolder value ifTrue:[
        shownImage := nil.
        imgView := builder componentAt:#Preview.
        previewLabel := builder componentAt:#PreviewLabel.
        plug := Plug new.
        plug respondTo:#closePreview with:[ self previewVisibleHolder value:false ].

        previewLabel menuHolder:(self class previewLabelMenu decodeAsLiteralArray).
        previewLabel menuPerformer:plug asValue.

        previewProcess notNil ifTrue:[
            previewProcess terminate
        ].
        previewProcess := [
                                |imgView oldBg shownImage lbl|

                                oldBg := previewLabel backgroundColor.
                                previewLabel backgroundColor:(Color red lightened lightened).
                                [
                                    self showPreview.
                                    previewProcess := nil.
                                ] ensure:[
                                    previewLabel backgroundColor:oldBg.
                                ].
                          ] forkAt:7.
    ] ifFalse:[
        imgView notNil ifTrue:[
            imgView image:nil.
        ]
    ].
!

updateToolVisibility
    |builder toolBar filenameEntryField vPanel topOffset visible d|

    builder := self builder.

    topOffset := 0.
    visible := self toolBarVisibleHolder value.
    visible ifTrue:[
        toolBar := builder componentAt:#ToolbarBox.
        topOffset := topOffset + toolBar height.
    ].

    visible := self filenameEntryFieldVisibleHolder value.
    visible ifTrue:[
        filenameEntryField := builder componentAt:#FilenameEntryFieldBox.
        d := filenameEntryField layout bottomOffset - filenameEntryField layout topOffset.
        filenameEntryField layout topOffset:topOffset bottomOffset:topOffset + d.
        topOffset := topOffset + filenameEntryField height.
        filenameEntryField container notNil ifTrue:[
            filenameEntryField containerChangedSize.
        ].
    ].

    vPanel := builder componentAt:#BrowserBox.
    vPanel layout topOffset:topOffset+1.
    vPanel container notNil ifTrue:[
        vPanel containerChangedSize.
    ].
! !

!FileBrowserV2 methodsFor:'event handling'!

crPressedInPathField
    |path fn|

    path := fileEntryFieldHolder value.
    fn := path asFilename.
    (fn exists and:[ fn isDirectory not ]) ifTrue:[
        self openApplForFile:path.
    ]
!

processEvent:anEvent
    "filter keyboard events.
     Return true, if I have eaten the event"

    |focusView key rawKey fileName|

    anEvent isKeyPressEvent ifTrue:[
        focusView := anEvent targetView.
        key := anEvent key.
        rawKey := anEvent rawKey.

        (focusView isSameOrComponentOf:self window) ifTrue:[

            (focusView == pathEntryField) ifFalse:[ ^ false].

            (key == #Return) ifTrue:[
                fileName := pathEntryField list first asFilename.
                (fileName exists and:[fileName isDirectory not]) ifTrue:[
                    self openApplForFile:fileName
                ].
            ].
        ]
    ].
    ^ false
! !

!FileBrowserV2 methodsFor:'menu accessing'!

menuFileHistory
    "initialize the file history menu
    "
    <resource: #programMenu >

    |menu hist text removeItem removeCol|

    menu := Menu new.
    menu findGuiResourcesIn:self.
    menu receiver:self.

    hist := self fileHistory.
    hist isEmpty ifTrue:[^ nil].

    removeCol := OrderedCollection new.
    hist do:[:aFileItem|
        "aFileItem fileName exists" true ifTrue:[
            menu addItem:(MenuItem label: aFileItem fileName asString value:[
                self setCurrentFileName:(aFileItem fileName).
                self openApplByFileItem:aFileItem
            ]).
        ] ifFalse:[
            removeCol add:aFileItem.
        ]
    ].
    "/ remove all not existing history entries
    removeCol do:[ : el |
        hist remove:el.
    ].
    removeItem := MenuItem new.
    removeItem translateLabel:true.
    text := resources string:'Clear History'.
    "/ text := LabelAndIcon icon:(self class clearHistoryIcon) string:text.
    removeItem label:text.
    removeItem value:[
        self fileHistory removeAll.
        self enableFileHistory value:false.
    ].
    menu addSeparator.
    menu addItem:removeItem.
    ^ menu
! !

!FileBrowserV2 methodsFor:'startup & release'!

closeRequest
    self 
        applicationNamed:#FileApplicationNoteBook 
        ifPresentDo:[:appl | appl tryCloseApplications ifFalse:[^ self] ]. 

    ^ super closeRequest.
!

hideFilenameEntryFieldButtonCreated:aButton

    aButton passiveLevel:(MenuPanel defaultLevel). 
    aButton activeLevel:-1.
    aButton backgroundColor:(MenuPanel defaultBackgroundColor).
!

hideToolBarButtonCreated:aButton

    aButton passiveLevel:(MenuPanel defaultLevel). 
    aButton activeLevel:-1.
    aButton backgroundColor:(MenuPanel defaultBackgroundColor).
!

initialize

    self masterApplication:nil.
    self dirHistory resetForwardBackward.
!

makeDependent

    super makeDependent.
    self sortBlockProperty addDependent:self.
    self filenameEntryFieldVisibleHolder addDependent:self.
    self toolBarVisibleHolder addDependent:self.
    self previewVisibleHolder addDependent:self.
!

postBuildDirectoryTree:aWidget
    aWidget application multipleSelect:true.
!

postBuildEditField:aWidget

    pathEntryField := aWidget.
    aWidget model:self fileEntryFieldHolder.
    aWidget listHolder:self dirHistory.
    aWidget level:-1.
    aWidget acceptIfUnchanged:true.
    aWidget crAction:[ self crPressedInPathField ].
!

postBuildFilterBox:aWidget

    self filterValueBox value:aWidget.
    self filterBackgroundColor value:aWidget backgroundColor.
!

postBuildPathViewBox:aWidget

    aWidget backgroundColor:(MenuPanel defaultBackgroundColor).
!

postBuildWith:aBuilder

    super postBuildWith:aBuilder.
    self updateToolVisibility.
!

postOpenWith:aBuilder

    super postOpenWith:aBuilder.
    self currentFileNameHolderChangedForCommon.
    self currentFileNameHolderChanged.

    self windowGroup addPreEventHook:self.
!

release

    self saveRuntimeAspectValues.
    ^ super release
! !

!FileBrowserV2 class methodsFor:'documentation'!

version
    ^ '$Header: /cvs/stx/stx/libtool/FileBrowserV2.st,v 1.136 2005-05-31 10:07:21 cg Exp $'
! !

FileBrowserV2 initialize!