FileBrowser.st
changeset 3861 8d5fcf90ae5f
parent 3860 8c491484ea20
child 3862 eee340e1a930
--- a/FileBrowser.st	Tue Sep 10 16:02:13 2002 +0200
+++ b/FileBrowser.st	Wed Sep 11 14:55:33 2002 +0200
@@ -18,15 +18,15 @@
 		myName killButton pauseToggle compressTabs lockUpdate
 		previousDirectory currentFileName timeOfFileRead tabSpec
 		commandView commandIndex fileEncoding tabRulerView scrollView
-		icons listUpdateProcess currentFileInFileName
+		icons matchedIcons listUpdateProcess currentFileInFileName
 		lastFileDiffDirectory sortByWhat sortCaseless showingDetails
 		showingTimeAndDate showingHiddenFiles showingBigImagePreview
 		imagePreviewView imageRenderProcess dosEOLMode doAutoUpdate
 		doNotShowFontDialog lastEnforcedNameSpace'
 	classVariableNames:'DirectoryHistory DirectoryHistoryWhere DirectoryBookmarks
 		HistorySize DefaultIcon CommandHistory CommandHistorySize Icons
-		DefaultCommandPerSuffix DefaultCommandPerMIME VisitedFileHistory
-		LastEnforcedNameSpace'
+		MatchedIcons DefaultCommandPerSuffix DefaultCommandPerMIME
+		VisitedFileHistory LastEnforcedNameSpace'
 	poolDictionaries:''
 	category:'Interface-Browsers'
 !
@@ -154,6 +154,7 @@
 !FileBrowser class methodsFor:'class initialization'!
 
 icons
+self halt.
     Icons isNil ifTrue:[
         self initializeIcons
     ].
@@ -181,6 +182,7 @@
     #(
         "/ internal-type to icon mappings.
         (#directory             'ICON_DIRECTORY'            'tiny_yellow_dir.xpm'            )
+        (#directoryOpen         'ICON_DIRECTORY_OPEN'       'tiny_yellow_dir_open.xpm'       )
         (#directoryLocked       'ICON_DIRECTORY_LOCKED'     'tiny_yellow_dir_locked.xpm'     )
         (#directoryLink         'ICON_DIRECTORY_LINK'       'tiny_yellow_dir_link.xpm'       )
         (#file                  'ICON_FILE'                 'tiny_file_plain.xpm'            )
@@ -196,6 +198,9 @@
         (#archive               'ICON_ARCHIVE'              'tiny_file_tar.xpm'              )
         (#specialFile           'ICON_SPECIALFILE'          'tiny_file_special.xpm'          )
 
+        (#addOnLocked           'ICON_ADDON_LOCKED'         'tiny_addOn_lock.xpm'            )
+        (#addOnLinked           'ICON_ADDON_LINKED'         'tiny_addOn_link.xpm'            )
+
         (#directoryGray         'ICON_DIRECTORY_GRAY'       'tiny_yellow_dir_gray.xpm'       )
      ) do:[:entry |
         |key resource defaultName nm img|
@@ -219,11 +224,8 @@
 !
 
 initializeIcons
-    |resources|
-
-    resources := self classResources.
-
     Icons := Dictionary new.
+    MatchedIcons := OrderedCollection new.
     self initializeFileTypeIcons.
     self initializeMimeTypeIcons.
 
@@ -235,56 +237,55 @@
 !
 
 initializeMimeTypeIcons
-
     #(
         "/ mime-type to icon mappings.
-        'image/jpeg'                                    'tiny_file_pix.xpm'
-        'image/gif'                                     'tiny_file_pix.xpm'
-        'image/tiff'                                    'tiny_file_pix.xpm'
-        'image/x-xbitmap'                               'tiny_file_pix.xpm'
-        'image/x-xpixmap'                               'tiny_file_pix.xpm'
-        'image/x-png'                                   'tiny_file_pix.xpm'
-        'image/x-photo-cd'                              'tiny_file_pix.xpm'
-        'image/x-MS-bmp'                                'tiny_file_pix.xpm'
-        'image/x-rgb'                                   'tiny_file_pix.xpm'
-        'image/x-portable-pixmap'                       'tiny_file_pix.xpm'
-        'image/x-portable-graymap'                      'tiny_file_pix.xpm'
-        'image/x-portable-bitmap'                       'tiny_file_pix.xpm'
-        'image/x-portable-anymap'                       'tiny_file_pix.xpm'
-        'image/x-xwindowdump'                           'tiny_file_pix.xpm'
-        'image/x-cmu-raster'                            'tiny_file_pix.xpm'
-        'image/x-targa'                                 'tiny_file_pix.xpm'
+"/        'image/jpeg'                                    'tiny_file_pix.xpm'
+"/        'image/gif'                                     'tiny_file_pix.xpm'
+"/        'image/tiff'                                    'tiny_file_pix.xpm'
+"/        'image/x-xbitmap'                               'tiny_file_pix.xpm'
+"/        'image/x-xpixmap'                               'tiny_file_pix.xpm'
+"/        'image/x-png'                                   'tiny_file_pix.xpm'
+"/        'image/x-photo-cd'                              'tiny_file_pix.xpm'
+"/        'image/x-MS-bmp'                                'tiny_file_pix.xpm'
+"/        'image/x-rgb'                                   'tiny_file_pix.xpm'
+"/        'image/x-portable-pixmap'                       'tiny_file_pix.xpm'
+"/        'image/x-portable-graymap'                      'tiny_file_pix.xpm'
+"/        'image/x-portable-bitmap'                       'tiny_file_pix.xpm'
+"/        'image/x-portable-anymap'                       'tiny_file_pix.xpm'
+"/        'image/x-xwindowdump'                           'tiny_file_pix.xpm'
+"/        'image/x-cmu-raster'                            'tiny_file_pix.xpm'
+"/        'image/x-targa'                                 'tiny_file_pix.xpm'
+        'image/*'                                       'tiny_file_pix.xpm'
 
         "/ misc text ...
 
-        'text/html'                                     'tiny_file_text.xpm'
-        'text/html'                                     'tiny_file_text.xpm'
-        'text/plain'                                    'tiny_file_text.xpm'
+"/        'text/html'                                     'tiny_file_text.xpm'
+"/        'text/plain'                                    'tiny_file_text.xpm'
+        'text/*'                                        'tiny_file_text.xpm'
 
         'application/postscript'                        'tiny_file_postscript.xpm'
         'application/pdf'                               'tiny_file_pdf.xpm'
-        'application/rtf'                               'tiny_file_text.xpm'
+        'application/rtf'                               'tiny_file_rtf.xpm'
 
         "/ video formats ...
 
-        'video/x-sgi-movie'                             'tiny_file_movie.xpm'
-        'video/x-msvideo'                               'tiny_file_movie.xpm'
-        'video/quicktime'                               'tiny_file_movie.xpm'
-        'video/x-mpeg2'                                 'tiny_file_movie.xpm'
-        'video/mpeg'                                    'tiny_file_movie.xpm'
+"/        'video/x-sgi-movie'                             'tiny_file_movie.xpm'
+"/        'video/x-msvideo'                               'tiny_file_movie.xpm'
+"/        'video/quicktime'                               'tiny_file_movie.xpm'
+"/        'video/x-mpeg2'                                 'tiny_file_movie.xpm'
+"/        'video/mpeg'                                    'tiny_file_movie.xpm'
+        'video/*'                                       'tiny_file_movie.xpm'
 
         "/ audio formats ...
 
-        'audio/x-pn-realaudio'                          'tiny_file_sound.xpm'
-        'audio/x-mpeg'                                  'tiny_file_sound.xpm'
-        'audio/x-mp3'                                   'tiny_file_sound.xpm'
-        'audio/x-wav'                                   'tiny_file_sound.xpm'
-        'audio/x-aiff'                                  'tiny_file_sound.xpm'
-        'audio/basic'                                   'tiny_file_sound.xpm'
-
-        "/ more multimedia ...
-
-        'audio/x-shockwave-flash'                       'tiny_file_sound.xpm'
+"/        'audio/x-pn-realaudio'                          'tiny_file_sound.xpm'
+"/        'audio/x-mpeg'                                  'tiny_file_sound.xpm'
+"/        'audio/x-mp3'                                   'tiny_file_sound.xpm'
+"/        'audio/x-wav'                                   'tiny_file_sound.xpm'
+"/        'audio/x-aiff'                                  'tiny_file_sound.xpm'
+"/        'audio/basic'                                   'tiny_file_sound.xpm'
+"/        'audio/x-shockwave-flash'                       'tiny_file_sound.xpm'
+        'audio/*'                                       'tiny_file_sound.xpm'
 
         "/ misc stuff
         'application/winword'                           'tiny_file_text.xpm'
@@ -296,6 +297,7 @@
         'application/x-cpp-source'                      'tiny_file_text.xpm'
         'application/x-javascript'                      'tiny_file_text.xpm'
         'application/x-java-source'                     'tiny_file_java.xpm'
+
         'application/x-sh'                              'tiny_file_text.xpm'
         'application/x-csh'                             'tiny_file_text.xpm'
         'application/x-tcl'                             'tiny_file_text.xpm'
@@ -313,11 +315,17 @@
         'application/x-cpio'                          'tiny_file_archive.xpm'
         'application/x-shar'                          'tiny_file_archive.xpm'
         'application/java-archive'                    'tiny_file_archive.xpm'
-     ) pairWiseDo:[:mimeType :fileName |
+
+        '*'                                           'tiny_file_plain.xpm'
+     ) pairWiseDo:[:mimeTypePattern :fileName |
         | nm |
 
         nm := 'xpmBitmaps/document_images/' , fileName.
-        Icons at:mimeType put:(Smalltalk imageFromFileNamed:nm forClass:self).
+        mimeTypePattern includesMatchCharacters ifTrue:[
+            MatchedIcons add:(mimeTypePattern-> (Smalltalk imageFromFileNamed:nm forClass:self)).
+        ] ifFalse:[    
+            Icons at:mimeTypePattern put:(Smalltalk imageFromFileNamed:nm forClass:self).
+        ]
     ]
 
     "
@@ -1531,6 +1539,112 @@
     ^ m
 ! !
 
+!FileBrowser class methodsFor:'private - presentation'!
+
+fileTypeFor:aFilename
+    |key|
+
+    aFilename isDirectory ifTrue:[
+        key := #directory.
+    ] ifFalse:[
+        key := #file.
+        aFilename isExecutableProgram ifTrue:[
+            key := #executableFile
+        ].
+    ].
+"/    aFilename isDirectory ifTrue:[
+"/        aFilename isSymbolicLink ifTrue:[
+"/            key := #directoryLink
+"/        ] ifFalse:[
+"/            key := #directory.
+"/            (aFilename isReadable not or:[aFilename isExecutable not]) ifTrue:[
+"/                key := #directoryLocked
+"/            ].
+"/        ]
+"/    ] ifFalse:[
+"/        aFilename isSymbolicLink ifTrue:[
+"/            aFilename isReadable not ifTrue:[
+"/                key := #fileLocked
+"/            ] ifFalse:[
+"/                key := #fileLink
+"/            ]
+"/        ] ifFalse:[
+"/            key := #file.
+"/            aFilename isExecutableProgram ifTrue:[
+"/                key := #executableFile
+"/            ].
+"/            (aFilename isReadable not) ifTrue:[
+"/                key := #fileLocked
+"/            ].
+"/        ].
+"/    ].
+
+    ^ key
+!
+
+getAddOnIconsFor:aFilename
+    "given a fileName, return an appropriate icon"
+
+    | addIcns isDirectory isReadable|
+
+    addIcns := OrderedCollection new.
+    aFilename isSymbolicLink ifTrue:[
+        addIcns add:(self iconForKeyMatching:#addOnLinked).
+    ].
+    isDirectory := aFilename isDirectory.
+    isReadable := aFilename isReadable.
+    ((isReadable not and:[isDirectory not]) or:[(isDirectory) and:[(isReadable not) or:[aFilename isExecutable not]]]) ifTrue:[
+        addIcns add:(self iconForKeyMatching:#addOnLocked).
+    ].
+    ^ addIcns
+!
+
+iconForFile:aFilename
+    "given a fileName, return an appropriate icon"
+
+    |icn addIcns|
+
+    icn := self iconForKeyMatching:(self iconKeyForFile:aFilename).
+    addIcns := self getAddOnIconsFor:aFilename.
+    addIcns notEmpty ifTrue:[
+        addIcns addFirst:icn.
+        ^ MultiImage images:addIcns.
+    ].
+    ^ icn
+!
+
+iconForKeyMatching:mimeTypeOrKey
+    |assoc icn|
+
+    icn := Icons at:mimeTypeOrKey ifAbsent:nil.
+    icn notNil ifTrue:[^ icn].
+    assoc := MatchedIcons detect:[:assoc | assoc key match:mimeTypeOrKey] ifNone:nil.
+    assoc notNil ifTrue:[^ assoc value].
+    ^ nil.
+!
+
+iconKeyForFile:aFilenameArg
+    "given a fileName, return an appropriate icon"
+
+    |aFilename fileType mimeType suffix|
+
+    aFilename := aFilenameArg.
+
+    fileType := self fileTypeFor:aFilename.
+
+    aFilename isDirectory ifFalse:[
+        "/ aFilename isReadable ifTrue:[
+            suffix := aFilename suffix.
+            (suffix = 'bak' or:[suffix = 'sav']) ifTrue:[
+                aFilename := aFilename withoutSuffix.
+            ].
+            mimeType := MIMETypes mimeTypeForFilename:aFilename.
+        "/ ].
+    ].
+
+    ^ (mimeType ? fileType).
+! !
+
 !FileBrowser class methodsFor:'queries'!
 
 isVisualStartable
@@ -4102,6 +4216,7 @@
     commandIndex := 0.
 
     icons := Dictionary new.
+    matchedIcons := OrderedCollection new.
 
     Icons isNil ifTrue:[
         self class initializeIcons
@@ -7368,102 +7483,49 @@
     "Modified: / 27.7.1998 / 20:23:34 / cg"
 !
 
-iconForFile:aFilenameString
+iconForFile:aFilename
     "given a fileName, return an appropriate icon"
 
-    |f icn key key2 suff mimeType|
-
-    f := currentDirectory construct:aFilenameString.
-    f isDirectory ifTrue:[
-        f isSymbolicLink ifTrue:[
-            key := #directoryLink
-        ] ifFalse:[
-            key := #directory.
-            (f isReadable not or:[f isExecutable not]) ifTrue:[
-                key := #directoryLocked
-            ].
-        ]
-    ] ifFalse:[
-        f isSymbolicLink ifTrue:[
-            f isReadable not ifTrue:[
-                key := #fileLocked
-            ] ifFalse:[
-                key := #fileLink
-            ]
-        ] ifFalse:[
-            key := key2 := #file.
-            f isExecutableProgram ifTrue:[
-                key := key2 := #executableFile
-            ].
-            (f isReadable not) ifTrue:[
-                key := #fileLocked
-            ] ifFalse:[
-                suff := f suffix.
-                (suff = 'bak' or:[suff = 'sav']) ifTrue:[
-                    suff := f withoutSuffix suffix.
-                ].
-                suff size > 0 ifTrue:[
-                    mimeType := MIMETypes mimeTypeForSuffix:suff.
-                    mimeType notNil ifTrue:[
-                        (mimeType startsWith:'image/') ifTrue:[
-                            key := #imageFile
-                        ] ifFalse:[
-                            (mimeType startsWith:'text/') ifTrue:[
-                                key := #textFile
-                            ]
-                        ]
-                    ].
-                ].
-            ].
-        ].
-    ].
-
-    "/ local (device) icons
-    icons notNil ifTrue:[
-        mimeType notNil ifTrue:[
-            icn := icons at:mimeType ifAbsent:nil.
-        ] ifFalse:[
-            icn := icons at:key ifAbsent:nil.
-        ].
-        icn notNil ifTrue:[^ icn].
-    ].
+    |icn addIcns|
+
+    icn := self iconForKeyMatching:(self class iconKeyForFile:aFilename).
+    addIcns := self class getAddOnIconsFor:aFilename.
+    addIcns notEmpty ifTrue:[
+        addIcns addFirst:icn.
+        ^ MultiImage images:addIcns.
+    ].
+    ^ icn
+!
+
+iconForKeyMatching:mimeTypeOrKey
+    |assoc icn|
+
+    icn := icons at:mimeTypeOrKey ifAbsent:nil.
+    icn notNil ifTrue:[^ icn].
+    assoc := matchedIcons detect:[:assoc | assoc key match:mimeTypeOrKey] ifNone:nil.
+    assoc notNil ifTrue:[^ assoc value].
 
     "/ global icons
 
     Icons notNil ifTrue:[
-        mimeType notNil ifTrue:[
-            icn := Icons at:mimeType ifAbsent:nil.
-            "/ sight - check for parent-MIME types ...
-
-            [icn isNil and:[mimeType includes:$/]] whileTrue:[
-                mimeType := mimeType copyTo:(mimeType lastIndexOf:$/) - 1.
-                icn := Icons at:mimeType ifAbsent:nil.
-            ].
-        ].
+        icn := Icons at:mimeTypeOrKey ifAbsent:nil.
         icn notNil ifTrue:[
-            key := mimeType
-        ] ifFalse:[
-            icn := Icons at:key ifAbsent:nil.
+            icn := icn copy onDevice:device.
+            icn clearMaskedPixels.
+            icons at:mimeTypeOrKey put:icn.
+            ^ icn
         ].
-    ].
-
-    icn isNil ifTrue:[
-        (    (key := key2) isNil
-         or:[(icn := icons at:key ifAbsent:nil) notNil
-         or:[(icn := Icons at:key ifAbsent:nil) isNil]]
-        ) ifTrue:[
+
+        assoc := MatchedIcons detect:[:assoc | assoc key match:mimeTypeOrKey] ifNone:nil.
+        assoc notNil ifTrue:[
+            icn := assoc value copy onDevice:device.
+            icn clearMaskedPixels.
+            matchedIcons add:(assoc key -> icn).
             ^ icn
-        ]
-    ].
-
-    "/ remember device icon
-    icn := icn copy onDevice:device.
-    icn clearMaskedPixels.
-    icons at:key put:icn.
-    ^ icn
-
-    "Modified: / 18.9.1997 / 16:35:28 / stefan"
-    "Modified: / 23.12.1999 / 22:28:00 / cg"
+        ].
+    ].
+
+    ^ nil
 !
 
 stopImageRenderProcess
@@ -7781,7 +7843,7 @@
                                 ].
                             ].
 
-                            entry colAt:1 put:(self iconForFile:aFileName).
+                            entry colAt:1 put:(self iconForFile:(currentDirectory construct:aFileName)).
                             entry colAt:2 put:fileNameString.
 
                             "/fileListView at:lineIndex put:entry.
@@ -8021,5 +8083,5 @@
 !FileBrowser class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libtool/FileBrowser.st,v 1.490 2002-09-10 14:02:13 penk Exp $'
+    ^ '$Header: /cvs/stx/stx/libtool/FileBrowser.st,v 1.491 2002-09-11 12:55:33 penk Exp $'
 ! !