'From Squeak3.1alpha of 4 February 2001 [latest update: #3723] on 25 February 2001 at 1:14:18 am'! "Change Set: ZipUpdates-nk Date: 25 February 2001 Author: Ned Konz Updates to the ArchiveViewer. Assembled into an incremental update by Andreas Raab."! SystemWindow subclass: #ArchiveViewer instanceVariableNames: 'archive fileName memberIndex viewAllContents ' classVariableNames: '' poolDictionaries: '' category: 'Tools-ArchiveViewer'! !Archive methodsFor: 'archive operations' stamp: 'nk 2/24/2001 22:07'! addTree: aFileNameOrDirectory removingFirstCharacters: n | dir newMember fullPath relativePath | dir _ (aFileNameOrDirectory isString) ifTrue: [ FileDirectory on: aFileNameOrDirectory ] ifFalse: [ aFileNameOrDirectory ]. fullPath _ dir fullNameFor: ''. "this could be a bug..." relativePath _ fullPath copyFrom: n + 1 to: fullPath size. dir entries do: [ :ea | | fullName | fullName _ fullPath, ea name. newMember _ ea isDirectory ifTrue: [ self memberClass newFromDirectory: fullName ] ifFalse: [ self memberClass newFromFile: fullName ]. newMember fileName: relativePath, ea name. self addMember: newMember. ea isDirectory ifTrue: [ self addTree: fullName removingFirstCharacters: n ]. ]. ! ! !ArchiveViewer methodsFor: 'member operations' stamp: 'nk 2/24/2001 23:28'! addDirectory | directory | self canAddMember ifFalse: [ ^self ]. directory _ FileList2 modalFolderSelector. directory ifNil: [^ self]. archive addTree: directory removingFirstCharacters: directory pathName size + 1. self memberIndex: 0. self changed: #memberList.! ! !ArchiveViewer methodsFor: 'member operations' stamp: 'nk 2/24/2001 23:26'! addMember | result relative | self canAddMember ifFalse: [ ^self ]. result _ StandardFileMenu oldFile. result ifNil: [ ^self ]. relative _ result directory fullNameFor: result name. (relative beginsWith: FileDirectory default pathName) ifTrue: [ relative _ relative copyFrom: FileDirectory default pathName size + 2 to: relative size ]. (archive addFile: relative) desiredCompressionMethod: ZipArchive compressionDeflated. self memberIndex: self members size. self changed: #memberList.! ! !ArchiveViewer methodsFor: 'member operations' stamp: 'nk 2/24/2001 23:29'! addMemberFromClipboard | string newName | self canAddMember ifFalse: [ ^self ]. string _ Clipboard clipboardText asString. newName _ FillInTheBlankMorph request: 'New name for member:' initialAnswer: 'clipboardText'. newName notEmpty ifTrue: [ (archive addString: string as: newName) desiredCompressionMethod: ZipArchive compressionDeflated. self memberIndex: self members size. self changed: #memberList. ] ! ! !ArchiveViewer methodsFor: 'member operations' stamp: 'nk 2/24/2001 23:50'! canViewAllContents ^memberIndex > 0 and: [ viewAllContents not ]! ! !ArchiveViewer methodsFor: 'member operations' stamp: 'nk 2/24/2001 23:59'! changeViewAllContents (viewAllContents not and: [ self selectedMember uncompressedSize > 50000 ]) ifTrue: [ (PopUpMenu confirm: 'This member''s size is ', (self selectedMember uncompressedSize asString), '; do you really want to see all that data?') ifFalse: [ ^self ] ]. viewAllContents _ viewAllContents not. self changed: #contents! ! !ArchiveViewer methodsFor: 'member operations' stamp: 'nk 2/24/2001 23:29'! deleteMember self canDeleteMember ifFalse: [ ^self ]. archive removeMember: self selectedMember. self memberIndex: 0. self changed: #memberList. ! ! !ArchiveViewer methodsFor: 'member list' stamp: 'nk 2/24/2001 22:32'! displayLineFor: aMember | stream dateTime | stream _ WriteStream on: (String new: 60). dateTime _ Time dateAndTimeFromSeconds: aMember lastModTime. stream nextPutAll: (aMember uncompressedSize printString padded: #left to: 8 with: $ ); space; nextPutAll: (aMember compressedSize printString padded: #left to: 8 with: $ ); space; space; nextPutAll: (aMember crc32String ); space; space. dateTime first printOn: stream format: #(3 2 1 $- 2 1 2). stream space. dateTime second print24: true showSeconds: false on: stream. stream space; space; nextPutAll: (aMember fileName ). ^stream contents! ! !ArchiveViewer methodsFor: 'member list' stamp: 'nk 2/24/2001 23:46'! memberIndex: n memberIndex _ n. viewAllContents _ false. self changed: #memberIndex. self changed: #contents.! ! !ArchiveViewer methodsFor: 'archive operations' stamp: 'nk 2/24/2001 23:29'! createNewArchive self setLabel: '(new archive)'. archive _ ZipArchive new. self memberIndex: 0. self changed: #memberList.! ! !ArchiveViewer methodsFor: 'initialization' stamp: 'nk 2/24/2001 23:28'! archive: aZipArchive archive _ aZipArchive. self setLabel: 'New Zip Archive'. self memberIndex: 0. self changed: #memberList! ! !ArchiveViewer methodsFor: 'initialization' stamp: 'nk 2/24/2001 23:58'! contents self selectedMember ifNil: [ ^'' ]. viewAllContents ifFalse: [ ^self selectedMember contentsFrom: 1 to: 200 ]. ^self selectedMember contents ! ! !ArchiveViewer methodsFor: 'initialization' stamp: 'nk 2/25/2001 00:04'! contents: aText self shouldNotImplement.! ! !ArchiveViewer methodsFor: 'initialization' stamp: 'nk 2/24/2001 23:52'! createButtonBar | bar button | bar _ AlignmentMorph newRow. bar color: self backgroundColor; rubberBandCells: false; vResizing: #shrinkWrap; cellInset: 6@0. #( #( 'New\Archive' canCreateNewArchive createNewArchive 'Create a new, empty archive and discard this one' ) #( 'Load\Archive' canOpenNewArchive openNewArchive 'Open another archive and discard this one' ) #( 'Save\Archive As' canSaveArchive saveArchive 'Save this archive under a new name' ) #( 'Extract\All' canExtractAll extractAll 'Extract all this archive''s members into a directory' ) #( 'Add\File' canAddMember addMember 'Add a file to this archive' ) #( 'Add from\Clipboard' canAddMember addMemberFromClipboard 'Add the contents of the clipboard as a new file' ) #( 'Add\Directory' canAddMember addDirectory 'Add the entire contents of a directory, with all of its subdirectories' ) #( 'Extract\Member As' canExtractMember extractMember 'Extract the selected member to a file' ) #( 'Delete\Member' canDeleteMember deleteMember 'Remove the selected member from this archive' ) #( 'Rename\Member' canRenameMember renameMember 'Rename the selected member' ) #( 'View All\Contents' canViewAllContents changeViewAllContents 'Toggle the view of all the selected member''s contents' ) ) do: [ :arr | | buttonLabel | buttonLabel _ (TextMorph new) string: arr first withCRs fontName: #ComicPlain size: 9 wrap: false; hResizing: #shrinkWrap; lock; yourself. (button _ PluggableButtonMorph on: self getState: arr second action: arr third) vResizing: #shrinkWrap; hResizing: #spaceFill; onColor: self buttonOnColor offColor: self buttonOffColor; label: buttonLabel; setBalloonText: arr fourth; yourself. bar addMorphBack: button. buttonLabel composeToBounds. ]. ^bar.! ! !ArchiveViewer methodsFor: 'initialization' stamp: 'nk 2/24/2001 22:33'! createListHeadingUsingFont: font | sm | sm _ StringMorph contents: ' uncomp comp CRC-32 date time file name'. font ifNotNil: [ sm font: font ]. ^(AlignmentMorph newColumn) color: self backgroundColor; addMorph: sm; yourself.! ! !ArchiveViewer methodsFor: 'initialization' stamp: 'nk 2/24/2001 23:23'! createWindow | list heading font text | self color: self backgroundColor. self minimumExtent: 550@230. font _ (TextStyle named: #DefaultFixedTextStyle) ifNotNilDo: [ :ts | ts fontArray first ]. self addMorph: (self createButtonBar) fullFrame: (LayoutFrame fractions: (0@0 corner: 1.0@0.0) offsets: (0@0 corner: 0@44)). heading _ self createListHeadingUsingFont: font. self addMorph: heading fullFrame: (LayoutFrame fractions: (0@0 corner: 1.0@0.0) offsets: (0@44 corner: 0@60)). (list _ PluggableListMorph new) on: self list: #memberList selected: #memberIndex changeSelected: #memberIndex: menu: #memberMenu:shifted: keystroke: nil. list color: self backgroundColor. font ifNotNil: [ list font: font ]. self addMorph: list fullFrame: (LayoutFrame fractions: (0@0 corner: 1.0@0.8) offsets: (0@60 corner: 0@0)). text _ PluggableTextMorph on: self text: #contents accept: nil readSelection: nil menu: nil. self addMorph: text frame: (0@0.8 corner: 1.0@1.0). text lock. self setLabel: 'Ned''s Zip Viewer'! ! !ArchiveViewer methodsFor: 'initialization' stamp: 'nk 2/24/2001 23:28'! fileName: aString archive _ ZipArchive new readFrom: aString. self setLabel: aString. self memberIndex: 0. self changed: #memberList! ! !ArchiveViewer methodsFor: 'initialization' stamp: 'nk 2/24/2001 23:46'! initialize super initialize. memberIndex _ 0. viewAllContents _ false.! ! !FileList methodsFor: 'file list menu' stamp: 'nk 2/24/2001 18:19'! addFileToZip "Add the currently selected file to a new zip" | zip | zip _ (ZipArchive new) addFile: self fullName as: fileName; yourself. (ArchiveViewer open) archive: zip! ! !FileList methodsFor: 'file list menu' stamp: 'nk 2/24/2001 18:11'! itemsForAnyFile ^ #(('copy name to clipboard' 'rename' 'delete' 'compress' 'add file to zip') () (copyName renameFile deleteFile compressFile addFileToZip) )! ! !ZipArchiveMember methodsFor: 'accessing' stamp: 'nk 2/24/2001 22:28'! contents "Answer my contents as a string." | s | s _ RWBinaryOrTextStream on: (String new: self uncompressedSize). self extractTo: s. s text. ^s contents! ! !ZipArchiveMember methodsFor: 'accessing' stamp: 'nk 2/24/2001 23:53'! contentsFrom: start to: finish "Answer my contents as a string." | s | s _ RWBinaryOrTextStream on: (String new: finish - start + 1). self extractTo: s from: start to: finish. s text. ^s contents! ! !ZipArchiveMember methodsFor: 'private-writing' stamp: 'nk 2/24/2001 17:57'! copyRawDataTo: aStream from: start to: finish readDataRemaining _ readDataRemaining min: finish - start + 1. self readRawChunk: start - 1. [ readDataRemaining > 0 ] whileTrue: [ | data | data _ self readRawChunk: (32768 min: readDataRemaining). aStream nextPutAll: data. readDataRemaining _ readDataRemaining - data size. ]. ! ! !ZipArchiveMember methodsFor: 'private-writing' stamp: 'nk 2/24/2001 18:03'! extractTo: aStream from: start to: finish | oldCompression | self isEncrypted ifTrue: [ self error: 'encryption is unsupported' ]. aStream binary. oldCompression _ self desiredCompressionMethod: CompressionStored. self rewindData. self writeDataTo: aStream from: start to: finish. self desiredCompressionMethod: oldCompression. self endRead.! ! !ZipArchiveMember methodsFor: 'private-writing' stamp: 'nk 2/24/2001 18:01'! writeDataTo: aStream from: start to: finish "Copy my (possibly inflated or deflated) data to the given stream. But only the specified byte range. This might do decompression, or straight copying, depending on the values of compressionMethod and desiredCompressionMethod" uncompressedSize = 0 ifTrue: [ ^self ]. "nothing to do because no data" start > finish ifTrue: [ ^self ]. start > uncompressedSize ifTrue: [ ^self ]. (compressionMethod = CompressionStored and: [ desiredCompressionMethod = CompressionDeflated ]) ifTrue: [ ^self error: 'only supports uncompression or copying right now' ]. (compressionMethod = CompressionDeflated and: [ desiredCompressionMethod = CompressionStored ]) ifTrue: [ ^self uncompressDataTo: aStream from: start to: finish ]. self copyRawDataTo: aStream from: start to: finish.! ! !ZipFileMember methodsFor: 'private-writing' stamp: 'nk 2/24/2001 17:52'! uncompressDataTo: aStream from: start to: finish | decoder buffer chunkSize | decoder _ FastInflateStream on: stream. readDataRemaining _ readDataRemaining min: finish - start + 1. buffer _ ByteArray new: (32768 min: readDataRemaining). decoder next: start - 1. [ readDataRemaining > 0 ] whileTrue: [ chunkSize _ 32768 min: readDataRemaining. buffer _ decoder next: chunkSize into: buffer startingAt: 1. aStream next: chunkSize putAll: buffer startingAt: 1. readDataRemaining _ readDataRemaining - chunkSize. ]. ! !