--- a/FBrowser.st Tue Apr 22 19:33:37 1997 +0200
+++ b/FBrowser.st Wed Apr 23 13:30:25 1997 +0200
@@ -555,12 +555,13 @@
label := 'get'.
].
(self ask:(resources at:msg) yesButton:label) ifTrue:[
+ subView modified:false.
self doFileGet:viaDoubleClick
]
]
"Created: 19.6.1996 / 09:38:35 / cg"
- "Modified: 2.4.1997 / 23:24:40 / cg"
+ "Modified: 23.4.1997 / 13:04:11 / cg"
!
fileGetInfo
@@ -587,7 +588,7 @@
!
fileInsert
- "insert contents of file at cursor"
+ "insert contents of file at the cursor position"
|fileName|
@@ -596,7 +597,7 @@
self showFile:fileName insert:true encoding:fileEncoding
]
- "Modified: 22.2.1996 / 14:47:16 / cg"
+ "Modified: 23.4.1997 / 13:06:06 / cg"
!
fileListMenu
@@ -736,6 +737,8 @@
!
filePrint
+ "send a files contents to the printer (not in the menu)"
+
|fileName inStream printStream line|
self withWaitCursorDo:[
@@ -760,7 +763,7 @@
0 "compiler hint"
]
- "Modified: 9.11.1996 / 00:15:07 / cg"
+ "Modified: 23.4.1997 / 13:05:40 / cg"
!
fileRemove
@@ -799,7 +802,10 @@
fileSelect:lineNr
"selected a file - do nothing here"
+
^ self
+
+ "Modified: 23.4.1997 / 13:04:55 / cg"
!
fileSpawn
@@ -829,8 +835,9 @@
title:(resources at:'create new directory:') withCRs
okText:(resources at:'create')
action:[:newName | self doCreateDirectory:newName].
-"/ queryBox initialText:''.
queryBox showAtPointer
+
+ "Modified: 23.4.1997 / 13:04:27 / cg"
!
newFile
@@ -845,12 +852,10 @@
sel := subView selection.
sel notNil ifTrue:[
queryBox initialText:(sel asString)
-"/ ] ifFalse:[
-"/ queryBox initialText:''
].
queryBox showAtPointer
- "Modified: 21.2.1996 / 01:43:14 / cg"
+ "Modified: 23.4.1997 / 13:04:38 / cg"
!
openChangesBrowser
@@ -1556,6 +1561,451 @@
yesButton:yesButtonText
!
+getSelectedFileName
+ "returns the currently selected file; shows an error if
+ multiple files are selected"
+
+ |sel|
+
+ sel := fileListView selection.
+ (sel size > 1) ifTrue:[
+ self onlyOneSelection
+ ] ifFalse:[
+ sel notNil ifTrue:[
+ ^ fileList at:sel first
+ ]
+ ].
+ ^ nil
+!
+
+onlyOneSelection
+ "show a warning, that only one file must be selected for
+ this operation"
+
+ self warn:'exactly one file must be selected !!'
+!
+
+selectedFilesDo:aBlock
+ "evaluate aBlock on all selected files;
+ show a wait cursor while doing this"
+
+ |sel|
+
+ sel := fileListView selection.
+ sel notNil ifTrue:[
+ self withWaitCursorDo:[
+ sel do:[:aSelectionIndex |
+ aBlock value:(fileList at:aSelectionIndex )
+ ]
+ ]
+ ]
+
+!
+
+show:something
+ "show something in subview and undef acceptAction"
+
+ subView contents:something.
+ subView acceptAction:nil.
+ subView modified:false.
+ currentFileName := nil
+!
+
+showAlert:aString with:anErrorString
+ "show an alertbox, displaying the last Unix-error"
+
+ |msg|
+
+ anErrorString isNil ifTrue:[
+ msg := aString
+ ] ifFalse:[
+ msg := aString , '\\(' , anErrorString , ')'
+ ].
+ self warn:msg withCRs
+!
+
+withoutHiddenFiles:aCollection
+ "remove hidden files (i.e. those that start with '.') from
+ the list in aCollection"
+
+ |newCollection|
+
+ newCollection := aCollection species new.
+ aCollection do:[:fname |
+ |ignore|
+
+ ignore := false.
+
+ ((fname startsWith:'.') and:[fname ~= '..']) ifTrue:[
+ showDotFiles ifFalse:[
+ ignore := true
+ ]
+ ].
+ ignore ifFalse:[
+ newCollection add:fname
+ ]
+ ].
+ ^ newCollection
+
+ "Modified: 21.2.1996 / 01:33:18 / cg"
+! !
+
+!FileBrowser methodsFor:'private - actions & command execution'!
+
+binaryFileAction:aFilename
+ "for some binary files, if double clicked, we can do some useful
+ action ..."
+
+ (currentDirectory pathName , '/' , aFilename) asFilename isExecutable ifTrue:[
+ (OperatingSystem executeCommand:'cd ',currentDirectory pathName, '; ',aFilename)
+ ifTrue:[^true].
+ ].
+ ^ self imageAction:aFilename
+
+ "Modified: 19.6.1996 / 09:44:07 / cg"
+!
+
+doExecuteCommand:command replace:replace
+ "execute a unix command inserting the output of the command.
+ If replace is true, all text is replaced by the commands output;
+ otherwise, its inserted as selected text at the cursor position."
+
+ |stream line lnr myProcess myPriority startLine startCol stopSignal
+ access stillReplacing|
+
+ access := Semaphore forMutualExclusion name:'accessLock'.
+ stopSignal := Signal new.
+
+ "
+ must take killButton out of my group
+ "
+ windowGroup removeView:killButton.
+ "
+ bring it to front, and turn hidden-mode off
+ "
+ killButton raise.
+ killButton beVisible.
+ "
+ it will make me raise stopSignal when pressed
+ "
+ killButton
+ action:[
+ stream notNil ifTrue:[
+ access critical:[
+ myProcess interruptWith:[stopSignal raise].
+ ]
+ ]
+ ].
+ "
+ start it up under its own windowgroup
+ "
+ killButton openAutonomous.
+
+ "
+ go fork a pipe and read it
+ "
+ self label:(myName , ': executing ' , (command copyTo:(20 min:command size)) , ' ...').
+ [
+ self withWaitCursorDo:[
+ stopSignal catch:[
+ startLine := subView cursorLine.
+ startCol := subView cursorCol.
+
+ "
+ this can be a time consuming operation; therefore lower my priority
+ "
+ myProcess := Processor activeProcess.
+ myPriority := myProcess priority.
+ myProcess priority:(Processor userBackgroundPriority).
+
+ stream := PipeStream readingFrom:('cd '
+ , currentDirectory pathName
+ , '; '
+ , command
+ , ' 2>&1' ).
+ stream notNil ifTrue:[
+ [
+ |codeView lines|
+
+ stream buffered:true.
+ codeView := subView.
+
+ replace ifTrue:[
+ codeView list:nil.
+ lnr := 1.
+ ].
+
+ stillReplacing := replace.
+
+ [stream atEnd] whileFalse:[
+ (stream readWaitWithTimeoutMs:50) ifFalse:[
+ "
+ data available; read up to 100 lines
+ and insert as a single junk. This speeds up
+ display of long output (less line-scrolling).
+ "
+ lines := OrderedCollection new:100.
+ line := stream nextLine.
+ line notNil ifTrue:[lines add:line].
+
+ [stream atEnd not
+ and:[stream canReadWithoutBlocking
+ and:[lines size < 100]]] whileTrue:[
+ line := stream nextLine.
+ line notNil ifTrue:[lines add:line].
+ ].
+
+ "
+ need this critical section; otherwise,
+ we could get the signal while waiting for
+ an expose event ...
+ "
+ access critical:[
+ lines size > 0 ifTrue:[
+ stillReplacing ifTrue:[
+ lines do:[:line |
+ codeView at:lnr put:line withTabsExpanded.
+ codeView cursorToBottom; cursorDown:1.
+ lnr := lnr + 1.
+ lnr > codeView list size ifTrue:[
+ stillReplacing := false
+ ]
+ ].
+ ] ifFalse:[
+ codeView insertLines:lines before:codeView cursorLine.
+ codeView cursorDown:lines size.
+ ]
+ ].
+ ].
+ ].
+
+ shown ifTrue:[windowGroup processExposeEvents].
+ "
+ give others running at same prio a chance too
+ (especially other FileBrowsers doing the same)
+ "
+ Processor yield
+ ].
+ ] valueNowOrOnUnwindDo:[
+ stream shutDown "close". stream := nil.
+ ].
+
+ self updateCurrentDirectoryIfChanged
+
+ ].
+ replace ifTrue:[
+ subView modified:false.
+ ].
+ ]
+ ]
+ ] valueNowOrOnUnwindDo:[
+ |wg|
+
+ self label:myName; iconLabel:myName.
+ myProcess notNil ifTrue:[myProcess priority:myPriority].
+
+ "
+ remove the killButton from its group
+ (otherwise, it will be destroyed when we shut down the group)
+ "
+ wg := killButton windowGroup.
+ killButton windowGroup:nil.
+ "
+ shut down the windowgroup
+ "
+ wg notNil ifTrue:[
+ wg process terminate.
+ ].
+ "
+ hide the button, and make sure it will stay
+ hidden when we are realized again
+ "
+ killButton beInvisible.
+ "
+ clear its action (actually not needed, but
+ releases reference to thisContext earlier)
+ "
+ killButton action:nil.
+ ].
+
+ currentFileName isNil ifTrue:[
+ subView modified:false.
+ ].
+
+ subView size > 10000 ifTrue:[
+ self warn:'text quite large now - please cut off some lines'
+ ]
+
+ "Modified: 21.9.1995 / 11:18:46 / claus"
+ "Modified: 19.4.1997 / 15:29:54 / cg"
+!
+
+imageAction:aFilename
+ "for some image files, if double clicked, we can do some useful
+ action ..."
+
+ |img|
+
+ (Image isImageFileSuffix:(aFilename asFilename suffix))
+ ifTrue:[
+ img := Image fromFile:(currentDirectory pathName , '/' , aFilename).
+ img notNil ifTrue:[
+ img inspect.
+ ^ true
+ ]
+ ].
+ ^ false
+
+ "Created: 19.6.1996 / 09:43:50 / cg"
+ "Modified: 18.4.1997 / 14:56:04 / cg"
+!
+
+initialCommandFor:fileName into:aBox
+ "set a useful initial command for execute box."
+
+ |lcFilename cmd select|
+
+ "/ XXX should be changed to take stuff from a config file
+ "/ XXX or from resources.
+
+ ((currentDirectory typeOf:fileName) == #regular) ifTrue:[
+
+ (currentDirectory isExecutable:fileName) ifTrue:[
+ aBox initialText:(fileName , ' <arguments>').
+ ^ self
+ ].
+
+ lcFilename := fileName asLowercase.
+
+ select := true.
+
+ "some heuristics - my personal preferences ...
+ (actually this should come from a configfile)"
+
+ (fileName endsWith:'akefile') ifTrue:[
+ aBox initialText:'make target' selectFrom:6 to:11.
+ ^ self
+ ].
+ (lcFilename endsWith:'tar.z') ifTrue:[
+ cmd := 'zcat %1 | tar tvf -'.
+ select := false.
+ ].
+ (fileName endsWith:'.taz') ifTrue:[
+ aBox initialText:'zcat %1 | tar tvf -'.
+ select := false.
+ ].
+ (fileName endsWith:'.tar') ifTrue:[
+ cmd := 'tar tvf %1'.
+ select := 7.
+ ].
+ (fileName endsWith:'.zoo') ifTrue:[
+ cmd := 'zoo -list %1'.
+ select := 9.
+ ].
+ (lcFilename endsWith:'.zip') ifTrue:[
+ cmd := 'unzip -l %1'.
+ select := 8.
+ ].
+ (lcFilename endsWith:'.z') ifTrue:[
+ cmd := 'uncompress %1'
+ ].
+ (fileName endsWith:'tar.gz') ifTrue:[
+ cmd := ('gunzip < %1 | tar tvf -' ).
+ select := false.
+ ].
+ (fileName endsWith:'.tgz') ifTrue:[
+ cmd := ('gunzip < %1 | tar tvf -' ).
+ select := false.
+ ].
+ (fileName endsWith:'.gz') ifTrue:[
+ cmd := 'gunzip %1'.
+ ].
+ (lcFilename endsWith:'.html') ifTrue:[
+ cmd := 'netscape %1'
+ ].
+ (lcFilename endsWith:'.htm') ifTrue:[
+ cmd := 'netscape %1'
+ ].
+ (fileName endsWith:'.uue') ifTrue:[
+ cmd := 'uudecode %1'
+ ].
+ (fileName endsWith:'.c') ifTrue:[
+ cmd := 'cc -c %1'.
+ select := 5.
+ ].
+ (fileName endsWith:'.cc') ifTrue:[
+ cmd := 'g++ -c %1'.
+ select := 6.
+ ].
+ (fileName endsWith:'.C') ifTrue:[
+ cmd := 'g++ -c %1'.
+ select := 6.
+ ].
+ (fileName endsWith:'.xbm') ifTrue:[
+ cmd := 'bitmap %1'
+ ].
+ (lcFilename endsWith:'.ps') ifTrue:[
+ cmd := 'ghostview %1'
+ ].
+ ((fileName endsWith:'.1')
+ or:[fileName endsWith:'.man']) ifTrue:[
+ cmd := 'nroff -man %1'.
+ select := 10.
+ ].
+
+ cmd isNil ifTrue:[
+ DefaultCommandPerSuffix isNil ifTrue:[
+ cmd := '<cmd>'
+ ] ifFalse:[
+ cmd := DefaultCommandPerSuffix
+ at:(lcFilename asFilename suffix)
+ ifAbsent:'<cmd>'.
+ ].
+ cmd := cmd , ' %1'.
+ ].
+
+ cmd := cmd bindWith:fileName.
+ select == false ifTrue:[
+ aBox initialText:cmd
+ ] ifFalse:[
+ select isInteger ifFalse:[
+ select := (cmd indexOf:Character space ifAbsent:[cmd size + 1]) - 1.
+ ].
+ aBox initialText:cmd selectFrom:1 to:select
+ ]
+ ]
+
+ "Modified: 4.4.1997 / 12:26:40 / cg"
+!
+
+nonBinaryFileAction:aFilename
+ "for some nonBinary files, if double clicked, we can do some useful
+ action ..."
+
+ |fullPath lcName|
+
+ fullPath := currentDirectory pathName , '/' , aFilename.
+ lcName := aFilename asLowercase.
+ ((lcName endsWith:'.htm') or:[lcName endsWith:'.html']) ifTrue:[
+ HTMLDocumentView openOn:fullPath.
+ ^ true
+ ].
+
+ OperatingSystem isUNIXlike ifTrue:[
+ (#('.man' '.1' '.2' '.3') findFirst:[:suff | aFilename endsWith:suff]) ~~ 0
+ ifTrue:[
+ HTMLDocumentView openFullOnText:(HTMLDocGenerator manPageForFile:fullPath).
+ ^ true
+ ]
+ ].
+ ^ self imageAction:aFilename
+
+ "Created: 19.6.1996 / 09:36:38 / cg"
+ "Modified: 4.4.1997 / 10:49:00 / cg"
+! !
+
+!FileBrowser methodsFor:'private - directory stuff'!
+
changeToPreviousDirectory
"if text was modified show a queryBox,
otherwise change immediately to previous directory."
@@ -1757,523 +2207,41 @@
"Modified: 19.4.1997 / 15:30:32 / cg"
!
-doCreateFile:newName
- |aStream|
-
- (currentDirectory includes:newName) ifTrue:[
- (self
- ask:(resources string:'%1 already exists\\truncate ?' with:newName)
- yesButton:'truncate'
- ) ifFalse:[^ self].
- ].
-
- aStream := FileStream newFileNamed:newName in:currentDirectory.
- aStream notNil ifTrue:[
- aStream close.
- self updateCurrentDirectoryIfChanged
- ] ifFalse:[
- self showAlert:(resources string:'cannot create file ''%1'' !!' with:newName)
- with:(FileStream lastErrorString)
- ]
-
- "Modified: 19.4.1997 / 15:30:35 / cg"
-!
-
-doExecuteCommand:command replace:replace
- "execute a unix command inserting the output of the command.
- If replace is true, all text is replaced by the commands output;
- otherwise, its inserted as selected text at the cursor position."
-
- |stream line lnr myProcess myPriority startLine startCol stopSignal
- access stillReplacing|
-
- access := Semaphore forMutualExclusion name:'accessLock'.
- stopSignal := Signal new.
-
- "
- must take killButton out of my group
- "
- windowGroup removeView:killButton.
- "
- bring it to front, and turn hidden-mode off
- "
- killButton raise.
- killButton beVisible.
- "
- it will make me raise stopSignal when pressed
- "
- killButton
- action:[
- stream notNil ifTrue:[
- access critical:[
- myProcess interruptWith:[stopSignal raise].
- ]
- ]
- ].
- "
- start it up under its own windowgroup
- "
- killButton openAutonomous.
-
- "
- go fork a pipe and read it
- "
- self label:(myName , ': executing ' , (command copyTo:(20 min:command size)) , ' ...').
- [
- self withWaitCursorDo:[
- stopSignal catch:[
- startLine := subView cursorLine.
- startCol := subView cursorCol.
-
- "
- this can be a time consuming operation; therefore lower my priority
- "
- myProcess := Processor activeProcess.
- myPriority := myProcess priority.
- myProcess priority:(Processor userBackgroundPriority).
-
- stream := PipeStream readingFrom:('cd '
- , currentDirectory pathName
- , '; '
- , command
- , ' 2>&1' ).
- stream notNil ifTrue:[
- [
- |codeView lines|
-
- stream buffered:true.
- codeView := subView.
-
- replace ifTrue:[
- codeView list:nil.
- lnr := 1.
- ].
-
- stillReplacing := replace.
-
- [stream atEnd] whileFalse:[
- (stream readWaitWithTimeoutMs:50) ifFalse:[
- "
- data available; read up to 100 lines
- and insert as a single junk. This speeds up
- display of long output (less line-scrolling).
- "
- lines := OrderedCollection new:100.
- line := stream nextLine.
- line notNil ifTrue:[lines add:line].
-
- [stream atEnd not
- and:[stream canReadWithoutBlocking
- and:[lines size < 100]]] whileTrue:[
- line := stream nextLine.
- line notNil ifTrue:[lines add:line].
- ].
-
- "
- need this critical section; otherwise,
- we could get the signal while waiting for
- an expose event ...
- "
- access critical:[
- lines size > 0 ifTrue:[
- stillReplacing ifTrue:[
- lines do:[:line |
- codeView at:lnr put:line withTabsExpanded.
- codeView cursorToBottom; cursorDown:1.
- lnr := lnr + 1.
- lnr > codeView list size ifTrue:[
- stillReplacing := false
- ]
- ].
- ] ifFalse:[
- codeView insertLines:lines before:codeView cursorLine.
- codeView cursorDown:lines size.
- ]
- ].
- ].
- ].
-
- shown ifTrue:[windowGroup processExposeEvents].
- "
- give others running at same prio a chance too
- (especially other FileBrowsers doing the same)
- "
- Processor yield
- ].
- ] valueNowOrOnUnwindDo:[
- stream shutDown "close". stream := nil.
- ].
-
- self updateCurrentDirectoryIfChanged
-
+setCurrentDirectory:aPathName
+ "setup for another directory"
+
+ |newDirectory|
+
+ aPathName isEmpty ifTrue:[^ self].
+ (currentDirectory isDirectory:aPathName) ifTrue:[
+ newDirectory := FileDirectory directoryNamed:aPathName in:currentDirectory.
+ newDirectory notNil ifTrue:[
+ self currentDirectory:newDirectory pathName.
+ currentFileName notNil ifTrue:[
+ fileListView contents:nil.
+ currentFileName := nil.
+ ] ifFalse:[
+ fileListView setSelection:nil.
+ fileListView scrollToTop.
].
- replace ifTrue:[
- subView modified:false.
- ].
- ]
- ]
- ] valueNowOrOnUnwindDo:[
- |wg|
-
- self label:myName; iconLabel:myName.
- myProcess notNil ifTrue:[myProcess priority:myPriority].
-
- "
- remove the killButton from its group
- (otherwise, it will be destroyed when we shut down the group)
- "
- wg := killButton windowGroup.
- killButton windowGroup:nil.
- "
- shut down the windowgroup
- "
- wg notNil ifTrue:[
- wg process terminate.
- ].
- "
- hide the button, and make sure it will stay
- hidden when we are realized again
- "
- killButton beInvisible.
- "
- clear its action (actually not needed, but
- releases reference to thisContext earlier)
- "
- killButton action:nil.
- ].
-
- currentFileName isNil ifTrue:[
- subView modified:false.
- ].
-
- subView size > 10000 ifTrue:[
- self warn:'text quite large now - please cut off some lines'
- ]
-
- "Modified: 21.9.1995 / 11:18:46 / claus"
- "Modified: 19.4.1997 / 15:29:54 / cg"
-!
-
-doFileGet:viaDoubleClick
- "get selected file - show contents in subView"
-
- |fileName iconLbl winLbl|
-
- self withReadCursorDo:[
- fileName := self getSelectedFileName.
- fileName notNil ifTrue:[
- (currentDirectory isDirectory:fileName) ifTrue:[
- self doChangeCurrentDirectoryTo:fileName updateHistory:true.
- winLbl := myName.
- iconLbl := myName
- ] ifFalse:[
- (currentDirectory exists:fileName) ifFalse:[
- self warn:(resources string:'oops, ''%1'' is gone' with:fileName).
- ^ self
- ].
- timeOfFileRead := currentDirectory timeOfLastChange:fileName.
- self showFile:fileName insert:false encoding:fileEncoding doubleClick:viaDoubleClick.
- currentFileName := fileName.
-
- self fileTypeSpecificActions.
-
- subView acceptAction:[:theCode |
- self withCursor:(Cursor write) do:[
- self writeFile:fileName text:theCode encoding:fileEncoding.
- timeOfFileRead := currentDirectory timeOfLastChange:fileName.
- self label:myName , ': ' , currentFileName
- ]
- ].
-
- winLbl := myName , ': ' , fileName.
- (currentDirectory isWritable:fileName) ifFalse:[
- winLbl := winLbl , ' (readonly)'
- ].
- iconLbl := fileName
- ].
- self label:winLbl.
- self iconLabel:iconLbl.
+ self updateCurrentDirectory.
+ self showInfo.
]
]
- "Created: 19.6.1996 / 09:39:07 / cg"
- "Modified: 7.1.1997 / 20:21:44 / cg"
-!
-
-doRemove
- "remove the selected file(s) - no questions asked"
-
- |ok msg dir idx needUpdate toRemove updateRunning|
-
- updateRunning := listUpdateProcess notNil.
- self stopUpdateProcess.
- toRemove := OrderedCollection new.
-
- "/
- "/ did the directory change in the meanwhile ?
- "/
- needUpdate := (currentDirectory timeOfLastChange > timeOfLastCheck).
-
- lockUpdate := true.
- [
- self selectedFilesDo:[:fileName |
- ok := false.
- (currentDirectory isDirectory:fileName) ifTrue:[
- dir := FileDirectory directoryNamed:fileName in:currentDirectory.
- dir isEmpty ifTrue:[
- ok := currentDirectory removeDirectory:fileName
- ] ifFalse:[
- (self
- ask:(resources string:'directory ''%1'' is not empty\remove anyway ?' with:fileName)
- yesButton:'remove')
- ifFalse:[
- ^ self
- ].
- ok := currentDirectory removeDirectory:fileName
- ].
- ] ifFalse:[
- ok := currentDirectory remove:fileName.
- ].
- ok ifFalse:[
- "was not able to remove it"
- msg := (resources string:'cannot remove ''%1'' !!' with:fileName).
- self showAlert:msg with:(OperatingSystem lastErrorString)
- ] ifTrue:[
-"
- self show:nil
-"
- idx := fileList indexOf:fileName.
- idx ~~ 0 ifTrue:[
- toRemove add:idx.
- ]
- ]
- ].
- ] valueNowOrOnUnwindDo:[
- lockUpdate := false.
- fileListView setSelection:nil.
-
- "/
- "/ remove reverse - otherwise indices are wrong
- "/
- toRemove sort.
- toRemove reverseDo:[:idx |
- fileList removeIndex:idx.
- fileListView removeIndex:idx.
- ].
-
- updateRunning ifTrue:[
- self updateCurrentDirectory
- ] ifFalse:[
- "
- install a new check after some time
- "
- needUpdate ifFalse:[timeOfLastCheck := AbsoluteTime now].
- Processor addTimedBlock:checkBlock afterSeconds:checkDelta
- ]
- ]
-
- "Modified: 19.4.1997 / 14:03:55 / cg"
-!
-
-doRename:oldName to:newName
- (oldName notNil and:[newName notNil]) ifTrue:[
- (oldName isBlank or:[newName isBlank]) ifFalse:[
- currentDirectory renameFile:oldName newName:newName.
- self updateCurrentDirectoryIfChanged.
- ]
- ]
-
- "Modified: 19.4.1997 / 15:30:49 / cg"
-!
-
-fileCommentStrings
- "return useful comment definition; based upon the fileName for now"
-
- "/ for now,
- "/ define comment strings, by heuristics;
- "/ (should look for some mode= or similar string
- "/ found in the file itself - like emacs does it)
-
- (currentFileName = 'Make.proto'
- or:[currentFileName = 'Makefile'
- or:[currentFileName = 'makefile']]) ifTrue:[
- ^ #('#' (nil nil)).
- ].
- ((currentFileName endsWith:'.c')
- or:[(currentFileName endsWith:'.C')]) ifTrue:[
- ^ #(nil ('/*' '*/')).
- ].
- ((currentFileName endsWith:'.cc')
- or:[(currentFileName endsWith:'.CC')]) ifTrue:[
- ^ #('//' ('/*' '*/')).
- ].
- (currentFileName endsWith:'.java') ifTrue:[
- ^ #('//' (nil nil)).
- ].
-
- "/ smalltalk comments
-
- ^ #('"/' ('"' '"')).
-
- "Created: 7.1.1997 / 20:30:00 / cg"
-!
-
-fileTypeSpecificActions
- "any special fileTypeSpecific actions are done here,
- when a new file is selected"
-
- |commentStrings|
-
- commentStrings := self fileCommentStrings.
- commentStrings notNil ifTrue:[
- subView
- commentStrings:#('#' (nil nil)).
- ].
-
- "Modified: 7.1.1997 / 20:30:54 / cg"
+ "Modified: 21.9.1995 / 11:22:45 / claus"
+ "Modified: 25.5.1996 / 12:27:01 / cg"
!
-getFileInfoString:longInfo
- "get stat info on selected file - return a string which can be
- shown in a box"
-
- |fileName f fullPath text info fileOutput type modeBits modeString s ts|
-
- fileName := self getSelectedFileName.
- fileName isNil ifTrue:[^ nil].
-
- f := currentDirectory pathName asFilename construct:fileName.
- info := f info.
-
-"/ info := currentDirectory infoOf:fileName.
- info isNil ifTrue:[
- self showAlert:(resources string:'cannot get info of ''%1'' !!' with:fileName)
- with:(OperatingSystem lastErrorString).
- ^ nil
- ].
-
- text := StringCollection new.
- f isSymbolicLink ifTrue:[
- text add:(resources string:'symbolic link to: %1' with:(f linkInfo path))
- ].
-
- type := info type.
- (longInfo and:[type == #regular]) ifTrue:[
- fullPath := currentDirectory pathName , '/' , fileName.
- fileOutput := fullPath asFilename fileType.
- ].
-
- s := (resources at:'type: ').
- fileOutput isNil ifTrue:[
- s := s , type asString
- ] ifFalse:[
- s := s , 'regular (' , fileOutput , ')'
- ].
- text add:s.
- text add:(resources string:'size: %1' with:(info size) printString).
-
- modeBits := info mode.
- modeString := self getModeString:modeBits.
- longInfo ifTrue:[
- text add:(resources string:'access: %1 (%2)'
- with:modeString
- with:(modeBits printStringRadix:8))
- ] ifFalse:[
- text add:(resources string:'access: %1' with:modeString)
- ].
- text add:(resources string:'owner: %1'
- with:(OperatingSystem getUserNameFromID:(info uid))).
- longInfo ifTrue:[
- text add:(resources string:'group: %1'
- with:(OperatingSystem getGroupNameFromID:(info gid))).
-
- ts := info accessed.
- text add:(resources string:'last access: %1 %2'
- with:(ts asTime printString)
- with:(ts asDate printString)).
-
- ts := info modified.
- text add:(resources string:'last modification: %1 %2'
- with:(ts asTime printString)
- with:(ts asDate printString)).
- ].
- ^ text asString
-
- "Modified: 8.9.1995 / 11:59:28 / claus"
- "Modified: 1.11.1996 / 20:47:52 / cg"
-!
-
-getInfoFile
- "get filename of a description-file (.dir.info, README etc.);
- This file is automatically shown when a directory is enterred.
- You can add more names below if you like."
-
- #( '.dir.info'
- 'README'
- 'ReadMe'
- 'Readme'
- 'readme'
- ) do:[:f |
- (currentDirectory isReadable:f) ifTrue:[
- (currentDirectory isDirectory:f) ifFalse:[^ f].
- ]
- ].
- ^ nil
-!
-
-getModeString:modeBits
- "convert file-mode bits into a more user-friendly string.
- This is wrong here - should be moved into OperatingSystem."
-
- ^ self getModeString:modeBits
- with:#( 'owner:' $r $w $x
- ' group:' $r $w $x
- ' others:' $r $w $x )
-!
-
-getModeString:modeBits with:texts
- "convert file-mode bits into a more user-friendly string.
- This is wrong here - should be moved into OperatingSystem."
-
- |bits modeString|
-
- bits := modeBits bitAnd:8r777.
- modeString := ''.
-
- #( nil 8r400 8r200 8r100 nil 8r040 8r020 8r010 nil 8r004 8r002 8r001 )
- with: texts do:[:bitMask :access |
- |ch|
-
- bitMask isNil ifTrue:[
- modeString := modeString , (resources string:access)
- ] ifFalse:[
- (bits bitAnd:bitMask) == 0 ifTrue:[
- ch := $-
- ] ifFalse:[
- ch := access
- ].
- modeString := modeString copyWith:ch
- ]
- ].
- ^ modeString
-!
-
-getSelectedFileName
- "returns the currently selected file; shows an error if
- multiple files are selected"
-
- |sel|
-
- sel := fileListView selection.
- (sel size > 1) ifTrue:[
- self onlyOneSelection
- ] ifFalse:[
- sel notNil ifTrue:[
- ^ fileList at:sel first
- ]
- ].
- ^ nil
-!
+updateCurrentDirectoryIfChanged
+ (currentDirectory timeOfLastChange > timeOfLastCheck) ifTrue:[
+ self updateCurrentDirectory
+ ]
+
+ "Modified: 19.4.1997 / 15:30:03 / cg"
+! !
+
+!FileBrowser methodsFor:'private - encoding'!
guessEncodingFrom:aBuffer
"look for a string
@@ -2326,241 +2294,6 @@
"Modified: 23.1.1997 / 20:39:25 / cg"
!
-initialCommandFor:fileName into:aBox
- "set a useful initial command for execute box."
-
- |lcFilename cmd select|
-
- "/ XXX should be changed to take stuff from a config file
- "/ XXX or from resources.
-
- ((currentDirectory typeOf:fileName) == #regular) ifTrue:[
-
- (currentDirectory isExecutable:fileName) ifTrue:[
- aBox initialText:(fileName , ' <arguments>').
- ^ self
- ].
-
- lcFilename := fileName asLowercase.
-
- select := true.
-
- "some heuristics - my personal preferences ...
- (actually this should come from a configfile)"
-
- (fileName endsWith:'akefile') ifTrue:[
- aBox initialText:'make target' selectFrom:6 to:11.
- ^ self
- ].
- (lcFilename endsWith:'tar.z') ifTrue:[
- cmd := 'zcat %1 | tar tvf -'.
- select := false.
- ].
- (fileName endsWith:'.taz') ifTrue:[
- aBox initialText:'zcat %1 | tar tvf -'.
- select := false.
- ].
- (fileName endsWith:'.tar') ifTrue:[
- cmd := 'tar tvf %1'.
- select := 7.
- ].
- (fileName endsWith:'.zoo') ifTrue:[
- cmd := 'zoo -list %1'.
- select := 9.
- ].
- (lcFilename endsWith:'.zip') ifTrue:[
- cmd := 'unzip -l %1'.
- select := 8.
- ].
- (lcFilename endsWith:'.z') ifTrue:[
- cmd := 'uncompress %1'
- ].
- (fileName endsWith:'tar.gz') ifTrue:[
- cmd := ('gunzip < %1 | tar tvf -' ).
- select := false.
- ].
- (fileName endsWith:'.tgz') ifTrue:[
- cmd := ('gunzip < %1 | tar tvf -' ).
- select := false.
- ].
- (fileName endsWith:'.gz') ifTrue:[
- cmd := 'gunzip %1'.
- ].
- (lcFilename endsWith:'.html') ifTrue:[
- cmd := 'netscape %1'
- ].
- (lcFilename endsWith:'.htm') ifTrue:[
- cmd := 'netscape %1'
- ].
- (fileName endsWith:'.uue') ifTrue:[
- cmd := 'uudecode %1'
- ].
- (fileName endsWith:'.c') ifTrue:[
- cmd := 'cc -c %1'.
- select := 5.
- ].
- (fileName endsWith:'.cc') ifTrue:[
- cmd := 'g++ -c %1'.
- select := 6.
- ].
- (fileName endsWith:'.C') ifTrue:[
- cmd := 'g++ -c %1'.
- select := 6.
- ].
- (fileName endsWith:'.xbm') ifTrue:[
- cmd := 'bitmap %1'
- ].
- (lcFilename endsWith:'.ps') ifTrue:[
- cmd := 'ghostview %1'
- ].
- ((fileName endsWith:'.1')
- or:[fileName endsWith:'.man']) ifTrue:[
- cmd := 'nroff -man %1'.
- select := 10.
- ].
-
- cmd isNil ifTrue:[
- DefaultCommandPerSuffix isNil ifTrue:[
- cmd := '<cmd>'
- ] ifFalse:[
- cmd := DefaultCommandPerSuffix
- at:(lcFilename asFilename suffix)
- ifAbsent:'<cmd>'.
- ].
- cmd := cmd , ' %1'.
- ].
-
- cmd := cmd bindWith:fileName.
- select == false ifTrue:[
- aBox initialText:cmd
- ] ifFalse:[
- select isInteger ifFalse:[
- select := (cmd indexOf:Character space ifAbsent:[cmd size + 1]) - 1.
- ].
- aBox initialText:cmd selectFrom:1 to:select
- ]
- ]
-
- "Modified: 4.4.1997 / 12:26:40 / cg"
-!
-
-onlyOneSelection
- "show a warning, that only one file must be selected for
- this operation"
-
- self warn:'exactly one file must be selected !!'
-!
-
-selectedFilesDo:aBlock
- "evaluate aBlock on all selected files;
- show a wait cursor while doing this"
-
- |sel|
-
- sel := fileListView selection.
- sel notNil ifTrue:[
- self withWaitCursorDo:[
- sel do:[:aSelectionIndex |
- aBlock value:(fileList at:aSelectionIndex )
- ]
- ]
- ]
-
-!
-
-setCurrentDirectory:aPathName
- "setup for another directory"
-
- |newDirectory|
-
- aPathName isEmpty ifTrue:[^ self].
- (currentDirectory isDirectory:aPathName) ifTrue:[
- newDirectory := FileDirectory directoryNamed:aPathName in:currentDirectory.
- newDirectory notNil ifTrue:[
- self currentDirectory:newDirectory pathName.
- currentFileName notNil ifTrue:[
- fileListView contents:nil.
- currentFileName := nil.
- ] ifFalse:[
- fileListView setSelection:nil.
- fileListView scrollToTop.
- ].
- self updateCurrentDirectory.
- self showInfo.
- ]
- ]
-
- "Modified: 21.9.1995 / 11:22:45 / claus"
- "Modified: 25.5.1996 / 12:27:01 / cg"
-!
-
-show:something
- "show something in subview and undef acceptAction"
-
- subView contents:something.
- subView acceptAction:nil.
- subView modified:false.
- currentFileName := nil
-!
-
-showAlert:aString with:anErrorString
- "show an alertbox, displaying the last Unix-error"
-
- |msg|
-
- anErrorString isNil ifTrue:[
- msg := aString
- ] ifFalse:[
- msg := aString , '\\(' , anErrorString , ')'
- ].
- self warn:msg withCRs
-!
-
-showInfo
- "show directory info when dir has changed"
-
- |info txt|
-
- info := self getInfoFile.
- info notNil ifTrue:[
- txt := self readFile:info
- ].
- self show:txt.
-!
-
-sizePrintString:size
- "helper for update-directory to return a string with a files size.
- This one gives the size in byte, Kb or Mb depending on size.
- If you dont like this, just uncomment the first statement below."
-
- |unitString n|
-
-"
- ^ size printString.
-"
- unitString := ''.
- size < (500 * 1024) ifTrue:[
- size < 1024 ifTrue:[
- n := size
- ] ifFalse:[
- n := (size * 10 // 1024 / 10.0).
- unitString := ' Kb'
- ]
- ] ifFalse:[
- n := (size * 10 // 1024 // 1024 / 10.0).
- unitString := ' Mb'
- ].
- ^ (n printStringLeftPaddedTo:5) , unitString.
-!
-
-updateCurrentDirectoryIfChanged
- (currentDirectory timeOfLastChange > timeOfLastCheck) ifTrue:[
- self updateCurrentDirectory
- ]
-
- "Modified: 19.4.1997 / 15:30:03 / cg"
-!
-
validateFontEncodingFor:newEncoding ask:ask
"if required, query user if he/she wants to change to another font,
which is able to display text encoded as specified by newEncoding"
@@ -2653,93 +2386,645 @@
]
"Created: 26.10.1996 / 12:06:54 / cg"
+! !
+
+!FileBrowser methodsFor:'private - file stuff'!
+
+doCreateFile:newName
+ "create an empty file"
+
+ |aStream|
+
+ (currentDirectory includes:newName) ifTrue:[
+ (self
+ ask:(resources string:'%1 already exists\\truncate ?' with:newName)
+ yesButton:'truncate'
+ ) ifFalse:[^ self].
+ ].
+
+ aStream := FileStream newFileNamed:newName in:currentDirectory.
+ aStream notNil ifTrue:[
+ aStream close.
+ self updateCurrentDirectoryIfChanged
+ ] ifFalse:[
+ self showAlert:(resources string:'cannot create file ''%1'' !!' with:newName)
+ with:(FileStream lastErrorString)
+ ]
+
+ "Modified: 23.4.1997 / 13:19:12 / cg"
!
-withoutHiddenFiles:aCollection
- "remove hidden files (i.e. those that start with '.') from
- the list in aCollection"
-
- |newCollection|
-
- newCollection := aCollection species new.
- aCollection do:[:fname |
- |ignore|
-
- ignore := false.
-
- ((fname startsWith:'.') and:[fname ~= '..']) ifTrue:[
- showDotFiles ifFalse:[
- ignore := true
+doFileGet:viaDoubleClick
+ "get selected file - show contents in subView.
+ This is invoked either by the 'get file' menu item, or via double click.
+ When invoked via the menu (viaDoubleClick argument is false),
+ the automatic file action is not performed - instead, the file is always
+ shown in the codeView (if possible).
+ This distinction was done to allow xpm or xbm files (which ahve an automatic
+ action) to be edited."
+
+ |fileName iconLbl winLbl|
+
+ self withReadCursorDo:[
+ fileName := self getSelectedFileName.
+ fileName notNil ifTrue:[
+ (currentDirectory isDirectory:fileName) ifTrue:[
+ self doChangeCurrentDirectoryTo:fileName updateHistory:true.
+ winLbl := myName.
+ iconLbl := myName
+ ] ifFalse:[
+ (currentDirectory exists:fileName) ifFalse:[
+ self warn:(resources string:'oops, ''%1'' is gone' with:fileName).
+ ^ self
+ ].
+ timeOfFileRead := currentDirectory timeOfLastChange:fileName.
+ self showFile:fileName insert:false encoding:fileEncoding doubleClick:viaDoubleClick.
+ currentFileName := fileName.
+
+ self fileTypeSpecificActions.
+
+ subView acceptAction:[:theCode |
+ self withCursor:(Cursor write) do:[
+ self writeFile:fileName text:theCode encoding:fileEncoding.
+ timeOfFileRead := currentDirectory timeOfLastChange:fileName.
+ self label:myName , ': ' , currentFileName
+ ]
+ ].
+
+ winLbl := myName , ': ' , fileName.
+ (currentDirectory isWritable:fileName) ifFalse:[
+ winLbl := winLbl , ' (readonly)'
+ ].
+ iconLbl := fileName
+ ].
+ self label:winLbl.
+ self iconLabel:iconLbl.
+ ]
+ ]
+
+ "Created: 19.6.1996 / 09:39:07 / cg"
+ "Modified: 23.4.1997 / 13:19:01 / cg"
+!
+
+doRemove
+ "remove the selected file(s) - no questions asked"
+
+ |ok msg dir idx needUpdate toRemove updateRunning|
+
+ updateRunning := listUpdateProcess notNil.
+ self stopUpdateProcess.
+ toRemove := OrderedCollection new.
+
+ "/
+ "/ did the directory change in the meanwhile ?
+ "/
+ needUpdate := (currentDirectory timeOfLastChange > timeOfLastCheck).
+
+ lockUpdate := true.
+ [
+ self selectedFilesDo:[:fileName |
+ ok := false.
+ (currentDirectory isDirectory:fileName) ifTrue:[
+ dir := FileDirectory directoryNamed:fileName in:currentDirectory.
+ dir isEmpty ifTrue:[
+ ok := currentDirectory removeDirectory:fileName
+ ] ifFalse:[
+ (self
+ ask:(resources string:'directory ''%1'' is not empty\remove anyway ?' with:fileName)
+ yesButton:'remove')
+ ifFalse:[
+ ^ self
+ ].
+ ok := currentDirectory removeDirectory:fileName
+ ].
+ ] ifFalse:[
+ ok := currentDirectory remove:fileName.
+ ].
+ ok ifFalse:[
+ "was not able to remove it"
+ msg := (resources string:'cannot remove ''%1'' !!' with:fileName).
+ self showAlert:msg with:(OperatingSystem lastErrorString)
+ ] ifTrue:[
+"
+ self show:nil
+"
+ idx := fileList indexOf:fileName.
+ idx ~~ 0 ifTrue:[
+ toRemove add:idx.
+ ]
]
].
- ignore ifFalse:[
- newCollection add:fname
+ ] valueNowOrOnUnwindDo:[
+ lockUpdate := false.
+ fileListView setSelection:nil.
+
+ "/
+ "/ remove reverse - otherwise indices are wrong
+ "/
+ toRemove sort.
+ toRemove reverseDo:[:idx |
+ fileList removeIndex:idx.
+ fileListView removeIndex:idx.
+ ].
+
+ updateRunning ifTrue:[
+ self updateCurrentDirectory
+ ] ifFalse:[
+ "
+ install a new check after some time
+ "
+ needUpdate ifFalse:[timeOfLastCheck := AbsoluteTime now].
+ Processor addTimedBlock:checkBlock afterSeconds:checkDelta
+ ]
+ ]
+
+ "Modified: 19.4.1997 / 14:03:55 / cg"
+!
+
+doRename:oldName to:newName
+ "rename file(s) (or directories)"
+
+ (oldName notNil and:[newName notNil]) ifTrue:[
+ (oldName isBlank or:[newName isBlank]) ifFalse:[
+ currentDirectory renameFile:oldName newName:newName.
+ self updateCurrentDirectoryIfChanged.
+ ]
+ ]
+
+ "Modified: 23.4.1997 / 13:19:37 / cg"
+! !
+
+!FileBrowser methodsFor:'private - file type & info'!
+
+fileCommentStrings
+ "return a useful comment definition; based upon the fileName for now"
+
+ "/ for now,
+ "/ define comment strings, by heuristics;
+ "/ (should look for some mode= or similar string
+ "/ found in the file itself - like emacs does it)
+
+ (currentFileName = 'Make.proto'
+ or:[currentFileName = 'Makefile'
+ or:[currentFileName = 'makefile']]) ifTrue:[
+ ^ #('#' (nil nil)).
+ ].
+ ((currentFileName endsWith:'.c')
+ or:[(currentFileName endsWith:'.C')]) ifTrue:[
+ ^ #(nil ('/*' '*/')).
+ ].
+ ((currentFileName endsWith:'.cc')
+ or:[(currentFileName endsWith:'.CC')]) ifTrue:[
+ ^ #('//' ('/*' '*/')).
+ ].
+ (currentFileName endsWith:'.java') ifTrue:[
+ ^ #('//' (nil nil)).
+ ].
+
+ "/ smalltalk comments
+
+ ^ #('"/' ('"' '"')).
+
+ "Created: 7.1.1997 / 20:30:00 / cg"
+ "Modified: 23.4.1997 / 13:11:49 / cg"
+!
+
+fileTypeSpecificActions
+ "any special fileTypeSpecific actions are done here,
+ when a new file is selected"
+
+ |commentStrings|
+
+ commentStrings := self fileCommentStrings.
+ commentStrings notNil ifTrue:[
+ subView
+ commentStrings:#('#' (nil nil)).
+ ].
+
+ "Modified: 7.1.1997 / 20:30:54 / cg"
+!
+
+getFileInfoString:longInfo
+ "get stat info on selected file - return a string which can be
+ shown in a box"
+
+ |fileName f fullPath text info fileOutput type modeBits modeString s ts|
+
+ fileName := self getSelectedFileName.
+ fileName isNil ifTrue:[^ nil].
+
+ f := currentDirectory pathName asFilename construct:fileName.
+ info := f info.
+
+"/ info := currentDirectory infoOf:fileName.
+ info isNil ifTrue:[
+ self showAlert:(resources string:'cannot get info of ''%1'' !!' with:fileName)
+ with:(OperatingSystem lastErrorString).
+ ^ nil
+ ].
+
+ text := StringCollection new.
+ f isSymbolicLink ifTrue:[
+ text add:(resources string:'symbolic link to: %1' with:(f linkInfo path))
+ ].
+
+ type := info type.
+ (longInfo and:[type == #regular]) ifTrue:[
+ fullPath := currentDirectory pathName , '/' , fileName.
+ fileOutput := fullPath asFilename fileType.
+ ].
+
+ s := (resources at:'type: ').
+ fileOutput isNil ifTrue:[
+ s := s , type asString
+ ] ifFalse:[
+ s := s , 'regular (' , fileOutput , ')'
+ ].
+ text add:s.
+ text add:(resources string:'size: %1' with:(info size) printString).
+
+ modeBits := info mode.
+ modeString := self getModeString:modeBits.
+ longInfo ifTrue:[
+ text add:(resources string:'access: %1 (%2)'
+ with:modeString
+ with:(modeBits printStringRadix:8))
+ ] ifFalse:[
+ text add:(resources string:'access: %1' with:modeString)
+ ].
+ text add:(resources string:'owner: %1'
+ with:(OperatingSystem getUserNameFromID:(info uid))).
+ longInfo ifTrue:[
+ text add:(resources string:'group: %1'
+ with:(OperatingSystem getGroupNameFromID:(info gid))).
+
+ ts := info accessed.
+ text add:(resources string:'last access: %1 %2'
+ with:(ts asTime printString)
+ with:(ts asDate printString)).
+
+ ts := info modified.
+ text add:(resources string:'last modification: %1 %2'
+ with:(ts asTime printString)
+ with:(ts asDate printString)).
+ ].
+ ^ text asString
+
+ "Modified: 8.9.1995 / 11:59:28 / claus"
+ "Modified: 1.11.1996 / 20:47:52 / cg"
+!
+
+getInfoFile
+ "get filename of a description-file (.dir.info, README etc.);
+ This file is automatically shown when a directory is enterred.
+ You can add more names below if you like."
+
+ #(
+ '.dir.info'
+ 'README'
+ 'ReadMe'
+ 'Readme'
+ 'readme'
+ 'read.me'
+ 'Read.me'
+ 'READ.ME'
+ ) do:[:f |
+ (currentDirectory isReadable:f) ifTrue:[
+ (currentDirectory isDirectory:f) ifFalse:[^ f].
]
].
- ^ newCollection
-
- "Modified: 21.2.1996 / 01:33:18 / cg"
-! !
-
-!FileBrowser methodsFor:'private - actions'!
-
-binaryFileAction:aFilename
- "for some binary files, if double clicked, we can do some useful
- action ..."
-
- (currentDirectory pathName , '/' , aFilename) asFilename isExecutable ifTrue:[
- (OperatingSystem executeCommand:'cd ',currentDirectory pathName, '; ',aFilename)
- ifTrue:[^true].
- ].
- ^ self imageAction:aFilename
-
- "Modified: 19.6.1996 / 09:44:07 / cg"
+ ^ nil
+
+ "Modified: 23.4.1997 / 13:12:36 / cg"
+!
+
+getModeString:modeBits
+ "convert file-mode bits into a more user-friendly string.
+ This is wrong here - should be moved into OperatingSystem."
+
+ ^ self getModeString:modeBits
+ with:#( 'owner:' $r $w $x
+ ' group:' $r $w $x
+ ' others:' $r $w $x )
!
-imageAction:aFilename
- "for some image files, if double clicked, we can do some useful
- action ..."
-
- |img|
-
- (Image isImageFileSuffix:(aFilename asFilename suffix))
- ifTrue:[
- img := Image fromFile:(currentDirectory pathName , '/' , aFilename).
- img notNil ifTrue:[
- img inspect.
- ^ true
+getModeString:modeBits with:texts
+ "convert file-mode bits into a more user-friendly string.
+ This is wrong here - should be moved into OperatingSystem."
+
+ |bits modeString|
+
+ bits := modeBits bitAnd:8r777.
+ modeString := ''.
+
+ #( nil 8r400 8r200 8r100 nil 8r040 8r020 8r010 nil 8r004 8r002 8r001 )
+ with: texts do:[:bitMask :access |
+ |ch|
+
+ bitMask isNil ifTrue:[
+ modeString := modeString , (resources string:access)
+ ] ifFalse:[
+ (bits bitAnd:bitMask) == 0 ifTrue:[
+ ch := $-
+ ] ifFalse:[
+ ch := access
+ ].
+ modeString := modeString copyWith:ch
]
].
- ^ false
-
- "Created: 19.6.1996 / 09:43:50 / cg"
- "Modified: 18.4.1997 / 14:56:04 / cg"
+ ^ modeString
+!
+
+showInfo
+ "show directory info when dir has changed"
+
+ |info txt|
+
+ info := self getInfoFile.
+ info notNil ifTrue:[
+ txt := self readFile:info
+ ].
+ self show:txt.
+!
+
+sizePrintString:size
+ "helper for update-directory to return a string with a files size.
+ This one gives the size in byte, Kb or Mb depending on size.
+ If you dont like this, just uncomment the first statement below."
+
+ |unitString n|
+
+"
+ ^ size printString.
+"
+ unitString := ''.
+ size < (500 * 1024) ifTrue:[
+ size < 1024 ifTrue:[
+ n := size
+ ] ifFalse:[
+ n := (size * 10 // 1024 / 10.0).
+ unitString := ' Kb'
+ ]
+ ] ifFalse:[
+ n := (size * 10 // 1024 // 1024 / 10.0).
+ unitString := ' Mb'
+ ].
+ ^ (n printStringLeftPaddedTo:5) , unitString.
+! !
+
+!FileBrowser methodsFor:'private - file-I/O'!
+
+readFile:fileName
+ "read in the file, answer its contents as StringCollection"
+
+ ^ self readFile:fileName lineDelimiter:Character cr encoding:nil
+
+ "Modified: 22.2.1996 / 14:57:08 / cg"
+!
+
+readFile:fileName lineDelimiter:aCharacter encoding:encoding
+ "read in the file, return its contents as StringCollection.
+ The files lines are delimited by aCharacter.
+ If encoding is nonNil, the file is assumed to be coded according to
+ that symbol, and #decodeString: should be able to convert it."
+
+ |stream text msg sz|
+
+ stream := FileStream readonlyFileNamed:fileName in:currentDirectory.
+ stream isNil ifTrue:[
+ msg := (resources string:'cannot read file ''%1'' !!' with:fileName).
+ self showAlert:msg with:(FileStream lastErrorString).
+ ^ nil
+ ].
+
+ "
+ for very big files, give ObjectMemory a hint, to preallocate more
+ "
+ (sz := stream size) > 1000000 ifTrue:[
+ Processor activeProcess withPriority:Processor userBackgroundPriority do:[
+ ObjectMemory announceSpaceNeed:(sz + (sz // 5)) "/ add 20% for tab expansion
+ ].
+ ].
+
+ text := self readStream:stream lineDelimiter:aCharacter encoding:encoding.
+ stream close.
+ ^ text
+
+ "Created: 22.2.1996 / 14:56:48 / cg"
+ "Modified: 8.10.1996 / 21:01:57 / cg"
+!
+
+readStream:aStream
+ "read in from aStream, answer its contents as StringCollection"
+
+ ^ self readStream:aStream lineDelimiter:Character cr encoding:nil
+
+ "Modified: 22.2.1996 / 14:58:40 / cg"
!
-nonBinaryFileAction:aFilename
- "for some nonBinary files, if double clicked, we can do some useful
- action ..."
-
- |fullPath lcName|
-
- fullPath := currentDirectory pathName , '/' , aFilename.
- lcName := aFilename asLowercase.
- ((lcName endsWith:'.htm') or:[lcName endsWith:'.html']) ifTrue:[
- HTMLDocumentView openOn:fullPath.
- ^ true
+readStream:aStream lineDelimiter:aCharacter encoding:encoding
+ "read from aStream, answer its contents as StringCollection.
+ The files lines are delimited by aCharacter.
+ If encoding is nonNil, the file is assumed to be coded according to
+ that symbol, and #decodeString: should be able to convert it."
+
+ |text line enc|
+
+ text := StringCollection new.
+
+ enc := encoding.
+ enc == #iso8859 ifTrue:[
+ enc := nil
+ ].
+
+ aCharacter == Character cr ifTrue:[
+ [aStream atEnd] whileFalse:[
+ line := aStream nextLine withTabsExpanded.
+ enc notNil ifTrue:[
+ line := line decodeFrom:enc
+ ].
+ text add:line
+ ].
+ ] ifFalse:[
+ [aStream atEnd] whileFalse:[
+ line := (aStream upTo:aCharacter) withTabsExpanded.
+ enc notNil ifTrue:[
+ line := line decodeFrom:enc
+ ].
+ text add:line
+ ].
].
-
- OperatingSystem isUNIXlike ifTrue:[
- (#('.man' '.1' '.2' '.3') findFirst:[:suff | aFilename endsWith:suff]) ~~ 0
- ifTrue:[
- HTMLDocumentView openFullOnText:(HTMLDocGenerator manPageForFile:fullPath).
- ^ true
+ ^ text
+
+ "Created: 22.2.1996 / 14:58:25 / cg"
+ "Modified: 2.4.1997 / 21:31:36 / cg"
+!
+
+showFile:fileName
+ "show contents of fileName in subView"
+
+ self showFile:fileName insert:false encoding:fileEncoding
+
+ "Modified: 22.2.1996 / 14:47:10 / cg"
+!
+
+showFile:fileName insert:insert encoding:encoding
+ "show/insert contents of fileName in subView"
+
+ ^ self
+ showFile:fileName insert:insert encoding:encoding doubleClick:false
+
+ "Modified: 19.6.1996 / 09:40:19 / cg"
+!
+
+showFile:fileName insert:insert encoding:encoding doubleClick:viaDoubleClick
+ "show/insert contents of fileName in subView"
+
+ |buffer s n i ok convert text msg eol guess action enc|
+
+ ((currentDirectory typeOf:fileName) == #regular) ifFalse:[
+ "asked for a non-file - ignore it ..."
+ (currentDirectory exists:fileName) ifFalse:[
+ msg := '''%1'' does not exist !!'.
+ ] ifTrue:[
+ msg := '''%1'' is not a regular file !!'.
+ ].
+ self warn:(resources string:msg with:fileName).
+ ^ self
+ ].
+
+ "/
+ "/ check if file is a text file
+ "/
+ s := FileStream readonlyFileNamed:fileName in:currentDirectory.
+ s isNil ifTrue:[
+ self showAlert:(resources string:'cannot read file ''%1'' !!' with:fileName)
+ with:(FileStream lastErrorString).
+ ^ nil
+ ].
+
+ buffer := String new:300.
+ n := s nextBytes:300 into:buffer.
+ s close.
+
+ enc := encoding.
+ ok := true.
+ guess := self guessEncodingFrom:buffer.
+
+ guess == #binary ifTrue:[
+ ok := false.
+ viaDoubleClick ifTrue:[
+ (self binaryFileAction:fileName) ifTrue:[^ self].
+ ].
+ (self confirm:(resources string:'''%1'' seems to be a binary file - show anyway ?' with:fileName))
+ ifFalse:[^ self]
+ ] ifFalse:[
+ viaDoubleClick ifTrue:[
+ (self nonBinaryFileAction:fileName) ifTrue:[^ self].
+ ].
+
+ "/ ascii should work in any font ...
+
+ guess ~~ #ascii ifTrue:[
+ fileEncoding ~~ guess ifTrue:[
+ action := Dialog choose:(resources string:'''%1'' seems to be ' , guess , ' encoded.' with:fileName)
+ labels:(resources array:#('cancel' 'show' 'change font'))
+ values:#(nil #show #encoding)
+ default:#encoding.
+ action isNil ifTrue:[^ self].
+ action == #encoding ifTrue:[
+ fileEncoding := guess asSymbol.
+ self validateFontEncodingFor:fileEncoding ask:false.
+ enc := fileEncoding.
+ ]
+ ]
+ ].
+ ].
+
+ convert := false.
+ ok ifTrue:[
+ "/
+ "/ check if line delimiter is a cr
+ "/
+ i := buffer indexOf:Character cr.
+ i == 0 ifTrue:[
+ "/
+ "/ no newline found - try cr
+ "/
+ i := buffer indexOf:(Character value:13).
+ i ~~ 0 ifTrue:[
+ convert := self confirm:(resources string:'''%1'' seems to have CR as line delimiter - convert to NL ?' with:fileName).
+ ]
]
].
- ^ self imageAction:aFilename
-
- "Created: 19.6.1996 / 09:36:38 / cg"
- "Modified: 4.4.1997 / 10:49:00 / cg"
+
+ insert ifFalse:[
+ "/ release old text first
+ "/ - we might need the memory in case of huge files
+ "/ (helps if you have a 4Mb file in the view,
+ "/ and click on another biggy)
+
+ subView contents:nil.
+ ].
+
+ convert ifTrue:[
+ eol := Character value:13
+ ] ifFalse:[
+ eol := Character cr
+ ].
+ text := self readFile:fileName lineDelimiter:eol encoding:enc.
+
+ insert ifFalse:[
+ self show:text
+ ] ifTrue:[
+ subView insertSelectedStringAtCursor:text asString
+ ].
+
+ "Created: 19.6.1996 / 09:39:52 / cg"
+ "Modified: 23.1.1997 / 20:31:43 / cg"
+!
+
+writeFile:fileName text:someText encoding:encoding
+ |stream msg startNr nLines string|
+
+ stream := FileStream newFileNamed:fileName in:currentDirectory.
+ stream isNil ifTrue:[
+ msg := (resources string:'cannot write file ''%1'' !!' with:fileName).
+ self showAlert:msg with:(FileStream lastErrorString)
+ ] ifFalse:[
+ someText isString ifTrue:[
+ stream nextPutAll:someText.
+ ] ifFalse:[
+ "
+ on some systems, writing linewise is very slow (via NFS)
+ therefore we convert to a string and write it in chunks
+ to avoid creating huge strings, we do it in blocks of 1000 lines
+ "
+ startNr := 1.
+ nLines := someText size.
+ [startNr <= nLines] whileTrue:[
+ string := someText asStringWithCRsFrom:startNr
+ to:((startNr + 1000) min:nLines)
+ compressTabs:compressTabs.
+ encoding notNil ifTrue:[
+ string := string encodeInto:encoding
+ ].
+ stream nextPutAll:string.
+ startNr := startNr + 1000 + 1.
+ ].
+"/ someText do:[:line |
+"/ line notNil ifTrue:[
+"/ stream nextPutAll:line.
+"/ ].
+"/ stream cr.
+"/ ]
+ ].
+ stream close.
+ subView modified:false
+ ]
+
+ "Created: 22.2.1996 / 15:03:10 / cg"
+ "Modified: 22.2.1996 / 15:08:31 / cg"
! !
!FileBrowser methodsFor:'private - presentation'!
@@ -3190,261 +3475,6 @@
"Modified: 21.4.1997 / 15:01:27 / cg"
! !
-!FileBrowser methodsFor:'private-file-I/O'!
-
-readFile:fileName
- "read in the file, answer its contents as StringCollection"
-
- ^ self readFile:fileName lineDelimiter:Character cr encoding:nil
-
- "Modified: 22.2.1996 / 14:57:08 / cg"
-!
-
-readFile:fileName lineDelimiter:aCharacter encoding:encoding
- "read in the file, return its contents as StringCollection.
- The files lines are delimited by aCharacter.
- If encoding is nonNil, the file is assumed to be coded according to
- that symbol, and #decodeString: should be able to convert it."
-
- |stream text msg sz|
-
- stream := FileStream readonlyFileNamed:fileName in:currentDirectory.
- stream isNil ifTrue:[
- msg := (resources string:'cannot read file ''%1'' !!' with:fileName).
- self showAlert:msg with:(FileStream lastErrorString).
- ^ nil
- ].
-
- "
- for very big files, give ObjectMemory a hint, to preallocate more
- "
- (sz := stream size) > 1000000 ifTrue:[
- Processor activeProcess withPriority:Processor userBackgroundPriority do:[
- ObjectMemory announceSpaceNeed:(sz + (sz // 5)) "/ add 20% for tab expansion
- ].
- ].
-
- text := self readStream:stream lineDelimiter:aCharacter encoding:encoding.
- stream close.
- ^ text
-
- "Created: 22.2.1996 / 14:56:48 / cg"
- "Modified: 8.10.1996 / 21:01:57 / cg"
-!
-
-readStream:aStream
- "read in from aStream, answer its contents as StringCollection"
-
- ^ self readStream:aStream lineDelimiter:Character cr encoding:nil
-
- "Modified: 22.2.1996 / 14:58:40 / cg"
-!
-
-readStream:aStream lineDelimiter:aCharacter encoding:encoding
- "read from aStream, answer its contents as StringCollection.
- The files lines are delimited by aCharacter.
- If encoding is nonNil, the file is assumed to be coded according to
- that symbol, and #decodeString: should be able to convert it."
-
- |text line enc|
-
- text := StringCollection new.
-
- enc := encoding.
- enc == #iso8859 ifTrue:[
- enc := nil
- ].
-
- aCharacter == Character cr ifTrue:[
- [aStream atEnd] whileFalse:[
- line := aStream nextLine withTabsExpanded.
- enc notNil ifTrue:[
- line := line decodeFrom:enc
- ].
- text add:line
- ].
- ] ifFalse:[
- [aStream atEnd] whileFalse:[
- line := (aStream upTo:aCharacter) withTabsExpanded.
- enc notNil ifTrue:[
- line := line decodeFrom:enc
- ].
- text add:line
- ].
- ].
- ^ text
-
- "Created: 22.2.1996 / 14:58:25 / cg"
- "Modified: 2.4.1997 / 21:31:36 / cg"
-!
-
-showFile:fileName
- "show contents of fileName in subView"
-
- self showFile:fileName insert:false encoding:fileEncoding
-
- "Modified: 22.2.1996 / 14:47:10 / cg"
-!
-
-showFile:fileName insert:insert encoding:encoding
- "show/insert contents of fileName in subView"
-
- ^ self
- showFile:fileName insert:insert encoding:encoding doubleClick:false
-
- "Modified: 19.6.1996 / 09:40:19 / cg"
-!
-
-showFile:fileName insert:insert encoding:encoding doubleClick:viaDoubleClick
- "show/insert contents of fileName in subView"
-
- |buffer s n i ok convert text msg eol guess action enc|
-
- ((currentDirectory typeOf:fileName) == #regular) ifFalse:[
- "asked for a non-file - ignore it ..."
- (currentDirectory exists:fileName) ifFalse:[
- msg := '''%1'' does not exist !!'.
- ] ifTrue:[
- msg := '''%1'' is not a regular file !!'.
- ].
- self warn:(resources string:msg with:fileName).
- ^ self
- ].
-
- "/
- "/ check if file is a text file
- "/
- s := FileStream readonlyFileNamed:fileName in:currentDirectory.
- s isNil ifTrue:[
- self showAlert:(resources string:'cannot read file ''%1'' !!' with:fileName)
- with:(FileStream lastErrorString).
- ^ nil
- ].
-
- buffer := String new:300.
- n := s nextBytes:300 into:buffer.
- s close.
-
- enc := encoding.
- ok := true.
- guess := self guessEncodingFrom:buffer.
-
- guess == #binary ifTrue:[
- ok := false.
- viaDoubleClick ifTrue:[
- (self binaryFileAction:fileName) ifTrue:[^ self].
- ].
- (self confirm:(resources string:'''%1'' seems to be a binary file - show anyway ?' with:fileName))
- ifFalse:[^ self]
- ] ifFalse:[
- viaDoubleClick ifTrue:[
- (self nonBinaryFileAction:fileName) ifTrue:[^ self].
- ].
-
- "/ ascii should work in any font ...
-
- guess ~~ #ascii ifTrue:[
- fileEncoding ~~ guess ifTrue:[
- action := Dialog choose:(resources string:'''%1'' seems to be ' , guess , ' encoded.' with:fileName)
- labels:(resources array:#('cancel' 'show' 'change font'))
- values:#(nil #show #encoding)
- default:#encoding.
- action isNil ifTrue:[^ self].
- action == #encoding ifTrue:[
- fileEncoding := guess asSymbol.
- self validateFontEncodingFor:fileEncoding ask:false.
- enc := fileEncoding.
- ]
- ]
- ].
- ].
-
- convert := false.
- ok ifTrue:[
- "/
- "/ check if line delimiter is a cr
- "/
- i := buffer indexOf:Character cr.
- i == 0 ifTrue:[
- "/
- "/ no newline found - try cr
- "/
- i := buffer indexOf:(Character value:13).
- i ~~ 0 ifTrue:[
- convert := self confirm:(resources string:'''%1'' seems to have CR as line delimiter - convert to NL ?' with:fileName).
- ]
- ]
- ].
-
- insert ifFalse:[
- "/ release old text first
- "/ - we might need the memory in case of huge files
- "/ (helps if you have a 4Mb file in the view,
- "/ and click on another biggy)
-
- subView contents:nil.
- ].
-
- convert ifTrue:[
- eol := Character value:13
- ] ifFalse:[
- eol := Character cr
- ].
- text := self readFile:fileName lineDelimiter:eol encoding:enc.
-
- insert ifFalse:[
- self show:text
- ] ifTrue:[
- subView insertSelectedStringAtCursor:text asString
- ].
-
- "Created: 19.6.1996 / 09:39:52 / cg"
- "Modified: 23.1.1997 / 20:31:43 / cg"
-!
-
-writeFile:fileName text:someText encoding:encoding
- |stream msg startNr nLines string|
-
- stream := FileStream newFileNamed:fileName in:currentDirectory.
- stream isNil ifTrue:[
- msg := (resources string:'cannot write file ''%1'' !!' with:fileName).
- self showAlert:msg with:(FileStream lastErrorString)
- ] ifFalse:[
- someText isString ifTrue:[
- stream nextPutAll:someText.
- ] ifFalse:[
- "
- on some systems, writing linewise is very slow (via NFS)
- therefore we convert to a string and write it in chunks
- to avoid creating huge strings, we do it in blocks of 1000 lines
- "
- startNr := 1.
- nLines := someText size.
- [startNr <= nLines] whileTrue:[
- string := someText asStringWithCRsFrom:startNr
- to:((startNr + 1000) min:nLines)
- compressTabs:compressTabs.
- encoding notNil ifTrue:[
- string := string encodeInto:encoding
- ].
- stream nextPutAll:string.
- startNr := startNr + 1000 + 1.
- ].
-"/ someText do:[:line |
-"/ line notNil ifTrue:[
-"/ stream nextPutAll:line.
-"/ ].
-"/ stream cr.
-"/ ]
- ].
- stream close.
- subView modified:false
- ]
-
- "Created: 22.2.1996 / 15:03:10 / cg"
- "Modified: 22.2.1996 / 15:08:31 / cg"
-! !
-
!FileBrowser methodsFor:'queries'!
path
@@ -3457,6 +3487,6 @@
!FileBrowser class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libtool/Attic/FBrowser.st,v 1.151 1997-04-21 13:03:56 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libtool/Attic/FBrowser.st,v 1.152 1997-04-23 11:30:25 cg Exp $'
! !
FileBrowser initialize!
--- a/FileBrowser.st Tue Apr 22 19:33:37 1997 +0200
+++ b/FileBrowser.st Wed Apr 23 13:30:25 1997 +0200
@@ -555,12 +555,13 @@
label := 'get'.
].
(self ask:(resources at:msg) yesButton:label) ifTrue:[
+ subView modified:false.
self doFileGet:viaDoubleClick
]
]
"Created: 19.6.1996 / 09:38:35 / cg"
- "Modified: 2.4.1997 / 23:24:40 / cg"
+ "Modified: 23.4.1997 / 13:04:11 / cg"
!
fileGetInfo
@@ -587,7 +588,7 @@
!
fileInsert
- "insert contents of file at cursor"
+ "insert contents of file at the cursor position"
|fileName|
@@ -596,7 +597,7 @@
self showFile:fileName insert:true encoding:fileEncoding
]
- "Modified: 22.2.1996 / 14:47:16 / cg"
+ "Modified: 23.4.1997 / 13:06:06 / cg"
!
fileListMenu
@@ -736,6 +737,8 @@
!
filePrint
+ "send a files contents to the printer (not in the menu)"
+
|fileName inStream printStream line|
self withWaitCursorDo:[
@@ -760,7 +763,7 @@
0 "compiler hint"
]
- "Modified: 9.11.1996 / 00:15:07 / cg"
+ "Modified: 23.4.1997 / 13:05:40 / cg"
!
fileRemove
@@ -799,7 +802,10 @@
fileSelect:lineNr
"selected a file - do nothing here"
+
^ self
+
+ "Modified: 23.4.1997 / 13:04:55 / cg"
!
fileSpawn
@@ -829,8 +835,9 @@
title:(resources at:'create new directory:') withCRs
okText:(resources at:'create')
action:[:newName | self doCreateDirectory:newName].
-"/ queryBox initialText:''.
queryBox showAtPointer
+
+ "Modified: 23.4.1997 / 13:04:27 / cg"
!
newFile
@@ -845,12 +852,10 @@
sel := subView selection.
sel notNil ifTrue:[
queryBox initialText:(sel asString)
-"/ ] ifFalse:[
-"/ queryBox initialText:''
].
queryBox showAtPointer
- "Modified: 21.2.1996 / 01:43:14 / cg"
+ "Modified: 23.4.1997 / 13:04:38 / cg"
!
openChangesBrowser
@@ -1556,6 +1561,451 @@
yesButton:yesButtonText
!
+getSelectedFileName
+ "returns the currently selected file; shows an error if
+ multiple files are selected"
+
+ |sel|
+
+ sel := fileListView selection.
+ (sel size > 1) ifTrue:[
+ self onlyOneSelection
+ ] ifFalse:[
+ sel notNil ifTrue:[
+ ^ fileList at:sel first
+ ]
+ ].
+ ^ nil
+!
+
+onlyOneSelection
+ "show a warning, that only one file must be selected for
+ this operation"
+
+ self warn:'exactly one file must be selected !!'
+!
+
+selectedFilesDo:aBlock
+ "evaluate aBlock on all selected files;
+ show a wait cursor while doing this"
+
+ |sel|
+
+ sel := fileListView selection.
+ sel notNil ifTrue:[
+ self withWaitCursorDo:[
+ sel do:[:aSelectionIndex |
+ aBlock value:(fileList at:aSelectionIndex )
+ ]
+ ]
+ ]
+
+!
+
+show:something
+ "show something in subview and undef acceptAction"
+
+ subView contents:something.
+ subView acceptAction:nil.
+ subView modified:false.
+ currentFileName := nil
+!
+
+showAlert:aString with:anErrorString
+ "show an alertbox, displaying the last Unix-error"
+
+ |msg|
+
+ anErrorString isNil ifTrue:[
+ msg := aString
+ ] ifFalse:[
+ msg := aString , '\\(' , anErrorString , ')'
+ ].
+ self warn:msg withCRs
+!
+
+withoutHiddenFiles:aCollection
+ "remove hidden files (i.e. those that start with '.') from
+ the list in aCollection"
+
+ |newCollection|
+
+ newCollection := aCollection species new.
+ aCollection do:[:fname |
+ |ignore|
+
+ ignore := false.
+
+ ((fname startsWith:'.') and:[fname ~= '..']) ifTrue:[
+ showDotFiles ifFalse:[
+ ignore := true
+ ]
+ ].
+ ignore ifFalse:[
+ newCollection add:fname
+ ]
+ ].
+ ^ newCollection
+
+ "Modified: 21.2.1996 / 01:33:18 / cg"
+! !
+
+!FileBrowser methodsFor:'private - actions & command execution'!
+
+binaryFileAction:aFilename
+ "for some binary files, if double clicked, we can do some useful
+ action ..."
+
+ (currentDirectory pathName , '/' , aFilename) asFilename isExecutable ifTrue:[
+ (OperatingSystem executeCommand:'cd ',currentDirectory pathName, '; ',aFilename)
+ ifTrue:[^true].
+ ].
+ ^ self imageAction:aFilename
+
+ "Modified: 19.6.1996 / 09:44:07 / cg"
+!
+
+doExecuteCommand:command replace:replace
+ "execute a unix command inserting the output of the command.
+ If replace is true, all text is replaced by the commands output;
+ otherwise, its inserted as selected text at the cursor position."
+
+ |stream line lnr myProcess myPriority startLine startCol stopSignal
+ access stillReplacing|
+
+ access := Semaphore forMutualExclusion name:'accessLock'.
+ stopSignal := Signal new.
+
+ "
+ must take killButton out of my group
+ "
+ windowGroup removeView:killButton.
+ "
+ bring it to front, and turn hidden-mode off
+ "
+ killButton raise.
+ killButton beVisible.
+ "
+ it will make me raise stopSignal when pressed
+ "
+ killButton
+ action:[
+ stream notNil ifTrue:[
+ access critical:[
+ myProcess interruptWith:[stopSignal raise].
+ ]
+ ]
+ ].
+ "
+ start it up under its own windowgroup
+ "
+ killButton openAutonomous.
+
+ "
+ go fork a pipe and read it
+ "
+ self label:(myName , ': executing ' , (command copyTo:(20 min:command size)) , ' ...').
+ [
+ self withWaitCursorDo:[
+ stopSignal catch:[
+ startLine := subView cursorLine.
+ startCol := subView cursorCol.
+
+ "
+ this can be a time consuming operation; therefore lower my priority
+ "
+ myProcess := Processor activeProcess.
+ myPriority := myProcess priority.
+ myProcess priority:(Processor userBackgroundPriority).
+
+ stream := PipeStream readingFrom:('cd '
+ , currentDirectory pathName
+ , '; '
+ , command
+ , ' 2>&1' ).
+ stream notNil ifTrue:[
+ [
+ |codeView lines|
+
+ stream buffered:true.
+ codeView := subView.
+
+ replace ifTrue:[
+ codeView list:nil.
+ lnr := 1.
+ ].
+
+ stillReplacing := replace.
+
+ [stream atEnd] whileFalse:[
+ (stream readWaitWithTimeoutMs:50) ifFalse:[
+ "
+ data available; read up to 100 lines
+ and insert as a single junk. This speeds up
+ display of long output (less line-scrolling).
+ "
+ lines := OrderedCollection new:100.
+ line := stream nextLine.
+ line notNil ifTrue:[lines add:line].
+
+ [stream atEnd not
+ and:[stream canReadWithoutBlocking
+ and:[lines size < 100]]] whileTrue:[
+ line := stream nextLine.
+ line notNil ifTrue:[lines add:line].
+ ].
+
+ "
+ need this critical section; otherwise,
+ we could get the signal while waiting for
+ an expose event ...
+ "
+ access critical:[
+ lines size > 0 ifTrue:[
+ stillReplacing ifTrue:[
+ lines do:[:line |
+ codeView at:lnr put:line withTabsExpanded.
+ codeView cursorToBottom; cursorDown:1.
+ lnr := lnr + 1.
+ lnr > codeView list size ifTrue:[
+ stillReplacing := false
+ ]
+ ].
+ ] ifFalse:[
+ codeView insertLines:lines before:codeView cursorLine.
+ codeView cursorDown:lines size.
+ ]
+ ].
+ ].
+ ].
+
+ shown ifTrue:[windowGroup processExposeEvents].
+ "
+ give others running at same prio a chance too
+ (especially other FileBrowsers doing the same)
+ "
+ Processor yield
+ ].
+ ] valueNowOrOnUnwindDo:[
+ stream shutDown "close". stream := nil.
+ ].
+
+ self updateCurrentDirectoryIfChanged
+
+ ].
+ replace ifTrue:[
+ subView modified:false.
+ ].
+ ]
+ ]
+ ] valueNowOrOnUnwindDo:[
+ |wg|
+
+ self label:myName; iconLabel:myName.
+ myProcess notNil ifTrue:[myProcess priority:myPriority].
+
+ "
+ remove the killButton from its group
+ (otherwise, it will be destroyed when we shut down the group)
+ "
+ wg := killButton windowGroup.
+ killButton windowGroup:nil.
+ "
+ shut down the windowgroup
+ "
+ wg notNil ifTrue:[
+ wg process terminate.
+ ].
+ "
+ hide the button, and make sure it will stay
+ hidden when we are realized again
+ "
+ killButton beInvisible.
+ "
+ clear its action (actually not needed, but
+ releases reference to thisContext earlier)
+ "
+ killButton action:nil.
+ ].
+
+ currentFileName isNil ifTrue:[
+ subView modified:false.
+ ].
+
+ subView size > 10000 ifTrue:[
+ self warn:'text quite large now - please cut off some lines'
+ ]
+
+ "Modified: 21.9.1995 / 11:18:46 / claus"
+ "Modified: 19.4.1997 / 15:29:54 / cg"
+!
+
+imageAction:aFilename
+ "for some image files, if double clicked, we can do some useful
+ action ..."
+
+ |img|
+
+ (Image isImageFileSuffix:(aFilename asFilename suffix))
+ ifTrue:[
+ img := Image fromFile:(currentDirectory pathName , '/' , aFilename).
+ img notNil ifTrue:[
+ img inspect.
+ ^ true
+ ]
+ ].
+ ^ false
+
+ "Created: 19.6.1996 / 09:43:50 / cg"
+ "Modified: 18.4.1997 / 14:56:04 / cg"
+!
+
+initialCommandFor:fileName into:aBox
+ "set a useful initial command for execute box."
+
+ |lcFilename cmd select|
+
+ "/ XXX should be changed to take stuff from a config file
+ "/ XXX or from resources.
+
+ ((currentDirectory typeOf:fileName) == #regular) ifTrue:[
+
+ (currentDirectory isExecutable:fileName) ifTrue:[
+ aBox initialText:(fileName , ' <arguments>').
+ ^ self
+ ].
+
+ lcFilename := fileName asLowercase.
+
+ select := true.
+
+ "some heuristics - my personal preferences ...
+ (actually this should come from a configfile)"
+
+ (fileName endsWith:'akefile') ifTrue:[
+ aBox initialText:'make target' selectFrom:6 to:11.
+ ^ self
+ ].
+ (lcFilename endsWith:'tar.z') ifTrue:[
+ cmd := 'zcat %1 | tar tvf -'.
+ select := false.
+ ].
+ (fileName endsWith:'.taz') ifTrue:[
+ aBox initialText:'zcat %1 | tar tvf -'.
+ select := false.
+ ].
+ (fileName endsWith:'.tar') ifTrue:[
+ cmd := 'tar tvf %1'.
+ select := 7.
+ ].
+ (fileName endsWith:'.zoo') ifTrue:[
+ cmd := 'zoo -list %1'.
+ select := 9.
+ ].
+ (lcFilename endsWith:'.zip') ifTrue:[
+ cmd := 'unzip -l %1'.
+ select := 8.
+ ].
+ (lcFilename endsWith:'.z') ifTrue:[
+ cmd := 'uncompress %1'
+ ].
+ (fileName endsWith:'tar.gz') ifTrue:[
+ cmd := ('gunzip < %1 | tar tvf -' ).
+ select := false.
+ ].
+ (fileName endsWith:'.tgz') ifTrue:[
+ cmd := ('gunzip < %1 | tar tvf -' ).
+ select := false.
+ ].
+ (fileName endsWith:'.gz') ifTrue:[
+ cmd := 'gunzip %1'.
+ ].
+ (lcFilename endsWith:'.html') ifTrue:[
+ cmd := 'netscape %1'
+ ].
+ (lcFilename endsWith:'.htm') ifTrue:[
+ cmd := 'netscape %1'
+ ].
+ (fileName endsWith:'.uue') ifTrue:[
+ cmd := 'uudecode %1'
+ ].
+ (fileName endsWith:'.c') ifTrue:[
+ cmd := 'cc -c %1'.
+ select := 5.
+ ].
+ (fileName endsWith:'.cc') ifTrue:[
+ cmd := 'g++ -c %1'.
+ select := 6.
+ ].
+ (fileName endsWith:'.C') ifTrue:[
+ cmd := 'g++ -c %1'.
+ select := 6.
+ ].
+ (fileName endsWith:'.xbm') ifTrue:[
+ cmd := 'bitmap %1'
+ ].
+ (lcFilename endsWith:'.ps') ifTrue:[
+ cmd := 'ghostview %1'
+ ].
+ ((fileName endsWith:'.1')
+ or:[fileName endsWith:'.man']) ifTrue:[
+ cmd := 'nroff -man %1'.
+ select := 10.
+ ].
+
+ cmd isNil ifTrue:[
+ DefaultCommandPerSuffix isNil ifTrue:[
+ cmd := '<cmd>'
+ ] ifFalse:[
+ cmd := DefaultCommandPerSuffix
+ at:(lcFilename asFilename suffix)
+ ifAbsent:'<cmd>'.
+ ].
+ cmd := cmd , ' %1'.
+ ].
+
+ cmd := cmd bindWith:fileName.
+ select == false ifTrue:[
+ aBox initialText:cmd
+ ] ifFalse:[
+ select isInteger ifFalse:[
+ select := (cmd indexOf:Character space ifAbsent:[cmd size + 1]) - 1.
+ ].
+ aBox initialText:cmd selectFrom:1 to:select
+ ]
+ ]
+
+ "Modified: 4.4.1997 / 12:26:40 / cg"
+!
+
+nonBinaryFileAction:aFilename
+ "for some nonBinary files, if double clicked, we can do some useful
+ action ..."
+
+ |fullPath lcName|
+
+ fullPath := currentDirectory pathName , '/' , aFilename.
+ lcName := aFilename asLowercase.
+ ((lcName endsWith:'.htm') or:[lcName endsWith:'.html']) ifTrue:[
+ HTMLDocumentView openOn:fullPath.
+ ^ true
+ ].
+
+ OperatingSystem isUNIXlike ifTrue:[
+ (#('.man' '.1' '.2' '.3') findFirst:[:suff | aFilename endsWith:suff]) ~~ 0
+ ifTrue:[
+ HTMLDocumentView openFullOnText:(HTMLDocGenerator manPageForFile:fullPath).
+ ^ true
+ ]
+ ].
+ ^ self imageAction:aFilename
+
+ "Created: 19.6.1996 / 09:36:38 / cg"
+ "Modified: 4.4.1997 / 10:49:00 / cg"
+! !
+
+!FileBrowser methodsFor:'private - directory stuff'!
+
changeToPreviousDirectory
"if text was modified show a queryBox,
otherwise change immediately to previous directory."
@@ -1757,523 +2207,41 @@
"Modified: 19.4.1997 / 15:30:32 / cg"
!
-doCreateFile:newName
- |aStream|
-
- (currentDirectory includes:newName) ifTrue:[
- (self
- ask:(resources string:'%1 already exists\\truncate ?' with:newName)
- yesButton:'truncate'
- ) ifFalse:[^ self].
- ].
-
- aStream := FileStream newFileNamed:newName in:currentDirectory.
- aStream notNil ifTrue:[
- aStream close.
- self updateCurrentDirectoryIfChanged
- ] ifFalse:[
- self showAlert:(resources string:'cannot create file ''%1'' !!' with:newName)
- with:(FileStream lastErrorString)
- ]
-
- "Modified: 19.4.1997 / 15:30:35 / cg"
-!
-
-doExecuteCommand:command replace:replace
- "execute a unix command inserting the output of the command.
- If replace is true, all text is replaced by the commands output;
- otherwise, its inserted as selected text at the cursor position."
-
- |stream line lnr myProcess myPriority startLine startCol stopSignal
- access stillReplacing|
-
- access := Semaphore forMutualExclusion name:'accessLock'.
- stopSignal := Signal new.
-
- "
- must take killButton out of my group
- "
- windowGroup removeView:killButton.
- "
- bring it to front, and turn hidden-mode off
- "
- killButton raise.
- killButton beVisible.
- "
- it will make me raise stopSignal when pressed
- "
- killButton
- action:[
- stream notNil ifTrue:[
- access critical:[
- myProcess interruptWith:[stopSignal raise].
- ]
- ]
- ].
- "
- start it up under its own windowgroup
- "
- killButton openAutonomous.
-
- "
- go fork a pipe and read it
- "
- self label:(myName , ': executing ' , (command copyTo:(20 min:command size)) , ' ...').
- [
- self withWaitCursorDo:[
- stopSignal catch:[
- startLine := subView cursorLine.
- startCol := subView cursorCol.
-
- "
- this can be a time consuming operation; therefore lower my priority
- "
- myProcess := Processor activeProcess.
- myPriority := myProcess priority.
- myProcess priority:(Processor userBackgroundPriority).
-
- stream := PipeStream readingFrom:('cd '
- , currentDirectory pathName
- , '; '
- , command
- , ' 2>&1' ).
- stream notNil ifTrue:[
- [
- |codeView lines|
-
- stream buffered:true.
- codeView := subView.
-
- replace ifTrue:[
- codeView list:nil.
- lnr := 1.
- ].
-
- stillReplacing := replace.
-
- [stream atEnd] whileFalse:[
- (stream readWaitWithTimeoutMs:50) ifFalse:[
- "
- data available; read up to 100 lines
- and insert as a single junk. This speeds up
- display of long output (less line-scrolling).
- "
- lines := OrderedCollection new:100.
- line := stream nextLine.
- line notNil ifTrue:[lines add:line].
-
- [stream atEnd not
- and:[stream canReadWithoutBlocking
- and:[lines size < 100]]] whileTrue:[
- line := stream nextLine.
- line notNil ifTrue:[lines add:line].
- ].
-
- "
- need this critical section; otherwise,
- we could get the signal while waiting for
- an expose event ...
- "
- access critical:[
- lines size > 0 ifTrue:[
- stillReplacing ifTrue:[
- lines do:[:line |
- codeView at:lnr put:line withTabsExpanded.
- codeView cursorToBottom; cursorDown:1.
- lnr := lnr + 1.
- lnr > codeView list size ifTrue:[
- stillReplacing := false
- ]
- ].
- ] ifFalse:[
- codeView insertLines:lines before:codeView cursorLine.
- codeView cursorDown:lines size.
- ]
- ].
- ].
- ].
-
- shown ifTrue:[windowGroup processExposeEvents].
- "
- give others running at same prio a chance too
- (especially other FileBrowsers doing the same)
- "
- Processor yield
- ].
- ] valueNowOrOnUnwindDo:[
- stream shutDown "close". stream := nil.
- ].
-
- self updateCurrentDirectoryIfChanged
-
+setCurrentDirectory:aPathName
+ "setup for another directory"
+
+ |newDirectory|
+
+ aPathName isEmpty ifTrue:[^ self].
+ (currentDirectory isDirectory:aPathName) ifTrue:[
+ newDirectory := FileDirectory directoryNamed:aPathName in:currentDirectory.
+ newDirectory notNil ifTrue:[
+ self currentDirectory:newDirectory pathName.
+ currentFileName notNil ifTrue:[
+ fileListView contents:nil.
+ currentFileName := nil.
+ ] ifFalse:[
+ fileListView setSelection:nil.
+ fileListView scrollToTop.
].
- replace ifTrue:[
- subView modified:false.
- ].
- ]
- ]
- ] valueNowOrOnUnwindDo:[
- |wg|
-
- self label:myName; iconLabel:myName.
- myProcess notNil ifTrue:[myProcess priority:myPriority].
-
- "
- remove the killButton from its group
- (otherwise, it will be destroyed when we shut down the group)
- "
- wg := killButton windowGroup.
- killButton windowGroup:nil.
- "
- shut down the windowgroup
- "
- wg notNil ifTrue:[
- wg process terminate.
- ].
- "
- hide the button, and make sure it will stay
- hidden when we are realized again
- "
- killButton beInvisible.
- "
- clear its action (actually not needed, but
- releases reference to thisContext earlier)
- "
- killButton action:nil.
- ].
-
- currentFileName isNil ifTrue:[
- subView modified:false.
- ].
-
- subView size > 10000 ifTrue:[
- self warn:'text quite large now - please cut off some lines'
- ]
-
- "Modified: 21.9.1995 / 11:18:46 / claus"
- "Modified: 19.4.1997 / 15:29:54 / cg"
-!
-
-doFileGet:viaDoubleClick
- "get selected file - show contents in subView"
-
- |fileName iconLbl winLbl|
-
- self withReadCursorDo:[
- fileName := self getSelectedFileName.
- fileName notNil ifTrue:[
- (currentDirectory isDirectory:fileName) ifTrue:[
- self doChangeCurrentDirectoryTo:fileName updateHistory:true.
- winLbl := myName.
- iconLbl := myName
- ] ifFalse:[
- (currentDirectory exists:fileName) ifFalse:[
- self warn:(resources string:'oops, ''%1'' is gone' with:fileName).
- ^ self
- ].
- timeOfFileRead := currentDirectory timeOfLastChange:fileName.
- self showFile:fileName insert:false encoding:fileEncoding doubleClick:viaDoubleClick.
- currentFileName := fileName.
-
- self fileTypeSpecificActions.
-
- subView acceptAction:[:theCode |
- self withCursor:(Cursor write) do:[
- self writeFile:fileName text:theCode encoding:fileEncoding.
- timeOfFileRead := currentDirectory timeOfLastChange:fileName.
- self label:myName , ': ' , currentFileName
- ]
- ].
-
- winLbl := myName , ': ' , fileName.
- (currentDirectory isWritable:fileName) ifFalse:[
- winLbl := winLbl , ' (readonly)'
- ].
- iconLbl := fileName
- ].
- self label:winLbl.
- self iconLabel:iconLbl.
+ self updateCurrentDirectory.
+ self showInfo.
]
]
- "Created: 19.6.1996 / 09:39:07 / cg"
- "Modified: 7.1.1997 / 20:21:44 / cg"
-!
-
-doRemove
- "remove the selected file(s) - no questions asked"
-
- |ok msg dir idx needUpdate toRemove updateRunning|
-
- updateRunning := listUpdateProcess notNil.
- self stopUpdateProcess.
- toRemove := OrderedCollection new.
-
- "/
- "/ did the directory change in the meanwhile ?
- "/
- needUpdate := (currentDirectory timeOfLastChange > timeOfLastCheck).
-
- lockUpdate := true.
- [
- self selectedFilesDo:[:fileName |
- ok := false.
- (currentDirectory isDirectory:fileName) ifTrue:[
- dir := FileDirectory directoryNamed:fileName in:currentDirectory.
- dir isEmpty ifTrue:[
- ok := currentDirectory removeDirectory:fileName
- ] ifFalse:[
- (self
- ask:(resources string:'directory ''%1'' is not empty\remove anyway ?' with:fileName)
- yesButton:'remove')
- ifFalse:[
- ^ self
- ].
- ok := currentDirectory removeDirectory:fileName
- ].
- ] ifFalse:[
- ok := currentDirectory remove:fileName.
- ].
- ok ifFalse:[
- "was not able to remove it"
- msg := (resources string:'cannot remove ''%1'' !!' with:fileName).
- self showAlert:msg with:(OperatingSystem lastErrorString)
- ] ifTrue:[
-"
- self show:nil
-"
- idx := fileList indexOf:fileName.
- idx ~~ 0 ifTrue:[
- toRemove add:idx.
- ]
- ]
- ].
- ] valueNowOrOnUnwindDo:[
- lockUpdate := false.
- fileListView setSelection:nil.
-
- "/
- "/ remove reverse - otherwise indices are wrong
- "/
- toRemove sort.
- toRemove reverseDo:[:idx |
- fileList removeIndex:idx.
- fileListView removeIndex:idx.
- ].
-
- updateRunning ifTrue:[
- self updateCurrentDirectory
- ] ifFalse:[
- "
- install a new check after some time
- "
- needUpdate ifFalse:[timeOfLastCheck := AbsoluteTime now].
- Processor addTimedBlock:checkBlock afterSeconds:checkDelta
- ]
- ]
-
- "Modified: 19.4.1997 / 14:03:55 / cg"
-!
-
-doRename:oldName to:newName
- (oldName notNil and:[newName notNil]) ifTrue:[
- (oldName isBlank or:[newName isBlank]) ifFalse:[
- currentDirectory renameFile:oldName newName:newName.
- self updateCurrentDirectoryIfChanged.
- ]
- ]
-
- "Modified: 19.4.1997 / 15:30:49 / cg"
-!
-
-fileCommentStrings
- "return useful comment definition; based upon the fileName for now"
-
- "/ for now,
- "/ define comment strings, by heuristics;
- "/ (should look for some mode= or similar string
- "/ found in the file itself - like emacs does it)
-
- (currentFileName = 'Make.proto'
- or:[currentFileName = 'Makefile'
- or:[currentFileName = 'makefile']]) ifTrue:[
- ^ #('#' (nil nil)).
- ].
- ((currentFileName endsWith:'.c')
- or:[(currentFileName endsWith:'.C')]) ifTrue:[
- ^ #(nil ('/*' '*/')).
- ].
- ((currentFileName endsWith:'.cc')
- or:[(currentFileName endsWith:'.CC')]) ifTrue:[
- ^ #('//' ('/*' '*/')).
- ].
- (currentFileName endsWith:'.java') ifTrue:[
- ^ #('//' (nil nil)).
- ].
-
- "/ smalltalk comments
-
- ^ #('"/' ('"' '"')).
-
- "Created: 7.1.1997 / 20:30:00 / cg"
-!
-
-fileTypeSpecificActions
- "any special fileTypeSpecific actions are done here,
- when a new file is selected"
-
- |commentStrings|
-
- commentStrings := self fileCommentStrings.
- commentStrings notNil ifTrue:[
- subView
- commentStrings:#('#' (nil nil)).
- ].
-
- "Modified: 7.1.1997 / 20:30:54 / cg"
+ "Modified: 21.9.1995 / 11:22:45 / claus"
+ "Modified: 25.5.1996 / 12:27:01 / cg"
!
-getFileInfoString:longInfo
- "get stat info on selected file - return a string which can be
- shown in a box"
-
- |fileName f fullPath text info fileOutput type modeBits modeString s ts|
-
- fileName := self getSelectedFileName.
- fileName isNil ifTrue:[^ nil].
-
- f := currentDirectory pathName asFilename construct:fileName.
- info := f info.
-
-"/ info := currentDirectory infoOf:fileName.
- info isNil ifTrue:[
- self showAlert:(resources string:'cannot get info of ''%1'' !!' with:fileName)
- with:(OperatingSystem lastErrorString).
- ^ nil
- ].
-
- text := StringCollection new.
- f isSymbolicLink ifTrue:[
- text add:(resources string:'symbolic link to: %1' with:(f linkInfo path))
- ].
-
- type := info type.
- (longInfo and:[type == #regular]) ifTrue:[
- fullPath := currentDirectory pathName , '/' , fileName.
- fileOutput := fullPath asFilename fileType.
- ].
-
- s := (resources at:'type: ').
- fileOutput isNil ifTrue:[
- s := s , type asString
- ] ifFalse:[
- s := s , 'regular (' , fileOutput , ')'
- ].
- text add:s.
- text add:(resources string:'size: %1' with:(info size) printString).
-
- modeBits := info mode.
- modeString := self getModeString:modeBits.
- longInfo ifTrue:[
- text add:(resources string:'access: %1 (%2)'
- with:modeString
- with:(modeBits printStringRadix:8))
- ] ifFalse:[
- text add:(resources string:'access: %1' with:modeString)
- ].
- text add:(resources string:'owner: %1'
- with:(OperatingSystem getUserNameFromID:(info uid))).
- longInfo ifTrue:[
- text add:(resources string:'group: %1'
- with:(OperatingSystem getGroupNameFromID:(info gid))).
-
- ts := info accessed.
- text add:(resources string:'last access: %1 %2'
- with:(ts asTime printString)
- with:(ts asDate printString)).
-
- ts := info modified.
- text add:(resources string:'last modification: %1 %2'
- with:(ts asTime printString)
- with:(ts asDate printString)).
- ].
- ^ text asString
-
- "Modified: 8.9.1995 / 11:59:28 / claus"
- "Modified: 1.11.1996 / 20:47:52 / cg"
-!
-
-getInfoFile
- "get filename of a description-file (.dir.info, README etc.);
- This file is automatically shown when a directory is enterred.
- You can add more names below if you like."
-
- #( '.dir.info'
- 'README'
- 'ReadMe'
- 'Readme'
- 'readme'
- ) do:[:f |
- (currentDirectory isReadable:f) ifTrue:[
- (currentDirectory isDirectory:f) ifFalse:[^ f].
- ]
- ].
- ^ nil
-!
-
-getModeString:modeBits
- "convert file-mode bits into a more user-friendly string.
- This is wrong here - should be moved into OperatingSystem."
-
- ^ self getModeString:modeBits
- with:#( 'owner:' $r $w $x
- ' group:' $r $w $x
- ' others:' $r $w $x )
-!
-
-getModeString:modeBits with:texts
- "convert file-mode bits into a more user-friendly string.
- This is wrong here - should be moved into OperatingSystem."
-
- |bits modeString|
-
- bits := modeBits bitAnd:8r777.
- modeString := ''.
-
- #( nil 8r400 8r200 8r100 nil 8r040 8r020 8r010 nil 8r004 8r002 8r001 )
- with: texts do:[:bitMask :access |
- |ch|
-
- bitMask isNil ifTrue:[
- modeString := modeString , (resources string:access)
- ] ifFalse:[
- (bits bitAnd:bitMask) == 0 ifTrue:[
- ch := $-
- ] ifFalse:[
- ch := access
- ].
- modeString := modeString copyWith:ch
- ]
- ].
- ^ modeString
-!
-
-getSelectedFileName
- "returns the currently selected file; shows an error if
- multiple files are selected"
-
- |sel|
-
- sel := fileListView selection.
- (sel size > 1) ifTrue:[
- self onlyOneSelection
- ] ifFalse:[
- sel notNil ifTrue:[
- ^ fileList at:sel first
- ]
- ].
- ^ nil
-!
+updateCurrentDirectoryIfChanged
+ (currentDirectory timeOfLastChange > timeOfLastCheck) ifTrue:[
+ self updateCurrentDirectory
+ ]
+
+ "Modified: 19.4.1997 / 15:30:03 / cg"
+! !
+
+!FileBrowser methodsFor:'private - encoding'!
guessEncodingFrom:aBuffer
"look for a string
@@ -2326,241 +2294,6 @@
"Modified: 23.1.1997 / 20:39:25 / cg"
!
-initialCommandFor:fileName into:aBox
- "set a useful initial command for execute box."
-
- |lcFilename cmd select|
-
- "/ XXX should be changed to take stuff from a config file
- "/ XXX or from resources.
-
- ((currentDirectory typeOf:fileName) == #regular) ifTrue:[
-
- (currentDirectory isExecutable:fileName) ifTrue:[
- aBox initialText:(fileName , ' <arguments>').
- ^ self
- ].
-
- lcFilename := fileName asLowercase.
-
- select := true.
-
- "some heuristics - my personal preferences ...
- (actually this should come from a configfile)"
-
- (fileName endsWith:'akefile') ifTrue:[
- aBox initialText:'make target' selectFrom:6 to:11.
- ^ self
- ].
- (lcFilename endsWith:'tar.z') ifTrue:[
- cmd := 'zcat %1 | tar tvf -'.
- select := false.
- ].
- (fileName endsWith:'.taz') ifTrue:[
- aBox initialText:'zcat %1 | tar tvf -'.
- select := false.
- ].
- (fileName endsWith:'.tar') ifTrue:[
- cmd := 'tar tvf %1'.
- select := 7.
- ].
- (fileName endsWith:'.zoo') ifTrue:[
- cmd := 'zoo -list %1'.
- select := 9.
- ].
- (lcFilename endsWith:'.zip') ifTrue:[
- cmd := 'unzip -l %1'.
- select := 8.
- ].
- (lcFilename endsWith:'.z') ifTrue:[
- cmd := 'uncompress %1'
- ].
- (fileName endsWith:'tar.gz') ifTrue:[
- cmd := ('gunzip < %1 | tar tvf -' ).
- select := false.
- ].
- (fileName endsWith:'.tgz') ifTrue:[
- cmd := ('gunzip < %1 | tar tvf -' ).
- select := false.
- ].
- (fileName endsWith:'.gz') ifTrue:[
- cmd := 'gunzip %1'.
- ].
- (lcFilename endsWith:'.html') ifTrue:[
- cmd := 'netscape %1'
- ].
- (lcFilename endsWith:'.htm') ifTrue:[
- cmd := 'netscape %1'
- ].
- (fileName endsWith:'.uue') ifTrue:[
- cmd := 'uudecode %1'
- ].
- (fileName endsWith:'.c') ifTrue:[
- cmd := 'cc -c %1'.
- select := 5.
- ].
- (fileName endsWith:'.cc') ifTrue:[
- cmd := 'g++ -c %1'.
- select := 6.
- ].
- (fileName endsWith:'.C') ifTrue:[
- cmd := 'g++ -c %1'.
- select := 6.
- ].
- (fileName endsWith:'.xbm') ifTrue:[
- cmd := 'bitmap %1'
- ].
- (lcFilename endsWith:'.ps') ifTrue:[
- cmd := 'ghostview %1'
- ].
- ((fileName endsWith:'.1')
- or:[fileName endsWith:'.man']) ifTrue:[
- cmd := 'nroff -man %1'.
- select := 10.
- ].
-
- cmd isNil ifTrue:[
- DefaultCommandPerSuffix isNil ifTrue:[
- cmd := '<cmd>'
- ] ifFalse:[
- cmd := DefaultCommandPerSuffix
- at:(lcFilename asFilename suffix)
- ifAbsent:'<cmd>'.
- ].
- cmd := cmd , ' %1'.
- ].
-
- cmd := cmd bindWith:fileName.
- select == false ifTrue:[
- aBox initialText:cmd
- ] ifFalse:[
- select isInteger ifFalse:[
- select := (cmd indexOf:Character space ifAbsent:[cmd size + 1]) - 1.
- ].
- aBox initialText:cmd selectFrom:1 to:select
- ]
- ]
-
- "Modified: 4.4.1997 / 12:26:40 / cg"
-!
-
-onlyOneSelection
- "show a warning, that only one file must be selected for
- this operation"
-
- self warn:'exactly one file must be selected !!'
-!
-
-selectedFilesDo:aBlock
- "evaluate aBlock on all selected files;
- show a wait cursor while doing this"
-
- |sel|
-
- sel := fileListView selection.
- sel notNil ifTrue:[
- self withWaitCursorDo:[
- sel do:[:aSelectionIndex |
- aBlock value:(fileList at:aSelectionIndex )
- ]
- ]
- ]
-
-!
-
-setCurrentDirectory:aPathName
- "setup for another directory"
-
- |newDirectory|
-
- aPathName isEmpty ifTrue:[^ self].
- (currentDirectory isDirectory:aPathName) ifTrue:[
- newDirectory := FileDirectory directoryNamed:aPathName in:currentDirectory.
- newDirectory notNil ifTrue:[
- self currentDirectory:newDirectory pathName.
- currentFileName notNil ifTrue:[
- fileListView contents:nil.
- currentFileName := nil.
- ] ifFalse:[
- fileListView setSelection:nil.
- fileListView scrollToTop.
- ].
- self updateCurrentDirectory.
- self showInfo.
- ]
- ]
-
- "Modified: 21.9.1995 / 11:22:45 / claus"
- "Modified: 25.5.1996 / 12:27:01 / cg"
-!
-
-show:something
- "show something in subview and undef acceptAction"
-
- subView contents:something.
- subView acceptAction:nil.
- subView modified:false.
- currentFileName := nil
-!
-
-showAlert:aString with:anErrorString
- "show an alertbox, displaying the last Unix-error"
-
- |msg|
-
- anErrorString isNil ifTrue:[
- msg := aString
- ] ifFalse:[
- msg := aString , '\\(' , anErrorString , ')'
- ].
- self warn:msg withCRs
-!
-
-showInfo
- "show directory info when dir has changed"
-
- |info txt|
-
- info := self getInfoFile.
- info notNil ifTrue:[
- txt := self readFile:info
- ].
- self show:txt.
-!
-
-sizePrintString:size
- "helper for update-directory to return a string with a files size.
- This one gives the size in byte, Kb or Mb depending on size.
- If you dont like this, just uncomment the first statement below."
-
- |unitString n|
-
-"
- ^ size printString.
-"
- unitString := ''.
- size < (500 * 1024) ifTrue:[
- size < 1024 ifTrue:[
- n := size
- ] ifFalse:[
- n := (size * 10 // 1024 / 10.0).
- unitString := ' Kb'
- ]
- ] ifFalse:[
- n := (size * 10 // 1024 // 1024 / 10.0).
- unitString := ' Mb'
- ].
- ^ (n printStringLeftPaddedTo:5) , unitString.
-!
-
-updateCurrentDirectoryIfChanged
- (currentDirectory timeOfLastChange > timeOfLastCheck) ifTrue:[
- self updateCurrentDirectory
- ]
-
- "Modified: 19.4.1997 / 15:30:03 / cg"
-!
-
validateFontEncodingFor:newEncoding ask:ask
"if required, query user if he/she wants to change to another font,
which is able to display text encoded as specified by newEncoding"
@@ -2653,93 +2386,645 @@
]
"Created: 26.10.1996 / 12:06:54 / cg"
+! !
+
+!FileBrowser methodsFor:'private - file stuff'!
+
+doCreateFile:newName
+ "create an empty file"
+
+ |aStream|
+
+ (currentDirectory includes:newName) ifTrue:[
+ (self
+ ask:(resources string:'%1 already exists\\truncate ?' with:newName)
+ yesButton:'truncate'
+ ) ifFalse:[^ self].
+ ].
+
+ aStream := FileStream newFileNamed:newName in:currentDirectory.
+ aStream notNil ifTrue:[
+ aStream close.
+ self updateCurrentDirectoryIfChanged
+ ] ifFalse:[
+ self showAlert:(resources string:'cannot create file ''%1'' !!' with:newName)
+ with:(FileStream lastErrorString)
+ ]
+
+ "Modified: 23.4.1997 / 13:19:12 / cg"
!
-withoutHiddenFiles:aCollection
- "remove hidden files (i.e. those that start with '.') from
- the list in aCollection"
-
- |newCollection|
-
- newCollection := aCollection species new.
- aCollection do:[:fname |
- |ignore|
-
- ignore := false.
-
- ((fname startsWith:'.') and:[fname ~= '..']) ifTrue:[
- showDotFiles ifFalse:[
- ignore := true
+doFileGet:viaDoubleClick
+ "get selected file - show contents in subView.
+ This is invoked either by the 'get file' menu item, or via double click.
+ When invoked via the menu (viaDoubleClick argument is false),
+ the automatic file action is not performed - instead, the file is always
+ shown in the codeView (if possible).
+ This distinction was done to allow xpm or xbm files (which ahve an automatic
+ action) to be edited."
+
+ |fileName iconLbl winLbl|
+
+ self withReadCursorDo:[
+ fileName := self getSelectedFileName.
+ fileName notNil ifTrue:[
+ (currentDirectory isDirectory:fileName) ifTrue:[
+ self doChangeCurrentDirectoryTo:fileName updateHistory:true.
+ winLbl := myName.
+ iconLbl := myName
+ ] ifFalse:[
+ (currentDirectory exists:fileName) ifFalse:[
+ self warn:(resources string:'oops, ''%1'' is gone' with:fileName).
+ ^ self
+ ].
+ timeOfFileRead := currentDirectory timeOfLastChange:fileName.
+ self showFile:fileName insert:false encoding:fileEncoding doubleClick:viaDoubleClick.
+ currentFileName := fileName.
+
+ self fileTypeSpecificActions.
+
+ subView acceptAction:[:theCode |
+ self withCursor:(Cursor write) do:[
+ self writeFile:fileName text:theCode encoding:fileEncoding.
+ timeOfFileRead := currentDirectory timeOfLastChange:fileName.
+ self label:myName , ': ' , currentFileName
+ ]
+ ].
+
+ winLbl := myName , ': ' , fileName.
+ (currentDirectory isWritable:fileName) ifFalse:[
+ winLbl := winLbl , ' (readonly)'
+ ].
+ iconLbl := fileName
+ ].
+ self label:winLbl.
+ self iconLabel:iconLbl.
+ ]
+ ]
+
+ "Created: 19.6.1996 / 09:39:07 / cg"
+ "Modified: 23.4.1997 / 13:19:01 / cg"
+!
+
+doRemove
+ "remove the selected file(s) - no questions asked"
+
+ |ok msg dir idx needUpdate toRemove updateRunning|
+
+ updateRunning := listUpdateProcess notNil.
+ self stopUpdateProcess.
+ toRemove := OrderedCollection new.
+
+ "/
+ "/ did the directory change in the meanwhile ?
+ "/
+ needUpdate := (currentDirectory timeOfLastChange > timeOfLastCheck).
+
+ lockUpdate := true.
+ [
+ self selectedFilesDo:[:fileName |
+ ok := false.
+ (currentDirectory isDirectory:fileName) ifTrue:[
+ dir := FileDirectory directoryNamed:fileName in:currentDirectory.
+ dir isEmpty ifTrue:[
+ ok := currentDirectory removeDirectory:fileName
+ ] ifFalse:[
+ (self
+ ask:(resources string:'directory ''%1'' is not empty\remove anyway ?' with:fileName)
+ yesButton:'remove')
+ ifFalse:[
+ ^ self
+ ].
+ ok := currentDirectory removeDirectory:fileName
+ ].
+ ] ifFalse:[
+ ok := currentDirectory remove:fileName.
+ ].
+ ok ifFalse:[
+ "was not able to remove it"
+ msg := (resources string:'cannot remove ''%1'' !!' with:fileName).
+ self showAlert:msg with:(OperatingSystem lastErrorString)
+ ] ifTrue:[
+"
+ self show:nil
+"
+ idx := fileList indexOf:fileName.
+ idx ~~ 0 ifTrue:[
+ toRemove add:idx.
+ ]
]
].
- ignore ifFalse:[
- newCollection add:fname
+ ] valueNowOrOnUnwindDo:[
+ lockUpdate := false.
+ fileListView setSelection:nil.
+
+ "/
+ "/ remove reverse - otherwise indices are wrong
+ "/
+ toRemove sort.
+ toRemove reverseDo:[:idx |
+ fileList removeIndex:idx.
+ fileListView removeIndex:idx.
+ ].
+
+ updateRunning ifTrue:[
+ self updateCurrentDirectory
+ ] ifFalse:[
+ "
+ install a new check after some time
+ "
+ needUpdate ifFalse:[timeOfLastCheck := AbsoluteTime now].
+ Processor addTimedBlock:checkBlock afterSeconds:checkDelta
+ ]
+ ]
+
+ "Modified: 19.4.1997 / 14:03:55 / cg"
+!
+
+doRename:oldName to:newName
+ "rename file(s) (or directories)"
+
+ (oldName notNil and:[newName notNil]) ifTrue:[
+ (oldName isBlank or:[newName isBlank]) ifFalse:[
+ currentDirectory renameFile:oldName newName:newName.
+ self updateCurrentDirectoryIfChanged.
+ ]
+ ]
+
+ "Modified: 23.4.1997 / 13:19:37 / cg"
+! !
+
+!FileBrowser methodsFor:'private - file type & info'!
+
+fileCommentStrings
+ "return a useful comment definition; based upon the fileName for now"
+
+ "/ for now,
+ "/ define comment strings, by heuristics;
+ "/ (should look for some mode= or similar string
+ "/ found in the file itself - like emacs does it)
+
+ (currentFileName = 'Make.proto'
+ or:[currentFileName = 'Makefile'
+ or:[currentFileName = 'makefile']]) ifTrue:[
+ ^ #('#' (nil nil)).
+ ].
+ ((currentFileName endsWith:'.c')
+ or:[(currentFileName endsWith:'.C')]) ifTrue:[
+ ^ #(nil ('/*' '*/')).
+ ].
+ ((currentFileName endsWith:'.cc')
+ or:[(currentFileName endsWith:'.CC')]) ifTrue:[
+ ^ #('//' ('/*' '*/')).
+ ].
+ (currentFileName endsWith:'.java') ifTrue:[
+ ^ #('//' (nil nil)).
+ ].
+
+ "/ smalltalk comments
+
+ ^ #('"/' ('"' '"')).
+
+ "Created: 7.1.1997 / 20:30:00 / cg"
+ "Modified: 23.4.1997 / 13:11:49 / cg"
+!
+
+fileTypeSpecificActions
+ "any special fileTypeSpecific actions are done here,
+ when a new file is selected"
+
+ |commentStrings|
+
+ commentStrings := self fileCommentStrings.
+ commentStrings notNil ifTrue:[
+ subView
+ commentStrings:#('#' (nil nil)).
+ ].
+
+ "Modified: 7.1.1997 / 20:30:54 / cg"
+!
+
+getFileInfoString:longInfo
+ "get stat info on selected file - return a string which can be
+ shown in a box"
+
+ |fileName f fullPath text info fileOutput type modeBits modeString s ts|
+
+ fileName := self getSelectedFileName.
+ fileName isNil ifTrue:[^ nil].
+
+ f := currentDirectory pathName asFilename construct:fileName.
+ info := f info.
+
+"/ info := currentDirectory infoOf:fileName.
+ info isNil ifTrue:[
+ self showAlert:(resources string:'cannot get info of ''%1'' !!' with:fileName)
+ with:(OperatingSystem lastErrorString).
+ ^ nil
+ ].
+
+ text := StringCollection new.
+ f isSymbolicLink ifTrue:[
+ text add:(resources string:'symbolic link to: %1' with:(f linkInfo path))
+ ].
+
+ type := info type.
+ (longInfo and:[type == #regular]) ifTrue:[
+ fullPath := currentDirectory pathName , '/' , fileName.
+ fileOutput := fullPath asFilename fileType.
+ ].
+
+ s := (resources at:'type: ').
+ fileOutput isNil ifTrue:[
+ s := s , type asString
+ ] ifFalse:[
+ s := s , 'regular (' , fileOutput , ')'
+ ].
+ text add:s.
+ text add:(resources string:'size: %1' with:(info size) printString).
+
+ modeBits := info mode.
+ modeString := self getModeString:modeBits.
+ longInfo ifTrue:[
+ text add:(resources string:'access: %1 (%2)'
+ with:modeString
+ with:(modeBits printStringRadix:8))
+ ] ifFalse:[
+ text add:(resources string:'access: %1' with:modeString)
+ ].
+ text add:(resources string:'owner: %1'
+ with:(OperatingSystem getUserNameFromID:(info uid))).
+ longInfo ifTrue:[
+ text add:(resources string:'group: %1'
+ with:(OperatingSystem getGroupNameFromID:(info gid))).
+
+ ts := info accessed.
+ text add:(resources string:'last access: %1 %2'
+ with:(ts asTime printString)
+ with:(ts asDate printString)).
+
+ ts := info modified.
+ text add:(resources string:'last modification: %1 %2'
+ with:(ts asTime printString)
+ with:(ts asDate printString)).
+ ].
+ ^ text asString
+
+ "Modified: 8.9.1995 / 11:59:28 / claus"
+ "Modified: 1.11.1996 / 20:47:52 / cg"
+!
+
+getInfoFile
+ "get filename of a description-file (.dir.info, README etc.);
+ This file is automatically shown when a directory is enterred.
+ You can add more names below if you like."
+
+ #(
+ '.dir.info'
+ 'README'
+ 'ReadMe'
+ 'Readme'
+ 'readme'
+ 'read.me'
+ 'Read.me'
+ 'READ.ME'
+ ) do:[:f |
+ (currentDirectory isReadable:f) ifTrue:[
+ (currentDirectory isDirectory:f) ifFalse:[^ f].
]
].
- ^ newCollection
-
- "Modified: 21.2.1996 / 01:33:18 / cg"
-! !
-
-!FileBrowser methodsFor:'private - actions'!
-
-binaryFileAction:aFilename
- "for some binary files, if double clicked, we can do some useful
- action ..."
-
- (currentDirectory pathName , '/' , aFilename) asFilename isExecutable ifTrue:[
- (OperatingSystem executeCommand:'cd ',currentDirectory pathName, '; ',aFilename)
- ifTrue:[^true].
- ].
- ^ self imageAction:aFilename
-
- "Modified: 19.6.1996 / 09:44:07 / cg"
+ ^ nil
+
+ "Modified: 23.4.1997 / 13:12:36 / cg"
+!
+
+getModeString:modeBits
+ "convert file-mode bits into a more user-friendly string.
+ This is wrong here - should be moved into OperatingSystem."
+
+ ^ self getModeString:modeBits
+ with:#( 'owner:' $r $w $x
+ ' group:' $r $w $x
+ ' others:' $r $w $x )
!
-imageAction:aFilename
- "for some image files, if double clicked, we can do some useful
- action ..."
-
- |img|
-
- (Image isImageFileSuffix:(aFilename asFilename suffix))
- ifTrue:[
- img := Image fromFile:(currentDirectory pathName , '/' , aFilename).
- img notNil ifTrue:[
- img inspect.
- ^ true
+getModeString:modeBits with:texts
+ "convert file-mode bits into a more user-friendly string.
+ This is wrong here - should be moved into OperatingSystem."
+
+ |bits modeString|
+
+ bits := modeBits bitAnd:8r777.
+ modeString := ''.
+
+ #( nil 8r400 8r200 8r100 nil 8r040 8r020 8r010 nil 8r004 8r002 8r001 )
+ with: texts do:[:bitMask :access |
+ |ch|
+
+ bitMask isNil ifTrue:[
+ modeString := modeString , (resources string:access)
+ ] ifFalse:[
+ (bits bitAnd:bitMask) == 0 ifTrue:[
+ ch := $-
+ ] ifFalse:[
+ ch := access
+ ].
+ modeString := modeString copyWith:ch
]
].
- ^ false
-
- "Created: 19.6.1996 / 09:43:50 / cg"
- "Modified: 18.4.1997 / 14:56:04 / cg"
+ ^ modeString
+!
+
+showInfo
+ "show directory info when dir has changed"
+
+ |info txt|
+
+ info := self getInfoFile.
+ info notNil ifTrue:[
+ txt := self readFile:info
+ ].
+ self show:txt.
+!
+
+sizePrintString:size
+ "helper for update-directory to return a string with a files size.
+ This one gives the size in byte, Kb or Mb depending on size.
+ If you dont like this, just uncomment the first statement below."
+
+ |unitString n|
+
+"
+ ^ size printString.
+"
+ unitString := ''.
+ size < (500 * 1024) ifTrue:[
+ size < 1024 ifTrue:[
+ n := size
+ ] ifFalse:[
+ n := (size * 10 // 1024 / 10.0).
+ unitString := ' Kb'
+ ]
+ ] ifFalse:[
+ n := (size * 10 // 1024 // 1024 / 10.0).
+ unitString := ' Mb'
+ ].
+ ^ (n printStringLeftPaddedTo:5) , unitString.
+! !
+
+!FileBrowser methodsFor:'private - file-I/O'!
+
+readFile:fileName
+ "read in the file, answer its contents as StringCollection"
+
+ ^ self readFile:fileName lineDelimiter:Character cr encoding:nil
+
+ "Modified: 22.2.1996 / 14:57:08 / cg"
+!
+
+readFile:fileName lineDelimiter:aCharacter encoding:encoding
+ "read in the file, return its contents as StringCollection.
+ The files lines are delimited by aCharacter.
+ If encoding is nonNil, the file is assumed to be coded according to
+ that symbol, and #decodeString: should be able to convert it."
+
+ |stream text msg sz|
+
+ stream := FileStream readonlyFileNamed:fileName in:currentDirectory.
+ stream isNil ifTrue:[
+ msg := (resources string:'cannot read file ''%1'' !!' with:fileName).
+ self showAlert:msg with:(FileStream lastErrorString).
+ ^ nil
+ ].
+
+ "
+ for very big files, give ObjectMemory a hint, to preallocate more
+ "
+ (sz := stream size) > 1000000 ifTrue:[
+ Processor activeProcess withPriority:Processor userBackgroundPriority do:[
+ ObjectMemory announceSpaceNeed:(sz + (sz // 5)) "/ add 20% for tab expansion
+ ].
+ ].
+
+ text := self readStream:stream lineDelimiter:aCharacter encoding:encoding.
+ stream close.
+ ^ text
+
+ "Created: 22.2.1996 / 14:56:48 / cg"
+ "Modified: 8.10.1996 / 21:01:57 / cg"
+!
+
+readStream:aStream
+ "read in from aStream, answer its contents as StringCollection"
+
+ ^ self readStream:aStream lineDelimiter:Character cr encoding:nil
+
+ "Modified: 22.2.1996 / 14:58:40 / cg"
!
-nonBinaryFileAction:aFilename
- "for some nonBinary files, if double clicked, we can do some useful
- action ..."
-
- |fullPath lcName|
-
- fullPath := currentDirectory pathName , '/' , aFilename.
- lcName := aFilename asLowercase.
- ((lcName endsWith:'.htm') or:[lcName endsWith:'.html']) ifTrue:[
- HTMLDocumentView openOn:fullPath.
- ^ true
+readStream:aStream lineDelimiter:aCharacter encoding:encoding
+ "read from aStream, answer its contents as StringCollection.
+ The files lines are delimited by aCharacter.
+ If encoding is nonNil, the file is assumed to be coded according to
+ that symbol, and #decodeString: should be able to convert it."
+
+ |text line enc|
+
+ text := StringCollection new.
+
+ enc := encoding.
+ enc == #iso8859 ifTrue:[
+ enc := nil
+ ].
+
+ aCharacter == Character cr ifTrue:[
+ [aStream atEnd] whileFalse:[
+ line := aStream nextLine withTabsExpanded.
+ enc notNil ifTrue:[
+ line := line decodeFrom:enc
+ ].
+ text add:line
+ ].
+ ] ifFalse:[
+ [aStream atEnd] whileFalse:[
+ line := (aStream upTo:aCharacter) withTabsExpanded.
+ enc notNil ifTrue:[
+ line := line decodeFrom:enc
+ ].
+ text add:line
+ ].
].
-
- OperatingSystem isUNIXlike ifTrue:[
- (#('.man' '.1' '.2' '.3') findFirst:[:suff | aFilename endsWith:suff]) ~~ 0
- ifTrue:[
- HTMLDocumentView openFullOnText:(HTMLDocGenerator manPageForFile:fullPath).
- ^ true
+ ^ text
+
+ "Created: 22.2.1996 / 14:58:25 / cg"
+ "Modified: 2.4.1997 / 21:31:36 / cg"
+!
+
+showFile:fileName
+ "show contents of fileName in subView"
+
+ self showFile:fileName insert:false encoding:fileEncoding
+
+ "Modified: 22.2.1996 / 14:47:10 / cg"
+!
+
+showFile:fileName insert:insert encoding:encoding
+ "show/insert contents of fileName in subView"
+
+ ^ self
+ showFile:fileName insert:insert encoding:encoding doubleClick:false
+
+ "Modified: 19.6.1996 / 09:40:19 / cg"
+!
+
+showFile:fileName insert:insert encoding:encoding doubleClick:viaDoubleClick
+ "show/insert contents of fileName in subView"
+
+ |buffer s n i ok convert text msg eol guess action enc|
+
+ ((currentDirectory typeOf:fileName) == #regular) ifFalse:[
+ "asked for a non-file - ignore it ..."
+ (currentDirectory exists:fileName) ifFalse:[
+ msg := '''%1'' does not exist !!'.
+ ] ifTrue:[
+ msg := '''%1'' is not a regular file !!'.
+ ].
+ self warn:(resources string:msg with:fileName).
+ ^ self
+ ].
+
+ "/
+ "/ check if file is a text file
+ "/
+ s := FileStream readonlyFileNamed:fileName in:currentDirectory.
+ s isNil ifTrue:[
+ self showAlert:(resources string:'cannot read file ''%1'' !!' with:fileName)
+ with:(FileStream lastErrorString).
+ ^ nil
+ ].
+
+ buffer := String new:300.
+ n := s nextBytes:300 into:buffer.
+ s close.
+
+ enc := encoding.
+ ok := true.
+ guess := self guessEncodingFrom:buffer.
+
+ guess == #binary ifTrue:[
+ ok := false.
+ viaDoubleClick ifTrue:[
+ (self binaryFileAction:fileName) ifTrue:[^ self].
+ ].
+ (self confirm:(resources string:'''%1'' seems to be a binary file - show anyway ?' with:fileName))
+ ifFalse:[^ self]
+ ] ifFalse:[
+ viaDoubleClick ifTrue:[
+ (self nonBinaryFileAction:fileName) ifTrue:[^ self].
+ ].
+
+ "/ ascii should work in any font ...
+
+ guess ~~ #ascii ifTrue:[
+ fileEncoding ~~ guess ifTrue:[
+ action := Dialog choose:(resources string:'''%1'' seems to be ' , guess , ' encoded.' with:fileName)
+ labels:(resources array:#('cancel' 'show' 'change font'))
+ values:#(nil #show #encoding)
+ default:#encoding.
+ action isNil ifTrue:[^ self].
+ action == #encoding ifTrue:[
+ fileEncoding := guess asSymbol.
+ self validateFontEncodingFor:fileEncoding ask:false.
+ enc := fileEncoding.
+ ]
+ ]
+ ].
+ ].
+
+ convert := false.
+ ok ifTrue:[
+ "/
+ "/ check if line delimiter is a cr
+ "/
+ i := buffer indexOf:Character cr.
+ i == 0 ifTrue:[
+ "/
+ "/ no newline found - try cr
+ "/
+ i := buffer indexOf:(Character value:13).
+ i ~~ 0 ifTrue:[
+ convert := self confirm:(resources string:'''%1'' seems to have CR as line delimiter - convert to NL ?' with:fileName).
+ ]
]
].
- ^ self imageAction:aFilename
-
- "Created: 19.6.1996 / 09:36:38 / cg"
- "Modified: 4.4.1997 / 10:49:00 / cg"
+
+ insert ifFalse:[
+ "/ release old text first
+ "/ - we might need the memory in case of huge files
+ "/ (helps if you have a 4Mb file in the view,
+ "/ and click on another biggy)
+
+ subView contents:nil.
+ ].
+
+ convert ifTrue:[
+ eol := Character value:13
+ ] ifFalse:[
+ eol := Character cr
+ ].
+ text := self readFile:fileName lineDelimiter:eol encoding:enc.
+
+ insert ifFalse:[
+ self show:text
+ ] ifTrue:[
+ subView insertSelectedStringAtCursor:text asString
+ ].
+
+ "Created: 19.6.1996 / 09:39:52 / cg"
+ "Modified: 23.1.1997 / 20:31:43 / cg"
+!
+
+writeFile:fileName text:someText encoding:encoding
+ |stream msg startNr nLines string|
+
+ stream := FileStream newFileNamed:fileName in:currentDirectory.
+ stream isNil ifTrue:[
+ msg := (resources string:'cannot write file ''%1'' !!' with:fileName).
+ self showAlert:msg with:(FileStream lastErrorString)
+ ] ifFalse:[
+ someText isString ifTrue:[
+ stream nextPutAll:someText.
+ ] ifFalse:[
+ "
+ on some systems, writing linewise is very slow (via NFS)
+ therefore we convert to a string and write it in chunks
+ to avoid creating huge strings, we do it in blocks of 1000 lines
+ "
+ startNr := 1.
+ nLines := someText size.
+ [startNr <= nLines] whileTrue:[
+ string := someText asStringWithCRsFrom:startNr
+ to:((startNr + 1000) min:nLines)
+ compressTabs:compressTabs.
+ encoding notNil ifTrue:[
+ string := string encodeInto:encoding
+ ].
+ stream nextPutAll:string.
+ startNr := startNr + 1000 + 1.
+ ].
+"/ someText do:[:line |
+"/ line notNil ifTrue:[
+"/ stream nextPutAll:line.
+"/ ].
+"/ stream cr.
+"/ ]
+ ].
+ stream close.
+ subView modified:false
+ ]
+
+ "Created: 22.2.1996 / 15:03:10 / cg"
+ "Modified: 22.2.1996 / 15:08:31 / cg"
! !
!FileBrowser methodsFor:'private - presentation'!
@@ -3190,261 +3475,6 @@
"Modified: 21.4.1997 / 15:01:27 / cg"
! !
-!FileBrowser methodsFor:'private-file-I/O'!
-
-readFile:fileName
- "read in the file, answer its contents as StringCollection"
-
- ^ self readFile:fileName lineDelimiter:Character cr encoding:nil
-
- "Modified: 22.2.1996 / 14:57:08 / cg"
-!
-
-readFile:fileName lineDelimiter:aCharacter encoding:encoding
- "read in the file, return its contents as StringCollection.
- The files lines are delimited by aCharacter.
- If encoding is nonNil, the file is assumed to be coded according to
- that symbol, and #decodeString: should be able to convert it."
-
- |stream text msg sz|
-
- stream := FileStream readonlyFileNamed:fileName in:currentDirectory.
- stream isNil ifTrue:[
- msg := (resources string:'cannot read file ''%1'' !!' with:fileName).
- self showAlert:msg with:(FileStream lastErrorString).
- ^ nil
- ].
-
- "
- for very big files, give ObjectMemory a hint, to preallocate more
- "
- (sz := stream size) > 1000000 ifTrue:[
- Processor activeProcess withPriority:Processor userBackgroundPriority do:[
- ObjectMemory announceSpaceNeed:(sz + (sz // 5)) "/ add 20% for tab expansion
- ].
- ].
-
- text := self readStream:stream lineDelimiter:aCharacter encoding:encoding.
- stream close.
- ^ text
-
- "Created: 22.2.1996 / 14:56:48 / cg"
- "Modified: 8.10.1996 / 21:01:57 / cg"
-!
-
-readStream:aStream
- "read in from aStream, answer its contents as StringCollection"
-
- ^ self readStream:aStream lineDelimiter:Character cr encoding:nil
-
- "Modified: 22.2.1996 / 14:58:40 / cg"
-!
-
-readStream:aStream lineDelimiter:aCharacter encoding:encoding
- "read from aStream, answer its contents as StringCollection.
- The files lines are delimited by aCharacter.
- If encoding is nonNil, the file is assumed to be coded according to
- that symbol, and #decodeString: should be able to convert it."
-
- |text line enc|
-
- text := StringCollection new.
-
- enc := encoding.
- enc == #iso8859 ifTrue:[
- enc := nil
- ].
-
- aCharacter == Character cr ifTrue:[
- [aStream atEnd] whileFalse:[
- line := aStream nextLine withTabsExpanded.
- enc notNil ifTrue:[
- line := line decodeFrom:enc
- ].
- text add:line
- ].
- ] ifFalse:[
- [aStream atEnd] whileFalse:[
- line := (aStream upTo:aCharacter) withTabsExpanded.
- enc notNil ifTrue:[
- line := line decodeFrom:enc
- ].
- text add:line
- ].
- ].
- ^ text
-
- "Created: 22.2.1996 / 14:58:25 / cg"
- "Modified: 2.4.1997 / 21:31:36 / cg"
-!
-
-showFile:fileName
- "show contents of fileName in subView"
-
- self showFile:fileName insert:false encoding:fileEncoding
-
- "Modified: 22.2.1996 / 14:47:10 / cg"
-!
-
-showFile:fileName insert:insert encoding:encoding
- "show/insert contents of fileName in subView"
-
- ^ self
- showFile:fileName insert:insert encoding:encoding doubleClick:false
-
- "Modified: 19.6.1996 / 09:40:19 / cg"
-!
-
-showFile:fileName insert:insert encoding:encoding doubleClick:viaDoubleClick
- "show/insert contents of fileName in subView"
-
- |buffer s n i ok convert text msg eol guess action enc|
-
- ((currentDirectory typeOf:fileName) == #regular) ifFalse:[
- "asked for a non-file - ignore it ..."
- (currentDirectory exists:fileName) ifFalse:[
- msg := '''%1'' does not exist !!'.
- ] ifTrue:[
- msg := '''%1'' is not a regular file !!'.
- ].
- self warn:(resources string:msg with:fileName).
- ^ self
- ].
-
- "/
- "/ check if file is a text file
- "/
- s := FileStream readonlyFileNamed:fileName in:currentDirectory.
- s isNil ifTrue:[
- self showAlert:(resources string:'cannot read file ''%1'' !!' with:fileName)
- with:(FileStream lastErrorString).
- ^ nil
- ].
-
- buffer := String new:300.
- n := s nextBytes:300 into:buffer.
- s close.
-
- enc := encoding.
- ok := true.
- guess := self guessEncodingFrom:buffer.
-
- guess == #binary ifTrue:[
- ok := false.
- viaDoubleClick ifTrue:[
- (self binaryFileAction:fileName) ifTrue:[^ self].
- ].
- (self confirm:(resources string:'''%1'' seems to be a binary file - show anyway ?' with:fileName))
- ifFalse:[^ self]
- ] ifFalse:[
- viaDoubleClick ifTrue:[
- (self nonBinaryFileAction:fileName) ifTrue:[^ self].
- ].
-
- "/ ascii should work in any font ...
-
- guess ~~ #ascii ifTrue:[
- fileEncoding ~~ guess ifTrue:[
- action := Dialog choose:(resources string:'''%1'' seems to be ' , guess , ' encoded.' with:fileName)
- labels:(resources array:#('cancel' 'show' 'change font'))
- values:#(nil #show #encoding)
- default:#encoding.
- action isNil ifTrue:[^ self].
- action == #encoding ifTrue:[
- fileEncoding := guess asSymbol.
- self validateFontEncodingFor:fileEncoding ask:false.
- enc := fileEncoding.
- ]
- ]
- ].
- ].
-
- convert := false.
- ok ifTrue:[
- "/
- "/ check if line delimiter is a cr
- "/
- i := buffer indexOf:Character cr.
- i == 0 ifTrue:[
- "/
- "/ no newline found - try cr
- "/
- i := buffer indexOf:(Character value:13).
- i ~~ 0 ifTrue:[
- convert := self confirm:(resources string:'''%1'' seems to have CR as line delimiter - convert to NL ?' with:fileName).
- ]
- ]
- ].
-
- insert ifFalse:[
- "/ release old text first
- "/ - we might need the memory in case of huge files
- "/ (helps if you have a 4Mb file in the view,
- "/ and click on another biggy)
-
- subView contents:nil.
- ].
-
- convert ifTrue:[
- eol := Character value:13
- ] ifFalse:[
- eol := Character cr
- ].
- text := self readFile:fileName lineDelimiter:eol encoding:enc.
-
- insert ifFalse:[
- self show:text
- ] ifTrue:[
- subView insertSelectedStringAtCursor:text asString
- ].
-
- "Created: 19.6.1996 / 09:39:52 / cg"
- "Modified: 23.1.1997 / 20:31:43 / cg"
-!
-
-writeFile:fileName text:someText encoding:encoding
- |stream msg startNr nLines string|
-
- stream := FileStream newFileNamed:fileName in:currentDirectory.
- stream isNil ifTrue:[
- msg := (resources string:'cannot write file ''%1'' !!' with:fileName).
- self showAlert:msg with:(FileStream lastErrorString)
- ] ifFalse:[
- someText isString ifTrue:[
- stream nextPutAll:someText.
- ] ifFalse:[
- "
- on some systems, writing linewise is very slow (via NFS)
- therefore we convert to a string and write it in chunks
- to avoid creating huge strings, we do it in blocks of 1000 lines
- "
- startNr := 1.
- nLines := someText size.
- [startNr <= nLines] whileTrue:[
- string := someText asStringWithCRsFrom:startNr
- to:((startNr + 1000) min:nLines)
- compressTabs:compressTabs.
- encoding notNil ifTrue:[
- string := string encodeInto:encoding
- ].
- stream nextPutAll:string.
- startNr := startNr + 1000 + 1.
- ].
-"/ someText do:[:line |
-"/ line notNil ifTrue:[
-"/ stream nextPutAll:line.
-"/ ].
-"/ stream cr.
-"/ ]
- ].
- stream close.
- subView modified:false
- ]
-
- "Created: 22.2.1996 / 15:03:10 / cg"
- "Modified: 22.2.1996 / 15:08:31 / cg"
-! !
-
!FileBrowser methodsFor:'queries'!
path
@@ -3457,6 +3487,6 @@
!FileBrowser class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libtool/FileBrowser.st,v 1.151 1997-04-21 13:03:56 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libtool/FileBrowser.st,v 1.152 1997-04-23 11:30:25 cg Exp $'
! !
FileBrowser initialize!