ChangesBrowser.st
changeset 37 50f59bad66b1
parent 33 11474e0f4d00
child 45 950b84ba89e6
--- a/ChangesBrowser.st	Sat Aug 13 20:40:49 1994 +0200
+++ b/ChangesBrowser.st	Mon Aug 22 20:07:28 1994 +0200
@@ -15,7 +15,7 @@
 StandardSystemView subclass:#ChangesBrowser
        instanceVariableNames:'changeListView codeView changeFileName 
                               changeChunks changePositions
-                              changeClassNames
+                              changeClassNames changeHeaderLines
                               anyChanges changeNrShown changeNrProcessed
                               fileBox'
        classVariableNames:''
@@ -27,7 +27,7 @@
 COPYRIGHT (c) 1990 by Claus Gittinger
             All Rights Reserved
 
-$Header: /cvs/stx/stx/libtool/ChangesBrowser.st,v 1.14 1994-08-07 20:00:05 claus Exp $
+$Header: /cvs/stx/stx/libtool/ChangesBrowser.st,v 1.15 1994-08-22 18:06:51 claus Exp $
 '!
 
 !ChangesBrowser class methodsFor:'documentation'!
@@ -48,7 +48,7 @@
 
 version
 "
-$Header: /cvs/stx/stx/libtool/ChangesBrowser.st,v 1.14 1994-08-07 20:00:05 claus Exp $
+$Header: /cvs/stx/stx/libtool/ChangesBrowser.st,v 1.15 1994-08-22 18:06:51 claus Exp $
 "
 !
 
@@ -130,8 +130,12 @@
                                'compare with current version'
                                '-'
                                'make change a patch'
-                               'save change in a file'
-                               'update sourcefile from change'
+"/                               'update sourcefile from change'
+                               '-'
+                               'save change in file ...'
+                               'save changes to end in file ...'
+                               'save changes for this class to end in file ...'
+                               'save all changes for this class in file ...'
                                '-'
                                'writeback changeFile').
 
@@ -153,8 +157,12 @@
                                      doCompare
                                      nil
                                      doMakePatch
-                                     doSaveChangeInFile
-                                     doMakePermanent
+"/                                     doMakePermanent
+                                     nil
+                                     doSave
+                                     doSaveRest
+                                     doSaveClassRest
+                                     doSaveClassAll
                                      nil
                                      doWriteBack)
                           receiver:self
@@ -163,7 +171,7 @@
 
 realize
     super realize.
-    self readChangesFile.
+    self readChangesFileInBackground:true.
     self setChangeList.
     changeListView action:[:lineNr | self changeSelection:lineNr].
     self disableMenuEntries.
@@ -240,20 +248,22 @@
 !ChangesBrowser methodsFor:'private'!
 
 enableMenuEntries
-    "enable all entries refering to a class"
+    "enable all entries refering to a selected change"
 
     #(doApply doApplyRest doDelete doDeleteRest doDeleteClassRest
-      doDeleteClassAll doCompare doMakePatch doSaveChangeInFile doMakePermanent) 
+      doDeleteClassAll doCompare doMakePatch doSaveChangeInFile doMakePermanent
+      doSave doSaveRest doSaveClassAll doSaveClassRest) 
     do:[:sel |
         changeListView middleButtonMenu enable:sel
     ].
 !
 
 disableMenuEntries
-    "enable all entries refering to a class"
+    "enable all entries refering to a selected change"
 
     #(doApply doApplyRest doDelete doDeleteRest doDeleteClassRest
-      doDeleteClassAll doCompare doMakePatch doSaveChangeInFile doMakePermanent) 
+      doDeleteClassAll doCompare doMakePatch doSaveChangeInFile doMakePermanent
+      doSave doSaveRest doSaveClassAll doSaveClassRest) 
     do:[:sel |
         changeListView middleButtonMenu disable:sel
     ].
@@ -276,23 +286,6 @@
     changeFileName := aFileName
 !
 
-withCursor:aCursor do:aBlock
-    "evaluate aBlock while showing another cursor"
-
-    |oldListCursor oldCodeViewCursor|
-
-    oldListCursor := changeListView cursor.
-    oldCodeViewCursor := codeView cursor.
-
-    changeListView cursor:aCursor.
-    codeView cursor:aCursor.
-
-    aBlock valueNowOrOnUnwindDo:[
-        changeListView cursor:oldListCursor.
-        codeView cursor:oldCodeViewCursor
-    ]
-!
-
 classNameOfChange:changeNr
     "return the classname of a change (for xxx class - changes xxx is returned)
      - since parsing ascii methods is slow, keep result cached in 
@@ -381,6 +374,7 @@
 autoSelect:changeNr
     self class autoSelectNext ifTrue:[
         (changeNr <= changeChunks size) ifTrue:[
+            self clearCodeView.
             changeListView selection:changeNr.
             self changeSelection:changeNr.
             ^ self
@@ -399,7 +393,7 @@
         self warn:'cannot create temporary file'.
         ^ self
     ].
-   
+
     inStream := FileStream readonlyFileNamed:changeFileName.
     inStream isNil ifTrue:[^ nil].
 
@@ -426,7 +420,6 @@
                         done := chunk isEmpty
                     ]
                 ].
-                0 "compiler kludge"
             ] ifFalse:[
                 outStream nextChunkPut:chunk.
                 outStream cr
@@ -435,7 +428,8 @@
         outStream close.
         inStream close.
         dir := FileDirectory currentDirectory.
-        dir removeFile:changeFileName.
+"/        dir removeFile:changeFileName.
+        dir renameFile:'changes' newName:'changes.bak'.
         dir renameFile:'n_changes' newName:changeFileName.
         anyChanges := false
     ]
@@ -445,15 +439,23 @@
     "extract type-information from changes and stuff into top selection
      view"
 
-    changeListView contents:changeChunks.
+    changeListView contents:changeHeaderLines "changeChunks".
+    self disableMenuEntries
 !
 
 readChangesFile
     "read the changes file, create a list of header-lines (changeChunks)
      and a list of chunk-positions (changePositions)"
 
-    |aStream index text done sawExcla chunkPos excla
-     myProcess myPriority p sel cls|
+    ^ self readChangesFileInBackground:false
+!
+
+readChangesFileInBackground:inBackground
+    "read the changes file, create a list of header-lines (changeChunks)
+     and a list of chunk-positions (changePositions)"
+
+    |aStream index chunkText headerLine done sawExcla chunkPos excla
+     myProcess myPriority p sel cls text first category|
 
     aStream := FileStream readonlyFileNamed:changeFileName.
     aStream isNil ifTrue:[^ nil].
@@ -463,12 +465,14 @@
          this is a time consuming operation (especially, if reading an
          NFS-mounted directory; therefore lower my priority ...
         "
-        myProcess := Processor activeProcess.
-        myPriority := myProcess priority.
-        myProcess priority:(Processor userBackgroundPriority).
+        inBackground ifTrue:[
+            myProcess := Processor activeProcess.
+            myPriority := myProcess priority.
+            myProcess priority:(Processor userBackgroundPriority).
+        ].
         [
-
             changeChunks := OrderedCollection new.
+            changeHeaderLines := OrderedCollection new.
             changePositions := OrderedCollection new.
             excla := aStream class chunkSeparator.
 
@@ -479,42 +483,45 @@
                 aStream skipSeparators.
                 chunkPos := aStream position.
                 sawExcla := aStream peekFor:excla.
-                text := aStream nextChunk.
-                text notNil ifTrue:[
-                    changePositions add:chunkPos.
-
+                chunkText := aStream nextChunk.
+                chunkText notNil ifTrue:[
                     "
                      only first line is saved in changeChunks ...
                     "
-                    index := text indexOf:(Character cr).
+                    index := chunkText indexOf:(Character cr).
                     (index ~~ 0) ifTrue:[
-                        text := text copyTo:(index - 1).
+                        chunkText := chunkText copyTo:(index - 1).
 
                         "take care for comment changes - must still be a
                          valid expression for classNameOfChange: to work"
 
-                        (text endsWith:'comment:''') ifTrue:[
-                            text := text , '...'''
+                        (chunkText endsWith:'comment:''') ifTrue:[
+                            chunkText := chunkText , '...'''
                         ]
 
                     ].
 
+                    changeChunks add:chunkText.
+                    changePositions add:chunkPos.
+
                     sawExcla ifFalse:[
-                        (text startsWith:'''---- snap') ifFalse:[
-"/                            text := '(doIt) ' , text.
+                        (chunkText startsWith:'''---- snap') ifFalse:[
+                            headerLine := chunkText , ' (doIt)'
+                        ] ifTrue:[
+                            headerLine := chunkText
                         ].
-                        changeChunks add:text.
+                        changeHeaderLines add:headerLine.
                     ] ifTrue:[
                         "
                          method definitions actually consist of
                          two (or more) chunks; skip next chunk(s)
                          up to an empty one.
-                         (the system currently only writes one chunk,
-                          but in theory, more could follow for the same
-                          class/category).
+                         The system only writes one chunk,
+                         and we cannot handle more in this ChangesBrowser ....
                         "
                         cls := nil.
-                        p := Parser parseExpression:text.
+                        p := Parser parseExpression:chunkText.
+
                         (p notNil and:[p ~~ #Error]) ifTrue:[
                             sel := p selector.
                             (sel == #methodsFor:) ifTrue:[
@@ -523,14 +530,12 @@
                                     cls := cls , 'class'
                                 ] ifFalse:[
                                     cls := p receiver name
-                                ]
+                                ].
+                                category := (p args at:1)  evaluate.
                             ]
                         ].
-                        cls isNil ifTrue:[
-                            changeChunks add:text , ' (change)'.
-                        ].
-
                         done := false.
+                        first := true.
                         [done] whileFalse:[
                             text := aStream nextChunk.
                             text isNil ifTrue:[
@@ -539,11 +544,28 @@
                                 done := text isEmpty
                             ].
                             done ifFalse:[
-                                cls notNil ifTrue:[
-                                    p := Parser parseMethodSpecification:text.
-                                    (p notNil and:[p ~~ #Error]) ifTrue:[
-                                        sel := p selector.
-                                        changeChunks add: cls , ' ' , sel
+                                first ifFalse:[
+                                    Transcript showCr:'only one method per ''methodsFor:'' handled'.
+                                ] ifTrue:[
+                                    first := false.
+                                    "
+                                     try to find the selector
+                                    "
+                                    sel := nil.
+                                    cls notNil ifTrue:[
+                                        p := Parser 
+                                                 parseMethodSpecification:text
+                                                 in:nil
+                                                 ignoreErrors:true
+                                                 ignoreWarnings:true.
+                                        (p notNil and:[p ~~ #Error]) ifTrue:[
+                                            sel := p selector.
+                                        ]
+                                    ].
+                                    sel isNil ifTrue:[
+                                        changeHeaderLines add:chunkText , ' (change)'.
+                                    ] ifFalse:[
+                                        changeHeaderLines add:cls , ' ' , sel , ' ' , '(change category: ''' , category , ''')'.
                                     ]
                                 ]
                             ]
@@ -551,11 +573,11 @@
                     ]
                 ]
             ].
-            changeClassNames := VariableArray new:(changeChunks size).
+            changeClassNames := OrderedCollection new grow:(changeChunks size).
             aStream close.
             anyChanges := false
         ] valueNowOrOnUnwindDo:[
-            myProcess priority:myPriority.
+            inBackground ifTrue:[myProcess priority:myPriority].
         ].
     ]
 !
@@ -566,7 +588,8 @@
     anyChanges := true.
     changeChunks removeIndex:changeNr.
     changePositions removeIndex:changeNr.
-    changeClassNames removeIndex:changeNr
+    changeClassNames removeIndex:changeNr.
+    changeHeaderLines removeIndex:changeNr
 !
 
 
@@ -699,9 +722,9 @@
 !
 
 appendChange:changeNr toFile:fileName
-    "append change to a file"
+    "append change to a file. return true if ok."
 
-    |aStream outStream chunk sawExcla|
+    |aStream outStream chunk sawExcla separator|
 
     outStream := FileStream oldFileNamed:fileName.
     outStream isNil ifTrue:[
@@ -709,17 +732,23 @@
             outStream := FileStream newFileNamed:fileName.
             outStream isNil ifTrue:[
                 self warn:'cannot update file ''', fileName , ''''.
-                ^ self
+                ^ false
             ]
         ]
     ].
+
     outStream setToEnd.
 
     aStream := self streamForChange:changeNr.
-    aStream isNil ifTrue:[^ self].
-    sawExcla := aStream peekFor:(aStream class chunkSeparator).
+    aStream isNil ifTrue:[
+        self warn:'oops cannot read change'.
+        ^ false
+    ].
+
+    separator := aStream class chunkSeparator.
+    sawExcla := aStream peekFor:separator.
     sawExcla ifTrue:[
-        outStream nextPut:$!!
+        outStream nextPut:separator
     ].
     chunk := aStream nextChunk.
     outStream nextChunkPut:chunk.
@@ -730,11 +759,12 @@
         outStream space
     ].
     sawExcla ifTrue:[
-        outStream nextPut:$!!
+        outStream nextPut:separator
     ].
     outStream cr.
     aStream close.
-    outStream close
+    outStream close.
+    ^ true
 !
 
 makeChangeAPatch:changeNr
@@ -808,21 +838,116 @@
     self enableMenuEntries
 !
 
-doSaveChangeInFile
-    "user wants a change to be appended to a file"
+doSaveClass
+    "user wants changes for some class from current to end to be appended to a file"
+
+    self doSaveClassFrom:1
+!
+
+doSaveClassAll
+    "user wants changes for some class from current to end to be appended to a file"
+
+    self doSaveClassFrom:1
+!
+
+doSaveClassRest
+    "user wants changes for some class from current to end to be appended to a file"
 
     |changeNr|
 
     changeNr := changeListView selection.
     changeNr notNil ifTrue:[
-        fileBox isNil ifTrue:[
-            fileBox := FileSelectionBox new.
-        ].
+        self doSaveClassFrom:changeNr
+    ]
+!
+
+saveClass:aClassName from:startNr
+    "user wants changes from current to end to be appended to a file"
+
+    |changeNr classNameToSave fileBox|
+
+    changeNr := changeListView selection.
+    changeNr notNil ifTrue:[
+        fileBox := FileSelectionBox new.
+        fileBox title:'append change to:'.
+        fileBox okText:'append'.
+        fileBox abortText:'cancel'.
+        fileBox action:[:fileName |
+                            |thisClassName|
+                            self withCursor:(Cursor write) do:[
+                                startNr to:(changeChunks size) do:[:changeNr |
+                                    thisClassName := self classNameOfChange:changeNr.
+                                    thisClassName = aClassName ifTrue:[
+                                        changeListView selection:changeNr.
+                                        (self appendChange:changeNr toFile:fileName) ifFalse:[
+                                            ^ self
+                                        ]
+                                    ]
+                                ]
+                            ]
+                       ].
+
+        fileBox pattern:'*.chg'.
+        fileBox showAtPointer
+    ]
+!
+
+doSaveClassFrom:startNr
+    "user wants changes from current to end to be appended to a file"
+
+    |changeNr classNameToSave|
+
+    changeNr := changeListView selection.
+    changeNr notNil ifTrue:[
+        classNameToSave := self classNameOfChange:changeNr.
+        classNameToSave notNil ifTrue:[
+            self saveClass:classNameToSave from:startNr
+        ]
+    ]
+!
+
+doSaveRest
+    "user wants changes from current to end to be appended to a file"
+
+    |changeNr fileBox|
+
+    changeNr := changeListView selection.
+    changeNr notNil ifTrue:[
+        fileBox := FileSelectionBox new.
+        fileBox title:'append change to:'.
+        fileBox okText:'append'.
+        fileBox abortText:'cancel'.
+        fileBox action:[:fileName |
+                            self withCursor:(Cursor write) do:[
+                                changeNr to:(changeChunks size) do:[:changeNr |
+                                    changeListView selection:changeNr.
+                                    (self appendChange:changeNr toFile:fileName) ifFalse:[
+                                        ^ self
+                                    ]
+                                ]
+                            ]
+                       ].
+
+        fileBox pattern:'*.chg'.
+        fileBox showAtPointer
+    ]
+!
+
+doSave
+    "user wants a change to be appended to a file"
+
+    |changeNr fileBox|
+
+    changeNr := changeListView selection.
+    changeNr notNil ifTrue:[
+        fileBox := FileSelectionBox new.
         fileBox title:'append change to:'.
         fileBox okText:'append'.
         fileBox abortText:'cancel'.
         fileBox action:[:fileName | 
-                            self appendChange:changeNr toFile:fileName.
+                            self withCursor:(Cursor write) do:[
+                                self appendChange:changeNr toFile:fileName.
+                            ].
                             self autoSelect:(changeNr + 1)
                        ].
 
@@ -978,15 +1103,20 @@
 
     anyChanges ifTrue:[
         self writeBackChanges.
-        self doUpdate
+        realized ifTrue:[
+            self readChangesFileInBackground:false.
+            self setChangeList
+        ]
     ]
 !
 
 doUpdate
     "reread the changes-file"
 
-    self readChangesFile.
-    changeListView setContents:changeChunks
+    self readChangesFileInBackground:true.
+    realized ifTrue:[
+        self setChangeList
+    ]
 !
 
 doCompare
@@ -1043,8 +1173,11 @@
                     (aParseTree selector == #methodsFor:) ifTrue:[
                         thisClass := (aParseTree receiver evaluate).
                         codeChunk := aStream nextChunk.
-                        codeParser := Parser parseMethodSpecification:codeChunk
-                                                                   in:thisClass.
+                        codeParser := Parser 
+                                          parseMethodSpecification:codeChunk
+                                          in:thisClass
+                                          ignoreErrors:true
+                                          ignoreWarnings:true.
                         codeParser notNil ifTrue:[
                             selectors at:changeNr put:(codeParser selector).
                             classes at:changeNr put:thisClass.
@@ -1105,7 +1238,7 @@
                 self silentDeleteChange:(deleteSet at:index).
                 index := index - 1
             ].
-            changeListView setContents:changeChunks.
+            self setChangeList.
             changeListView firstLineShown > changeChunks size ifTrue:[
                 changeListView makeLineVisible:changeChunks size
             ].