DirectoryContentsBrowser.st
changeset 3887 81925afd23fd
child 3888 72008987dddc
equal deleted inserted replaced
3886:4ca44c42e103 3887:81925afd23fd
       
     1 "{ Package: 'penk:FileBrowserV2' }"
       
     2 
       
     3 AbstractFileBrowserV2 subclass:#DirectoryContentsBrowser
       
     4 	instanceVariableNames:'browser updateDirectoryContentsTask modificationTime directory
       
     5 		columnDescriptors filterBlock iconIndex fileDescriptionIndex
       
     6 		iconExtent tableColumns sortBlock currentSortOrder previewIndex
       
     7 		allItemsList updateColumnsTask currentItemList wantSelectFiles
       
     8 		updateToExternFileHolderLock lastResponse oldDropItem oldItemIcon'
       
     9 	classVariableNames:''
       
    10 	poolDictionaries:''
       
    11 	category:'ANewFileBrowser'
       
    12 !
       
    13 
       
    14 Object subclass:#DirectoryContentsItem
       
    15 	instanceVariableNames:'fileName fileInfo icon fileType link linkInfo
       
    16 		contentsBrowserChangeModificationTime isDirectory baseName suffix
       
    17 		preview group owner pathName permissions size timeAndDate date
       
    18 		lastButOneSuffix suffixes modificationTime modifiedByMe mimeType
       
    19 		iconKey'
       
    20 	classVariableNames:''
       
    21 	poolDictionaries:''
       
    22 	privateIn:DirectoryContentsBrowser
       
    23 !
       
    24 
       
    25 !DirectoryContentsBrowser class methodsFor:'documentation'!
       
    26 
       
    27 documentation
       
    28 
       
    29 "
       
    30     DirectoryContentsBrowser openIn:'/home/ca/work/stx/goodies/bitmaps/xpmBitmaps'
       
    31     DirectoryContentsBrowser openIn:'/home/ca/TEST'
       
    32 "
       
    33 ! !
       
    34 
       
    35 !DirectoryContentsBrowser class methodsFor:'instance creation'!
       
    36 
       
    37 openIn:aDirectory
       
    38     "opens a directory (standalone) for a directory
       
    39     "
       
    40     self openIn:aDirectory withDirectories:false
       
    41 
       
    42 "
       
    43 self openIn:(Filename currentDirectory construct:'.cvsignore')
       
    44 "
       
    45 !
       
    46 
       
    47 openIn:aDirectory withDirectories:withDirectoriesBoolean
       
    48     "opens a directory (standalone) for a directory
       
    49     "
       
    50     |browser|
       
    51 
       
    52     browser := DirectoryContentsBrowser new.
       
    53     browser open.
       
    54     aDirectory notNil ifTrue:[
       
    55         browser currentFileNameHolder value:(OrderedCollection with:(aDirectory asFilename))
       
    56     ].
       
    57     browser viewDirectoriesInDirectoryContentsBrowser value:withDirectoriesBoolean.
       
    58   ^ browser
       
    59 
       
    60 "
       
    61 self openIn:(Filename currentDirectory asAbsoluteFilename) withDirectories:false
       
    62 "
       
    63 ! !
       
    64 
       
    65 !DirectoryContentsBrowser class methodsFor:'classAccess'!
       
    66 
       
    67 itemClass
       
    68 
       
    69     ^ DirectoryContentsItem
       
    70 
       
    71 
       
    72 "
       
    73 self itemClass
       
    74 "
       
    75 ! !
       
    76 
       
    77 !DirectoryContentsBrowser class methodsFor:'constant'!
       
    78 
       
    79 updateTaskPriority
       
    80     "returns the priority of the update task
       
    81     "
       
    82     ^ 8
       
    83 ! !
       
    84 
       
    85 !DirectoryContentsBrowser class methodsFor:'interface specs'!
       
    86 
       
    87 tableColumns
       
    88     "This resource specification was automatically generated
       
    89      by the DataSetBuilder of ST/X."
       
    90 
       
    91     "Do not manually edit this!! If it is corrupted,
       
    92      the DataSetBuilder may not be able to read the specification."
       
    93 
       
    94     "
       
    95      DataSetBuilder new openOnClass:DirectoryContentsBrowser andSelector:#tableColumns
       
    96     "
       
    97 
       
    98     <resource: #tableColumns>
       
    99 
       
   100     ^#(
       
   101       #(#DataSetColumnSpec
       
   102          #labelButtonType: #Group
       
   103          #width: 22
       
   104          #minWidth: 22
       
   105          #height: 16
       
   106          #model: #icon
       
   107          #canSelect: false
       
   108          #showRowSeparator: false
       
   109          #showColSeparator: false
       
   110        )
       
   111       #(#DataSetColumnSpec
       
   112          #label: 'Filename'
       
   113          #id: #filename
       
   114          #labelAlignment: #left
       
   115          #labelButtonType: #Button
       
   116          #labelActionSelector: #sortList:
       
   117          #labelActionArgument: 'baseName'
       
   118          #minWidth: 150
       
   119          #model: #baseName
       
   120          #canSelect: false
       
   121          #showRowSeparator: false
       
   122          #showColSeparator: false
       
   123        )
       
   124       #(#DataSetColumnSpec
       
   125          #label: 'Suffix'
       
   126          #id: #suffix
       
   127          #labelAlignment: #left
       
   128          #labelButtonType: #Button
       
   129          #labelActionSelector: #sortList:
       
   130          #labelActionArgument: 'suffix'
       
   131          #width: 40
       
   132          #model: #suffix
       
   133          #canSelect: false
       
   134          #isResizeable: false
       
   135          #showRowSeparator: false
       
   136          #showColSeparator: false
       
   137        )
       
   138       #(#DataSetColumnSpec
       
   139          #label: 'Perm'
       
   140          #id: #perm
       
   141          #labelAlignment: #left
       
   142          #labelButtonType: #Button
       
   143          #labelActionSelector: #sortList:
       
   144          #labelActionArgument: 'permissions'
       
   145          #width: 75
       
   146          #model: #permissions
       
   147          #canSelect: false
       
   148          #isResizeable: false
       
   149          #showRowSeparator: false
       
   150          #showColSeparator: false
       
   151        )
       
   152       #(#DataSetColumnSpec
       
   153          #label: 'Owner'
       
   154          #id: #owner
       
   155          #labelAlignment: #left
       
   156          #labelButtonType: #Button
       
   157          #labelActionSelector: #sortList:
       
   158          #labelActionArgument: 'owner'
       
   159          #usePreferredWidth: true
       
   160          #width: 50
       
   161          #model: #owner
       
   162          #canSelect: false
       
   163          #showRowSeparator: false
       
   164          #showColSeparator: false
       
   165        )
       
   166       #(#DataSetColumnSpec
       
   167          #label: 'Group'
       
   168          #id: #group
       
   169          #labelAlignment: #left
       
   170          #labelButtonType: #Button
       
   171          #labelActionSelector: #sortList:
       
   172          #labelActionArgument: 'group'
       
   173          #usePreferredWidth: true
       
   174          #width: 40
       
   175          #model: #group
       
   176          #canSelect: false
       
   177          #showRowSeparator: false
       
   178          #showColSeparator: false
       
   179        )
       
   180       #(#DataSetColumnSpec
       
   181          #label: 'Size'
       
   182          #id: #size
       
   183          #translateLabel: true
       
   184          #labelAlignment: #right
       
   185          #labelButtonType: #Button
       
   186          #labelActionSelector: #sortList:
       
   187          #labelActionArgument: 'size'
       
   188          #columnAlignment: #right
       
   189          #usePreferredWidth: true
       
   190          #model: #sizeString
       
   191          #canSelect: false
       
   192          #showRowSeparator: false
       
   193          #showColSeparator: false
       
   194        )
       
   195       #(#DataSetColumnSpec
       
   196          #label: 'Date & Time'
       
   197          #id: #timeAndDate
       
   198          #labelAlignment: #right
       
   199          #labelButtonType: #Button
       
   200          #labelActionSelector: #sortList:
       
   201          #labelActionArgument: 'modificationTime'
       
   202          #columnAlignment: #right
       
   203          #usePreferredWidth: true
       
   204          #width: 140
       
   205          #model: #timeAndDate
       
   206          #writeSelector: #date:
       
   207          #canSelect: false
       
   208          #showRowSeparator: false
       
   209          #showColSeparator: false
       
   210        )
       
   211       #(#DataSetColumnSpec
       
   212          #label: 'File Info'
       
   213          #id: #fileInfo
       
   214          #labelAlignment: #left
       
   215          #labelButtonType: #Button
       
   216          #labelActionSelector: #sortList:
       
   217          #labelActionArgument: 'fileType'
       
   218          #width: 250
       
   219          #model: #fileInfoString
       
   220          #canSelect: false
       
   221          #showRowSeparator: false
       
   222          #showColSeparator: false
       
   223        )
       
   224       #(#DataSetColumnSpec
       
   225          #label: 'Pre +/-'
       
   226          #id: #preview
       
   227          #labelButtonType: #Button
       
   228          #labelActionSelector: #doResizeImage
       
   229          #labelActionArgument: ''
       
   230          #columnAlignment: #center
       
   231          #width: 45
       
   232          #height: 16
       
   233          #model: #preview
       
   234          #canSelect: false
       
   235          #showRowSeparator: false
       
   236          #showColSeparator: false
       
   237        )
       
   238       )
       
   239     
       
   240 !
       
   241 
       
   242 windowSpec
       
   243     "This resource specification was automatically generated
       
   244      by the UIPainter of ST/X."
       
   245 
       
   246     "Do not manually edit this!! If it is corrupted,
       
   247      the UIPainter may not be able to read the specification."
       
   248 
       
   249     "
       
   250      UIPainter new openOnClass:DirectoryContentsBrowser andSelector:#windowSpec
       
   251      DirectoryContentsBrowser new openInterface:#windowSpec
       
   252      DirectoryContentsBrowser open
       
   253     "
       
   254 
       
   255     <resource: #canvas>
       
   256 
       
   257     ^ 
       
   258      #(#FullSpec
       
   259         #name: #windowSpec
       
   260         #window: 
       
   261        #(#WindowSpec
       
   262           #label: 'Directory ContentsBrowser'
       
   263           #name: 'Directory ContentsBrowser'
       
   264           #min: #(#Point 10 10)
       
   265           #max: #(#Point 1152 900)
       
   266           #bounds: #(#Rectangle 723 276 1311 754)
       
   267           #menu: #menu
       
   268         )
       
   269         #component: 
       
   270        #(#SpecCollection
       
   271           #collection: #(
       
   272            #(#DataSetSpec
       
   273               #name: 'browser'
       
   274               #layout: #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0)
       
   275               #model: #selectionInFileList
       
   276               #menu: #directoryContentsBrowserMenu
       
   277               #hasHorizontalScrollBar: true
       
   278               #hasVerticalScrollBar: true
       
   279               #miniScrollerHorizontal: false
       
   280               #miniScrollerVertical: false
       
   281               #dataList: #descriptions
       
   282               #has3Dsepartors: false
       
   283               #doubleClickSelector: #doubleClickedAt:
       
   284               #columnHolder: #tableColumns
       
   285               #multipleSelectOk: true
       
   286               #verticalSpacing: 0
       
   287               #columns: 
       
   288              #(#OrderedCollection
       
   289                 
       
   290                #(#DataSetColumnSpec
       
   291                   #labelButtonType: #Group
       
   292                   #width: 22
       
   293                   #minWidth: 22
       
   294                   #height: 16
       
   295                   #model: #icon
       
   296                   #canSelect: false
       
   297                   #showRowSeparator: false
       
   298                   #showColSeparator: false
       
   299                 ) 
       
   300                #(#DataSetColumnSpec
       
   301                   #label: 'file name'
       
   302                   #labelAlignment: #left
       
   303                   #labelButtonType: #Button
       
   304                   #model: #baseName
       
   305                   #canSelect: false
       
   306                   #showRowSeparator: false
       
   307                   #showColSeparator: false
       
   308                 )
       
   309                 
       
   310                #(#DataSetColumnSpec
       
   311                   #label: '+/-'
       
   312                   #labelButtonType: #Button
       
   313                   #labelActionSelector: #doResizeImage
       
   314                   #labelActionArgument: ''
       
   315                   #columnAlignment: #center
       
   316                   #width: 30
       
   317                   #height: 16
       
   318                   #model: #preview
       
   319                   #canSelect: false
       
   320                   #showRowSeparator: false
       
   321                   #showSelectionHighLighted: false
       
   322                   #showColSeparator: false
       
   323                 )
       
   324               )
       
   325               #viewClassName: 'DirectoryContentsBrowser::Widget'
       
   326               #postBuildCallback: #postBuildBrowser:
       
   327               #properties: 
       
   328              #(#PropertyListDictionary
       
   329                 #dragArgument: #browser
       
   330                 #startDragSelector: #doStartDrag:in:
       
   331                 #displayObjectSelector: #getDisplayObjects:
       
   332                 #dropObjectSelector: #getDropObjects:
       
   333                 #dropArgument: #browser
       
   334                 #canDropSelector: #canDrop:argument:
       
   335                 #leaveSelector: #dropLeave:
       
   336                 #dropSelector: #doDrop:argument:
       
   337               )
       
   338             )
       
   339            )
       
   340          
       
   341         )
       
   342       )
       
   343 ! !
       
   344 
       
   345 !DirectoryContentsBrowser class methodsFor:'menu specs'!
       
   346 
       
   347 directoryContentsBrowserMenu
       
   348     "This resource specification was automatically generated
       
   349      by the MenuEditor of ST/X."
       
   350 
       
   351     "Do not manually edit this!! If it is corrupted,
       
   352      the MenuEditor may not be able to read the specification."
       
   353 
       
   354     "
       
   355      MenuEditor new openOnClass:DirectoryContentsBrowser andSelector:#directoryContentsBrowserMenu
       
   356      (Menu new fromLiteralArrayEncoding:(DirectoryContentsBrowser directoryContentsBrowserMenu)) startUp
       
   357     "
       
   358 
       
   359     <resource: #menu>
       
   360 
       
   361     ^ 
       
   362      #(#Menu
       
   363         #(
       
   364          #(#MenuItem
       
   365             #label: 'Copy'
       
   366             #translateLabel: true
       
   367             #value: #doCopy
       
   368             #shortcutKeyCharacter: #Copy
       
   369           )
       
   370          #(#MenuItem
       
   371             #label: 'Cut'
       
   372             #translateLabel: true
       
   373             #value: #doCut
       
   374             #shortcutKeyCharacter: #Cut
       
   375           )
       
   376          #(#MenuItem
       
   377             #label: 'Paste'
       
   378             #translateLabel: true
       
   379             #value: #pasteFiles
       
   380             #enabled: #canPaste
       
   381             #shortcutKeyCharacter: #Paste
       
   382           )
       
   383          #(#MenuItem
       
   384             #label: 'Delete'
       
   385             #translateLabel: true
       
   386             #nameKey: #delete
       
   387             #value: #doDelete
       
   388             #shortcutKeyCharacter: #Delete
       
   389           )
       
   390          #(#MenuItem
       
   391             #label: 'Rename'
       
   392             #translateLabel: true
       
   393             #value: #renameSelection
       
   394             #enabled: #hasSelection
       
   395             #shortcutKeyCharacter: #Replace
       
   396           )
       
   397          #(#MenuItem
       
   398             #label: 'Copy File List'
       
   399             #translateLabel: true
       
   400             #value: #copyFileList
       
   401             #enabled: #fileListIsNotEmpty
       
   402           )
       
   403          #(#MenuItem
       
   404             #label: '-'
       
   405           )
       
   406          #(#MenuItem
       
   407             #label: 'View'
       
   408             #translateLabel: true
       
   409             #nameKey: #View
       
   410             #submenuChannel: #viewBrowserMenu
       
   411           )
       
   412          #(#MenuItem
       
   413             #label: 'Sort'
       
   414             #translateLabel: true
       
   415             #nameKey: #Sort
       
   416             #submenuChannel: #sortMenu
       
   417           )
       
   418          #(#MenuItem
       
   419             #label: 'Show File Contents'
       
   420             #translateLabel: true
       
   421             #value: #doShowFileContents
       
   422             #enabled: #hasSelection
       
   423           )
       
   424          #(#MenuItem
       
   425             #label: 'Ignore Case in Sort'
       
   426             #translateLabel: true
       
   427             #indication: #sortCaseless
       
   428           )
       
   429          #(#MenuItem
       
   430             #label: '-'
       
   431           )
       
   432          #(#MenuItem
       
   433             #label: 'New'
       
   434             #translateLabel: true
       
   435             #submenuChannel: #newMenu
       
   436           )
       
   437          #(#MenuItem
       
   438             #label: 'Properties...'
       
   439             #translateLabel: true
       
   440             #value: #doShowProperties
       
   441             #enabled: #hasSelection
       
   442           )
       
   443          #(#MenuItem
       
   444             #label: 'File In'
       
   445             #translateLabel: true
       
   446             #value: #fileFileIn
       
   447             #enabled: #hasSelection
       
   448             #shortcutKeyCharacter: #Accept
       
   449           )
       
   450          #(#MenuItem
       
   451             #label: 'File in to NameSpace...'
       
   452             #translateLabel: true
       
   453             #value: #fileFileInToNameSpace
       
   454             #enabled: #hasSelection
       
   455           )
       
   456          #(#MenuItem
       
   457             #label: '-'
       
   458           )
       
   459          #(#MenuItem
       
   460             #label: 'Directory Up'
       
   461             #translateLabel: true
       
   462             #value: #doGoDirectoryUp
       
   463             #enabled: #enableDirectoryUp
       
   464             #shortcutKeyCharacter: #CursorLeft
       
   465           )
       
   466          #(#MenuItem
       
   467             #label: 'Update'
       
   468             #translateLabel: true
       
   469             #value: #doUpdate
       
   470           )
       
   471          #(#MenuItem
       
   472             #label: 'Select All'
       
   473             #translateLabel: true
       
   474             #value: #doSelectAll
       
   475           )
       
   476          )
       
   477         nil
       
   478         nil
       
   479       )
       
   480 !
       
   481 
       
   482 sortMenu
       
   483     "This resource specification was automatically generated
       
   484      by the MenuEditor of ST/X."
       
   485 
       
   486     "Do not manually edit this!! If it is corrupted,
       
   487      the MenuEditor may not be able to read the specification."
       
   488 
       
   489     "
       
   490      MenuEditor new openOnClass:DirectoryContentsBrowser andSelector:#sortMenu
       
   491      (Menu new fromLiteralArrayEncoding:(DirectoryContentsBrowser sortMenu)) startUp
       
   492     "
       
   493 
       
   494     <resource: #menu>
       
   495 
       
   496     ^ 
       
   497      #(#Menu
       
   498         #(
       
   499          #(#MenuItem
       
   500             #label: 'By Filename'
       
   501             #translateLabel: true
       
   502             #hideMenuOnActivated: false
       
   503             #choice: #sortBlockHolder
       
   504             #choiceValue: #baseName
       
   505           )
       
   506          #(#MenuItem
       
   507             #label: 'By Type'
       
   508             #translateLabel: true
       
   509             #hideMenuOnActivated: false
       
   510             #choice: #sortBlockHolder
       
   511             #choiceValue: #suffix
       
   512           )
       
   513          #(#MenuItem
       
   514             #label: 'By Permissions'
       
   515             #translateLabel: true
       
   516             #hideMenuOnActivated: false
       
   517             #choice: #sortBlockHolder
       
   518             #choiceValue: #permissions
       
   519           )
       
   520          #(#MenuItem
       
   521             #label: 'By Owner'
       
   522             #translateLabel: true
       
   523             #hideMenuOnActivated: false
       
   524             #isVisible: #viewOwner
       
   525             #choice: #sortBlockHolder
       
   526             #choiceValue: #owner
       
   527           )
       
   528          #(#MenuItem
       
   529             #label: 'By Group'
       
   530             #translateLabel: true
       
   531             #hideMenuOnActivated: false
       
   532             #isVisible: #viewOwner
       
   533             #choice: #sortBlockHolder
       
   534             #choiceValue: #group
       
   535           )
       
   536          #(#MenuItem
       
   537             #label: 'By Size'
       
   538             #translateLabel: true
       
   539             #hideMenuOnActivated: false
       
   540             #choice: #sortBlockHolder
       
   541             #choiceValue: #size
       
   542           )
       
   543          #(#MenuItem
       
   544             #label: 'By Date && Time'
       
   545             #translateLabel: true
       
   546             #hideMenuOnActivated: false
       
   547             #choice: #sortBlockHolder
       
   548             #choiceValue: #timeAndDate
       
   549           )
       
   550          #(#MenuItem
       
   551             #label: 'By Description'
       
   552             #translateLabel: true
       
   553             #hideMenuOnActivated: false
       
   554             #choice: #sortBlockHolder
       
   555             #choiceValue: #fileType
       
   556           )
       
   557          )
       
   558         nil
       
   559         nil
       
   560       )
       
   561 !
       
   562 
       
   563 viewBrowserMenu
       
   564     "This resource specification was automatically generated
       
   565      by the MenuEditor of ST/X."
       
   566 
       
   567     "Do not manually edit this!! If it is corrupted,
       
   568      the MenuEditor may not be able to read the specification."
       
   569 
       
   570     "
       
   571      MenuEditor new openOnClass:DirectoryContentsBrowser andSelector:#viewBrowserMenu
       
   572      (Menu new fromLiteralArrayEncoding:(DirectoryContentsBrowser viewBrowserMenu)) startUp
       
   573     "
       
   574 
       
   575     <resource: #menu>
       
   576 
       
   577     ^ 
       
   578      #(#Menu
       
   579         #(
       
   580          #(#MenuItem
       
   581             #label: 'View Details'
       
   582             #translateLabel: true
       
   583             #hideMenuOnActivated: false
       
   584             #indication: #viewDetails
       
   585           )
       
   586          #(#MenuItem
       
   587             #label: 'View Suffix'
       
   588             #translateLabel: true
       
   589             #hideMenuOnActivated: false
       
   590             #enabled: #viewDetails
       
   591             #indication: #viewType
       
   592           )
       
   593          #(#MenuItem
       
   594             #label: 'View Permissions'
       
   595             #translateLabel: true
       
   596             #hideMenuOnActivated: false
       
   597             #enabled: #viewDetails
       
   598             #indication: #viewPermissions
       
   599           )
       
   600          #(#MenuItem
       
   601             #label: 'View Owner'
       
   602             #translateLabel: true
       
   603             #hideMenuOnActivated: false
       
   604             #enabled: #viewDetails
       
   605             #indication: #viewOwner
       
   606           )
       
   607          #(#MenuItem
       
   608             #label: 'View Group'
       
   609             #translateLabel: true
       
   610             #hideMenuOnActivated: false
       
   611             #enabled: #viewDetails
       
   612             #indication: #viewGroup
       
   613           )
       
   614          #(#MenuItem
       
   615             #label: 'View Size'
       
   616             #translateLabel: true
       
   617             #hideMenuOnActivated: false
       
   618             #enabled: #viewDetails
       
   619             #indication: #viewSize
       
   620           )
       
   621          #(#MenuItem
       
   622             #label: 'View Date && Time'
       
   623             #translateLabel: true
       
   624             #hideMenuOnActivated: false
       
   625             #enabled: #viewDetails
       
   626             #indication: #viewTime
       
   627           )
       
   628          #(#MenuItem
       
   629             #label: 'View File Info'
       
   630             #translateLabel: true
       
   631             #hideMenuOnActivated: false
       
   632             #enabled: #viewDetails
       
   633             #indication: #viewDescription
       
   634           )
       
   635          #(#MenuItem
       
   636             #label: 'View Preview'
       
   637             #translateLabel: true
       
   638             #hideMenuOnActivated: false
       
   639             #enabled: #viewDetails
       
   640             #indication: #viewPreview
       
   641           )
       
   642          #(#MenuItem
       
   643             #label: '-'
       
   644           )
       
   645          #(#MenuItem
       
   646             #label: 'Show Hidden Files'
       
   647             #translateLabel: true
       
   648             #indication: #showHiddenFiles
       
   649           )
       
   650          )
       
   651         nil
       
   652         nil
       
   653       )
       
   654 ! !
       
   655 
       
   656 !DirectoryContentsBrowser methodsFor:'accessing'!
       
   657 
       
   658 columnDescriptors
       
   659     "get the column description
       
   660     "
       
   661     ^ columnDescriptors
       
   662 !
       
   663 
       
   664 columnDescriptors:aListOfColumns
       
   665     "set the column description
       
   666     "
       
   667     columnDescriptors = aListOfColumns ifTrue:[
       
   668         ^ self
       
   669     ].
       
   670 
       
   671     columnDescriptors    := OrderedCollection new.
       
   672     previewIndex        := 0.
       
   673     iconIndex            := 0.
       
   674     fileDescriptionIndex := 0.
       
   675     iconExtent           := nil.
       
   676 
       
   677     aListOfColumns keysAndValuesDo:[:anIndex :aDesc| |col|
       
   678         col := aDesc isSequenceable ifTrue:[DataSetColumnSpec new fromLiteralArrayEncoding:aDesc]
       
   679                                    ifFalse:[aDesc].
       
   680         columnDescriptors add:col.
       
   681 
       
   682         col readSelector == #preview ifTrue:[
       
   683             previewIndex := anIndex.
       
   684             iconExtent := Point x:(col width) y:(col height).
       
   685         ] ifFalse:[
       
   686             col readSelector == #fileInfoString ifTrue:[
       
   687                 fileDescriptionIndex := anIndex.
       
   688             ] ifFalse:[
       
   689                 col readSelector == #icon ifTrue:[
       
   690                     iconIndex  := anIndex.
       
   691                 ]
       
   692             ]
       
   693         ]
       
   694     ].
       
   695 
       
   696 !
       
   697 
       
   698 directory
       
   699     "returns the current directory or nil
       
   700     "
       
   701     ^ directory
       
   702 
       
   703 !
       
   704 
       
   705 directory:aDirectory
       
   706     "change the current directory and read the items
       
   707     "
       
   708     directory := aDirectory.
       
   709     self readDirectory.
       
   710 !
       
   711 
       
   712 filterBlock
       
   713     "return the value of the instance variable 'filterBlock' (automatically generated)"
       
   714 
       
   715     ^ filterBlock
       
   716 !
       
   717 
       
   718 filterBlock:something
       
   719     "set the value of the instance variable 'filterBlock' (automatically generated)"
       
   720 
       
   721     filterBlock := something.
       
   722 !
       
   723 
       
   724 oldChangedIcon
       
   725 
       
   726     oldItemIcon isNil ifTrue:[
       
   727         oldItemIcon := Association new.
       
   728     ].
       
   729     ^ oldItemIcon
       
   730 !
       
   731 
       
   732 oldItemIcon
       
   733 
       
   734     oldItemIcon isNil ifTrue:[
       
   735         oldItemIcon := Association new.
       
   736     ].
       
   737     ^ oldItemIcon
       
   738 !
       
   739 
       
   740 sortBlock
       
   741 
       
   742 
       
   743     sortBlock isNil ifTrue:[
       
   744         self sortBlock:[ : a : b |
       
   745                             self sortCaseless value ifTrue:[
       
   746                                 a asString asLowercase < b asString asLowercase.
       
   747                             ] ifFalse:[
       
   748                                 a asString < b asString.
       
   749                             ]
       
   750                         ].
       
   751     ].
       
   752     ^ sortBlock
       
   753 !
       
   754 
       
   755 sortBlock:aSortBlock
       
   756 
       
   757 " sort directories before files anyway "
       
   758     sortBlock := [:a :b|
       
   759         | res |
       
   760         (self viewDirectoriesInDirectoryContentsBrowser
       
   761         and:[(a isDirectory == b isDirectory) not]) ifTrue:[
       
   762             res := a isDirectory 
       
   763         ] ifFalse:[
       
   764             res := aSortBlock value:a value:b.
       
   765         ].
       
   766         res
       
   767     ].
       
   768     ^ sortBlock
       
   769 !
       
   770 
       
   771 updateColumnsTask
       
   772     "return the value of the instance variable 'updateColumnsTask' (automatically generated)"
       
   773 
       
   774     ^ updateColumnsTask
       
   775 !
       
   776 
       
   777 updateColumnsTask:something
       
   778     "set the value of the instance variable 'updateColumnsTask' (automatically generated)"
       
   779 
       
   780     updateColumnsTask := something.
       
   781 !
       
   782 
       
   783 updateDirectoryContentsTask
       
   784     "return the value of the instance variable 'updateDirectoryContentsTask' (automatically generated)"
       
   785 
       
   786     ^ updateDirectoryContentsTask
       
   787 !
       
   788 
       
   789 updateDirectoryContentsTask:something
       
   790     "set the value of the instance variable 'updateDirectoryContentsTask' (automatically generated)"
       
   791 
       
   792     updateDirectoryContentsTask := something.
       
   793 !
       
   794 
       
   795 updateToExternFileHolderLock
       
   796     "return the value of the instance variable 'updateToExternFileHolder' (automatically generated)"
       
   797 
       
   798     updateToExternFileHolderLock isNil ifTrue:[
       
   799         updateToExternFileHolderLock := self class newLock.
       
   800     ].
       
   801     ^ updateToExternFileHolderLock
       
   802 ! !
       
   803 
       
   804 !DirectoryContentsBrowser methodsFor:'actions'!
       
   805 
       
   806 doResizeImage
       
   807     |column w h|
       
   808 
       
   809     previewIndex == 0 ifTrue:[^ self].
       
   810 
       
   811 
       
   812     column := columnDescriptors at:previewIndex.
       
   813     w := iconExtent x.
       
   814     h := iconExtent y.
       
   815 
       
   816     w == column width ifTrue:[
       
   817         w := w * 2.
       
   818         h := h * 2.
       
   819     ].
       
   820     column width:w.
       
   821     column height:h.
       
   822 
       
   823     self updateColumnsTaskStop.
       
   824     self descriptions do:[:el| el resetImageFile ].
       
   825     browser columnDescriptors:columnDescriptors.
       
   826     self updateColumnsTaskStart.
       
   827 !
       
   828 
       
   829 doUpdate
       
   830 
       
   831     modificationTime := nil.
       
   832     self updateDirectoryContentsTaskRestart.
       
   833 !
       
   834 
       
   835 doubleClickedAt:anIndex
       
   836     |item|
       
   837 
       
   838     item := self descriptions at:anIndex ifAbsent:nil.
       
   839     self enterActionFor:item.
       
   840 !
       
   841 
       
   842 enterActionFor:anItem
       
   843     | filename|
       
   844 
       
   845     filename := anItem fileName.
       
   846     filename = '..' asFilename ifTrue:[
       
   847         self currentFileNameHolder value:(OrderedCollection with:(self directory directory)).
       
   848         ^ self.
       
   849     ].
       
   850     filename isDirectory ifTrue:[
       
   851         self currentFileNameHolder value:(OrderedCollection with:filename).
       
   852         ^ self.
       
   853     ].
       
   854     self openApplByFileItem:anItem.
       
   855 !
       
   856 
       
   857 selectFileName:aColOfFilenames
       
   858     | indexInDescriptions curSel descr index|
       
   859 
       
   860     descr := self descriptions.
       
   861     indexInDescriptions := OrderedCollection new.
       
   862     aColOfFilenames do:[ : file |
       
   863         index := descr findFirst:[: item |
       
   864             item fileName = file.
       
   865         ].
       
   866         index ~= 0 ifTrue:[
       
   867             indexInDescriptions add:index.
       
   868         ]
       
   869     ].
       
   870     curSel := self selectionInFileList value.
       
   871     curSel = indexInDescriptions ifTrue:[
       
   872         ^ self.
       
   873     ].
       
   874     self selectionInFileList value:indexInDescriptions withoutNotifying:self.
       
   875 ! !
       
   876 
       
   877 !DirectoryContentsBrowser methodsFor:'aspects'!
       
   878 
       
   879 descriptions
       
   880     ^ self browserFileList
       
   881 !
       
   882 
       
   883 descriptions:aCol
       
   884 
       
   885     | showDir|
       
   886 
       
   887     self updateColumnsTaskStop.  "/ dont access rows while rows changed
       
   888     self updateToExternFileHolderLock doLocked:[
       
   889         aCol isEmpty ifTrue:[
       
   890             self descriptions contents:aCol.
       
   891         ] ifFalse:[
       
   892             showDir := self viewDirectoriesInDirectoryContentsBrowser value.
       
   893             (showDir and:[self directory isRootDirectory not]) ifTrue:[
       
   894                 aCol addFirst:(DirectoryContentsItem with:('..' asFilename)).
       
   895             ].
       
   896             self descriptions contents:aCol.
       
   897         ].
       
   898     ].
       
   899     self updateColumnsTaskStart.
       
   900     wantSelectFiles notNil ifTrue:[
       
   901         self selectFileName:wantSelectFiles.
       
   902     ].
       
   903 !
       
   904 
       
   905 tableColumns
       
   906     "automatically generated by UIPainter ..."
       
   907 
       
   908     "*** the code below creates a default model when invoked."
       
   909     "*** (which may not be the one you wanted)"
       
   910     "*** Please change as required and accept it in the browser."
       
   911     "*** (and replace this comment by something more useful ;-)"
       
   912 
       
   913     tableColumns isNil ifTrue:[
       
   914         tableColumns := self class tableColumns asValue.
       
   915 "/ if your app needs to be notified of changes, uncomment one of the lines below:
       
   916 "/       tableColumns addDependent:self.
       
   917 "/       tableColumns onChangeSend:#tableColumnsChanged to:self.
       
   918     ].
       
   919     ^ tableColumns.
       
   920 ! !
       
   921 
       
   922 !DirectoryContentsBrowser methodsFor:'change & update'!
       
   923 
       
   924 fileNamesChanged:aColOfFiles
       
   925     "filename changed
       
   926     "
       
   927     | newDir currentDir colDirectories|
       
   928 
       
   929 
       
   930     wantSelectFiles := aColOfFiles. "/ set the file to the current filename to change selection if update process have added the list
       
   931     aColOfFiles isEmpty ifTrue:[
       
   932         self directory:nil.
       
   933         ^ self
       
   934     ].
       
   935     colDirectories := self getDirectoriesForFileList:aColOfFiles.
       
   936     colDirectories asSet size > 1 ifTrue:[
       
   937         self directory:nil.
       
   938         ^ self
       
   939     ].
       
   940     newDir := colDirectories first.
       
   941     currentDir := self directory.
       
   942     newDir = currentDir ifTrue:[
       
   943         self selectFileName:aColOfFiles.
       
   944         ^ self.
       
   945     ] ifFalse:[
       
   946         "/ change of the directory filename 
       
   947         self directory:newDir.
       
   948     ].
       
   949 !
       
   950 
       
   951 filterChanged
       
   952 
       
   953     self filterBlock: [: el | (self showHiddenFiles value ifFalse:[
       
   954                             (el asString startsWith:'.') not])
       
   955                             and:[self filterModel value match:el]].
       
   956 
       
   957     self evaluateFilter.
       
   958 !
       
   959 
       
   960 update:something with:aParameter from:aModel
       
   961     "one of my models changed
       
   962     "
       
   963     | selection|
       
   964 
       
   965     aModel == self filterModel ifTrue:[
       
   966         self filterChanged.
       
   967         ^ self.
       
   968     ].             
       
   969     aModel == self sortBlockHolder ifTrue:[
       
   970         self sortList:(self sortBlockHolder value) withReverse:false.
       
   971         ^ self.
       
   972     ].             
       
   973     aModel == self currentFileNameHolder ifTrue:[
       
   974         self fileNamesChanged:aModel value.
       
   975         " do not return here because the AbstractFileBrowserComponent have to do something
       
   976           for every application "  
       
   977 "/        ^ self.
       
   978     ].             
       
   979     aModel == self sortCaseless ifTrue:[
       
   980         ^ self sortList:#baseName withReverse:false.
       
   981     ].             
       
   982     aModel == self selectionInFileList ifTrue:[
       
   983         self updateToExternFileHolderLock doIfUnLocked:[
       
   984             self directory isNil ifTrue:[^ self].   
       
   985             selection := self getSelectedFiles.
       
   986             selection isEmpty ifTrue:[
       
   987                 self currentFileNameHolder value:(OrderedCollection with:self directory) withoutNotifying:self.
       
   988             ] ifFalse:[
       
   989                 wantSelectFiles := selection.
       
   990                 self currentFileNameHolder value:selection withoutNotifying:self.
       
   991             ].
       
   992         ].
       
   993         ^ self.
       
   994     ].
       
   995     aModel == self viewDirectoriesInDirectoryContentsBrowser ifTrue:[
       
   996         self evaluateFilter.
       
   997         ^ self
       
   998     ].
       
   999 
       
  1000     super update:something with:aParameter from:aModel
       
  1001 !
       
  1002 
       
  1003 viewedColumnsChanged
       
  1004 
       
  1005     | columns buffer |
       
  1006 
       
  1007     columns := OrderedCollection new.
       
  1008     self class tableColumns do:[:el|
       
  1009         columns add:(DataSetColumnSpec new fromLiteralArrayEncoding:el).
       
  1010     ].
       
  1011     buffer := columns copy.
       
  1012     self viewDetails value = false ifTrue:[
       
  1013         browser showLabels:false.
       
  1014         buffer do:[:col |
       
  1015             (col readSelector = #baseName or:[col readSelector = #icon]) ifFalse:[
       
  1016                 columns remove:col.                
       
  1017             ]
       
  1018         ]
       
  1019     ] ifFalse:[
       
  1020         browser showLabels:true.
       
  1021         buffer do:[:col |
       
  1022             | id |
       
  1023             id := col id.
       
  1024             id notNil ifTrue:[
       
  1025 
       
  1026                 (id == #filename) ifTrue:[
       
  1027                         self viewType value ifTrue:[
       
  1028                             col readSelector:#baseNameWithOutSuffix
       
  1029                         ] ifFalse:[
       
  1030                             col readSelector:#baseName
       
  1031                         ].
       
  1032                     ] ifFalse:[
       
  1033                     (id == #suffix and:[self viewType value not]) ifTrue:[
       
  1034                         columns remove:col. 
       
  1035                         ] ifFalse:[
       
  1036                             (id == #group and:[self viewGroup value not]) ifTrue:[
       
  1037                                 columns remove:col. 
       
  1038                             ] ifFalse:[
       
  1039                                 (id == #owner and:[self viewOwner value not]) ifTrue:[
       
  1040                                     columns remove:col.
       
  1041                                 ] ifFalse:[
       
  1042                                     (id == #perm and:[self viewPermissions value not]) ifTrue:[
       
  1043                                         columns remove:col.
       
  1044                                     ] ifFalse:[
       
  1045                                         (id == #preview and:[self viewPreview value not]) ifTrue:[
       
  1046                                             columns remove:col.
       
  1047                                         ] ifFalse:[
       
  1048                                             (id == #size and:[self viewSize value not]) ifTrue:[
       
  1049                                                 columns remove:col.
       
  1050                                             ] ifFalse:[
       
  1051                                                 (id == #timeAndDate and:[self viewTime value not]) ifTrue:[
       
  1052                                                     columns remove:col.
       
  1053                                                 ] ifFalse:[
       
  1054                                                     (id == #fileInfo and:[self viewDescription value not]) ifTrue:[
       
  1055                                                         columns remove:col.
       
  1056                                                 ] 
       
  1057                                             ]
       
  1058                                         ]
       
  1059                                     ]
       
  1060                                 ]
       
  1061                             ]
       
  1062                         ]
       
  1063                     ]
       
  1064                 ]
       
  1065             ]
       
  1066         ]
       
  1067     ].
       
  1068     self tableColumns value:columns.
       
  1069     self columnDescriptors:(self tableColumns value).
       
  1070 ! !
       
  1071 
       
  1072 !DirectoryContentsBrowser methodsFor:'directory contents'!
       
  1073 
       
  1074 evaluateFilter
       
  1075 
       
  1076     | showDir|
       
  1077 
       
  1078     showDir := self viewDirectoriesInDirectoryContentsBrowser value.
       
  1079 
       
  1080     currentItemList := OrderedCollection new.
       
  1081     allItemsList size ~~ 0 ifTrue:[ 
       
  1082         self filterBlock isNil ifTrue:[
       
  1083             allItemsList do:[:aItem | 
       
  1084                 (showDir not and:[aItem isDirectory]) ifFalse:[
       
  1085                     currentItemList add:aItem 
       
  1086                 ]
       
  1087             ]
       
  1088         ] ifFalse:[
       
  1089             allItemsList do:[:aItem | 
       
  1090                 (showDir not and:[aItem isDirectory]) ifFalse:[
       
  1091                     (self filterBlock value:aItem baseName) ifTrue:[currentItemList add:aItem].
       
  1092                 ]
       
  1093             ]
       
  1094         ].
       
  1095     ].
       
  1096     self evaluateSortBlock.
       
  1097 !
       
  1098 
       
  1099 evaluateSortBlock
       
  1100 
       
  1101     | newList|
       
  1102 
       
  1103     newList := SortedCollection sortBlock:(self sortBlock).
       
  1104     newList addAll:currentItemList.
       
  1105     self descriptions:(newList asList).
       
  1106 !
       
  1107 
       
  1108 readDirectory
       
  1109 
       
  1110     self updateDirectoryContentsTaskStop.
       
  1111     allItemsList := self readDirectoryItems.
       
  1112     self evaluateFilter.  "/ filter makes a sort anyway
       
  1113     self updateDirectoryContentsTaskStart.
       
  1114 !
       
  1115 
       
  1116 readDirectoryItems
       
  1117 
       
  1118     |dir contents list|
       
  1119 
       
  1120 
       
  1121     dir := self directory.
       
  1122     list := OrderedCollection new.
       
  1123     dir notNil ifTrue:[
       
  1124         modificationTime := self directory modificationTime.
       
  1125         contents := self directory directoryContentsAsFilenames.
       
  1126         (contents ? #()) do:[:aFile|
       
  1127             list add:(DirectoryContentsItem with:aFile).
       
  1128         ].
       
  1129     ].
       
  1130     ^ list
       
  1131 ! !
       
  1132 
       
  1133 !DirectoryContentsBrowser methodsFor:'drag & drop'!
       
  1134 
       
  1135 canDrop:aContext argument:arg2 
       
  1136 
       
  1137     | dir archivListDrop source lineNr destinationItem dropToFile|
       
  1138 
       
  1139     dir := self directory.
       
  1140     dir isNil ifTrue:[ ^ false].
       
  1141     source := aContext dropSource.
       
  1142     source isNil ifTrue:[ ^ false].
       
  1143     archivListDrop := (source argument == #archivApplication).
       
  1144     lineNr := self getLineNumberFor:aContext.
       
  1145     lineNr notNil ifTrue:[
       
  1146         destinationItem := self descriptions at:lineNr.
       
  1147     ].
       
  1148     destinationItem isNil ifTrue:[
       
  1149         oldDropItem notNil ifTrue:[
       
  1150             self enqueueChangeDraggedItem:nil with:aContext.
       
  1151             oldDropItem := nil.
       
  1152         ].
       
  1153         dropToFile := self directory.
       
  1154     ] ifFalse:[
       
  1155         dropToFile := destinationItem fileName.
       
  1156     ].
       
  1157 
       
  1158     (destinationItem ~~ oldDropItem) ifTrue:[
       
  1159         oldDropItem := destinationItem.
       
  1160         self enqueueChangeDraggedItem:nil with:aContext.
       
  1161         (destinationItem notNil and:[destinationItem isDirectory]) ifTrue:[
       
  1162             self enqueueChangeDraggedItem:destinationItem with:aContext.
       
  1163         ].
       
  1164         archivListDrop ifTrue:[
       
  1165             lastResponse := self canDropArchiv:(aContext dropObjects) for:dropToFile.
       
  1166         ] ifFalse:[
       
  1167             lastResponse := self canDropFiles:(aContext dropObjects) for:dropToFile.
       
  1168         ]
       
  1169     ].
       
  1170     ^ lastResponse
       
  1171 !
       
  1172 
       
  1173 changeDraggedItem:anItem with:aDropContext
       
  1174 
       
  1175     self changeDraggedItem:anItem with:aDropContext saveDraw:true
       
  1176 !
       
  1177 
       
  1178 changeDraggedItem:anItem with:aDropContext saveDraw:saveDraw
       
  1179 
       
  1180     saveDraw ifTrue:[
       
  1181         aDropContext saveDraw:[
       
  1182             self changeIconFor:anItem.
       
  1183             self windowGroup processExposeEvents
       
  1184         ]
       
  1185     ] ifFalse:[
       
  1186         self changeIconFor:anItem.
       
  1187         self windowGroup processExposeEvents
       
  1188     ]
       
  1189 !
       
  1190 
       
  1191 changeIconFor:anItemOrNil
       
  1192     |icon oldItem|
       
  1193 
       
  1194     oldItem := self oldItemIcon.
       
  1195     (anItemOrNil isNil or:[(oldItem key) ~~ anItemOrNil]) ifTrue:[
       
  1196         (oldItem notNil and:[oldItem key notNil]) ifTrue:[
       
  1197             icon := oldItem value.
       
  1198             icon notNil ifTrue:[
       
  1199                 oldItem key icon:(oldItem value).
       
  1200                 browser invalidateVisibleRow:(oldItem key) colAt:iconIndex
       
  1201             ].
       
  1202         ].
       
  1203         oldItem key:anItemOrNil.
       
  1204 
       
  1205         anItemOrNil notNil ifTrue:[
       
  1206             oldItem value:(anItemOrNil icon).
       
  1207             icon := FileBrowser iconForKeyMatching:#directoryOpenGray.
       
  1208             icon notNil ifTrue:[
       
  1209                 anItemOrNil icon:icon.
       
  1210                 browser invalidateVisibleRow:anItemOrNil colAt:iconIndex
       
  1211             ].
       
  1212         ].
       
  1213     ].
       
  1214 !
       
  1215 
       
  1216 doDrop:aContext
       
  1217 
       
  1218     |col answer destinationPath source receiver lineNr destinationItem|
       
  1219 
       
  1220     source := aContext dropSource.
       
  1221     lineNr := self getLineNumberFor:aContext.
       
  1222     lineNr notNil ifTrue:[
       
  1223         destinationItem := self descriptions at:lineNr.
       
  1224     ].
       
  1225     destinationItem isNil ifTrue:[
       
  1226         destinationPath := self directory.
       
  1227     ] ifFalse:[
       
  1228         destinationPath := self getDirWithoutFileName:(destinationItem fileName).
       
  1229     ].
       
  1230     source argument == #archivApplication ifTrue:[
       
  1231         receiver := source receiver.
       
  1232         receiver extractSelectedFilesTo:destinationPath askForExtractOptions:true.
       
  1233         ^ true.
       
  1234     ].
       
  1235     col := OrderedCollection new.
       
  1236     aContext dropObjects do:[:obj|
       
  1237         col add:(obj theObject).
       
  1238     ].
       
  1239     answer := self copyOrMoveDialog:col.
       
  1240     
       
  1241     answer == #copy ifTrue:[
       
  1242         "/ copy files
       
  1243         self copyFiles:col to:destinationPath.
       
  1244     ].
       
  1245     answer == #move ifTrue:[
       
  1246         "/ copy files
       
  1247         self moveFiles:col to:destinationPath.
       
  1248     ].
       
  1249     ^ true
       
  1250 !
       
  1251 
       
  1252 doDrop:aContext argument:arg2 
       
  1253 
       
  1254     | aBoolean |
       
  1255 
       
  1256     aBoolean := self doDrop:aContext.
       
  1257     self dropLeave:aContext.
       
  1258     ^ aBoolean.
       
  1259 !
       
  1260 
       
  1261 doStartDrag:aDropSource in:aView
       
  1262     "set the cursors before starting the drag & drop operation
       
  1263     "
       
  1264     |sel|
       
  1265 
       
  1266 
       
  1267     sel := self selectionInFileList value.
       
  1268     ((((self descriptions at:(sel first)) fileName) = ('..' asFilename)) and:[ sel size == 1 ]) ifTrue:[
       
  1269         ^ self.
       
  1270     ].
       
  1271     super doStartDrag:aDropSource in:aView
       
  1272 !
       
  1273 
       
  1274 dropLeave:aDropContext
       
  1275 
       
  1276     oldDropItem := nil.
       
  1277     self changeDraggedItem:nil with:aDropContext saveDraw:false.
       
  1278     lastResponse := nil.
       
  1279 !
       
  1280 
       
  1281 enqueueChangeDraggedItem:anItem with:aContext 
       
  1282 
       
  1283     self enqueueMessage:#'changeDraggedItem:with:' for:self arguments:(Array with:anItem with:aContext) 
       
  1284 !
       
  1285 
       
  1286 getDisplayObjects:anArgument
       
  1287 
       
  1288     | sel string size fnName stream|
       
  1289     sel := self selectionInFileList value.
       
  1290     (((self descriptions at:(sel first)) fileName) = ('..' asFilename)) ifTrue:[
       
  1291         sel removeFirst.
       
  1292     ].
       
  1293     size := sel size.
       
  1294     size == 0  ifTrue:[^ ''].
       
  1295     stream := WriteStream on:''.
       
  1296     stream nextPutAll:(self descriptions at:sel first) fileName baseName asString.
       
  1297     size == 1 ifTrue:[
       
  1298         fnName := 'ui_menuitem.xpm'.
       
  1299     ] ifFalse:[
       
  1300         fnName := 'ui_submenu_open.xpm'.
       
  1301         stream nextPutAll:' ... '.
       
  1302         stream nextPutAll:(self descriptions at:sel last) fileName baseName asString.
       
  1303     ].
       
  1304     string := stream contents.
       
  1305     stream close.
       
  1306     ^ Array with:(LabelAndIcon icon:(Image fromFile:fnName)
       
  1307                              string:(Text string:string emphasis:#bold)
       
  1308                  )
       
  1309 !
       
  1310 
       
  1311 getDropObjects:anArgument
       
  1312 
       
  1313     | sel ret file|
       
  1314     sel := self selectionInFileList value.
       
  1315     ret := sel collect:[:el| 
       
  1316         file := (self descriptions at:el) fileName.
       
  1317         file ~= '..' asFilename ifTrue:[
       
  1318             DropObject newFile:((self descriptions at:el) fileName)
       
  1319         ]
       
  1320     ].
       
  1321     ^ ret
       
  1322 !
       
  1323 
       
  1324 getLineNumberFor:aDropContext
       
  1325     | yVisible|
       
  1326 
       
  1327     yVisible := (aDropContext targetPoint y).
       
  1328     ^ browser yVisibleToRowNr:yVisible.
       
  1329 ! !
       
  1330 
       
  1331 !DirectoryContentsBrowser methodsFor:'event handling'!
       
  1332 
       
  1333 processEvent:anEvent
       
  1334     "filter keyboard events.
       
  1335      Return true, if I have eaten the event"
       
  1336 
       
  1337     |focusView key rawKey|
       
  1338 
       
  1339     anEvent isKeyPressEvent ifTrue:[
       
  1340         focusView := anEvent targetView.
       
  1341         key := anEvent key.
       
  1342         rawKey := anEvent rawKey.
       
  1343 
       
  1344         (focusView == browser) ifTrue:[
       
  1345 "/            (key ~= #'Alt_L') ifTrue:[self halt.].
       
  1346             key == #Paste ifTrue:[
       
  1347                 self pasteFiles.
       
  1348                 ^ true.
       
  1349             ].
       
  1350             (key == #CursorLeft) ifTrue:[
       
  1351                 self doGoDirectoryUp.
       
  1352                 ^ true
       
  1353             ].
       
  1354             (key == #CursorRight) ifTrue:[
       
  1355                 self doBack.
       
  1356                 ^ true
       
  1357             ].
       
  1358             self descriptions size == 0 ifTrue:[
       
  1359                 ^ false
       
  1360             ].
       
  1361             key == #Copy ifTrue:[
       
  1362                 self doCopy.
       
  1363                 ^ true.
       
  1364             ].
       
  1365             (key == #Return) ifTrue:[
       
  1366                 self doOpenSelectedFile.
       
  1367                 ^ true.
       
  1368             ].
       
  1369             key == #Delete ifTrue:[
       
  1370                 self doDelete.
       
  1371                 ^ true.
       
  1372             ].
       
  1373             key == #Cut ifTrue:[
       
  1374                 self doCut.
       
  1375                 ^ true.
       
  1376             ].
       
  1377         ]
       
  1378     ].
       
  1379     ^ false
       
  1380 ! !
       
  1381 
       
  1382 !DirectoryContentsBrowser methodsFor:'file actions'!
       
  1383 
       
  1384 doCopy
       
  1385     "copy current selected files/directories
       
  1386     "
       
  1387 
       
  1388     self copyFilesToClipBoard:(self getFilesFromSelection).
       
  1389 !
       
  1390 
       
  1391 doCut
       
  1392     "cut current selected files/directories
       
  1393     "
       
  1394 
       
  1395     self cutFilesToClipBoard:(self getFilesFromSelection).
       
  1396 !
       
  1397 
       
  1398 doDelete
       
  1399     "delete current selected files/directories
       
  1400     "
       
  1401     self deleteFiles:(self getFilesFromSelection).
       
  1402 ! !
       
  1403 
       
  1404 !DirectoryContentsBrowser methodsFor:'menu accessing'!
       
  1405 
       
  1406 sortMenu
       
  1407 
       
  1408     <resource: #programMenu >
       
  1409 
       
  1410     |menu|
       
  1411 
       
  1412     menu :=  Menu new fromLiteralArrayEncoding:self class sortMenu.
       
  1413     menu ifNil:[ ^ nil ].
       
  1414     menu receiver:self.
       
  1415     ^ menu
       
  1416 !
       
  1417 
       
  1418 viewBrowserMenu
       
  1419 
       
  1420     <resource: #programMenu >
       
  1421 
       
  1422     |menu|
       
  1423 
       
  1424     menu :=  Menu new fromLiteralArrayEncoding:self class viewBrowserMenu.
       
  1425     menu ifNil:[ ^ nil ].
       
  1426     menu receiver:self.
       
  1427     ^ menu
       
  1428 ! !
       
  1429 
       
  1430 !DirectoryContentsBrowser methodsFor:'menu actions'!
       
  1431 
       
  1432 doOpenSelectedFile
       
  1433 
       
  1434     | sel index item|
       
  1435 
       
  1436     sel := self selectionInFileList value.
       
  1437     (sel notNil and:[sel notEmpty]) ifTrue:[
       
  1438         index := sel first.
       
  1439         item := self descriptions at:index ifAbsent:nil.
       
  1440         self enterActionFor:item.
       
  1441     ].
       
  1442 !
       
  1443 
       
  1444 doSelectAll
       
  1445 
       
  1446     | sel |
       
  1447 
       
  1448     sel := OrderedCollection new.
       
  1449     self descriptions keysAndValuesDo:[:index :value |
       
  1450         (index == 1 and:[(value fileName asString = '..')]) ifFalse:[
       
  1451             sel add:index.
       
  1452         ]
       
  1453     ].
       
  1454     self selectionInFileList value:sel.
       
  1455 !
       
  1456 
       
  1457 doShowFileContents
       
  1458 
       
  1459     | sel index item|
       
  1460 
       
  1461     sel := self selectionInFileList value.
       
  1462     (sel notNil and:[sel notEmpty]) ifTrue:[
       
  1463         index := sel first.
       
  1464         item := self descriptions at:index ifAbsent:nil.
       
  1465         self openTextEditorOn:item.
       
  1466     ].
       
  1467 ! !
       
  1468 
       
  1469 !DirectoryContentsBrowser methodsFor:'queries'!
       
  1470 
       
  1471 allItemsOfCurrentDirectory
       
  1472 
       
  1473     ^ self descriptions.
       
  1474 !
       
  1475 
       
  1476 fileListIsEmpty
       
  1477 
       
  1478     ^ self descriptions isEmpty
       
  1479 !
       
  1480 
       
  1481 getAllFilesAsStringCollection
       
  1482     |files items|
       
  1483 
       
  1484     items := self descriptions.
       
  1485     files := OrderedCollection new.
       
  1486     items isEmpty ifTrue:[
       
  1487         ^ files
       
  1488     ].
       
  1489     items do:[:aItem | 
       
  1490         aItem isDirectory not ifTrue:[
       
  1491             files add:aItem fileName asString
       
  1492         ].
       
  1493     ].
       
  1494     ^ files.
       
  1495 !
       
  1496 
       
  1497 getFileInfoStringForFirstSelectedFile:longInfo
       
  1498     "get stat info on selected file - return a string which can be
       
  1499      shown in a box"
       
  1500 
       
  1501     | item |
       
  1502 
       
  1503     ((item := self getFirstItemFromSelection) isNil) ifTrue:[^ nil].
       
  1504     ^ item getFileInfoString:longInfo
       
  1505 !
       
  1506 
       
  1507 getFileItemsFromSelection
       
  1508     |indices files|
       
  1509 
       
  1510     indices := self selectionInFileList value.
       
  1511     files := OrderedCollection new.
       
  1512     (indices isNil or:[indices isEmpty]) ifTrue:[
       
  1513         ^ files
       
  1514     ].
       
  1515     indices do:[:i | 
       
  1516         |item|
       
  1517 
       
  1518         item := self descriptions at:i.
       
  1519         item isDirectory not ifTrue:[
       
  1520             files add:item
       
  1521         ]
       
  1522     ].
       
  1523     ^ files.
       
  1524 !
       
  1525 
       
  1526 getFirstItemFromSelection
       
  1527     |indices|
       
  1528 
       
  1529     indices := self selectionInFileList value.
       
  1530     (indices isNil or:[indices isEmpty]) ifTrue:[
       
  1531         ^ nil
       
  1532     ].
       
  1533     ^ self descriptions at:(indices first).
       
  1534 !
       
  1535 
       
  1536 getItemsFromSelection
       
  1537     |indices items|
       
  1538 
       
  1539     indices := self selectionInFileList value.
       
  1540     items := OrderedCollection new.
       
  1541     (indices isNil or:[indices isEmpty]) ifTrue:[
       
  1542         ^ items
       
  1543     ].
       
  1544     indices do:[:i | 
       
  1545         |filename|
       
  1546 
       
  1547         items add:(self descriptions at:i)
       
  1548     ].
       
  1549     ^ items.
       
  1550 !
       
  1551 
       
  1552 getSelectedFiles
       
  1553 
       
  1554     |indices files|
       
  1555 
       
  1556     indices := self selectionInFileList value.
       
  1557     files := OrderedCollection new.
       
  1558     (indices isNil or:[indices isEmpty]) ifTrue:[
       
  1559         ^ files
       
  1560     ].
       
  1561     indices do:[:i | 
       
  1562         |filename|
       
  1563         filename := (self descriptions at:i) fileName.
       
  1564         filename asString ~= '..' ifTrue:[
       
  1565             files add:(self descriptions at:i) fileName
       
  1566         ]
       
  1567     ].
       
  1568     ^ files.
       
  1569 ! !
       
  1570 
       
  1571 !DirectoryContentsBrowser methodsFor:'sorting'!
       
  1572 
       
  1573 sortList:instanceName 
       
  1574 
       
  1575     self sortList:instanceName withReverse:true.
       
  1576 !
       
  1577 
       
  1578 sortList:instanceName withReverse:aBoolean
       
  1579 
       
  1580     | aSymbol cmpOp sortCaselessLocal|
       
  1581 
       
  1582     aSymbol := instanceName asSymbol.
       
  1583     sortCaselessLocal := self sortCaseless value.
       
  1584     currentSortOrder isNil ifTrue:[
       
  1585         currentSortOrder := aSymbol, sortCaselessLocal asString.
       
  1586         currentSortOrder := Dictionary new.
       
  1587         currentSortOrder at:#column put:aSymbol.
       
  1588         currentSortOrder at:#reverse put:false.
       
  1589         currentSortOrder at:#sortCaseless put:sortCaselessLocal.
       
  1590     ] ifFalse:[
       
  1591         (currentSortOrder at:#sortCaseless) ~= sortCaselessLocal ifTrue:[
       
  1592             "/ sort caseless changed
       
  1593             currentSortOrder at:#sortCaseless put:sortCaselessLocal.
       
  1594         ] ifFalse:[
       
  1595             (currentSortOrder at:#column) = aSymbol ifTrue:[
       
  1596                 "/ same column like before - change sort order ifReverse is true
       
  1597                 aBoolean ifTrue:[
       
  1598                     | isReverse |
       
  1599                     isReverse := currentSortOrder at:#reverse.
       
  1600                     currentSortOrder at:#reverse put:(isReverse not).
       
  1601                 ].
       
  1602             ] ifFalse:[
       
  1603                 "/ another column - remark column
       
  1604                 currentSortOrder at:#column put:aSymbol.
       
  1605             ]
       
  1606         ]
       
  1607     ].
       
  1608     (currentSortOrder at:#reverse) ifTrue:[
       
  1609         cmpOp := #'>'
       
  1610     ] ifFalse:[
       
  1611         cmpOp := #'<'
       
  1612     ].
       
  1613     self sortBlock: [:a :b | 
       
  1614             |entry1 entry2|
       
  1615 
       
  1616             entry1 := (a perform:aSymbol).
       
  1617             entry2 := (b perform:aSymbol).
       
  1618             ((entry1 isNil) or:[entry2 isNil]) ifTrue:[
       
  1619                 ((entry1 isNil) and:[entry2 isNil]) ifTrue:[true] ifFalse:[
       
  1620                     ((entry1 notNil) and:[entry2 isNil]) ifTrue:[
       
  1621                        (currentSortOrder at:#reverse)
       
  1622                     ].
       
  1623                     (currentSortOrder at:#reverse) not
       
  1624                 ]
       
  1625             ] ifFalse:[
       
  1626                 (aSymbol = #baseName) ifTrue:[
       
  1627                     sortCaselessLocal ifTrue:[
       
  1628                         entry1 := entry1 asString asLowercase.
       
  1629                         entry2 := entry2 asString asLowercase.
       
  1630                     ] ifFalse:[
       
  1631                         entry1 := entry1 asString.
       
  1632                         entry2 := entry2 asString.
       
  1633                     ].
       
  1634                 ].
       
  1635                 entry1 perform:cmpOp with:entry2
       
  1636             ]
       
  1637     ].
       
  1638     self sortBlockHolder value:instanceName.
       
  1639     self evaluateSortBlock.
       
  1640 ! !
       
  1641 
       
  1642 !DirectoryContentsBrowser methodsFor:'startup / release'!
       
  1643 
       
  1644 makeDependent
       
  1645 
       
  1646     self currentFileNameHolder addDependent:self.
       
  1647     self viewDirectoriesInDirectoryContentsBrowser addDependent:self.
       
  1648     self filterModel addDependent:self.
       
  1649     self sortBlockHolder addDependent:self.
       
  1650     self selectionInFileList addDependent:self.
       
  1651     self sortCaseless addDependent:self.
       
  1652     self viewDescription onChangeSend:#viewedColumnsChanged to:self.
       
  1653     self viewDetails onChangeSend:#viewedColumnsChanged to:self.
       
  1654     self viewGroup onChangeSend:#viewedColumnsChanged to:self.
       
  1655     self viewOwner onChangeSend:#viewedColumnsChanged to:self.
       
  1656     self viewPermissions onChangeSend:#viewedColumnsChanged to:self.
       
  1657     self viewPreview onChangeSend:#viewedColumnsChanged to:self.
       
  1658     self viewSize onChangeSend:#viewedColumnsChanged to:self.
       
  1659     self viewTime onChangeSend:#viewedColumnsChanged to:self.
       
  1660     self viewType onChangeSend:#viewedColumnsChanged to:self.
       
  1661     self showHiddenFiles onChangeSend:#filterChanged to:self.
       
  1662 !
       
  1663 
       
  1664 postBuildBrowser:aWidget
       
  1665 
       
  1666     browser       := aWidget scrolledView.
       
  1667     browser wantsFocusWithPointerEnter.
       
  1668 "/ dont register icons anymore
       
  1669 "/    FileBrowser icons keysAndValuesDo:[:aKey :anIcon|
       
  1670 "/        browser registerImage:anIcon key:aKey.
       
  1671 "/    ].
       
  1672     self columnDescriptors:(self class tableColumns).
       
  1673 !
       
  1674 
       
  1675 postBuildWith:aBuilder
       
  1676 
       
  1677     self viewedColumnsChanged.
       
  1678     self filterChanged.
       
  1679     ^ super postBuildWith:aBuilder.
       
  1680 !
       
  1681 
       
  1682 postOpenAsSubcanvasWith:aBuilder
       
  1683 
       
  1684     self windowGroup addPreEventHook:self.
       
  1685     ^ super postOpenAsSubcanvasWith:aBuilder.
       
  1686 !
       
  1687 
       
  1688 postOpenWith:aBuilder
       
  1689 
       
  1690     "
       
  1691     only invoked if the application not started from a master
       
  1692     "
       
  1693     self currentFileNameHolder changed.
       
  1694     self windowGroup addPreEventHook:self.
       
  1695     ^ super postOpenWith:aBuilder.
       
  1696 !
       
  1697 
       
  1698 preBuildWith:aBuilder
       
  1699 
       
  1700     self masterApplication isNil ifTrue:[
       
  1701         self masterApplication:nil.
       
  1702     ].
       
  1703     ^ super preBuildWith:aBuilder.
       
  1704 !
       
  1705 
       
  1706 release
       
  1707     "release my resources
       
  1708     "                    
       
  1709     self updateColumnsTaskStop.
       
  1710     self updateDirectoryContentsTaskStop.
       
  1711     super release.
       
  1712 !
       
  1713 
       
  1714 releaseAsSubCanvas
       
  1715 
       
  1716     self updateColumnsTaskStop.
       
  1717     self updateDirectoryContentsTaskStop.
       
  1718     ^ super releaseAsSubCanvas.
       
  1719 ! !
       
  1720 
       
  1721 !DirectoryContentsBrowser methodsFor:'task update columns'!
       
  1722 
       
  1723 findNextBuildInDescFor:aBlock
       
  1724     |vis idx|
       
  1725 
       
  1726     vis := browser indexOfFirstRowShown.
       
  1727     vis = 0 ifTrue:[vis := 1].
       
  1728     idx := self descriptions findFirst:aBlock startingAt:vis.
       
  1729 
       
  1730     idx == 0 ifTrue:[
       
  1731         (idx := self descriptions findLast:aBlock startingAt:(vis - 1)) == 0 ifTrue:[
       
  1732             ^ nil
       
  1733         ]
       
  1734     ].
       
  1735     ^ self descriptions at:idx ifAbsent:nil
       
  1736 !
       
  1737 
       
  1738 findNextItemFor:aBlock
       
  1739 
       
  1740    ^ allItemsList detect:aBlock ifNone:[nil].
       
  1741 !
       
  1742 
       
  1743 getFileInfoFor:aItem
       
  1744 
       
  1745     | type|
       
  1746 
       
  1747     type := aItem fileName fileType.
       
  1748     aItem fileType:type.
       
  1749     ^ type
       
  1750 !
       
  1751 
       
  1752 getIconFor:aItem
       
  1753 
       
  1754     | key icon|
       
  1755     key := aItem iconKey.
       
  1756     icon := FileBrowser iconForKeyMatching:key.
       
  1757     ^ FileBrowser addOnIconsFor:(aItem fileName) to:icon.
       
  1758 !
       
  1759 
       
  1760 getIconForMimeTypeByContents:aItem
       
  1761 
       
  1762     | currentIcon newIcon icon|
       
  1763     newIcon := FileBrowser iconForKeyMatching:(aItem mimeTypeForContents).
       
  1764     currentIcon := aItem icon.
       
  1765     (currentIcon class == MultiImage) ifTrue:[
       
  1766         | images |
       
  1767         images := currentIcon images.
       
  1768         images removeFirst.
       
  1769         images addFirst:newIcon.
       
  1770         icon := currentIcon.
       
  1771     ] ifFalse:[
       
  1772         icon := newIcon.
       
  1773     ].
       
  1774     ^ icon
       
  1775 !
       
  1776 
       
  1777 getPreviewFor:aItem
       
  1778 
       
  1779     | column icon|
       
  1780     
       
  1781     column := browser columnAt:previewIndex.
       
  1782     column isNil ifTrue:[
       
  1783         previewIndex := 0.
       
  1784     ] ifFalse:[
       
  1785         (aItem hasMimeType and:[aItem mimeType isImage]) ifTrue:[
       
  1786             Exception handle:[:ex|
       
  1787                 icon := nil.
       
  1788             ] do:[ |scale extent w h |
       
  1789                 icon := Image fromFile:(aItem pathName).
       
  1790                 icon notNil ifTrue:[
       
  1791                     extent := icon extent.
       
  1792                     w := column width - 4.
       
  1793                     h := column height.
       
  1794 
       
  1795                     (extent x > w or:[extent y > h]) ifTrue:[
       
  1796                         scale := extent / (w@h).
       
  1797                         scale := scale x max:(scale y).
       
  1798                         icon  := icon magnifiedTo:((extent / scale max:8.0) asInteger).
       
  1799                     ].
       
  1800                     icon := icon onDevice:(browser device).
       
  1801                     icon clearMaskedPixels.
       
  1802                 ]
       
  1803             ]
       
  1804         ] ifFalse:[ icon := nil].
       
  1805         aItem preview:(icon ? '').
       
  1806     ].
       
  1807     ^ icon
       
  1808 !
       
  1809 
       
  1810 updateChangesFor:aItem
       
  1811 
       
  1812     aItem modifiedByMe ifTrue:[
       
  1813         aItem modifiedByMe:false.
       
  1814     ] ifFalse:[
       
  1815         self notifyChannel value:aItem fileName asString, ' was changed by someone else'.
       
  1816         aItem resetItemForChangesFromSomeOneElse.
       
  1817     ].
       
  1818 !
       
  1819 
       
  1820 updateColumnsTaskCycle
       
  1821 
       
  1822 " update items in the foolowing order
       
  1823     - update item if item properties are changed
       
  1824     - update icon for visible items by suffix
       
  1825     - update icon for visible items by contents
       
  1826     - update file info for visible items if file info column is shown 
       
  1827     - update preview for visible items if preview column is shown 
       
  1828 
       
  1829     - update icon for invisible items by suffix
       
  1830     - update icon for invisible items by contents
       
  1831     - update file info for invisible items if file info column is shown 
       
  1832     - update preview for invisible items if preview column is shown 
       
  1833     - update file info for invisible items if file info column is not shown 
       
  1834 "
       
  1835 
       
  1836     |desc icon type preview|
       
  1837 
       
  1838     currentItemList notEmpty ifTrue:[
       
  1839         "/ update item if item properties are changed
       
  1840         desc := self findNextBuildInDescFor:[:n| n changedForDirectoryContentsBrowser ].
       
  1841         
       
  1842         desc notNil ifTrue:[
       
  1843             browser invalidateVisibleRow:desc.
       
  1844             self updateChangesFor:desc.
       
  1845             ^ true.
       
  1846         ].
       
  1847         "/ update icon for visible items by suffix
       
  1848         desc := self findNextBuildInDescFor:[:n| n icon isNil ].
       
  1849         desc notNil ifTrue:[
       
  1850             icon := self getIconFor:desc.
       
  1851             desc icon:icon.
       
  1852             (icon notNil and:[iconIndex ~~ 0]) ifTrue:[
       
  1853                 browser invalidateVisibleRow:desc colAt:iconIndex
       
  1854             ].
       
  1855             ^ true
       
  1856         ].
       
  1857         "/ update icon for visible items by contents
       
  1858         desc := self findNextBuildInDescFor:[:n| 
       
  1859             (n iconKey == #file 
       
  1860             and:[n mimeTypeForContents asSymbol ~= #unknown])
       
  1861         ].
       
  1862         desc notNil ifTrue:[
       
  1863             icon := self getIconForMimeTypeByContents:desc.
       
  1864             desc icon:icon.
       
  1865             (icon notNil and:[iconIndex ~~ 0]) ifTrue:[
       
  1866                 browser invalidateVisibleRow:desc colAt:iconIndex
       
  1867             ].
       
  1868             ^ true
       
  1869         ].
       
  1870         "/ update file info for visible items if file info column is shown
       
  1871         fileDescriptionIndex ~~ 0 ifTrue:[
       
  1872             desc := self findNextBuildInDescFor:[:n| n fileType isNil ].
       
  1873             desc notNil ifTrue:[
       
  1874                 type := self getFileInfoFor:desc.
       
  1875                 type notNil ifTrue:[browser invalidateVisibleRow:desc colAt:fileDescriptionIndex].
       
  1876                 ^ true
       
  1877             ]
       
  1878         ].
       
  1879         "/ update preview for visible items if preview column is shown
       
  1880         previewIndex ~~ 0 ifTrue:[
       
  1881             desc := self findNextBuildInDescFor:[:n| n preview isNil ].
       
  1882             desc notNil ifTrue:[
       
  1883                 preview := self getPreviewFor:desc.
       
  1884                 preview notNil ifTrue:[
       
  1885                     browser invalidateVisibleRow:desc colAt:previewIndex
       
  1886                 ].
       
  1887                 ^ true
       
  1888             ]
       
  1889         ].
       
  1890     ].
       
  1891 
       
  1892     "/ may we want to see the other items later make this items to
       
  1893     allItemsList notEmpty ifTrue:[
       
  1894         "/ update icon for invisible items by suffix
       
  1895         desc := self findNextItemFor:[:n| n icon isNil ].
       
  1896         desc notNil ifTrue:[
       
  1897             icon := self getIconFor:desc.
       
  1898             desc icon:icon.
       
  1899             ^ true
       
  1900         ].
       
  1901         "/ update icon for invisible items by contents
       
  1902         desc := self findNextItemFor:[:n| (n iconKey == #file and:[n mimeTypeForContents ~= #unknown])].
       
  1903         desc notNil ifTrue:[
       
  1904             icon := self getIconForMimeTypeByContents:desc.
       
  1905             desc icon:icon.
       
  1906             ^ true
       
  1907         ].
       
  1908         "/ update file info for invisible items if file info column is shown
       
  1909         fileDescriptionIndex ~~ 0 ifTrue:[
       
  1910             desc := self findNextItemFor:[:n| n fileType isNil ].
       
  1911             desc notNil ifTrue:[
       
  1912                 self getFileInfoFor:desc.
       
  1913                 ^ true
       
  1914             ].
       
  1915         ].
       
  1916         "/ update preview for invisible items if preview column is shown 
       
  1917         previewIndex ~~ 0 ifTrue:[
       
  1918             desc := self findNextItemFor:[:n| n preview isNil ].
       
  1919             desc notNil ifTrue:[
       
  1920                 self getPreviewFor:desc.
       
  1921                 ^ true
       
  1922             ].
       
  1923         ].
       
  1924         "/ update file info for invisible items if file info column is not shown
       
  1925         desc := self findNextItemFor:[:n| n fileType isNil ].
       
  1926         desc notNil ifTrue:[
       
  1927             self getFileInfoFor:desc.
       
  1928             ^ true
       
  1929         ].
       
  1930     ].
       
  1931     ^ false
       
  1932 !
       
  1933 
       
  1934 updateColumnsTaskRestart
       
  1935 
       
  1936     self updateColumnsTaskStop.
       
  1937     self updateColumnsTaskStart.
       
  1938 !
       
  1939 
       
  1940 updateColumnsTaskStart
       
  1941 
       
  1942     | somethigToDo p |
       
  1943 
       
  1944     somethigToDo := true.
       
  1945     self directory notNil ifTrue:[
       
  1946         p := [ 
       
  1947                  [   
       
  1948                      [true] whileTrue:[
       
  1949                          somethigToDo := false.
       
  1950                          (browser shown and:[self directory notNil]) ifTrue:[
       
  1951                              somethigToDo := self updateColumnsTaskCycle.
       
  1952                              Processor yield.
       
  1953                          ].
       
  1954                          somethigToDo ifFalse:[
       
  1955                              Delay waitForSeconds:1.0
       
  1956                          ]
       
  1957                      ]
       
  1958                  ] valueNowOrOnUnwindDo:[
       
  1959                      self updateColumnsTask:nil.
       
  1960                  ]
       
  1961              ] newProcess.
       
  1962         p priority:(Processor systemBackgroundPriority).
       
  1963 
       
  1964         self updateColumnsTask: p.   
       
  1965         self updateColumnsTask name:('DirectoryContentsBrowser update columns[', self directory baseName, ']').
       
  1966         self updateColumnsTask resume.
       
  1967     ]
       
  1968 !
       
  1969 
       
  1970 updateColumnsTaskStop
       
  1971     |task|
       
  1972 
       
  1973     (task := self updateColumnsTask) notNil ifTrue:[
       
  1974         self updateColumnsTask:nil.
       
  1975 
       
  1976         Object errorSignal handle:[:ex|
       
  1977             Dialog warn:ex description.
       
  1978         ]do:[
       
  1979             task isDead ifFalse:[
       
  1980                 task terminateWithAllSubprocesses.
       
  1981                 task waitUntilTerminated.
       
  1982             ]
       
  1983         ]
       
  1984     ].
       
  1985 ! !
       
  1986 
       
  1987 !DirectoryContentsBrowser methodsFor:'task update dir contents'!
       
  1988 
       
  1989 updateDirectoryContentsTaskCycle
       
  1990 
       
  1991     | contents|
       
  1992 
       
  1993     "/ DIRECTORY CONTNETS HAVE CHANGED
       
  1994     (modificationTime ~= self directory modificationTime) ifTrue:[
       
  1995         modificationTime := self directory modificationTime.
       
  1996         contents := self directory directoryContentsAsFilenames.
       
  1997         contents size == 0 ifTrue:[ 
       
  1998             allItemsList removeAll. 
       
  1999         ] ifFalse:[
       
  2000             "/ MERGE WITH CURRENT CONTENTS
       
  2001             allItemsList reverseDo:[:aDesc|
       
  2002                 "/ remove no longer valid files
       
  2003                 (contents detect:[:f| aDesc fileName = f] ifNone:nil) isNil ifTrue:[
       
  2004                     allItemsList removeIdentical:aDesc
       
  2005                 ]
       
  2006             ].
       
  2007             allItemsList size ~~ contents size ifTrue:[
       
  2008                 "/ add new files
       
  2009                 | addedFiles |
       
  2010                 addedFiles := OrderedCollection new.
       
  2011                 contents reverseDo:[:aFile|
       
  2012                     (allItemsList detect:[:item| item fileName = aFile] ifNone:[nil]) isNil ifTrue:[
       
  2013                         addedFiles add:(DirectoryContentsItem with:aFile)
       
  2014                     ]
       
  2015                 ].
       
  2016                 allItemsList addAll:addedFiles.
       
  2017             ]
       
  2018         ].
       
  2019         self evaluateFilter.
       
  2020     ].
       
  2021 !
       
  2022 
       
  2023 updateDirectoryContentsTaskRestart
       
  2024 
       
  2025     self updateDirectoryContentsTaskStop.
       
  2026     self updateDirectoryContentsTaskStart.
       
  2027 !
       
  2028 
       
  2029 updateDirectoryContentsTaskStart
       
  2030     |p|
       
  2031 
       
  2032     self directory notNil ifTrue:[
       
  2033         p := [ 
       
  2034                  [   
       
  2035                      [true] whileTrue:[
       
  2036                          (browser shown and:[self directory notNil]) ifTrue:[
       
  2037                              self updateDirectoryContentsTaskCycle.
       
  2038                              Processor yield.
       
  2039                          ].
       
  2040                          Delay waitForSeconds:1.0
       
  2041                      ]
       
  2042                  ] valueNowOrOnUnwindDo:[
       
  2043                      self updateDirectoryContentsTask:nil.
       
  2044                      self updateColumnsTaskStop.
       
  2045                  ]
       
  2046               ] newProcess.
       
  2047 
       
  2048         p priority:(Processor systemBackgroundPriority).
       
  2049         self updateDirectoryContentsTask:p.
       
  2050 
       
  2051         p name:('DirectoryContentsBrowser update contents[', self directory baseName, ']').
       
  2052         p resume.
       
  2053     ]
       
  2054 !
       
  2055 
       
  2056 updateDirectoryContentsTaskStop
       
  2057     |task|
       
  2058 
       
  2059     (task := self updateDirectoryContentsTask) notNil ifTrue:[
       
  2060         self updateDirectoryContentsTask:nil.
       
  2061 
       
  2062         Object errorSignal handle:[:ex|
       
  2063             Dialog warn:ex description.
       
  2064         ]do:[
       
  2065             task isDead ifFalse:[
       
  2066                 task terminateWithAllSubprocesses.
       
  2067                 task waitUntilTerminated.
       
  2068             ]
       
  2069         ]
       
  2070     ].
       
  2071 ! !
       
  2072 
       
  2073 !DirectoryContentsBrowser::DirectoryContentsItem class methodsFor:'instance creation'!
       
  2074 
       
  2075 with:aFilename
       
  2076 
       
  2077     | instance |
       
  2078     instance := self new.
       
  2079     instance fileName:aFilename.
       
  2080     instance initialize.
       
  2081     ^ instance
       
  2082 ! !
       
  2083 
       
  2084 !DirectoryContentsBrowser::DirectoryContentsItem methodsFor:'accessing'!
       
  2085 
       
  2086 fileName
       
  2087     "returns the fileName
       
  2088     "
       
  2089     ^ fileName
       
  2090 
       
  2091 
       
  2092 !
       
  2093 
       
  2094 fileName:aFilename
       
  2095     "set fileName for instance
       
  2096     "
       
  2097     fileName := aFilename.
       
  2098 !
       
  2099 
       
  2100 fileType
       
  2101     "returns the type of the file
       
  2102     "
       
  2103 
       
  2104     ^ fileType 
       
  2105 !
       
  2106 
       
  2107 fileType:aType
       
  2108     "returns the type of the file
       
  2109     "
       
  2110 
       
  2111     fileType := aType.
       
  2112 !
       
  2113 
       
  2114 icon
       
  2115     "returns the icon assigned to the file
       
  2116     "
       
  2117     ^ icon
       
  2118 
       
  2119 
       
  2120 !
       
  2121 
       
  2122 icon:anIcon
       
  2123 
       
  2124     icon := anIcon.
       
  2125 !
       
  2126 
       
  2127 iconKey
       
  2128     "return the value of the instance variable 'iconKey' (automatically generated)"
       
  2129 
       
  2130     iconKey isNil ifTrue:[
       
  2131         iconKey := FileBrowser iconKeyForFile:(self fileName).
       
  2132     ].
       
  2133     ^ iconKey
       
  2134 !
       
  2135 
       
  2136 isDirectory
       
  2137     "return the value of the instance variable 'isDirectory' (automatically generated)"
       
  2138 
       
  2139     isDirectory isNil ifTrue:[
       
  2140         isDirectory := self fileName isDirectory.
       
  2141     ].
       
  2142     ^ isDirectory
       
  2143 !
       
  2144 
       
  2145 lastButOneSuffix
       
  2146     "returns the suffix of the file
       
  2147     "
       
  2148 
       
  2149     ^ self suffixes at:2
       
  2150 !
       
  2151 
       
  2152 lastSuffix
       
  2153     "returns the suffix of the file
       
  2154     "
       
  2155 
       
  2156     ^ self suffixes at:1
       
  2157 !
       
  2158 
       
  2159 link
       
  2160     "returns the type of the file
       
  2161     "
       
  2162     link isNil ifTrue:[
       
  2163         link := fileName isSymbolicLink.
       
  2164     ].
       
  2165     ^ link
       
  2166 !
       
  2167 
       
  2168 linkInfo
       
  2169     "returns the type of the file
       
  2170     "
       
  2171     linkInfo isNil ifTrue:[
       
  2172         linkInfo := self fileName linkInfo.
       
  2173     ].
       
  2174     ^ linkInfo
       
  2175 !
       
  2176 
       
  2177 mimeType
       
  2178     "return the value of the instance variable 'mimeType' (automatically generated)"
       
  2179 
       
  2180     mimeType isNil ifTrue:[
       
  2181         mimeType := MIMETypes mimeTypeForFilename:(self fileName).
       
  2182         mimeType isNil ifTrue:[
       
  2183             mimeType := #unknown
       
  2184         ]
       
  2185     ].
       
  2186     ^ mimeType
       
  2187 !
       
  2188 
       
  2189 modifiedByMe
       
  2190     "return the value of the instance variable 'modifiedByMe' (automatically generated)"
       
  2191 
       
  2192     ^ modifiedByMe
       
  2193 !
       
  2194 
       
  2195 modifiedByMe:something
       
  2196     "set the value of the instance variable 'modifiedByMe' (automatically generated)"
       
  2197 
       
  2198     modifiedByMe := something.
       
  2199 !
       
  2200 
       
  2201 preview
       
  2202 
       
  2203     ^ preview
       
  2204 !
       
  2205 
       
  2206 preview:aLabel
       
  2207 
       
  2208     preview := aLabel.
       
  2209 !
       
  2210 
       
  2211 suffix
       
  2212     "returns the suffix of the file
       
  2213     "
       
  2214     suffix isNil ifTrue:[
       
  2215         (OperatingSystem isUNIXlike and:[(self baseName at:1) == $.]) ifTrue:[
       
  2216             suffix := ''.
       
  2217         ] ifFalse:[
       
  2218             suffix := fileName suffix.
       
  2219         ]
       
  2220     ].
       
  2221     ^ suffix
       
  2222 !
       
  2223 
       
  2224 suffixes
       
  2225 
       
  2226     | lastSuff lastButOneSuff|
       
  2227 
       
  2228 
       
  2229     suffixes isNil ifTrue:[
       
  2230         ((lastSuff := self suffix) isEmpty) ifTrue:[  
       
  2231             lastSuff := nil.
       
  2232         ] ifFalse:[
       
  2233             lastSuff := lastSuff asLowercase. 
       
  2234         ].
       
  2235         ((lastButOneSuff := fileName withoutSuffix suffix) isEmpty) ifTrue:[  
       
  2236             lastButOneSuff := nil.
       
  2237         ] ifFalse:[
       
  2238             lastButOneSuff := lastButOneSuff asLowercase. 
       
  2239         ].
       
  2240 
       
  2241         (lastSuff notNil and:[lastButOneSuff notNil]) ifTrue:[
       
  2242             (lastSuff = 'bak' or:[lastSuff = 'sav']) ifTrue:[
       
  2243                 lastSuff := lastButOneSuff.
       
  2244                 lastButOneSuff := nil.
       
  2245             ]
       
  2246         ].
       
  2247         suffixes := Array with:lastSuff with:lastButOneSuff
       
  2248     ].
       
  2249     ^ suffixes
       
  2250 !
       
  2251 
       
  2252 type
       
  2253     "returns the type of the file
       
  2254     "
       
  2255     ^ self valueAt:#type
       
  2256 
       
  2257 ! !
       
  2258 
       
  2259 !DirectoryContentsBrowser::DirectoryContentsItem methodsFor:'actions'!
       
  2260 
       
  2261 resetImageFile
       
  2262 
       
  2263     " if the image preview extent is changed the icon will set to nil to force the update task to reload the image "
       
  2264 
       
  2265     (mimeType notNil and:[ mimeType isImage]) ifTrue:[
       
  2266         preview := nil
       
  2267     ]
       
  2268 !
       
  2269 
       
  2270 resetItemForChangesFromSomeOneElse
       
  2271 
       
  2272     " dont know what someone else is doing with the file - read all item properties new "
       
  2273     link := nil.
       
  2274     linkInfo := nil.
       
  2275     fileInfo := nil.
       
  2276     size := nil.
       
  2277     icon := nil.
       
  2278     link := nil.
       
  2279     fileType := nil.
       
  2280     preview := nil.
       
  2281     owner := nil.
       
  2282     modificationTime := nil.
       
  2283     permissions := nil.
       
  2284     timeAndDate := nil.
       
  2285     date := nil.
       
  2286     group := nil.
       
  2287 !
       
  2288 
       
  2289 resetItemForTextEditorChange
       
  2290 
       
  2291     " read size and time item properties new "
       
  2292     size := nil.
       
  2293     linkInfo := nil.
       
  2294     fileInfo := nil.
       
  2295     timeAndDate := nil.
       
  2296     date := nil.
       
  2297     modificationTime := nil.
       
  2298     modifiedByMe := true.
       
  2299 "/    textEditorChangeModificationTime := nil.
       
  2300 ! !
       
  2301 
       
  2302 !DirectoryContentsBrowser::DirectoryContentsItem methodsFor:'change queries'!
       
  2303 
       
  2304 changedForDirectoryContentsBrowser
       
  2305 
       
  2306     "check if item modification time is changed 
       
  2307     "
       
  2308     | time info|
       
  2309 
       
  2310     info := fileName asAbsoluteFilename info.
       
  2311     info isNil ifTrue:[ ^ false].
       
  2312     time := info modified.
       
  2313     contentsBrowserChangeModificationTime isNil ifTrue:[
       
  2314         contentsBrowserChangeModificationTime := time.
       
  2315         ^ false.
       
  2316     ].
       
  2317     ((contentsBrowserChangeModificationTime = time) not) ifTrue:[
       
  2318         contentsBrowserChangeModificationTime := time.
       
  2319         ^ true
       
  2320     ].
       
  2321     ^ false
       
  2322 ! !
       
  2323 
       
  2324 !DirectoryContentsBrowser::DirectoryContentsItem methodsFor:'compare'!
       
  2325 
       
  2326 = aItem
       
  2327 
       
  2328 "/    Transcript showCR:(aItem species == self species).
       
  2329     aItem species == self species ifFalse:[  ^ false].
       
  2330     aItem isNil ifTrue:[ ^ false].
       
  2331     ^ (self fileName = aItem fileName)
       
  2332 !
       
  2333 
       
  2334 hash
       
  2335     ^ fileName hash
       
  2336 ! !
       
  2337 
       
  2338 !DirectoryContentsBrowser::DirectoryContentsItem methodsFor:'instance creation'!
       
  2339 
       
  2340 initialize
       
  2341     "initialize instance 
       
  2342     "
       
  2343     contentsBrowserChangeModificationTime := (self valueAt:#modified).  "/ remark modification to get changes of file in contents browser
       
  2344 ! !
       
  2345 
       
  2346 !DirectoryContentsBrowser::DirectoryContentsItem methodsFor:'presentation'!
       
  2347 
       
  2348 baseName
       
  2349     "returns the baseName of the file
       
  2350     "
       
  2351     baseName isNil ifTrue:[
       
  2352         baseName := fileName baseName.
       
  2353     ].
       
  2354     ^ baseName
       
  2355 !
       
  2356 
       
  2357 baseName:aName
       
  2358     "rename the file
       
  2359     "
       
  2360     ^ self
       
  2361 !
       
  2362 
       
  2363 baseNameWithOutSuffix
       
  2364     "returns the baseName of the file
       
  2365     "
       
  2366     | baseNameWithOutSuff |
       
  2367 
       
  2368     baseNameWithOutSuff := self baseName asFilename withoutSuffix asString.
       
  2369     baseNameWithOutSuff isEmpty ifTrue:[
       
  2370         ^ self baseName
       
  2371     ].
       
  2372     ^ baseNameWithOutSuff.
       
  2373 !
       
  2374 
       
  2375 date
       
  2376     "returns the date
       
  2377     "
       
  2378     | modTime |
       
  2379 
       
  2380     date isNil ifTrue:[
       
  2381         modTime := self valueAt:#modified.
       
  2382         modTime isNil ifTrue:[
       
  2383             date := '???'
       
  2384         ] ifFalse:[
       
  2385             date := modTime asDate printString.
       
  2386         ]
       
  2387     ].
       
  2388     ^ date
       
  2389 !
       
  2390 
       
  2391 fileInfoString
       
  2392     "get stat info on selected file - return a string which can be
       
  2393      shown in a box"
       
  2394 
       
  2395     | afileType |
       
  2396 
       
  2397     fileName isNil ifTrue:[^ nil].
       
  2398     afileType := self fileType.
       
  2399     afileType isNil ifTrue:[
       
  2400         ^ ''.
       
  2401     ].
       
  2402     ^ afileType
       
  2403 !
       
  2404 
       
  2405 getFileInfoString:longInfo
       
  2406     "get stat info on selected file - return a string which can be
       
  2407      shown in a box"
       
  2408 
       
  2409     | filename text fileOutput type modeBits modeString s ts|
       
  2410 
       
  2411     filename := self fileName.
       
  2412 
       
  2413     text := StringCollection new.
       
  2414 
       
  2415     text add:('filename: ', filename asString).
       
  2416     self link ifTrue:[
       
  2417         text add:('symbolic link to: ', (self linkInfo path))
       
  2418     ].
       
  2419 
       
  2420     type := self valueAt:#type.
       
  2421     (longInfo and:[type == #regular]) ifTrue:[
       
  2422         fileOutput := self fileType.
       
  2423     ].
       
  2424 
       
  2425     s := ('type:   ').
       
  2426     fileOutput isNil ifTrue:[
       
  2427         s := s ,  type asString
       
  2428     ] ifFalse:[
       
  2429         s := s , 'regular (' , fileOutput , ')'
       
  2430     ].
       
  2431     text add:s.
       
  2432     text add:('size:   ', (self valueAt:#size) printString).
       
  2433 
       
  2434     modeBits := self valueAt:#mode.
       
  2435     modeString := self getModeString:modeBits.
       
  2436     longInfo ifTrue:[
       
  2437         text add:('access: ', modeString,' ', (modeBits printStringRadix:8)).
       
  2438     ] ifFalse:[
       
  2439         text add:('access: ', modeString)
       
  2440     ].
       
  2441     text add:('owner:  ',
       
  2442                (OperatingSystem getUserNameFromID:(self valueAt:#uid))).
       
  2443     longInfo ifTrue:[
       
  2444         text add:('group:  ',
       
  2445                    (OperatingSystem getGroupNameFromID:(self valueAt:#gid))).
       
  2446 
       
  2447         ts := self valueAt:#accessed.
       
  2448         text add:('last access:       ',ts asTime printString ,' ', ts asDate printString). 
       
  2449 
       
  2450         ts := (self valueAt:#modified).
       
  2451         text add:('last modification: ', ts asTime printString, ' ', ts asDate printString).
       
  2452     ].
       
  2453     ^ text asString
       
  2454 !
       
  2455 
       
  2456 getModeString:modeBits
       
  2457     "convert file-mode bits into a more user-friendly string.
       
  2458      This is wrong here - should be moved into OperatingSystem."
       
  2459 
       
  2460     ^ self getModeString:modeBits 
       
  2461                     with:#( 'owner:' $r $w $x 
       
  2462                             ' group:' $r $w $x 
       
  2463                             ' others:' $r $w $x )
       
  2464 !
       
  2465 
       
  2466 getModeString:modeBits with:texts
       
  2467     "convert file-mode bits into a more user-friendly string.
       
  2468      This is wrong here - should be moved into OperatingSystem."
       
  2469 
       
  2470     |bits modeString|
       
  2471 
       
  2472     bits := modeBits bitAnd:8r777.
       
  2473     modeString := ''.
       
  2474 
       
  2475     #( nil 8r400 8r200 8r100 nil 8r040 8r020 8r010 nil 8r004 8r002 8r001 ) 
       
  2476     with: texts do:[:bitMask :access |
       
  2477         |ch|
       
  2478 
       
  2479         bitMask isNil ifTrue:[
       
  2480             modeString := modeString , access
       
  2481         ] ifFalse:[
       
  2482             (bits bitAnd:bitMask) == 0 ifTrue:[
       
  2483                 ch := $-
       
  2484             ] ifFalse:[
       
  2485                 ch := access
       
  2486             ].
       
  2487             modeString := modeString copyWith:ch 
       
  2488         ]
       
  2489     ].
       
  2490     ^ modeString
       
  2491 !
       
  2492 
       
  2493 group
       
  2494     "returns the printable group
       
  2495     "
       
  2496     |gid|
       
  2497 
       
  2498     group isNil ifTrue:[
       
  2499         gid := self valueAt:#gid.
       
  2500         group := gid notNil ifTrue:[OperatingSystem getGroupNameFromID:gid] ifFalse:[^ '???']
       
  2501     ].
       
  2502     ^ group
       
  2503 !
       
  2504 
       
  2505 modificationTime
       
  2506     "returns the absolute time of modification
       
  2507     "
       
  2508     modificationTime isNil ifTrue:[
       
  2509         modificationTime := self valueAt:#modified.
       
  2510     ].
       
  2511     ^ modificationTime
       
  2512 !
       
  2513 
       
  2514 owner
       
  2515     "returns the printable owner
       
  2516     "
       
  2517     |uid|
       
  2518 
       
  2519     owner isNil ifTrue:[
       
  2520         uid := self valueAt:#uid.
       
  2521         owner := uid notNil ifTrue:[OperatingSystem getUserNameFromID:uid] ifFalse:[^ '???'].
       
  2522     ].
       
  2523     ^ owner
       
  2524 !
       
  2525 
       
  2526 pathName
       
  2527     "returns the pathName of the file
       
  2528     "
       
  2529     pathName isNil ifTrue:[
       
  2530         pathName := fileName pathName.
       
  2531     ].
       
  2532     ^ pathName
       
  2533 !
       
  2534 
       
  2535 permissions
       
  2536     "returns the permissions as printable string
       
  2537     "
       
  2538     |mode|
       
  2539 
       
  2540     permissions isNil ifTrue:[
       
  2541         (mode := self valueAt:#mode) notNil ifTrue:[
       
  2542             permissions := String new:9 withAll:$-.
       
  2543 
       
  2544             1 to:9 by:3 do:[:i|
       
  2545                 (mode bitAt:i    ) == 1 ifTrue:[permissions at:10 - i put:$x].
       
  2546                 (mode bitAt:i + 1) == 1 ifTrue:[permissions at:9  - i put:$w].
       
  2547                 (mode bitAt:i + 2) == 1 ifTrue:[permissions at:8  - i put:$r].
       
  2548             ]
       
  2549         ] ifFalse:[
       
  2550             permissions := '???'.
       
  2551         ].
       
  2552     ].
       
  2553     ^ permissions
       
  2554 !
       
  2555 
       
  2556 printString
       
  2557     ^ fileName asString
       
  2558 !
       
  2559 
       
  2560 size
       
  2561     "returns the size of the file
       
  2562     "
       
  2563     ^ self valueAt:#size 
       
  2564 !
       
  2565 
       
  2566 sizeString
       
  2567     "returns the size of the file
       
  2568     "
       
  2569     | unitString n locSize|
       
  2570 
       
  2571     size isNil ifTrue:[
       
  2572         unitString := ''.
       
  2573         locSize := self valueAt:#size.
       
  2574         locSize notNil ifTrue:[
       
  2575             locSize < (500 * 1024) ifTrue:[
       
  2576                 locSize < 1024 ifTrue:[
       
  2577                     n := locSize
       
  2578                 ] ifFalse:[
       
  2579                     n := (locSize * 10 // 1024 / 10.0).
       
  2580                     unitString := ' Kb'
       
  2581                 ]
       
  2582             ] ifFalse:[
       
  2583                 n := (locSize * 10 // 1024 // 1024 / 10.0).
       
  2584                 unitString := ' Mb'
       
  2585             ].
       
  2586             locSize := (n printStringLeftPaddedTo:5) , unitString.
       
  2587         ] ifFalse:[
       
  2588             locSize := '???'
       
  2589         ].
       
  2590         size := locSize.
       
  2591     ].
       
  2592     ^ size
       
  2593 !
       
  2594 
       
  2595 timeAndDate
       
  2596     "returns the date
       
  2597     "
       
  2598     | date modTime stream|
       
  2599 
       
  2600     timeAndDate isNil ifTrue:[
       
  2601         modTime := self valueAt:#modified.
       
  2602         modTime isNil ifTrue:[
       
  2603             timeAndDate :=  '???'
       
  2604         ] ifFalse:[
       
  2605             stream := WriteStream on:''.
       
  2606             date := modTime asDate.
       
  2607             stream nextPutAll:date printString.
       
  2608             stream space.
       
  2609             modTime printOn:stream format:'%h:%m:%s'.
       
  2610             timeAndDate := stream contents.
       
  2611             stream close.
       
  2612         ]
       
  2613     ].
       
  2614     ^ timeAndDate
       
  2615 ! !
       
  2616 
       
  2617 !DirectoryContentsBrowser::DirectoryContentsItem methodsFor:'private'!
       
  2618 
       
  2619 valueAt:aKey
       
  2620 
       
  2621     |info|
       
  2622 
       
  2623     fileInfo isNil ifTrue:[
       
  2624         fileInfo := IdentityDictionary new.
       
  2625 
       
  2626         self link = true ifTrue:[
       
  2627             info := self linkInfo
       
  2628         ] ifFalse:[
       
  2629             info := fileName info
       
  2630         ].
       
  2631         (info) notNil ifTrue:[
       
  2632             fileInfo at:#size       put:(info size).
       
  2633             fileInfo at:#mode       put:(info mode).
       
  2634             fileInfo at:#type       put:(info type).
       
  2635             fileInfo at:#uid        put:(info uid).
       
  2636             fileInfo at:#gid        put:(info gid).
       
  2637             fileInfo at:#accessed   put:(info accessed).
       
  2638             fileInfo at:#modified   put:(info modified).
       
  2639         ]
       
  2640     ].
       
  2641     ^ fileInfo at:aKey ifAbsent:nil
       
  2642 ! !
       
  2643 
       
  2644 !DirectoryContentsBrowser::DirectoryContentsItem methodsFor:'queries'!
       
  2645 
       
  2646 exists
       
  2647     "returns the fileName
       
  2648     "
       
  2649     ^ fileName exists 
       
  2650 !
       
  2651 
       
  2652 hasMimeType
       
  2653 
       
  2654     ^ (self mimeType ~= #unknown)
       
  2655 !
       
  2656 
       
  2657 mimeTypeForContents
       
  2658 
       
  2659     |mimeTypeForContents|
       
  2660 
       
  2661     mimeTypeForContents isNil ifTrue:[
       
  2662         mimeTypeForContents := MIMETypes mimeTypeOfContents:(self fileName).
       
  2663         mimeTypeForContents isNil ifTrue:[
       
  2664             mimeTypeForContents := #unknown
       
  2665         ] ifFalse:[
       
  2666             " set mimeType to mimeType of contents if a better mimeType is found "
       
  2667             mimeType := mimeTypeForContents.
       
  2668             iconKey := mimeTypeForContents.
       
  2669         ]
       
  2670     ].
       
  2671     ^ mimeTypeForContents
       
  2672 ! !
       
  2673 
       
  2674 !DirectoryContentsBrowser class methodsFor:'documentation'!
       
  2675 
       
  2676 version
       
  2677     ^ '$Header: /cvs/stx/stx/libtool/DirectoryContentsBrowser.st,v 1.1 2002-09-23 11:31:44 penk Exp $'
       
  2678 ! !