tz@424: " tz@502: COPYRIGHT (c) 1997 by eXept Software AG tz@424: All Rights Reserved tz@424: tz@424: This software is furnished under a license and may be used tz@424: only in accordance with the terms of that license and with the tz@424: inclusion of the above copyright notice. This software may not tz@424: be provided or otherwise made available to, or used by, any tz@424: other person. No title to or ownership of the software is tz@424: hereby transferred. tz@424: " cg@1385: "{ Package: 'stx:libtool2' }" cg@1385: cg@3298: "{ NameSpace: Smalltalk }" cg@3298: tz@424: ApplicationModel subclass:#DirectoryView tz@424: instanceVariableNames:'directory selectedFileFilter readTask monitoring tz@424: monitoringTimeBlock fileDoubleClickAction fileSelectAction tz@424: fileFilterSelectAction fileAttributes' tz@424: classVariableNames:'' tz@424: poolDictionaries:'' cg@2101: category:'Interface-Dialogs' tz@424: ! tz@424: tz@424: Object subclass:#FileRow tz@638: instanceVariableNames:'fileName size modified iconKey imageFromFile group owner tz@638: permissions baseName' cg@1385: classVariableNames:'MaxImageFileSize' tz@424: poolDictionaries:'' tz@424: privateIn:DirectoryView tz@424: ! tz@424: tz@424: !DirectoryView class methodsFor:'documentation'! tz@424: tz@424: copyright tz@424: " tz@502: COPYRIGHT (c) 1997 by eXept Software AG tz@424: All Rights Reserved tz@424: tz@424: This software is furnished under a license and may be used tz@424: only in accordance with the terms of that license and with the tz@424: inclusion of the above copyright notice. This software may not tz@424: be provided or otherwise made available to, or used by, any tz@424: other person. No title to or ownership of the software is tz@424: hereby transferred. tz@424: " tz@424: tz@424: ! tz@424: tz@424: documentation tz@424: " cg@2351: this is somewhat outdated. However, it is still used by the image editor and cg@2351: some other resource editors. cg@2351: It has the advantage of showing the file-contents... mawalch@3316: ...but the disadvantage of having an ugly layout and user interface. tz@502: tz@502: [author:] tz@502: Thomas Zwick tz@424: " tz@424: ! ! tz@424: tz@424: !DirectoryView class methodsFor:'instance creation'! tz@424: sv@516: openOnDirectory: aDirectoryString sv@516: "open a DirectoryView for a aDirectoryString" sv@516: sv@516: ^ (self new directory: aDirectoryString) open tz@424: sv@516: " sv@516: self openOnDirectory: '/etc' sv@516: " tz@424: sv@516: "Modified: / 28.1.1998 / 15:44:53 / stefan" tz@424: ! ! tz@424: tz@424: !DirectoryView class methodsFor:'interface specs'! tz@424: tz@823: windowSpec tz@823: "This resource specification was automatically generated tz@823: by the UIPainter of ST/X." tz@823: tz@823: "Do not manually edit this!! If it is corrupted, tz@823: the UIPainter may not be able to read the specification." tz@823: tz@823: " tz@823: UIPainter new openOnClass:DirectoryView andSelector:#windowSpec tz@823: DirectoryView new openInterface:#windowSpec tz@823: DirectoryView open tz@823: " tz@823: tz@823: tz@823: cg@1346: ^ cg@1346: #(#FullSpec cg@1346: #name: #windowSpec cg@1346: #window: cg@1346: #(#WindowSpec cg@1346: #label: 'Directory View' cg@1346: #name: 'Directory View' cg@1346: #min: #(#Point 10 10) cg@1346: #bounds: #(#Rectangle 13 23 413 323) cg@1346: ) cg@1346: #component: cg@1346: #(#SpecCollection cg@1346: #collection: #( cg@1346: #(#DataSetSpec cg@1346: #name: 'filesDataSetView' cg@1346: #layout: #(#LayoutFrame 0 0.0 24 0.0 -2 1.0 0 1.0) cg@1346: #model: #selectionOfFile cg@1346: #menu: #fileListMenu cg@1346: #hasHorizontalScrollBar: true cg@1346: #hasVerticalScrollBar: true cg@1346: #miniScrollerHorizontal: true cg@1346: #dataList: #listOfFiles cg@1346: #useIndex: false cg@1346: #has3Dsepartors: false cg@1346: #doubleClickSelector: #fileDoubleClicked cg@1346: #columnHolder: #fileAttributeColumns cg@1346: #valueChangeSelector: #fileSelected cg@1346: #verticalSpacing: 1 cg@1346: ) cg@1346: #(#ComboBoxSpec cg@1346: #name: 'formatComboBox' cg@1346: #layout: #(#LayoutFrame 63 0.0 0 0 0 1.0 22 0) cg@1346: #model: #selectionOfFileFilter cg@1346: #immediateAccept: false cg@1346: #acceptOnTab: false cg@1346: #acceptOnPointerLeave: false cg@1346: #comboList: #listOfFileFilters cg@1346: ) cg@1346: #(#LabelSpec cg@1346: #label: 'Filter: ' cg@1346: #name: 'filterLabel' cg@1346: #layout: #(#LayoutFrame 0 0 0 0 62 0 22 0) cg@1346: #adjust: #right cg@1346: ) cg@1346: ) cg@1346: cg@1346: ) tz@823: ) cg@1346: cg@1346: "Modified: / 11.2.2000 / 00:11:43 / cg" tz@823: ! ! tz@823: tz@823: !DirectoryView class methodsFor:'list specs'! tz@823: tz@820: tableColumnsForFileAttributes tz@820: "This resource specification was automatically generated tz@820: by the DataSetBuilder of ST/X." tz@820: tz@820: "Do not manually edit this!! If it is corrupted, tz@820: the DataSetBuilder may not be able to read the specification." tz@820: tz@820: " tz@820: DataSetBuilder new openOnClass:DirectoryView andSelector:#tableColumnsForFileAttributes tz@820: " tz@820: tz@820: tz@820: tz@424: tz@820: ^ #( tz@820: #(#DataSetColumnSpec tz@820: #label: '' tz@820: #width: 30 tz@820: #height: 22 tz@820: #printSelector: #iconOn: tz@820: #canSelect: false tz@820: ) tz@820: #(#DataSetColumnSpec tz@820: #label: 'File name' tz@820: #labelAlignment: #left tz@820: #minWidth: 150 tz@820: #model: #baseName tz@820: #canSelect: false tz@820: ) tz@820: #(#DataSetColumnSpec tz@820: #label: 'Size' tz@820: #labelAlignment: #left tz@820: #width: 70 tz@820: #model: #size tz@820: #canSelect: false tz@820: ) tz@820: #(#DataSetColumnSpec tz@820: #label: 'Modified' tz@820: #labelAlignment: #left tz@820: #model: #modified tz@820: #canSelect: false tz@820: ) tz@820: #(#DataSetColumnSpec tz@820: #label: 'Permissions' tz@820: #labelAlignment: #left tz@820: #width: 85 tz@820: #model: #permissions tz@820: #canSelect: false tz@820: ) tz@820: #(#DataSetColumnSpec tz@820: #label: 'Owner' tz@820: #labelAlignment: #left tz@820: #width: 50 tz@820: #model: #owner tz@820: #canSelect: false tz@820: ) tz@820: #(#DataSetColumnSpec tz@820: #label: 'Group' tz@820: #labelAlignment: #left tz@820: #width: 50 tz@820: #model: #group tz@820: #canSelect: false tz@820: ) tz@820: ) tz@424: ! ! tz@424: cg@1346: !DirectoryView class methodsFor:'menu specs'! cg@1346: cg@1346: fileListMenu cg@1346: "This resource specification was automatically generated cg@1346: by the MenuEditor of ST/X." cg@1346: cg@1346: "Do not manually edit this!! If it is corrupted, cg@1346: the MenuEditor may not be able to read the specification." cg@1346: cg@1346: " cg@1346: MenuEditor new openOnClass:DirectoryView andSelector:#fileListMenu cg@1346: (Menu new fromLiteralArrayEncoding:(DirectoryView fileListMenu)) startUp cg@1346: " cg@1346: cg@1346: cg@1346: cg@1346: ^ cg@1346: #(#Menu cg@1346: #( cg@1346: #(#MenuItem cg@1346: #label: 'Update' cg@1346: #translateLabel: true cg@1346: #value: #updateFileList cg@1346: ) cg@1346: ) cg@1346: nil cg@1346: nil cg@1346: ) cg@1346: cg@1346: "Created: / 11.2.2000 / 00:11:39 / cg" cg@1346: ! ! cg@1346: tz@424: !DirectoryView methodsFor:'accessing'! tz@424: tz@424: directory: aDirectory tz@424: tz@424: directory := aDirectory asFilename asAbsoluteFilename name tz@424: ! tz@424: tz@424: fileAttributes: anArray tz@424: tz@424: fileAttributes := anArray tz@424: ! tz@424: tz@424: fileDoubleClickAction: anActionBlock tz@424: tz@424: fileDoubleClickAction := anActionBlock tz@424: ! tz@424: tz@424: fileFilterSelectAction: anActionBlock tz@424: tz@424: fileFilterSelectAction := anActionBlock tz@424: ! tz@424: tz@424: fileSelectAction: anActionBlock tz@424: tz@424: fileSelectAction := anActionBlock tz@424: ! tz@424: tz@424: listOfFileFilters: aCollection tz@424: tz@424: self listOfFileFilters contents: aCollection. tz@424: self selectionOfFileFilter value: (self listOfFileFilters at: 1 ifAbsent: [nil]). tz@424: ! tz@424: tz@424: monitoring: aBoolean tz@424: tz@424: aBoolean tz@424: ifTrue: tz@424: [ tz@424: monitoringTimeBlock := [self readDirectory]. tz@424: self readDirectory. tz@424: ] tz@424: ifFalse: tz@424: [ tz@424: monitoring ifTrue: tz@424: [ tz@424: Processor removeTimedBlock:monitoringTimeBlock. tz@424: monitoringTimeBlock := nil tz@424: ] tz@424: ]. tz@424: tz@424: monitoring := aBoolean. tz@424: tz@424: ! ! tz@424: tz@424: !DirectoryView methodsFor:'aspects'! tz@424: tz@424: fileAttributeColumns tz@424: tz@424: |holder| tz@424: (holder := builder bindingAt:#fileAttributeColumns) isNil ifTrue:[ tz@424: |fileAttributeColumns| tz@424: builder aspectAt:#fileAttributeColumns put:(holder := List new). tz@820: fileAttributeColumns := self class tableColumnsForFileAttributes collect: [:i| i decodeAsLiteralArray]. tz@424: holder add: fileAttributeColumns first. tz@424: fileAttributeColumns do: tz@424: [:col| tz@424: (fileAttributes includes: col label) ifTrue: [holder add: col] tz@424: ]. tz@591: holder do: [:col| col label: ' ', col label] tz@424: ]. tz@424: ^ holder tz@424: ! tz@424: tz@424: listOfFileFilters tz@424: tz@424: |holder| tz@424: (holder := builder bindingAt:#listOfFileFilters) isNil ifTrue:[ tz@424: builder aspectAt:#listOfFileFilters put:(holder := List with: '*'). tz@424: ]. tz@424: ^ holder tz@424: ! tz@424: tz@424: listOfFiles tz@424: tz@424: |holder| tz@424: (holder := builder bindingAt:#listOfFiles) isNil ifTrue:[ tz@424: builder aspectAt:#listOfFiles put:(holder := List new). tz@424: ]. tz@424: ^ holder tz@424: ! tz@424: tz@424: selectionOfFile tz@424: tz@424: |holder| tz@424: (holder := builder bindingAt:#selectionOfFile) isNil ifTrue:[ tz@424: builder aspectAt:#selectionOfFile put:(holder := ValueHolder new). tz@424: ]. tz@424: ^ holder tz@424: tz@424: ! tz@424: tz@424: selectionOfFileFilter tz@424: tz@424: |holder| tz@424: (holder := builder bindingAt:#selectionOfFileFilter) isNil ifTrue:[ tz@424: builder aspectAt:#selectionOfFileFilter put: tz@424: (holder := AspectAdaptor new subject:self; forAspect:#selectedFileFilter). tz@424: selectedFileFilter := '*'. tz@424: ]. tz@424: ^ holder tz@424: ! ! tz@424: tz@424: !DirectoryView methodsFor:'callbacks'! tz@424: tz@424: fileDoubleClicked tz@424: tz@473: (fileDoubleClickAction notNil and: [self selectionOfFile value notNil]) tz@424: ifTrue: tz@424: [ tz@424: fileDoubleClickAction numArgs = 0 tz@424: ifTrue: tz@424: [ tz@424: fileDoubleClickAction value tz@424: ]. tz@424: fileDoubleClickAction numArgs = 1 tz@424: ifTrue: tz@451: [ tz@451: fileDoubleClickAction value: (directory asFilename construct: self selectionOfFile value baseName) name tz@424: ] tz@424: ] tz@424: ! tz@424: tz@424: fileSelected tz@424: tz@473: (fileSelectAction notNil and: [self selectionOfFile value notNil]) tz@424: ifTrue: tz@424: [ tz@424: fileSelectAction numArgs = 0 tz@424: ifTrue: tz@424: [ tz@424: fileSelectAction value tz@424: ]. tz@424: fileSelectAction numArgs = 1 tz@424: ifTrue: tz@424: [ tz@451: fileSelectAction value: (directory asFilename construct: self selectionOfFile value baseName) name tz@424: ] tz@424: ] tz@424: ! ! tz@424: tz@424: !DirectoryView methodsFor:'initialization'! tz@424: tz@424: initialize tz@424: tz@424: super initialize. cg@874: self createBuilder. tz@424: cg@3044: directory := (directory ? '.') asFilename asAbsoluteFilename directoryName. tz@424: monitoring := false. tz@593: fileAttributes := #('File name' 'Size' 'Modified'). tz@424: self selectionOfFileFilter value: (self listOfFileFilters at: 1 ifAbsent: [nil]). tz@424: cg@874: "Modified: / 20.6.1998 / 14:46:10 / cg" tz@424: ! ! tz@424: cg@2878: !DirectoryView methodsFor:'initialize-release'! cg@2878: cg@2878: release cg@2878: cg@2878: monitoring ifTrue: cg@2878: [ cg@2878: Processor removeTimedBlock:monitoringTimeBlock. cg@2878: monitoringTimeBlock := nil cg@2878: ]. cg@2878: cg@2878: super release cg@2878: cg@2878: ! ! cg@2878: cg@1346: !DirectoryView methodsFor:'menu actions'! cg@1346: cg@1346: updateFileList cg@1346: DirectoryContents flushCache. cg@1346: self readDirectory cg@1346: cg@1346: "Created: / 11.2.2000 / 00:12:46 / cg" cg@1346: "Modified: / 11.2.2000 / 00:14:32 / cg" cg@1346: ! ! cg@1346: tz@424: !DirectoryView methodsFor:'private'! tz@424: tz@424: readDirectory cg@2439: |allDirectories allFiles foundFiles filterList dir newContents| cg@828: cg@2439: allFiles := OrderedCollection new. cg@2439: allDirectories := OrderedCollection new. cg@2439: foundFiles := OrderedCollection new. cg@991: "/ filterList := self listOfFileFilters value. cg@991: filterList := self selectedFileFilter asCollectionOfSubstringsSeparatedBy:$;. cg@991: filterList := filterList collect:[:pattern | pattern withoutSeparators]. tz@614: cg@999: self withCursor:Cursor read do:[ cg@828: (dir := DirectoryContents directoryNamed: directory) notNil ifTrue:[ cg@979: "/ dir filesAndBasenamesDo:[:file :name| cg@979: "/ filterList do:[:filter| cg@979: "/ ((filter match:name) and:[(foundFiles includes: name) not]) cg@979: "/ ifTrue:[ cg@979: "/ foundFiles add: name cg@979: "/ ]. cg@979: "/ ]. cg@979: "/ ]. cg@979: dir filesAndBasenamesDo:[:file :name| cg@979: allFiles add: name tz@590: ]. cg@2439: dir directoriesAndBasenamesDo:[:file :name| cg@2439: allDirectories add: name cg@2439: ]. cg@991: cg@999: Filename isCaseSensitive ifFalse:[ cg@999: filterList do:[:filter| cg@999: |lcFilter| cg@999: cg@999: lcFilter := filter asLowercase. cg@999: foundFiles cg@999: addAll:(allFiles cg@999: select:[:name | lcFilter match:name asLowercase] cg@999: ). cg@999: ] cg@999: ] ifTrue:[ cg@999: filterList do:[:filter| cg@999: foundFiles cg@999: addAll:(allFiles cg@999: select:[:name | filter match:name] cg@999: ). cg@999: ] cg@979: ]. cg@979: cg@2439: foundFiles sort. cg@2439: allDirectories sort. cg@2439: cg@979: dir := directory asFilename. cg@2439: cg@2439: newContents := OrderedCollection new. cg@2439: newContents addAll:(allDirectories collect:[:name| FileRow new fileName:(dir construct:name)]). cg@2439: newContents addAll:(foundFiles collect:[:name| FileRow new fileName:(dir construct:name)]). cg@2439: cg@2439: self listOfFiles contents:newContents cg@828: ] tz@590: ] tz@614: cg@999: "Modified: / 23.9.1998 / 17:00:42 / cg" tz@590: ! tz@590: tz@590: readMonitoringDirectory sv@3597: cg@3303: "this is a very ugly piece of code - cg@3303: left in as a bad example of how to make ST look slow... cg@3303: DO NOT USE IT, but read to learn" cg@3303: cg@3018: |readBlock| tz@590: tz@424: readTask notNil ifTrue: [readTask terminate]. tz@424: readBlock := tz@424: [ cg@3299: |dir currentFilenames oldListOfFiles listOfFiles| cg@3018: cg@3018: dir := directory asFilename. cg@3018: currentFilenames := OrderedCollection new. cg@3018: (dir isReadable and:[dir isExecutable]) ifTrue: [ cg@3018: self listOfFileFilters value do: cg@3018: [:filter| cg@3018: (dir filesMatchingWithoutDotDirs: filter) do: [:aFileName| cg@3018: |file| cg@3018: (file := dir construct: aFileName) isDirectory ifFalse: [ cg@3018: currentFilenames add: file cg@3018: ] cg@3018: ]. tz@424: ]. tz@424: ]. cg@3299: listOfFiles := self listOfFiles. cg@3299: cg@3299: oldListOfFiles := listOfFiles copy. cg@3018: (currentFilenames asSortedCollection: [:f1 :f2| f1 baseName < f2 baseName]) asSet cg@3018: do: [:fileName| cg@3354: (oldListOfFiles contains:[:fileRow | fileRow fileName = fileName ]) cg@3354: ifFalse: [ cg@3299: |nearestFileRow newRow r| cg@3299: cg@3299: newRow := FileRow new fileName: fileName asFilename. cg@3299: "/ cg: how stupid is that? cg@3303: nearestFileRow := listOfFiles indexOf: (listOfFiles detect: [:fileRow| fileRow baseName > fileName baseName] ifNone: nil). cg@3303: "/ nearestFileRow := listOfFiles findFirst:[:fileRow | fileRow baseName > fileName baseName]. cg@3018: nearestFileRow = 0 cg@3299: ifTrue: [listOfFiles add: newRow] cg@3299: ifFalse: [listOfFiles add: newRow beforeIndex: nearestFileRow]. cg@3018: monitoring ifTrue: [self selectionOfFile value: r]. cg@3018: ] cg@3018: ]. cg@3299: cg@3299: listOfFiles cg@3018: reverseDo: [:fileRow| cg@3018: (currentFilenames includes: fileRow fileName) cg@3299: ifFalse: [listOfFiles remove: fileRow] cg@3018: ] tz@424: ]. tz@424: cg@3018: monitoring ifTrue: [ tz@424: readTask := readBlock forkAt: Processor userBackgroundPriority. tz@424: Processor addTimedBlock: monitoringTimeBlock afterSeconds: 1 cg@3018: ] ifFalse: [ tz@424: Cursor wait showWhile: [readBlock value] tz@424: ] cg@3354: cg@3354: "Modified: / 19-11-2016 / 20:34:14 / cg" tz@424: ! ! tz@424: tz@424: !DirectoryView methodsFor:'selection'! tz@424: tz@424: selectedFileFilter tz@424: tz@424: ^selectedFileFilter tz@424: tz@424: ! tz@424: cg@999: selectedFileFilter:aString cg@999: "change the file filter" cg@999: cg@999: |listOfFileFilters nArgs| tz@424: cg@999: aString = selectedFileFilter ifTrue:[^ self]. cg@999: cg@999: listOfFileFilters := self listOfFileFilters. cg@999: cg@999: "/ what is this for ? cg@999: aString size == 0 ifTrue: [ cg@999: listOfFileFilters remove: selectedFileFilter ifAbsent: nil tz@424: ]. cg@999: selectedFileFilter := aString. cg@999: cg@999: ((listOfFileFilters includes: selectedFileFilter) not cg@999: and:[selectedFileFilter notEmpty]) cg@999: ifTrue: [ cg@999: listOfFileFilters addFirst: selectedFileFilter cg@999: ]. cg@999: ((listOfFileFilters includes: selectedFileFilter) cg@999: and:[fileFilterSelectAction notNil]) cg@999: ifTrue: [ cg@999: (nArgs := fileFilterSelectAction numArgs) == 0 cg@999: ifTrue: [ tz@424: fileFilterSelectAction value cg@999: ] ifFalse:[ cg@999: nArgs == 1 ifTrue:[ cg@999: fileFilterSelectAction value: selectedFileFilter cg@999: ] ifFalse:[ cg@999: self error:'bad numArgs of fileFilter action block' cg@999: ] tz@424: ] tz@424: ]. tz@424: self readDirectory. cg@999: cg@999: "Modified: / 23.9.1998 / 16:53:05 / cg" tz@424: ! ! tz@424: cg@3035: !DirectoryView methodsFor:'startup & release'! tz@424: tz@424: closeRequest cg@3563: "/ is this needed? - I think release is sent anyway by super... tz@424: self release. tz@424: tz@424: super closeRequest tz@424: cg@3563: "Modified (comment): / 28-05-2018 / 09:50:20 / Claus Gittinger" tz@424: ! ! tz@424: tz@424: !DirectoryView::FileRow class methodsFor:'resources'! tz@424: tz@424: HFileIcon tz@424: tz@424: ^self hFileIcon tz@424: ! tz@424: tz@424: MakefileIcon cg@3298: "This resource specification was automatically generated cg@3298: by the ImageEditor of ST/X." cg@3298: cg@3298: "Do not manually edit this!! If it is corrupted, cg@3298: the ImageEditor may not be able to read the specification." cg@3298: tz@590: " cg@3298: self MakefileIcon inspect cg@3298: ImageEditor openOnClass:self andSelector:#MakefileIcon cg@3298: Icon flushCachedIcons tz@590: " tz@424: tz@424: tz@590: tz@590: ^Icon cg@3298: constantNamed:'DirectoryView::FileRow MakefileIcon' cg@3298: ifAbsentPut:[(Depth1Image width:20 height:19) bits:(ByteArray fromPackedString:'???9 @_0 @W2 @S0 @Q0 @_0 @O8 @@0 @@0 @@0)IV0/U$0)]&0)UT;)UV4 @@0 @@0???0???0') cg@3298: colorMapFromArray:#[255 255 255 0 0 0] cg@3298: mask:((ImageMask width:20 height:19) bits:(ByteArray fromPackedString:'??0@??8@??<@??>@???@??? ???0???0???0???0???0???0???0???0???0???0???0???0_??0'); yourself); yourself] penk@1627: ! tz@424: tz@424: binaryFileIcon cg@3298: "This resource specification was automatically generated cg@3298: by the ImageEditor of ST/X." cg@3298: cg@3298: "Do not manually edit this!! If it is corrupted, cg@3298: the ImageEditor may not be able to read the specification." cg@3298: tz@590: " cg@3298: self binaryFileIcon inspect cg@3298: ImageEditor openOnClass:self andSelector:#binaryFileIcon cg@3298: Icon flushCachedIcons tz@590: " tz@424: tz@424: tz@590: tz@590: ^Icon cg@3298: constantNamed:'DirectoryView::FileRow binaryFileIcon' cg@3298: ifAbsentPut:[(Depth1Image width:20 height:19) bits:(ByteArray fromPackedString:'???3 @_7 @W4#&S0&6Q0&6_3&6O5&6@0#&@9 @@0&\@2&6@0&6@0&6@1&6@8&\@0 @@0???0???1') cg@3298: colorMapFromArray:#[255 255 255 0 0 0] cg@3298: mask:((ImageMask width:20 height:19) bits:(ByteArray fromPackedString:'??0@??8@??<@??>@???@??? ???0???0???0???0???0???0???0???0???0???0???0???0_??0'); yourself); yourself] penk@1627: ! tz@424: tz@424: cFileIcon cg@3298: "This resource specification was automatically generated cg@3298: by the ImageEditor of ST/X." cg@3298: cg@3298: "Do not manually edit this!! If it is corrupted, cg@3298: the ImageEditor may not be able to read the specification." cg@3298: tz@590: " cg@3298: self cFileIcon inspect cg@3298: ImageEditor openOnClass:self andSelector:#cFileIcon cg@3298: Icon flushCachedIcons tz@590: " tz@424: tz@424: tz@590: tz@590: ^Icon cg@3298: constantNamed:'DirectoryView::FileRow cFileIcon' cg@3298: ifAbsentPut:[(Depth1Image width:20 height:19) bits:(ByteArray fromPackedString:'???9 @_0 @W2 @S0 @Q0 @_0 @O8 @@0 @@0 \@0 "@0 @0 @0&"@;&\@4 @@0 @@0???0???0') cg@3298: colorMapFromArray:#[255 255 255 0 0 0] cg@3298: mask:((ImageMask width:20 height:19) bits:(ByteArray fromPackedString:'??0@??8@??<@??>@???@??? ???0???0???0???0???0???0???0???0???0???0???0???0_??0'); yourself); yourself] penk@1627: ! tz@424: tz@424: exeFileIcon cg@3298: "This resource specification was automatically generated cg@3298: by the ImageEditor of ST/X." cg@3298: cg@3298: "Do not manually edit this!! If it is corrupted, cg@3298: the ImageEditor may not be able to read the specification." cg@3298: tz@590: " cg@3298: self exeFileIcon inspect cg@3298: ImageEditor openOnClass:self andSelector:#exeFileIcon cg@3298: Icon flushCachedIcons tz@590: " tz@424: tz@424: tz@590: tz@590: ^Icon cg@3298: constantNamed:'DirectoryView::FileRow exeFileIcon' cg@3298: ifAbsentPut:[(Depth2Image width:20 height:19) bits:(ByteArray fromPackedString:'UUUUUUU@@@@UUT@@@AEUP@@@DEU@@@@PET@@@AUUQUUUP@UF**)@ATUUUT@EQ???P@UG??=@AT_??4@EQ???P@UG??=@AT_??4@EQUUUP@U@@@@@AUUUUUUU cg@3298: UUUUUUTb') cg@3298: colorMapFromArray:#[255 255 255 0 0 0 0 127 127 170 170 170] cg@3298: mask:((ImageMask width:20 height:19) bits:(ByteArray fromPackedString:'??0@??8@??<@??>@???@??? ???0???0???0???0???0???0???0???0???0???0???0???0_??0'); yourself); yourself] penk@1627: ! tz@424: tz@424: fileIcon tz@590: "Generated by the Image Editor" tz@590: " tz@590: ImageEditor openOnClass:self andSelector:#fileIcon tz@590: " tz@424: tz@424: tz@590: tz@590: ^Icon tz@590: constantNamed:#'DirectoryView::FileRow fileIcon' penk@1627: ifAbsentPut:[(Depth1Image new) width: 20; height: 19; photometric:(#palette); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'???9 @_0 @W2 @S0 @Q0 @_0 @O8 @@0 @@0 @@0 @@0 @@0 @@0 @@; @@4 @@0 @@0???0???0') ; colorMap:((OrderedCollection new add:(Color white); add:(Color black); yourself)); mask:((ImageMask new) width: 20; height: 19; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'??0@??8@??<@??>@???@??? ???0???0???0???0???0???0???0???0???0???0???0???0_??0') ; yourself); yourself] penk@1627: ! tz@424: tz@424: hFileIcon tz@590: "Generated by the Image Editor" tz@590: " tz@590: ImageEditor openOnClass:self andSelector:#hFileIcon tz@590: " tz@424: tz@424: tz@590: tz@590: ^Icon tz@590: constantNamed:#'DirectoryView::FileRow hFileIcon' penk@1627: ifAbsentPut:[(Depth1Image new) width: 20; height: 19; photometric:(#palette); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'???9 @_0 @W2 @S0 @Q0 @_0 @O8 @0 @0 ,@0 2@0 "@0 "@0&"@;&"@4 @@0 @@0???0???0'); colorMap:((OrderedCollection new add:(Color white); add:(Color black); yourself)); mask:((ImageMask new) width: 20; height: 19; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'??0@??8@??<@??>@???@??? ???0???0???0???0???0???0???0???0???0???0???0???0_??0'); yourself); yourself] penk@1627: ! tz@424: tz@644: htmlFileIcon cg@3298: "This resource specification was automatically generated cg@3298: by the ImageEditor of ST/X." cg@3298: cg@3298: "Do not manually edit this!! If it is corrupted, cg@3298: the ImageEditor may not be able to read the specification." cg@3298: tz@644: " cg@3298: self htmlFileIcon inspect cg@3298: ImageEditor openOnClass:self andSelector:#htmlFileIcon cg@3298: Icon flushCachedIcons tz@644: " tz@424: tz@424: tz@644: tz@644: ^Icon cg@3298: constantNamed:'DirectoryView::FileRow htmlFileIcon' cg@3298: ifAbsentPut:[(Depth4Image width:20 height:19) bits:(ByteArray fromPackedString:' cg@3298: DQDQDQDQDQDQDQ????????DQDQD_???????1@QDQG???L3L3@???@??? ???0???0???0???0???0???0???0???0???0???0???0???0_??0'); yourself); yourself] penk@1627: ! tz@644: tz@644: imageFileIcon cg@3298: "This resource specification was automatically generated cg@3298: by the ImageEditor of ST/X." cg@3298: cg@3298: "Do not manually edit this!! If it is corrupted, cg@3298: the ImageEditor may not be able to read the specification." cg@3298: tz@644: " cg@3298: self imageFileIcon inspect cg@3298: ImageEditor openOnClass:self andSelector:#imageFileIcon cg@3298: Icon flushCachedIcons tz@644: " tz@644: tz@644: tz@644: tz@644: ^Icon cg@3298: constantNamed:'DirectoryView::FileRow imageFileIcon' cg@3298: ifAbsentPut:[(Depth4Image width:20 height:19) bits:(ByteArray fromPackedString:' cg@3298: @@@@@@@@@@@@@@DQDQDQDQ@@@@@ADQDQDQDPD@@@@QDQDQDQDAD@@@DQDQDQDQ@QD@@ADQDQDQDP@@@@@TQG]4)G50@@@@EDQ7^$+W4QDP@AQD]7R$_WDQD@ cg@3298: @SL6Y#$61!!DQ@@D3M&ZS''F0QDP@AL3Y&NS[FDQD@@RH%UR %-QDQ@@D"IUVB"5,QDP@AH"UUJBV5DQD@@QDQDQDQDQDQ@@DQDQDQDQDQDP@@@@@@@@@@@@@@ cg@3298: @@@@@@@@@@@@@@@a') cg@3298: colorMapFromArray:#[0 0 0 255 255 255 255 0 0 0 255 0 0 0 255 0 255 255 255 255 0 255 0 255 127 0 0 0 127 0 0 0 127 0 127 127 127 127 0 127 0 127] cg@3298: mask:((ImageMask width:20 height:19) bits:(ByteArray fromPackedString:'??0@??8@??<@??>@???@??? ???0???0???0???0???0???0???0???0???0???0???0???0_??0'); yourself); yourself] penk@1627: ! tz@424: tz@424: imgFileIcon tz@590: "Generated by the Image Editor" tz@590: " tz@590: ImageEditor openOnClass:self andSelector:#imgFileIcon tz@590: " tz@424: tz@424: tz@590: tz@590: ^Icon tz@590: constantNamed:#'DirectoryView::FileRow imgFileIcon' tz@644: ifAbsentPut:[(Depth1Image new) width: 20; height: 19; photometric:(#palette); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'???9 @_0 @W2 @S0 @Q0 @_0 @O8 @0 @@0!!-F0 **0 **0 **0&**;&*&4 @B0 @N0???0???0'); colorMap:((OrderedCollection new add:(Color white); add:(Color black); yourself)); mask:((ImageMask new) width: 20; height: 19; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'??0@??8@??<@??>@???@??? ???0???0???0???0???0???0???0???0???0???0???0???0_??0'); yourself); yourself] tz@644: ! tz@424: tz@424: linkedFileIcon tz@644: "Generated by the Image Editor" tz@644: " tz@644: ImageEditor openOnClass:self andSelector:#linkedFileIcon tz@644: " tz@424: tz@424: tz@644: tz@644: ^Icon tz@644: constantNamed:#'DirectoryView::FileRow linkedFileIcon' penk@1627: ifAbsentPut:[(Depth2Image new) width: 20; height: 19; photometric:(#palette); bitsPerSample:(#(2 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'UUUUUUU@@@@UUT@@@AEUP@@@DEU@@@@PET@@@AUUP@@@AUU@@@@@AT@@@@ EP@@@B U@@@**!!T@@J**EP@B B UB*(@HATJ*@@@EP@@@@@U@@@@@AUUUUUUUUUUUUUTb') ; colorMap:((OrderedCollection new add:(Color white); add:(Color black); add:(Color red:0.0 green:0.0 blue:100.0); add:(Color red:100.0 green:0.0 blue:0.0); yourself)); mask:((ImageMask new) width: 20; height: 19; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'??0@??8@??<@??>@???@??? ???0???0???0???0???0???0???0???0???0???0???0???0_??0') ; yourself); yourself] penk@1627: ! tz@424: tz@424: lockedFileIcon tz@644: "Generated by the Image Editor" tz@644: " tz@644: ImageEditor openOnClass:self andSelector:#lockedFileIcon tz@644: " tz@424: tz@424: tz@644: tz@644: ^Icon tz@644: constantNamed:#'DirectoryView::FileRow lockedFileIcon' penk@1627: ifAbsentPut:[(Depth2Image new) width: 20; height: 19; photometric:(#palette); bitsPerSample:(#(2 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'UUUUUUU(@@@UUT(@@AEUP(@@DEU@(@@PET@(@IUUP@(B!!UU@@((@AT@@*@@EP@B(@@U@@((@AT@J@(@EPB @(@U@(@@(ATJ@@@(ER @@@(U(@@@@)UUUUUUUUUUUUUTb') ; colorMap:((OrderedCollection new add:(Color white); add:(Color black); add:(Color red:100.0 green:0.0 blue:0.0); add:(Color red:0.0 green:100.0 blue:0.0); yourself)); mask:((ImageMask new) width: 20; height: 19; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'??0@??8@??<@??>@???@??? ???0???0???0???0???0???0???0???0???0???0???0???0_??0') ; yourself); yourself] penk@1627: ! tz@424: tz@424: protoFileIcon tz@424: tz@424: ^self MakefileIcon tz@424: ! tz@424: tz@424: rcFileIcon tz@644: "Generated by the Image Editor" tz@644: " tz@644: ImageEditor openOnClass:self andSelector:#rcFileIcon tz@644: " tz@424: tz@424: tz@644: tz@644: ^Icon tz@644: constantNamed:#'DirectoryView::FileRow rcFileIcon' penk@1627: ifAbsentPut:[(Depth1Image new) width: 20; height: 19; photometric:(#palette); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'???9 @_0 @W2 @S0 @Q0 @_0 @O8 @@0 @@0 ) 0 2P0 "@0 "@0&"P;&!! 4 @@0 @@0???0???0') ; colorMap:((OrderedCollection new add:(Color white); add:(Color black); yourself)); mask:((ImageMask new) width: 20; height: 19; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'??0@??8@??<@??>@???@??? ???0???0???0???0???0???0???0???0???0???0???0???0_??0') ; yourself); yourself] penk@1627: ! tz@424: tz@424: sFileIcon cg@3298: "This resource specification was automatically generated cg@3298: by the ImageEditor of ST/X." cg@3298: cg@3298: "Do not manually edit this!! If it is corrupted, cg@3298: the ImageEditor may not be able to read the specification." cg@3298: tz@644: " cg@3298: self sFileIcon inspect cg@3298: ImageEditor openOnClass:self andSelector:#sFileIcon cg@3298: Icon flushCachedIcons tz@644: " tz@424: tz@424: tz@644: tz@644: ^Icon cg@3298: constantNamed:'DirectoryView::FileRow sFileIcon' cg@3298: ifAbsentPut:[(Depth1Image width:20 height:19) bits:(ByteArray fromPackedString:'???9 @_0 @W2 @S0 @Q0 @_0 @O8 @@0 @@0 X@0 @0 0@0 X@0&H@;&0@4 @@0 @@0???0???0') cg@3298: colorMapFromArray:#[255 255 255 0 0 0] cg@3298: mask:((ImageMask width:20 height:19) bits:(ByteArray fromPackedString:'??0@??8@??<@??>@???@??? ???0???0???0???0???0???0???0???0???0???0???0???0_??0'); yourself); yourself] penk@1627: ! tz@424: tz@424: stFileIcon cg@3298: "This resource specification was automatically generated cg@3298: by the ImageEditor of ST/X." cg@3298: cg@3298: "Do not manually edit this!! If it is corrupted, cg@3298: the ImageEditor may not be able to read the specification." cg@3298: tz@590: " cg@3298: self stFileIcon inspect cg@3298: ImageEditor openOnClass:self andSelector:#stFileIcon cg@3298: Icon flushCachedIcons tz@590: " tz@424: tz@424: tz@590: tz@590: ^Icon cg@3298: constantNamed:'DirectoryView::FileRow stFileIcon' cg@3298: ifAbsentPut:[(Depth1Image width:20 height:19) bits:(ByteArray fromPackedString:'???9 @_0 @W2 @S0 @Q0 @_0 @O8 A@0 A@0 [00 !!@0 1@0 Y@0&I@;&004 @@0 @@0???0???0') cg@3298: colorMapFromArray:#[255 255 255 0 0 0] cg@3298: mask:((ImageMask width:20 height:19) bits:(ByteArray fromPackedString:'??0@??8@??<@??>@???@??? ???0???0???0???0???0???0???0???0???0???0???0???0_??0'); yourself); yourself] penk@1627: ! tz@424: tz@424: stcFileIcon cg@3298: "This resource specification was automatically generated cg@3298: by the ImageEditor of ST/X." cg@3298: cg@3298: "Do not manually edit this!! If it is corrupted, cg@3298: the ImageEditor may not be able to read the specification." cg@3298: tz@644: " cg@3298: self stcFileIcon inspect cg@3298: ImageEditor openOnClass:self andSelector:#stcFileIcon cg@3298: Icon flushCachedIcons tz@644: " tz@424: tz@424: tz@644: tz@644: ^Icon cg@3298: constantNamed:'DirectoryView::FileRow stcFileIcon' cg@3298: ifAbsentPut:[(Depth1Image width:20 height:19) bits:(ByteArray fromPackedString:'???9 @_0 @W2 @S0 @Q0 @_0 @O8 B@0 B@0 _L0 "R0 2P0 ZP0&JR;&3L4 @@0 @@0???0???0') cg@3298: colorMapFromArray:#[255 255 255 0 0 0] cg@3298: mask:((ImageMask width:20 height:19) bits:(ByteArray fromPackedString:'??0@??8@??<@??>@???@??? ???0???0???0???0???0???0???0???0???0???0???0???0_??0'); yourself); yourself] penk@1627: ! ! tz@424: tz@424: !DirectoryView::FileRow methodsFor:'accessing'! tz@424: tz@424: baseName tz@424: tz@424: ^baseName ? (baseName := fileName baseName) tz@424: tz@424: tz@424: tz@424: tz@424: tz@424: tz@424: tz@424: ! tz@424: tz@424: fileName tz@424: tz@424: ^fileName tz@424: ! tz@424: tz@424: fileName: aFileName tz@424: tz@614: fileName := aFileName tz@424: ! tz@424: tz@424: group tz@424: tz@424: ^group tz@424: ! tz@424: tz@424: iconOn:aGC tz@638: |icon| cg@3491: cg@3491: iconKey isNil ifTrue: [ tz@614: self validateAttributes. cg@3491: (imageFromFile isNil and: [iconKey == #imageFileIcon]) ifTrue: [ cg@3491: icon := self retrieveImageFromFileAndRegisterOn: aGC cg@3491: ] tz@424: ]. cg@3491: imageFromFile == true ifFalse: [ cg@3491: icon := aGC registerImage: (self class perform: iconKey) key: iconKey cg@3491: ] ifTrue: [ cg@3491: icon := aGC registeredImageAt: iconKey cg@3491: ]. cg@3491: ^ icon cg@645: cg@3491: "Modified: / 18-02-1998 / 18:01:52 / cg" cg@3491: "Modified (format): / 13-09-2017 / 09:57:53 / cg" tz@424: ! tz@424: tz@424: modified tz@424: tz@424: ^modified tz@424: ! tz@424: tz@424: owner tz@424: tz@424: ^owner tz@424: ! tz@424: tz@424: permissions tz@424: tz@424: ^permissions tz@424: ! tz@424: tz@638: retrieveImageFromFileAndRegisterOn: aGC cg@1385: "retrieve a bitmap image - but only if it is smaller than some limit (currently 20k)" tz@638: cg@1385: |image maxImageFileSize| cg@1385: cg@1385: maxImageFileSize := MaxImageFileSize ? 20000. cg@1385: tz@638: imageFromFile := false. cg@3491: (image := aGC registeredImageAt: fileName name asSymbol) isNil ifTrue:[ cg@1385: size < maxImageFileSize ifTrue:[ cg@2999: Error handle: [:ex|] cg@1385: do:[ cg@1385: (image := Image fromFile: fileName name) notNil ifTrue:[ cg@1385: image extent y > 22 ifTrue:[ tz@638: image := image magnifiedBy: 22/image extent y tz@638: ]. tz@638: image := aGC registerImage: image key: fileName name asSymbol. tz@638: ] tz@638: ] tz@638: ]. tz@638: ]. tz@638: image notNil ifTrue: [imageFromFile := true. iconKey := fileName name asSymbol]. tz@638: ^image cg@3491: cg@3491: "Modified (format): / 13-09-2017 / 09:58:19 / cg" tz@638: ! tz@638: tz@424: size cg@3491: size isNil ifTrue:[ cg@3491: self validateAttributes. cg@3491: ]. cg@3491: cg@607: size isNumber ifFalse:[^ size]. cg@3491: cg@3491: "/ ^ UnitConverter fileSizeStringFor:size. cg@3491: cg@607: size < 1000 ifTrue: [^ size printString]. cg@607: size < (100*1024) ifTrue: [^(((size/1024) * 10) asInteger/10) asFloat printString, ' Kb']. cg@607: size < (1000*1024) ifTrue: [^(((size/1024)) asInteger) printString, ' Kb']. cg@607: ^(((size/1048576) * 10) asInteger/10) asFloat printString, ' Mb' tz@424: cg@3491: "Modified: / 13-09-2017 / 09:58:42 / cg" tz@424: ! ! tz@424: tz@424: !DirectoryView::FileRow methodsFor:'private'! tz@424: tz@424: validateAttributes cg@2938: |info mode suffix| tz@638: sv@3366: permissions := '---------' copy. tz@424: cg@2938: (info := fileName info) isNil ifTrue:[ tz@424: iconKey := #lockedFileIcon. tz@424: size := owner := group := '?'. cg@2938: ^ self tz@424: ]. cg@3491: size := info fileSize. penk@1627: modified := info modificationTime printString. tz@424: owner := OperatingSystem getUserNameFromID: info uid. tz@424: group := OperatingSystem getGroupNameFromID: info gid. tz@424: mode := info mode. tz@424: tz@424: 1 to:9 by:3 do:[:i| tz@424: #((0 $x) (1 $w) (2 $r)) do: tz@424: [:m| tz@424: (mode bitAt:i + m first) == 1 ifTrue:[permissions at: 10 - m first - i put: m last] tz@424: ] tz@424: ]. tz@424: cg@2938: fileName isReadable ifFalse:[ sv@3366: ^ iconKey := #lockedFileIcon tz@424: ]. cg@2938: info type == #symbolicLink ifTrue:[ cg@2938: ^ iconKey := #linkedFileIcon cg@2938: ]. cg@2938: suffix := fileName suffix. cg@2938: cg@3634: ((suffix asSingleByteStringIfPossible isSingleByteCollection cg@3634: and:[ (self class respondsTo:(iconKey := (suffix, 'FileIcon') asSymbol))]) cg@3634: or: [fileName baseName asSingleByteStringIfPossible isSingleByteCollection cg@3634: and:[self class respondsTo: (iconKey := (fileName baseName, 'Icon') asSymbol)]] cg@2938: ) ifFalse:[ cg@2938: iconKey := #fileIcon. cg@2938: ((suffix = 'o') or:[suffix = 'so']) ifTrue: [ sv@3366: ^ iconKey := #binaryFileIcon cg@2938: ]. cg@2938: (Image isImageFileSuffix:suffix) ifTrue: [ sv@3366: ^ iconKey := #imageFileIcon cg@2938: ]. cg@2938: cg@2938: fileName isExecutableProgram ifTrue:[ sv@3366: ^ iconKey := #exeFileIcon cg@2938: ] cg@2938: ] cg@3491: cg@3491: "Modified: / 13-09-2017 / 10:00:42 / cg" cg@3634: "Modified: / 01-01-2019 / 15:23:11 / Claus Gittinger" tz@424: ! ! tz@424: tz@424: !DirectoryView class methodsFor:'documentation'! tz@424: tz@424: version tz@424: ^ '$Header$' cg@3299: ! cg@3299: cg@3299: version_CVS cg@3299: ^ '$Header$' tz@424: ! ! cg@2999: