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: 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... cg@2351: ...but the disabdvantage 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: #max: #(#Point 1152 900) 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: tz@424: 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 tz@590: tz@424: |readBlock| tz@424: readTask notNil ifTrue: [readTask terminate]. tz@424: readBlock := tz@424: [ tz@424: |dir currentFilenames oldListOfFiles| tz@424: dir := directory asFilename. tz@424: currentFilenames := OrderedCollection new. tz@424: (dir isReadable and:[dir isExecutable]) ifTrue: tz@424: [ tz@424: self listOfFileFilters value do: tz@424: [:filter| tz@424: (dir filesMatchingWithoutDotDirs: filter) do: tz@424: [:aFileName| tz@424: |file| tz@424: (file := dir construct: aFileName) isDirectory tz@424: ifFalse: tz@424: [ tz@424: currentFilenames add: file tz@424: ] tz@424: ]. tz@424: ]. tz@424: ]. tz@424: oldListOfFiles := self listOfFiles copy. tz@424: (currentFilenames asSortedCollection: [:f1 :f2| f1 baseName < f2 baseName]) asSet do: tz@424: [:fileName| tz@424: (oldListOfFiles detect: [:fileRow| fileRow fileName = fileName] ifNone: nil) isNil tz@424: ifTrue: tz@424: [ tz@424: |nearestFileRow r| tz@424: nearestFileRow := self listOfFiles indexOf: (self listOfFiles detect: [:fileRow| fileRow baseName > fileName baseName] ifNone: nil). tz@424: nearestFileRow = 0 tz@424: ifTrue: [self listOfFiles add: (r := FileRow new fileName: fileName asFilename)] tz@424: ifFalse: [self listOfFiles add: (r := FileRow new fileName: fileName asFilename) beforeIndex: nearestFileRow]. tz@424: monitoring ifTrue: [self selectionOfFile value: r]. tz@424: ] tz@424: ]. tz@424: self listOfFiles reverseDo: tz@424: [:fileRow| tz@424: (currentFilenames includes: fileRow fileName) tz@424: ifFalse: [self listOfFiles remove: fileRow] tz@424: ] tz@424: ]. tz@424: tz@424: monitoring tz@424: ifTrue: tz@424: [ tz@424: readTask := readBlock forkAt: Processor userBackgroundPriority. tz@424: Processor addTimedBlock: monitoringTimeBlock afterSeconds: 1 tz@424: ] tz@424: ifFalse: tz@424: [ tz@424: Cursor wait showWhile: [readBlock value] tz@424: ] 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: tz@424: !DirectoryView methodsFor:'startup / release'! tz@424: tz@424: closeRequest tz@424: tz@424: self release. tz@424: tz@424: super closeRequest tz@424: 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 tz@590: "Generated by the Image Editor" tz@590: " tz@590: ImageEditor openOnClass:self andSelector:#MakefileIcon tz@590: " tz@424: tz@424: tz@590: tz@590: ^Icon tz@590: constantNamed:#'DirectoryView::FileRow MakefileIcon' 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)IV0/U$0)]&0)UT;)UV4 @@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: binaryFileIcon tz@590: "Generated by the Image Editor" tz@590: " tz@590: ImageEditor openOnClass:self andSelector:#binaryFileIcon tz@590: " tz@424: tz@424: tz@590: tz@590: ^Icon tz@590: constantNamed:#'DirectoryView::FileRow binaryFileIcon' penk@1627: ifAbsentPut:[(Depth1Image new) width: 20; height: 19; photometric:(#palette); bitsPerSample:(#(1 )); samplesPerPixel:(1); 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'); 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: cFileIcon tz@590: "Generated by the Image Editor" tz@590: " tz@590: ImageEditor openOnClass:self andSelector:#cFileIcon tz@590: " tz@424: tz@424: tz@590: tz@590: ^Icon tz@590: constantNamed:#'DirectoryView::FileRow cFileIcon' 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: exeFileIcon tz@590: "Generated by the Image Editor" tz@590: " tz@590: ImageEditor openOnClass:self andSelector:#exeFileIcon tz@590: " tz@424: tz@424: tz@590: tz@590: ^Icon tz@590: constantNamed:#'DirectoryView::FileRow exeFileIcon' penk@1627: ifAbsentPut:[(Depth2Image new) width: 20; height: 19; photometric:(#palette); bitsPerSample:(#(2 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'UUUUUUU@@@@UUT@@@AEUP@@@DEU@@@@PETEUUUUUPZ**)UUAUUUUATG???4EP_???PUA???=ATG???4EP_???PUA???=ATEUUUTEP@@@@@U@@@@@AUUUUUUUUUUUUUTb'); colorMap:(((Array new:4) at:1 put:((Color white)); at:2 put:((Color black)); at:3 put:((Color red:0.0 green:49.9977 blue:49.9977)); at:4 put:((Color grey:66.9978)); 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: 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 tz@644: "Generated by the Image Editor" tz@644: " tz@644: ImageEditor openOnClass:self andSelector:#htmlFileIcon tz@644: " tz@424: tz@424: tz@644: tz@644: ^Icon tz@644: constantNamed:#'DirectoryView::FileRow htmlFileIcon' penk@1627: ifAbsentPut:[(Depth4Image new) width: 20; height: 19; photometric:(#palette); bitsPerSample:(#(4 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'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 tz@644: "Generated by the Image Editor" tz@644: " tz@644: ImageEditor openOnClass:self andSelector:#imageFileIcon tz@644: " tz@644: tz@644: tz@644: tz@644: ^Icon tz@644: constantNamed:#'DirectoryView::FileRow imageFileIcon' penk@1627: ifAbsentPut:[(Depth4Image new) width: 20; height: 19; photometric:(#palette); bitsPerSample:(#(4 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@@@@@@@@DQDQDQDQ@@@@@ADQDQDQDPD@@@@QDQDQDQDAD@@@DQDQDQDQ@QD@@ADQDQDQDP@@@@@TQG]4)G50@@@@EDQ7^$+W4QDP@AQD]7R$_WDQD@@SL6Y#$61!!DQ@@D3M&ZS''F0QDP@AL3Y&NS[FDQD@@RH%UR %-QDQ@@D"IUVB"5,QDP@AH"UUJBV5DQD@@QDQDQDQDQDQ@@DQDQDQDQDQDP@@@@@@@@@@@@@@@@@@@@@@@@@@@@@a') ; colorMap:((OrderedCollection new add:(Color black); add:(Color white); add:(Color red:100.0 green:0.0 blue:0.0); add:(Color red:0.0 green:100.0 blue:0.0); add:(Color red:0.0 green:0.0 blue:100.0); add:(Color red:0.0 green:100.0 blue:100.0); add:(Color red:100.0 green:100.0 blue:0.0); add:(Color red:100.0 green:0.0 blue:100.0); add:(Color red:49.9977 green:0.0 blue:0.0); add:(Color red:0.0 green:49.9977 blue:0.0); add:(Color red:0.0 green:0.0 blue:49.9977); add:(Color red:0.0 green:49.9977 blue:49.9977); add:(Color red:49.9977 green:49.9977 blue:0.0); add:(Color red:49.9977 green:0.0 blue:49.9977); add:(Color grey:49.9977); add:(Color grey:66.9978); 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: 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 tz@644: "Generated by the Image Editor" tz@644: " tz@644: ImageEditor openOnClass:self andSelector:#sFileIcon tz@644: " tz@424: tz@424: tz@644: tz@644: ^Icon tz@644: constantNamed:#'DirectoryView::FileRow sFileIcon' 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 X@0 @0 0@0 X@0&H@;&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: stFileIcon tz@590: "Generated by the Image Editor" tz@590: " tz@590: ImageEditor openOnClass:self andSelector:#stFileIcon tz@590: " tz@424: tz@424: tz@590: tz@590: ^Icon tz@590: constantNamed:#'DirectoryView::FileRow stFileIcon' 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 A@0 A@0 [00 !!@0 1@0 Y@0&I@;&004 @@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: stcFileIcon tz@644: "Generated by the Image Editor" tz@644: " tz@644: ImageEditor openOnClass:self andSelector:#stcFileIcon tz@644: " tz@424: tz@424: tz@644: tz@644: ^Icon tz@644: constantNamed:#'DirectoryView::FileRow stcFileIcon' 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 B@0 B@0 _L0 "R0 2P0 ZP0&JR;&3L4 @@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: !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@424: tz@638: |icon| tz@638: iconKey isNil tz@638: ifTrue: tz@424: [ tz@614: self validateAttributes. tz@638: (imageFromFile isNil and: [iconKey == #imageFileIcon]) tz@638: ifTrue: [icon := self retrieveImageFromFileAndRegisterOn: aGC] tz@424: ]. cg@645: imageFromFile == true tz@638: ifFalse: [icon := aGC registerImage: (self class perform: iconKey) key: iconKey] tz@638: ifTrue: [icon := aGC registeredImageAt: iconKey]. tz@638: ^icon cg@645: cg@645: "Modified: / 18.2.1998 / 18:01:52 / 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. tz@638: (image := aGC registeredImageAt: fileName name asSymbol) isNil cg@1385: ifTrue:[ cg@1385: size < maxImageFileSize ifTrue:[ tz@638: Object errorSignal 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 tz@638: tz@638: tz@638: tz@638: ! tz@638: tz@424: size cg@607: size isNumber ifFalse:[^ size]. 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@607: "Modified: / 6.2.1998 / 03:38:45 / cg" tz@424: ! ! tz@424: tz@424: !DirectoryView::FileRow methodsFor:'private'! tz@424: tz@424: validateAttributes tz@424: tz@638: |info mode| tz@638: tz@424: permissions := String new:9 withAll:$-. tz@424: tz@424: (info := fileName info) isNil tz@424: ifTrue: tz@424: [ tz@424: iconKey := #lockedFileIcon. tz@424: size := owner := group := '?'. tz@424: ^ self tz@424: ]. tz@424: size := info size. 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: tz@424: fileName isReadable tz@424: ifTrue: tz@424: [ tz@424: info type == #symbolicLink tz@424: ifTrue: tz@424: [ tz@424: ^iconKey := #linkedFileIcon tz@424: ] tz@424: ifFalse: tz@424: [ tz@424: ((DirectoryView::FileRow class implements: (iconKey := (fileName suffix, 'FileIcon') asSymbol)) tz@424: or: tz@424: [DirectoryView::FileRow class implements: (iconKey := (fileName baseName, 'Icon') asSymbol)]) tz@424: ifFalse: tz@424: [ tz@424: iconKey := #fileIcon. tz@424: (Image isImageFileSuffix:fileName suffix) tz@424: ifTrue: tz@424: [ tz@424: ^iconKey := #imageFileIcon tz@424: ]. tz@424: (fileName suffix = 'o') | (fileName suffix = 'so') tz@424: ifTrue: tz@424: [ tz@424: ^iconKey := #binaryFileIcon tz@424: ]. tz@424: tz@424: fileName isExecutableProgram tz@424: ifTrue: tz@424: [ tz@424: ^iconKey := #exeFileIcon tz@424: ] tz@424: ] tz@424: ] tz@424: ] tz@424: ifFalse: tz@424: [ tz@424: ^iconKey := #lockedFileIcon tz@424: ]. tz@424: ! ! tz@424: tz@424: !DirectoryView class methodsFor:'documentation'! tz@424: tz@424: version tz@424: ^ '$Header$' tz@424: ! !