#REFACTORING by exept
class: MultiViewToolApplication
added: #askForFile:default:forSave:thenDo:
changed:
#askForFile:default:thenDo:
#askForFile:thenDo:
#menuSaveAllAs
#menuSaveAs
"
COPYRIGHT (c) 2003 by eXept Software AG
All Rights Reserved
This software is furnished under a license and may be used
only in accordance with the terms of that license and with the
inclusion of the above copyright notice. This software may not
be provided or otherwise made available to, or used by, any
other person. No title to or ownership of the software is
hereby transferred.
"
"{ Package: 'stx:libtool' }"
"{ NameSpace: Smalltalk }"
AbstractFileBrowser subclass:#AbstractDirectoryBrowser
instanceVariableNames:'inDropMode canDropItem browser updateToExternFileHolderLock'
classVariableNames:''
poolDictionaries:''
category:'Interface-Tools-File'
!
!AbstractDirectoryBrowser class methodsFor:'documentation'!
copyright
"
COPYRIGHT (c) 2003 by eXept Software AG
All Rights Reserved
This software is furnished under a license and may be used
only in accordance with the terms of that license and with the
inclusion of the above copyright notice. This software may not
be provided or otherwise made available to, or used by, any
other person. No title to or ownership of the software is
hereby transferred.
"
!
documentation
"
Abstract class containing the common code from DirectoryTreeBrowser and
DirectoryContentsBrowser applications.
[Author:]
Christian Penk
"
! !
!AbstractDirectoryBrowser class methodsFor:'queries'!
isAbstract
^ self == AbstractDirectoryBrowser
! !
!AbstractDirectoryBrowser methodsFor:'accessing'!
directory
^ self subclassResponsibility
"Created: / 23-07-2018 / 12:49:38 / Stefan Vogel"
!
fileList
self subclassResponsibility
!
updateToExternFileHolderLock
updateToExternFileHolderLock isNil ifTrue:[
updateToExternFileHolderLock := self class newLock.
].
^ updateToExternFileHolderLock
! !
!AbstractDirectoryBrowser methodsFor:'actions'!
findFilesMatching:aGLOBPattern
"search files which match aGLOBPattern.
If a folder is selected, the search starts there;
otherwise in the top folder"
|selItem searchDir|
(selItem := self theSingleSelectedItemOrNil) notNil ifTrue:[
selItem isDirectory ifTrue:[
searchDir := selItem pathName
] ifFalse:[
searchDir := selItem pathName asFilename directory
].
] ifFalse:[
searchDir := self directory
].
^ self findFilesMatching:aGLOBPattern in:searchDir
"Created: / 17-07-2018 / 12:53:32 / Claus Gittinger"
"Modified: / 02-05-2019 / 20:41:57 / Claus Gittinger"
!
findFilesMatching:aGLOBPattern in:searchDir
"search files which match aGLOBPattern."
|matching|
matching := OrderedCollection new.
searchDir asFilename recursiveDirectoryContentsAsFilenamesDo:[:each |
(aGLOBPattern match:each baseName) ifTrue:[
matching add:each
].
].
^ matching
"Created: / 02-05-2019 / 18:58:30 / Claus Gittinger"
! !
!AbstractDirectoryBrowser methodsFor:'drag & drop'!
canDrop:aDropContext
^ inDropMode and:[canDropItem]
"Modified: / 13-10-2006 / 11:35:09 / cg"
!
doDrop:aContext
|col destinationPath receiver didDrop|
destinationPath := self dropDestinationPath.
self dropLeave:aContext.
destinationPath isNil ifTrue:[^ self].
aContext dropSource argument == #archivApplication ifTrue:[
receiver := aContext dropSource receiver.
receiver extractSelectedFilesTo:destinationPath askForExtractOptions:true.
^ self
].
self withWaitCursorDo:[
col := aContext dropObjects collect:#theObject.
didDrop := self copyOrMoveFiles:col to:destinationPath.
didDrop ifFalse:[
aContext clearHasDroppedFlagToSuppressFeedBack
].
]
!
dropDestinationPath
self subclassResponsibility
!
dropEnter:aContext
|dropObjects|
self dropTargetItemChangedTo:nil in:aContext.
inDropMode := false.
"/ self directory isNil ifTrue:[^ self].
dropObjects := aContext dropObjects.
dropObjects do:[:eachDropObject|
|checkObject|
eachDropObject isFileObject ifFalse:[^ self].
checkObject := eachDropObject theObject.
checkObject isFilename ifFalse:[^ self].
(aContext dropSource argument == #archivApplication) ifFalse:[
checkObject isSpecialFile ifTrue:[^ self].
checkObject isReadable ifFalse:[^ self].
].
].
inDropMode := true.
"Modified (format): / 15-11-2017 / 11:10:16 / cg"
!
dropLeave:aDropContext
"called, when leaving the widget"
inDropMode ifFalse:[ ^ self ].
self dropTargetItemChangedTo:nil in:aDropContext.
self removeExpandItemTimedBlock.
inDropMode := false.
!
dropTargetItemChangedTo:anItem in:aContext
self subclassResponsibility
!
getDropObjects:anArgument
^ self selectedFiles collect:[:file| DropObject newFile:file].
!
getLineNumberFor:aDropContext
| yVisible|
yVisible := (aDropContext targetPointInDeviceCoordinates y).
^ browser yVisibleToRowNr:yVisible.
"Modified: / 15-06-2018 / 02:32:03 / Claus Gittinger"
!
pushUserEvent:selector withArgument:argument
self window sensor
pushUserEvent:selector
for:self
withArgument:argument
!
removeExpandItemTimedBlock
"left blank"
! !
!AbstractDirectoryBrowser methodsFor:'file actions'!
doCopy
"copy the selected files/directories to the clipBoard"
self copyFilesToClipBoard:(self selectedFiles).
!
doCut
"cut the selected files/directories to the clipBoard"
self cutFilesToClipBoard:(self selectedFiles).
!
doDelete
"delete the selected files/directories"
self deleteFiles:(self selectedFiles copy).
!
doErase
"erase the selected files"
self eraseFiles:(self selectedFiles copy).
!
findAndSelectFilesMatching:aGLOBPattern
self selectFiles:(self findFilesMatching:aGLOBPattern).
"Created: / 17-07-2018 / 12:48:23 / Claus Gittinger"
!
findAndSelectNextFileMatching:aGLOBPattern
self
findAndSelectNextFileMatching:aGLOBPattern
under:(self theSingleSelectedItemOrNil ? self fileList root)
searchInfoInto:nil
!
findAndSelectNextFileMatching:aGLOBPattern under:topDirectoryItem
self findAndSelectNextFileMatching:aGLOBPattern under:topDirectoryItem searchInfoInto:nil
!
findAndSelectNextFileMatching:aGLOBPattern under:topDirectoryItem searchInfoInto:aBlockOrNil
|fileOrNil|
fileOrNil := self findNextFileMatching:aGLOBPattern startingAt:topDirectoryItem searchInfoInto:aBlockOrNil.
self selectFiles:(fileOrNil isNil
ifTrue:[#()]
ifFalse:[{ fileOrNil }])
"Created: / 02-05-2019 / 20:43:41 / Claus Gittinger"
!
findNextFileMatching:aGLOBPattern startingAt:anItemOrNil
"search files which match aGLOBPattern in the tree."
^ self findNextFileMatching:aGLOBPattern startingAt:anItemOrNil searchInfoInto:nil
"Created: / 02-05-2019 / 20:39:58 / Claus Gittinger"
!
findNextFileMatching:aGLOBPattern startingAt:anItemOrNil searchInfoInto:aBlockOrNil
"search files which match aGLOBPattern in the tree.
If not nil, aBlockOrNil is called whenever a new folder is searched (for visual feeedback)"
|searchFolder searchIndex stack|
stack := OrderedCollection new.
anItemOrNil isRootItem ifFalse:[
|i|
i := anItemOrNil.
[i isRootItem] whileFalse:[
stack addFirst:(i parent -> (i parent children indexOf:i)).
i := i parent.
].
].
anItemOrNil isDirectory ifTrue:[
searchFolder := anItemOrNil.
searchIndex := 0.
] ifFalse:[
searchFolder := anItemOrNil parent.
searchIndex := anItemOrNil parent children indexOf:anItemOrNil.
].
stack add:(searchFolder -> searchIndex).
[stack notEmpty] whileTrue:[
|work children|
work := stack removeLast.
searchFolder := work key.
searchIndex := work value.
"/ (searchFolder pathName startsWith:'/Appl') ifTrue:[self halt].
aBlockOrNil notNil ifTrue:[aBlockOrNil value:searchFolder pathName].
children := searchFolder children.
searchIndex+1 to:(children size) doWithExit:[:childIndex :exit|
|child fn|
child := children at:childIndex.
Transcript showCR:'search %1' with:child pathName.
fn := child fileName.
fn isSymbolicLink ifFalse:[
fn isDirectory ifFalse:[
(aGLOBPattern match:fn baseName) ifTrue:[
^ fn pathName asFilename
].
] ifTrue:[
"/ deeper, but remember to proceed here
stack add:(searchFolder -> childIndex).
stack add:(child -> 0).
exit value:nil.
]
]
].
].
^ nil
"Created: / 02-05-2019 / 20:39:58 / Claus Gittinger"
! !
!AbstractDirectoryBrowser methodsFor:'selection'!
selectedFiles
^ self selectedItems collect:#fileName.
! !
!AbstractDirectoryBrowser methodsFor:'startup & release'!
initialize
inDropMode := false.
^ super initialize.
!
postOpenAsSubcanvasWith:aBuilder
"this is sent after the applications window is opened inside another application.
Can be redefined in subclasses for actions after showing the canvas view."
"/ cg: used to be unconditionally true here;
"/ but then, when a FileDialog (which is not an AbstractFileBrowser) is opened,
"/ the commonPostBuild will not properly update its enable channels;
"/ especially the enableDirectoryUp is false.
"/ This whole FileBrowser is so complicated that it became almost unusable.
"/ (too much inheritance and knowledge - DirTree and DirContents should each only do
"/ what it should and not depend on shared functionality from their superclass)
self postOpenFromMaster:(self masterApplication class includesBehavior:AbstractFileBrowser).
"Modified (comment): / 22-05-2018 / 18:48:22 / Claus Gittinger"
!
postOpenFromMaster:fromMaster
self subclassResponsibility
!
postOpenWith:aBuilder
"this is sent after the applications main window is opened.
Can be redefined in subclasses for actions after opening the view."
super postOpenWith:aBuilder.
self postOpenFromMaster:false.
"Modified: / 16-07-2017 / 12:19:48 / cg"
!
preBuildWith:aBuilder
self masterApplication isNil ifTrue:[
self masterApplication:nil.
].
^ super preBuildWith:aBuilder.
! !
!AbstractDirectoryBrowser class methodsFor:'documentation'!
version
^ '$Header$'
!
version_CVS
^ '$Header$'
! !