NewChangesBrowser.st
changeset 6288 4767ba5caf5b
parent 5396 d924769c9cc4
child 7957 55841733ff69
equal deleted inserted replaced
6287:089039d26fa1 6288:4767ba5caf5b
    45 !
    45 !
    46 
    46 
    47 openOnFile:aFileName
    47 openOnFile:aFileName
    48     "opens a Changes Browser with the changes of the aFileName"
    48     "opens a Changes Browser with the changes of the aFileName"
    49 
    49 
    50     ^self new 
    50     ^self new
    51 	changeFileName:aFileName;
    51 	changeFileName:aFileName;
    52 	open
    52 	open
    53 
    53 
    54 ! !
    54 ! !
    55 
    55 
    78 
    78 
    79     "Do not manually edit this!! If it is corrupted,
    79     "Do not manually edit this!! If it is corrupted,
    80      the UIHelpTool may not be able to read the specification."
    80      the UIHelpTool may not be able to read the specification."
    81 
    81 
    82     "
    82     "
    83      UIHelpTool openOnClass:NewChangesBrowser    
    83      UIHelpTool openOnClass:NewChangesBrowser
    84     "
    84     "
    85 
    85 
    86     <resource: #help>
    86     <resource: #help>
    87 
    87 
    88     ^super helpSpec addPairsFrom:#(
    88     ^super helpSpec addPairsFrom:#(
   332     "
   332     "
   333 
   333 
   334     <resource: #canvas>
   334     <resource: #canvas>
   335 
   335 
   336     ^
   336     ^
   337      
   337 
   338        #(#FullSpec
   338        #(#FullSpec
   339 	  #window: 
   339 	  #window:
   340 	   #(#WindowSpec
   340 	   #(#WindowSpec
   341 	      #name: 'Changes Browser'
   341 	      #name: 'Changes Browser'
   342 	      #layout: #(#LayoutFrame 53 0 92 0 687 0 583 0)
   342 	      #layout: #(#LayoutFrame 53 0 92 0 687 0 583 0)
   343 	      #label: 'Changes Browser'
   343 	      #label: 'Changes Browser'
   344 	      #min: #(#Point 10 10)
   344 	      #min: #(#Point 10 10)
   345 	      #max: #(#Point 1152 900)
   345 	      #max: #(#Point 1152 900)
   346 	      #bounds: #(#Rectangle 53 92 688 584)
   346 	      #bounds: #(#Rectangle 53 92 688 584)
   347 	      #menu: #menu
   347 	      #menu: #menu
   348 	      #usePreferredExtent: false
   348 	      #usePreferredExtent: false
   349 	  )
   349 	  )
   350 	  #component: 
   350 	  #component:
   351 	   #(#SpecCollection
   351 	   #(#SpecCollection
   352 	      #collection: 
   352 	      #collection:
   353 	       #(
   353 	       #(
   354 		 #(#MenuPanelSpec
   354 		 #(#MenuPanelSpec
   355 		    #name: 'menuToolbarView'
   355 		    #name: 'menuToolbarView'
   356 		    #layout: #(#LayoutFrame 0 0.0 0 0 0 1.0 32 0)
   356 		    #layout: #(#LayoutFrame 0 0.0 0 0 0 1.0 32 0)
   357 		    #menu: #menuToolbar
   357 		    #menu: #menuToolbar
   359 		    #showSeparatingLines: true
   359 		    #showSeparatingLines: true
   360 		)
   360 		)
   361 		 #(#VariableVerticalPanelSpec
   361 		 #(#VariableVerticalPanelSpec
   362 		    #name: 'variableVerticalPanel1'
   362 		    #name: 'variableVerticalPanel1'
   363 		    #layout: #(#LayoutFrame 0 0.0 34 0 0 1.0 -26 1.0)
   363 		    #layout: #(#LayoutFrame 0 0.0 34 0 0 1.0 -26 1.0)
   364 		    #component: 
   364 		    #component:
   365 		     #(#SpecCollection
   365 		     #(#SpecCollection
   366 			#collection: 
   366 			#collection:
   367 			 #(
   367 			 #(
   368 			   #(#ViewSpec
   368 			   #(#ViewSpec
   369 			      #name: 'Box1'
   369 			      #name: 'Box1'
   370 			      #component: 
   370 			      #component:
   371 			       #(#SpecCollection
   371 			       #(#SpecCollection
   372 				  #collection: 
   372 				  #collection:
   373 				   #(
   373 				   #(
   374 				     #(#DataSetSpec
   374 				     #(#DataSetSpec
   375 					#name: 'changesDataSetView'
   375 					#name: 'changesDataSetView'
   376 					#layout: #(#LayoutFrame 0 0.0 0 0.0 0 1.0 -28 1.0)
   376 					#layout: #(#LayoutFrame 0 0.0 0 0.0 0 1.0 -28 1.0)
   377 					#model: #selectionOfChange
   377 					#model: #selectionOfChange
   387 					#valueChangeSelector: #changeSelected:
   387 					#valueChangeSelector: #changeSelected:
   388 				    )
   388 				    )
   389 				     #(#ViewSpec
   389 				     #(#ViewSpec
   390 					#name: 'Box2'
   390 					#name: 'Box2'
   391 					#layout: #(#LayoutFrame 0 0.0 -28 1 0 1.0 0 1.0)
   391 					#layout: #(#LayoutFrame 0 0.0 -28 1 0 1.0 0 1.0)
   392 					#component: 
   392 					#component:
   393 					 #(#SpecCollection
   393 					 #(#SpecCollection
   394 					    #collection: 
   394 					    #collection:
   395 					     #(
   395 					     #(
   396 					       #(#LabelSpec
   396 					       #(#LabelSpec
   397 						  #name: 'filterLabel'
   397 						  #name: 'filterLabel'
   398 						  #layout: #(#AlignmentOrigin 37 0 13 0.0 1 0.5)
   398 						  #layout: #(#AlignmentOrigin 37 0 13 0.0 1 0.5)
   399 						  #label: 'Filter:'
   399 						  #label: 'Filter:'
   626     "
   626     "
   627 
   627 
   628     <resource: #menu>
   628     <resource: #menu>
   629 
   629 
   630     ^
   630     ^
   631      
   631 
   632        #(#Menu
   632        #(#Menu
   633           
   633 
   634 	   #(
   634 	   #(
   635 	     #(#MenuItem
   635 	     #(#MenuItem
   636 		#label: 'About'
   636 		#label: 'About'
   637 		#translateLabel: true
   637 		#translateLabel: true
   638 		#activeHelpKey: #about
   638 		#activeHelpKey: #about
   641 	    )
   641 	    )
   642 	     #(#MenuItem
   642 	     #(#MenuItem
   643 		#label: 'File'
   643 		#label: 'File'
   644 		#translateLabel: true
   644 		#translateLabel: true
   645 		#activeHelpKey: #file
   645 		#activeHelpKey: #file
   646 		#submenu: 
   646 		#submenu:
   647 		 #(#Menu
   647 		 #(#Menu
   648                     
   648 
   649 		     #(
   649 		     #(
   650 		       #(#MenuItem
   650 		       #(#MenuItem
   651 			  #label: 'Reload'
   651 			  #label: 'Reload'
   652 			  #translateLabel: true
   652 			  #translateLabel: true
   653 			  #value: #doReload
   653 			  #value: #doReload
   699 		)
   699 		)
   700 	    )
   700 	    )
   701 	     #(#MenuItem
   701 	     #(#MenuItem
   702 		#label: 'Apply'
   702 		#label: 'Apply'
   703 		#translateLabel: true
   703 		#translateLabel: true
   704 		#submenu: 
   704 		#submenu:
   705 		 #(#Menu
   705 		 #(#Menu
   706                     
   706 
   707 		     #(
   707 		     #(
   708 		       #(#MenuItem
   708 		       #(#MenuItem
   709 			  #label: 'Change'
   709 			  #label: 'Change'
   710 			  #translateLabel: true
   710 			  #translateLabel: true
   711 			  #value: #doApply
   711 			  #value: #doApply
   759 	    )
   759 	    )
   760 	     #(#MenuItem
   760 	     #(#MenuItem
   761 		#label: 'Delete'
   761 		#label: 'Delete'
   762 		#translateLabel: true
   762 		#translateLabel: true
   763 		#activeHelpKey: #edit
   763 		#activeHelpKey: #edit
   764 		#submenu: 
   764 		#submenu:
   765 		 #(#Menu
   765 		 #(#Menu
   766                     
   766 
   767 		     #(
   767 		     #(
   768 		       #(#MenuItem
   768 		       #(#MenuItem
   769 			  #label: 'Change'
   769 			  #label: 'Change'
   770 			  #translateLabel: true
   770 			  #translateLabel: true
   771 			  #value: #doDelete
   771 			  #value: #doDelete
   826 	    )
   826 	    )
   827 	     #(#MenuItem
   827 	     #(#MenuItem
   828 		#label: 'Test'
   828 		#label: 'Test'
   829 		#translateLabel: true
   829 		#translateLabel: true
   830 		#activeHelpKey: #test
   830 		#activeHelpKey: #test
   831 		#submenu: 
   831 		#submenu:
   832 		 #(#Menu
   832 		 #(#Menu
   833                     
   833 
   834 		     #(
   834 		     #(
   835 		       #(#MenuItem
   835 		       #(#MenuItem
   836 			  #label: 'Find last Snapshot'
   836 			  #label: 'Find last Snapshot'
   837 			  #translateLabel: true
   837 			  #translateLabel: true
   838 			  #value: #doFindSnapshot:
   838 			  #value: #doFindSnapshot:
   864 	    )
   864 	    )
   865 	     #(#MenuItem
   865 	     #(#MenuItem
   866 		#label: 'Settings'
   866 		#label: 'Settings'
   867 		#translateLabel: true
   867 		#translateLabel: true
   868 		#activeHelpKey: #settings
   868 		#activeHelpKey: #settings
   869 		#submenu: 
   869 		#submenu:
   870 		 #(#Menu
   870 		 #(#Menu
   871                     
   871 
   872 		     #(
   872 		     #(
   873 		       #(#MenuItem
   873 		       #(#MenuItem
   874 			  #label: 'Auto Update'
   874 			  #label: 'Auto Update'
   875 			  #translateLabel: true
   875 			  #translateLabel: true
   876 			  #activeHelpKey: #settingsAutoUpdate
   876 			  #activeHelpKey: #settingsAutoUpdate
   892 		      )
   892 		      )
   893 		       #(#MenuItem
   893 		       #(#MenuItem
   894 			  #label: 'Columns'
   894 			  #label: 'Columns'
   895 			  #translateLabel: true
   895 			  #translateLabel: true
   896 			  #activeHelpKey: #settingsColumns
   896 			  #activeHelpKey: #settingsColumns
   897 			  #submenu: 
   897 			  #submenu:
   898 			   #(#Menu
   898 			   #(#Menu
   899                               
   899 
   900 			       #(
   900 			       #(
   901 				 #(#MenuItem
   901 				 #(#MenuItem
   902 				    #label: 'Category'
   902 				    #label: 'Category'
   903 				    #activeHelpKey: #settingsColumnsCategory
   903 				    #activeHelpKey: #settingsColumnsCategory
   904 				    #indication: #categoryColumn:
   904 				    #indication: #categoryColumn:
   972     "
   972     "
   973 
   973 
   974     <resource: #menu>
   974     <resource: #menu>
   975 
   975 
   976     ^
   976     ^
   977      
   977 
   978        #(#Menu
   978        #(#Menu
   979           
   979 
   980 	   #(
   980 	   #(
   981 	     #(#MenuItem
   981 	     #(#MenuItem
   982 		#label: 'Apply'
   982 		#label: 'Apply'
   983 		#translateLabel: true
   983 		#translateLabel: true
   984 		#value: #doApply
   984 		#value: #doApply
  1077     "
  1077     "
  1078 
  1078 
  1079     <resource: #menu>
  1079     <resource: #menu>
  1080 
  1080 
  1081     ^
  1081     ^
  1082      
  1082 
  1083        #(#Menu
  1083        #(#Menu
  1084           
  1084 
  1085 	   #(
  1085 	   #(
  1086 	     #(#MenuItem
  1086 	     #(#MenuItem
  1087 		#label: 'Load'
  1087 		#label: 'Load'
  1088 		#isButton: true
  1088 		#isButton: true
  1089 		#value: #doLoad
  1089 		#value: #doLoad
  1298 listOfChangeColumns
  1298 listOfChangeColumns
  1299     "initializes (during the startup) and returns the value holder for the columns"
  1299     "initializes (during the startup) and returns the value holder for the columns"
  1300 
  1300 
  1301     |holder|
  1301     |holder|
  1302     (holder := builder bindingAt:#listOfChangeColumns) isNil ifTrue:[
  1302     (holder := builder bindingAt:#listOfChangeColumns) isNil ifTrue:[
  1303         builder aspectAt:#listOfChangeColumns put:(holder := List new).
  1303 	builder aspectAt:#listOfChangeColumns put:(holder := List new).
  1304         self changeColumn: nil add: true.
  1304 	self changeColumn: nil add: true.
  1305         self changeColumn: #change add: true.
  1305 	self changeColumn: #change add: true.
  1306         self categoryColumn: self categoryColumn.
  1306 	self categoryColumn: self categoryColumn.
  1307         self timeStampColumn: self timeStampColumn.
  1307 	self timeStampColumn: self timeStampColumn.
  1308         self typeColumn: self typeColumn.
  1308 	self typeColumn: self typeColumn.
  1309 "/        self deltaInfoColumn: self deltaInfoColumn.
  1309 "/        self deltaInfoColumn: self deltaInfoColumn.
  1310         self positionsColumn: self positionsColumn.
  1310 	self positionsColumn: self positionsColumn.
  1311     ].
  1311     ].
  1312     ^ holder
  1312     ^ holder
  1313 
  1313 
  1314     "Modified: / 19.5.1998 / 20:30:31 / cg"
  1314     "Modified: / 19.5.1998 / 20:30:31 / cg"
  1315 !
  1315 !
  1316 
  1316 
  1317 listOfChanges
  1317 listOfChanges
  1318     "returns the value holder for the changes"
  1318     "returns the value holder for the changes"
  1319 
  1319 
  1320     |holder| 
  1320     |holder|
  1321     (holder := builder bindingAt:#listOfChanges) isNil ifTrue:[
  1321     (holder := builder bindingAt:#listOfChanges) isNil ifTrue:[
  1322 	builder aspectAt:#listOfChanges put:(holder := List new)
  1322 	builder aspectAt:#listOfChanges put:(holder := List new)
  1323     ].   
  1323     ].
  1324     ^ holder
  1324     ^ holder
  1325 !
  1325 !
  1326 
  1326 
  1327 selectionOfChange
  1327 selectionOfChange
  1328     "returns the value holder for the selected change"
  1328     "returns the value holder for the selected change"
  1329 
  1329 
  1330     |holder|
  1330     |holder|
  1331     (holder := builder bindingAt:#selectionOfChange) isNil ifTrue:[
  1331     (holder := builder bindingAt:#selectionOfChange) isNil ifTrue:[
  1332 	builder aspectAt:#selectionOfChange put:(holder :=  ValueHolder new).
  1332 	builder aspectAt:#selectionOfChange put:(holder :=  ValueHolder new).
  1333     ].                                           
  1333     ].
  1334     ^ holder
  1334     ^ holder
  1335 !
  1335 !
  1336 
  1336 
  1337 valueOfChangeText
  1337 valueOfChangeText
  1338     "returns the value holder for the source code of the selected change"
  1338     "returns the value holder for the source code of the selected change"
  1419     sawExcla := aStream peekFor:(aStream class chunkSeparator).
  1419     sawExcla := aStream peekFor:(aStream class chunkSeparator).
  1420     chunk := aStream nextChunk.
  1420     chunk := aStream nextChunk.
  1421     sawExcla ifTrue:[
  1421     sawExcla ifTrue:[
  1422 	chunk := aStream nextChunk
  1422 	chunk := aStream nextChunk
  1423     ].
  1423     ].
  1424     aStream close.        
  1424     aStream close.
  1425     self valueOfChangeText value:chunk.
  1425     self valueOfChangeText value:chunk.
  1426 
  1426 
  1427     self updateChannels
  1427     self updateChannels
  1428 ! !
  1428 ! !
  1429 
  1429 
  1432 update:something with:aParameter from:changedObject
  1432 update:something with:aParameter from:changedObject
  1433     "evaluates the filterCompletionBlock after returning the filter string"
  1433     "evaluates the filterCompletionBlock after returning the filter string"
  1434 
  1434 
  1435     super update:something with:aParameter from:changedObject.
  1435     super update:something with:aParameter from:changedObject.
  1436 
  1436 
  1437     changedObject == self valueOfFilter 
  1437     changedObject == self valueOfFilter
  1438     ifTrue: 
  1438     ifTrue:
  1439     [                           
  1439     [
  1440 	filterCompletionBlock value: changedObject value. 
  1440 	filterCompletionBlock value: changedObject value.
  1441 	self listOfChanges size > 0 ifTrue: [self addToHistory: changedObject value -> #doFilter:] 
  1441 	self listOfChanges size > 0 ifTrue: [self addToHistory: changedObject value -> #doFilter:]
  1442     ]
  1442     ]
  1443 
  1443 
  1444 
  1444 
  1445 
  1445 
  1446 
  1446 
  1449 !
  1449 !
  1450 
  1450 
  1451 updateChannels
  1451 updateChannels
  1452     "updates my channels"
  1452     "updates my channels"
  1453 
  1453 
  1454     |change|           
  1454     |change|
  1455     (change := self selectionOfChange value) notNil
  1455     (change := self selectionOfChange value) notNil
  1456     ifTrue:
  1456     ifTrue:
  1457     [
  1457     [
  1458 	self valueOfHavingSelection value: true.
  1458 	self valueOfHavingSelection value: true.
  1459 	self valueOfHavingChangeSelection value: 
  1459 	self valueOfHavingChangeSelection value:
  1460 	    ((change type = 'method') or: [(change type = 'class')])
  1460 	    ((change type = 'method') or: [(change type = 'class')])
  1461     ]
  1461     ]
  1462     ifFalse:
  1462     ifFalse:
  1463     [
  1463     [
  1464 	self valueOfHavingSelection value: false.
  1464 	self valueOfHavingSelection value: false.
  1508 	    |box|
  1508 	    |box|
  1509 
  1509 
  1510 	    "
  1510 	    "
  1511 	     start dialog - make certain cleanup is done
  1511 	     start dialog - make certain cleanup is done
  1512 	    "
  1512 	    "
  1513 	    action := OptionBox 
  1513 	    action := OptionBox
  1514 			  request:aString
  1514 			  request:aString
  1515 			  label:'Error'
  1515 			  label:'Error'
  1516 			  form:(WarningBox iconBitmap)
  1516 			  form:(WarningBox iconBitmap)
  1517 			  buttonLabels:#('cancel' 'skip' 'continue')
  1517 			  buttonLabels:#('cancel' 'skip' 'continue')
  1518 			  values:#(#abort #skip #continue)
  1518 			  values:#(#abort #skip #continue)
  1525 	].
  1525 	].
  1526 	action == #skip ifTrue:[
  1526 	action == #skip ifTrue:[
  1527 	    skipSignal raise.
  1527 	    skipSignal raise.
  1528 	    ^ false
  1528 	    ^ false
  1529 	].
  1529 	].
  1530 	^  false 
  1530 	^  false
  1531     ].
  1531     ].
  1532     ^self changeTextEditor error:aString position:relPos to:relEndPos from:aCompiler
  1532     ^self changeTextEditor error:aString position:relPos to:relEndPos from:aCompiler
  1533 
  1533 
  1534 !
  1534 !
  1535 
  1535 
  1558     "initializes the instance variables"
  1558     "initializes the instance variables"
  1559 
  1559 
  1560     super initialize.
  1560     super initialize.
  1561 
  1561 
  1562     changes           := List new.
  1562     changes           := List new.
  1563     self changeFileName: ObjectMemory nameForChanges. 
  1563     self changeFileName: ObjectMemory nameForChanges.
  1564     AutoUpdate        := AutoUpdate ? false.                                     
  1564     AutoUpdate        := AutoUpdate ? false.
  1565     PrivateAsSeparate := PrivateAsSeparate ? false.
  1565     PrivateAsSeparate := PrivateAsSeparate ? false.
  1566 
  1566 
  1567     ObjectMemory addDependent:self.
  1567     ObjectMemory addDependent:self.
  1568 ! !
  1568 ! !
  1569 
  1569 
  1666 !
  1666 !
  1667 
  1667 
  1668 autoSelectChange:aChange
  1668 autoSelectChange:aChange
  1669     "selects aChange"
  1669     "selects aChange"
  1670 
  1670 
  1671     self class autoSelectNext ifTrue:[         
  1671     self class autoSelectNext ifTrue:[
  1672 	((self listOfChanges indexOf: aChange) <= self listOfChanges size) ifTrue:[
  1672 	((self listOfChanges indexOf: aChange) <= self listOfChanges size) ifTrue:[
  1673 	    self selectionOfChange value: aChange.  
  1673 	    self selectionOfChange value: aChange.
  1674 	    self changeSelected:(self listOfChanges indexOf: aChange).
  1674 	    self changeSelected:(self listOfChanges indexOf: aChange).
  1675 	    self updateChannels.
  1675 	    self updateChannels.
  1676 	    ^ self
  1676 	    ^ self
  1677 	]
  1677 	]
  1678     ].         
  1678     ].
  1679     self updateChannels.
  1679     self updateChannels.
  1680     self unselectChange
  1680     self unselectChange
  1681 
  1681 
  1682 !
  1682 !
  1683 
  1683 
  1693     "selects aChange or the last"
  1693     "selects aChange or the last"
  1694 
  1694 
  1695     |last|
  1695     |last|
  1696 
  1696 
  1697     last := self listOfChanges size.
  1697     last := self listOfChanges size.
  1698     aChange notNil ifTrue:[  
  1698     aChange notNil ifTrue:[
  1699 	self autoSelectChange:aChange
  1699 	self autoSelectChange:aChange
  1700     ] ifFalse:[
  1700     ] ifFalse:[
  1701 	self selectionOfChange value: (self listOfChanges at: last ifAbsent: nil).
  1701 	self selectionOfChange value: (self listOfChanges at: last ifAbsent: nil).
  1702 	self changeSelected: last
  1702 	self changeSelected: last
  1703     ].
  1703     ].
  1710     |newListOfChangeColumns|
  1710     |newListOfChangeColumns|
  1711 
  1711 
  1712     newListOfChangeColumns := self listOfChangeColumns asOrderedCollection.
  1712     newListOfChangeColumns := self listOfChangeColumns asOrderedCollection.
  1713     addOrRemove
  1713     addOrRemove
  1714     ifTrue:
  1714     ifTrue:
  1715     [    
  1715     [
  1716 	newListOfChangeColumns add: 
  1716 	newListOfChangeColumns add:
  1717 	    ((self class tableColumnsForChangeAttributes 
  1717 	    ((self class tableColumnsForChangeAttributes
  1718 		collect: [:i| i decodeAsLiteralArray]) 
  1718 		collect: [:i| i decodeAsLiteralArray])
  1719 		    detect: [:column| column id = aColumnId])
  1719 		    detect: [:column| column id = aColumnId])
  1720     ]
  1720     ]
  1721     ifFalse:
  1721     ifFalse:
  1722     [
  1722     [
  1723 	newListOfChangeColumns remove: 
  1723 	newListOfChangeColumns remove:
  1724 	    (self listOfChangeColumns detect: [:column| column id = aColumnId] ifNone: nil) ifAbsent: nil
  1724 	    (self listOfChangeColumns detect: [:column| column id = aColumnId] ifNone: nil) ifAbsent: nil
  1725     ].
  1725     ].
  1726     self listOfChangeColumns contents: newListOfChangeColumns.
  1726     self listOfChangeColumns contents: newListOfChangeColumns.
  1727     self autoSelectLast
  1727     self autoSelectLast
  1728 
  1728 
  1759 checkIfFileHasChanged
  1759 checkIfFileHasChanged
  1760     "checks if changes file has changed"
  1760     "checks if changes file has changed"
  1761 
  1761 
  1762     |f info|
  1762     |f info|
  1763 
  1763 
  1764     Processor removeTimedBlock:autoUpdateBlock.   
  1764     Processor removeTimedBlock:autoUpdateBlock.
  1765     f := changeFileName asFilename.
  1765     f := changeFileName asFilename.
  1766     (info := f info) isNil ifTrue:[
  1766     (info := f info) isNil ifTrue:[
  1767         self newLabel:'unaccessable'
  1767 	self newLabel:'unaccessable'
  1768     ] ifFalse:[
  1768     ] ifFalse:[
  1769         (info modificationTime) > changeFileTimestamp ifTrue:[
  1769 	(info modificationTime) > changeFileTimestamp ifTrue:[
  1770             self newLabel:'outdated'.
  1770 	    self newLabel:'outdated'.
  1771             AutoUpdate ifTrue:[
  1771 	    AutoUpdate ifTrue:[
  1772                 self doReload
  1772 		self doReload
  1773             ]
  1773 	    ]
  1774         ] ifFalse:[
  1774 	] ifFalse:[
  1775             self newLabel:''
  1775 	    self newLabel:''
  1776         ]
  1776 	]
  1777     ].
  1777     ].
  1778     Processor addTimedBlock:autoUpdateBlock afterSeconds:5.
  1778     Processor addTimedBlock:autoUpdateBlock afterSeconds:5.
  1779 !
  1779 !
  1780 
  1780 
  1781 classNameOfChange:aChange
  1781 classNameOfChange:aChange
  1782     "returns the classname of aChange 
  1782     "returns the classname of aChange
  1783      (for classChanges (i.e. xxx class), the non-metaClassName (i.e. xxx) is returned)"
  1783      (for classChanges (i.e. xxx class), the non-metaClassName (i.e. xxx) is returned)"
  1784 
  1784 
  1785     |name|
  1785     |name|
  1786 
  1786 
  1787     name := self fullClassNameOfChange:aChange.
  1787     name := self fullClassNameOfChange:aChange.
  1851 		]
  1851 		]
  1852 	    ]
  1852 	    ]
  1853 	]
  1853 	]
  1854     ] ifTrue:[
  1854     ] ifTrue:[
  1855 	parseTree := Parser parseExpression:chunk.
  1855 	parseTree := Parser parseExpression:chunk.
  1856 	(parseTree notNil 
  1856 	(parseTree notNil
  1857 	 and:[parseTree ~~ #Error
  1857 	 and:[parseTree ~~ #Error
  1858 	 and:[parseTree isMessage]]) ifTrue:[
  1858 	 and:[parseTree isMessage]]) ifTrue:[
  1859 	    (parseTree selector == #methodsFor:) ifTrue:[
  1859 	    (parseTree selector == #methodsFor:) ifTrue:[
  1860 		thisClass := (parseTree receiver evaluate).
  1860 		thisClass := (parseTree receiver evaluate).
  1861 		thisClass isBehavior ifTrue:[
  1861 		thisClass isBehavior ifTrue:[
  1895 					showDiff := true.
  1895 					showDiff := true.
  1896 
  1896 
  1897 					"/
  1897 					"/
  1898 					"/ check if only historyLine diffs
  1898 					"/ check if only historyLine diffs
  1899 					"/
  1899 					"/
  1900 					(HistoryManager notNil 
  1900 					(HistoryManager notNil
  1901 					and:[HistoryManager isActive]) ifTrue:[
  1901 					and:[HistoryManager isActive]) ifTrue:[
  1902 					    (HistoryManager withoutHistoryLines:newSource)
  1902 					    (HistoryManager withoutHistoryLines:newSource)
  1903 					    =
  1903 					    =
  1904 					    (HistoryManager withoutHistoryLines:oldSource)
  1904 					    (HistoryManager withoutHistoryLines:oldSource)
  1905 					    ifTrue:[
  1905 					    ifTrue:[
  1918 			]
  1918 			]
  1919 		    ] ifFalse:[
  1919 		    ] ifFalse:[
  1920 			outcome := 'Change unparsable!!'
  1920 			outcome := 'Change unparsable!!'
  1921 		    ].
  1921 		    ].
  1922 		    (showDiff and:[oldSource notNil and:[newSource notNil]]) ifTrue:[
  1922 		    (showDiff and:[oldSource notNil and:[newSource notNil]]) ifTrue:[
  1923 			d := DiffTextView 
  1923 			d := DiffTextView
  1924 				openOn:oldSource label:'Current version (in image)'
  1924 				openOn:oldSource label:'Current version (in image)'
  1925 				and:newSource label:'Change version'.
  1925 				and:newSource label:'Change version'.
  1926 			d label:'method differences'.
  1926 			d label:'method differences'.
  1927 		    ]
  1927 		    ]
  1928 		] ifFalse:[
  1928 		] ifFalse:[
  1947 	]
  1947 	]
  1948     ]
  1948     ]
  1949 !
  1949 !
  1950 
  1950 
  1951 compressForClass:aClassNameOrNil
  1951 compressForClass:aClassNameOrNil
  1952     "compresses the list of changes; 
  1952     "compresses the list of changes;
  1953      this replaces multiple method-changes by the last (i.e. the most recent) change.
  1953      this replaces multiple method-changes by the last (i.e. the most recent) change.
  1954      If the class argument is nil, compress for all classes.
  1954      If the class argument is nil, compress for all classes.
  1955      otherwise, only changes for that class are compressed."
  1955      otherwise, only changes for that class are compressed."
  1956 
  1956 
  1957     |aStream searchIndex anyMore deleteSet index  
  1957     |aStream searchIndex anyMore deleteSet index
  1958      str snapshotProto snapshotPrefix snapshotNameIndex fileName|
  1958      str snapshotProto snapshotPrefix snapshotNameIndex fileName|
  1959 
  1959 
  1960     aStream := FileStream readonlyFileNamed:changeFileName.
  1960     aStream := FileStream readonlyFileNamed:changeFileName.
  1961     aStream isNil ifTrue:[^ self].
  1961     aStream isNil ifTrue:[^ self].
  1962 
  1962 
  2014 		"optimize a bit if multiple methods for same category arrive"
  2014 		"optimize a bit if multiple methods for same category arrive"
  2015 		(chunk = parseTreeChunk) ifFalse:[
  2015 		(chunk = parseTreeChunk) ifFalse:[
  2016 		    aParseTree := Parser parseExpression:chunk.
  2016 		    aParseTree := Parser parseExpression:chunk.
  2017 		    parseTreeChunk := chunk
  2017 		    parseTreeChunk := chunk
  2018 		].
  2018 		].
  2019 		(aParseTree notNil 
  2019 		(aParseTree notNil
  2020 		and:[(aParseTree ~~ #Error) 
  2020 		and:[(aParseTree ~~ #Error)
  2021 		and:[aParseTree isMessage]]) ifTrue:[
  2021 		and:[aParseTree isMessage]]) ifTrue:[
  2022 		    (aParseTree selector == #methodsFor:) ifTrue:[
  2022 		    (aParseTree selector == #methodsFor:) ifTrue:[
  2023 			thisClass := (aParseTree receiver evaluate).
  2023 			thisClass := (aParseTree receiver evaluate).
  2024 			codeChunk := aStream nextChunk.
  2024 			codeChunk := aStream nextChunk.
  2025 			codeParser := Parser 
  2025 			codeParser := Parser
  2026 					  parseMethodSpecification:codeChunk
  2026 					  parseMethodSpecification:codeChunk
  2027 					  in:thisClass
  2027 					  in:thisClass
  2028 					  ignoreErrors:true
  2028 					  ignoreErrors:true
  2029 					  ignoreWarnings:true.
  2029 					  ignoreWarnings:true.
  2030 			(codeParser notNil and:[codeParser ~~ #Error]) ifTrue:[
  2030 			(codeParser notNil and:[codeParser ~~ #Error]) ifTrue:[
  2035 		    ]
  2035 		    ]
  2036 		]
  2036 		]
  2037 	    ] ifFalse:[
  2037 	    ] ifFalse:[
  2038 		aParseTree := Parser parseExpression:chunk.
  2038 		aParseTree := Parser parseExpression:chunk.
  2039 		parseTreeChunk := chunk.
  2039 		parseTreeChunk := chunk.
  2040 		(aParseTree notNil 
  2040 		(aParseTree notNil
  2041 		and:[(aParseTree ~~ #Error) 
  2041 		and:[(aParseTree ~~ #Error)
  2042 		and:[aParseTree isMessage]]) ifTrue:[
  2042 		and:[aParseTree isMessage]]) ifTrue:[
  2043 		    (aParseTree selector == #removeSelector:) ifTrue:[
  2043 		    (aParseTree selector == #removeSelector:) ifTrue:[
  2044 			selectors at:changeNr put:(aParseTree arg1 value ).
  2044 			selectors at:changeNr put:(aParseTree arg1 value ).
  2045 			classes at:changeNr put:(aParseTree receiver evaluate).
  2045 			classes at:changeNr put:(aParseTree receiver evaluate).
  2046 			types at:changeNr put:#removeSelector
  2046 			types at:changeNr put:#removeSelector
  2061 	    ].
  2061 	    ].
  2062 	    changeNr := changeNr - 1
  2062 	    changeNr := changeNr - 1
  2063 	].
  2063 	].
  2064 	aStream close.
  2064 	aStream close.
  2065 
  2065 
  2066 	"for all changes, look for another class/selector occurence later
  2066 	"for all changes, look for another class/selector occurrence later
  2067 	 in the list and, if there is one, add change number to the delete set"
  2067 	 in the list and, if there is one, add change number to the delete set"
  2068 
  2068 
  2069 	deleteSet := OrderedCollection new.
  2069 	deleteSet := OrderedCollection new.
  2070 	changeNr := 1.
  2070 	changeNr := 1.
  2071 	[changeNr < changes size] whileTrue:[
  2071 	[changeNr < changes size] whileTrue:[
  2076 		compressThis := true
  2076 		compressThis := true
  2077 	    ] ifFalse:[
  2077 	    ] ifFalse:[
  2078 		"/ skipping unloaded/unknown classes
  2078 		"/ skipping unloaded/unknown classes
  2079 		thisClass isBehavior ifTrue:[
  2079 		thisClass isBehavior ifTrue:[
  2080 		    thisClass isMeta ifTrue:[
  2080 		    thisClass isMeta ifTrue:[
  2081 			compressThis := aClassNameOrNil = thisClass soleInstance name. 
  2081 			compressThis := aClassNameOrNil = thisClass soleInstance name.
  2082 		    ] ifFalse:[
  2082 		    ] ifFalse:[
  2083 			compressThis := aClassNameOrNil = thisClass name.
  2083 			compressThis := aClassNameOrNil = thisClass name.
  2084 			(PrivateAsSeparate not and: [thisClass isPrivate])
  2084 			(PrivateAsSeparate not and: [thisClass isPrivate])
  2085 			    ifTrue:[compressThis := aClassNameOrNil = thisClass owningClass name]
  2085 			    ifTrue:[compressThis := aClassNameOrNil = thisClass owningClass name]
  2086 		    ]
  2086 		    ]
  2100 				deleteSet add:changeNr.
  2100 				deleteSet add:changeNr.
  2101 				anyMore := false
  2101 				anyMore := false
  2102 			    ]
  2102 			    ]
  2103 			]
  2103 			]
  2104 		    ] ifFalse:[
  2104 		    ] ifFalse:[
  2105 			anyMore := false      
  2105 			anyMore := false
  2106 		    ]
  2106 		    ]
  2107 		].
  2107 		].
  2108 	    ].
  2108 	    ].
  2109 
  2109 
  2110 	    changeNr := changeNr + 1
  2110 	    changeNr := changeNr + 1
  2149 !
  2149 !
  2150 
  2150 
  2151 deleteChangesFrom:start to:stop
  2151 deleteChangesFrom:start to:stop
  2152     "deletes a range of changes"
  2152     "deletes a range of changes"
  2153 
  2153 
  2154     self unselectChange.     
  2154     self unselectChange.
  2155     stop to:start by:-1 do:[:changeNr|
  2155     stop to:start by:-1 do:[:changeNr|
  2156 	self silentDeleteChange:(self listOfChanges at: changeNr)
  2156 	self silentDeleteChange:(self listOfChanges at: changeNr)
  2157     ].
  2157     ].
  2158     self setChangeList
  2158     self setChangeList
  2159 !
  2159 !
  2160 
  2160 
  2161 fullClassNameOfChange:aChange
  2161 fullClassNameOfChange:aChange
  2162     "returns the full classname of aChange 
  2162     "returns the full classname of aChange
  2163      (for classChanges (i.e. xxx class), a string ending in ' class' is returned.
  2163      (for classChanges (i.e. xxx class), a string ending in ' class' is returned.
  2164      - since parsing ascii methods is slow, keep result cached in 
  2164      - since parsing ascii methods is slow, keep result cached in
  2165        changeClassNames for the next query"
  2165        changeClassNames for the next query"
  2166 
  2166 
  2167     |chunk aParseTree recTree sel name arg1Tree isMeta prevMethodDefNr
  2167     |chunk aParseTree recTree sel name arg1Tree isMeta prevMethodDefNr
  2168      words changeStream fullParseTree ownerTree ownerName oldDollarSetting|
  2168      words changeStream fullParseTree ownerTree ownerName oldDollarSetting|
  2169 
  2169 
  2233     recTree := aParseTree receiver.
  2233     recTree := aParseTree receiver.
  2234 
  2234 
  2235     "
  2235     "
  2236      is it a method-change, methodRemove or comment-change ?
  2236      is it a method-change, methodRemove or comment-change ?
  2237     "
  2237     "
  2238     (#(#'methodsFor:' 
  2238     (#(#'methodsFor:'
  2239        #'privateMethodsFor:' 
  2239        #'privateMethodsFor:'
  2240        #'protectedMethodsFor:' 
  2240        #'protectedMethodsFor:'
  2241        #'publicMethodsFor:' 
  2241        #'publicMethodsFor:'
  2242        #'removeSelector:' 
  2242        #'removeSelector:'
  2243        #'comment:'
  2243        #'comment:'
  2244        #'primitiveDefinitions:'
  2244        #'primitiveDefinitions:'
  2245        #'primitiveFunctions:'
  2245        #'primitiveFunctions:'
  2246        #'primitiveVariables:'
  2246        #'primitiveVariables:'
  2247        #'renameCategory:to:'
  2247        #'renameCategory:to:'
  2272     ].
  2272     ].
  2273 
  2273 
  2274     "
  2274     "
  2275      is it a change in a class-description ?
  2275      is it a change in a class-description ?
  2276     "
  2276     "
  2277     (('subclass:*' match:sel) 
  2277     (('subclass:*' match:sel)
  2278     or:[('variable*subclass:*' match:sel)]) ifTrue:[
  2278     or:[('variable*subclass:*' match:sel)]) ifTrue:[
  2279 	"/ must parse the full changes text, to get
  2279 	"/ must parse the full changes text, to get
  2280 	"/ privacy information.
  2280 	"/ privacy information.
  2281 
  2281 
  2282 	changeStream := self streamForChange:aChange.
  2282 	changeStream := self streamForChange:aChange.
  2316 
  2316 
  2317     "
  2317     "
  2318      is it a class remove ?
  2318      is it a class remove ?
  2319     "
  2319     "
  2320     (sel == #removeClass:) ifTrue:[
  2320     (sel == #removeClass:) ifTrue:[
  2321 	(recTree notNil 
  2321 	(recTree notNil
  2322 	and:[recTree ~~ #Error
  2322 	and:[recTree ~~ #Error
  2323 	and:[recTree isPrimary
  2323 	and:[recTree isPrimary
  2324 	and:[recTree name = 'Smalltalk']]]) ifTrue:[
  2324 	and:[recTree name = 'Smalltalk']]]) ifTrue:[
  2325 	    arg1Tree := aParseTree arg1.
  2325 	    arg1Tree := aParseTree arg1.
  2326 	    (arg1Tree notNil and:[arg1Tree isPrimary]) ifTrue:[
  2326 	    (arg1Tree notNil and:[arg1Tree isPrimary]) ifTrue:[
  2334     "
  2334     "
  2335      is it a method category change ?
  2335      is it a method category change ?
  2336     "
  2336     "
  2337     ((sel == #category:)
  2337     ((sel == #category:)
  2338     or:[sel == #privacy:]) ifTrue:[
  2338     or:[sel == #privacy:]) ifTrue:[
  2339 	(recTree notNil 
  2339 	(recTree notNil
  2340 	and:[recTree ~~ #Error
  2340 	and:[recTree ~~ #Error
  2341 	and:[recTree isMessage
  2341 	and:[recTree isMessage
  2342 	and:[recTree selector == #compiledMethodAt:]]]) ifTrue:[
  2342 	and:[recTree selector == #compiledMethodAt:]]]) ifTrue:[
  2343 	    isMeta := false.
  2343 	    isMeta := false.
  2344 	    recTree := recTree receiver.
  2344 	    recTree := recTree receiver.
  2370 readChangesFileInBackground:inBackground
  2370 readChangesFileInBackground:inBackground
  2371     "reads the changes file, creates a list of header-lines (changeChunks)
  2371     "reads the changes file, creates a list of header-lines (changeChunks)
  2372      and a list of chunk-positions (changePositions).
  2372      and a list of chunk-positions (changePositions).
  2373      Starting with 2.10.3, the entries are multi-col entries;
  2373      Starting with 2.10.3, the entries are multi-col entries;
  2374      the cols are:
  2374      the cols are:
  2375         1   delta (only if comparing)
  2375 	1   delta (only if comparing)
  2376                 '+' -> new method (w.r.t. current state)
  2376 		'+' -> new method (w.r.t. current state)
  2377                 '-' -> removed method (w.r.t. current state)
  2377 		'-' -> removed method (w.r.t. current state)
  2378                 '?' -> class does not exist currently
  2378 		'?' -> class does not exist currently
  2379                 '=' -> change is same as current methods source
  2379 		'=' -> change is same as current methods source
  2380         2   class/selector
  2380 	2   class/selector
  2381         3   type of change
  2381 	3   type of change
  2382                 doit
  2382 		doit
  2383                 method
  2383 		method
  2384                 category change
  2384 		category change
  2385         4   timestamp
  2385 	4   timestamp
  2386 
  2386 
  2387      since comparing slows down startup time, it is now disabled by
  2387      since comparing slows down startup time, it is now disabled by
  2388      default and can be enabled via a toggle."
  2388      default and can be enabled via a toggle."
  2389 
  2389 
  2390     |aStream maxLen i f v|
  2390     |aStream maxLen i f v|
  2411     v notNil ifTrue:[v raise].
  2411     v notNil ifTrue:[v raise].
  2412     v := self filterLabel.
  2412     v := self filterLabel.
  2413     v notNil ifTrue:[v label: 'Read:'; redraw].
  2413     v notNil ifTrue:[v label: 'Read:'; redraw].
  2414 
  2414 
  2415     self withReadCursorDo:[
  2415     self withReadCursorDo:[
  2416         |myProcess myPriority|
  2416 	|myProcess myPriority|
  2417 
  2417 
  2418         "
  2418 	"
  2419          this is a time consuming operation (especially, if reading an
  2419 	 this is a time consuming operation (especially, if reading an
  2420          NFS-mounted directory; therefore lower my priority...
  2420 	 NFS-mounted directory; therefore lower my priority...
  2421         "
  2421 	"
  2422         inBackground ifTrue:[
  2422 	inBackground ifTrue:[
  2423             myProcess := Processor activeProcess.
  2423 	    myProcess := Processor activeProcess.
  2424             myPriority := myProcess priority.
  2424 	    myPriority := myProcess priority.
  2425             myProcess priority:(Processor userBackgroundPriority).
  2425 	    myProcess priority:(Processor userBackgroundPriority).
  2426         ].
  2426 	].
  2427 
  2427 
  2428         [
  2428 	[
  2429             |excla timeStampInfo lastChange|
  2429 	    |excla timeStampInfo lastChange|
  2430 
  2430 
  2431             excla := aStream class chunkSeparator.
  2431 	    excla := aStream class chunkSeparator.
  2432 
  2432 
  2433             [aStream atEnd] whileFalse:[
  2433 	    [aStream atEnd] whileFalse:[
  2434                 |change changeDelta changeString changeType changeCategory
  2434 		|change changeDelta changeString changeType changeCategory
  2435                  line s l changeClass sawExcla category 
  2435 		 line s l changeClass sawExcla category
  2436                  chunkText chunkPos sel oldValue|
  2436 		 chunkText chunkPos sel oldValue|
  2437 
  2437 
  2438                 change := Change new.
  2438 		change := Change new.
  2439                 "
  2439 		"
  2440                  get a chunk (separated by excla)
  2440 		 get a chunk (separated by excla)
  2441                 "
  2441 		"
  2442                 oldValue := self valueOfReadProgress value.
  2442 		oldValue := self valueOfReadProgress value.
  2443                 self valueOfReadProgress value: (((aStream position/aStream size) * 100) rounded).
  2443 		self valueOfReadProgress value: (((aStream position/aStream size) * 100) rounded).
  2444 "/                oldValue ~~ self valueOfReadProgress value
  2444 "/                oldValue ~~ self valueOfReadProgress value
  2445 "/                    ifTrue: [self readProgressIndicator redrawEdges;redraw].
  2445 "/                    ifTrue: [self readProgressIndicator redrawEdges;redraw].
  2446 
  2446 
  2447                 aStream skipSeparators.
  2447 		aStream skipSeparators.
  2448                 chunkPos := aStream position.
  2448 		chunkPos := aStream position.
  2449 
  2449 
  2450                 sawExcla := aStream peekFor:excla.
  2450 		sawExcla := aStream peekFor:excla.
  2451                 chunkText := aStream nextChunk.
  2451 		chunkText := aStream nextChunk.
  2452                 chunkText notNil ifTrue:[
  2452 		chunkText notNil ifTrue:[
  2453                     |index headerLine cls|
  2453 		    |index headerLine cls|
  2454 
  2454 
  2455                     (chunkText startsWith:'''---- timestamp ') ifTrue:[
  2455 		    (chunkText startsWith:'''---- timestamp ') ifTrue:[
  2456                         timeStampInfo := (chunkText copyFrom:16 to:(chunkText size - 6)) withoutSpaces.
  2456 			timeStampInfo := (chunkText copyFrom:16 to:(chunkText size - 6)) withoutSpaces.
  2457                     ] ifFalse:[
  2457 		    ] ifFalse:[
  2458 
  2458 
  2459                         "
  2459 			"
  2460                          only first line is saved in changeChunks...
  2460 			 only first line is saved in changeChunks...
  2461                         "
  2461 			"
  2462                         index := chunkText indexOf:(Character cr).
  2462 			index := chunkText indexOf:(Character cr).
  2463                         (index ~~ 0) ifTrue:[
  2463 			(index ~~ 0) ifTrue:[
  2464                             chunkText := chunkText copyTo:(index - 1).
  2464 			    chunkText := chunkText copyTo:(index - 1).
  2465 
  2465 
  2466                             "take care for comment changes - must still be a
  2466 			    "take care for comment changes - must still be a
  2467                              valid expression for classNameOfChange: to work"
  2467 			     valid expression for classNameOfChange: to work"
  2468 
  2468 
  2469                             (chunkText endsWith:'comment:''') ifTrue:[
  2469 			    (chunkText endsWith:'comment:''') ifTrue:[
  2470                                 chunkText := chunkText , '...'''
  2470 				chunkText := chunkText , '...'''
  2471                             ].
  2471 			    ].
  2472                             (chunkText endsWith:'primitiveDefinitions:''') ifTrue:[
  2472 			    (chunkText endsWith:'primitiveDefinitions:''') ifTrue:[
  2473                                 sel := 'primitiveDefinitions:'.
  2473 				sel := 'primitiveDefinitions:'.
  2474                                 chunkText := chunkText copyWithoutLast:1
  2474 				chunkText := chunkText copyWithoutLast:1
  2475                             ].
  2475 			    ].
  2476                             (chunkText endsWith:'primitiveVariables:''') ifTrue:[
  2476 			    (chunkText endsWith:'primitiveVariables:''') ifTrue:[
  2477                                 sel := 'primitiveVariables:'.
  2477 				sel := 'primitiveVariables:'.
  2478                                 chunkText := chunkText copyWithoutLast:1
  2478 				chunkText := chunkText copyWithoutLast:1
  2479                             ].
  2479 			    ].
  2480                             (chunkText endsWith:'primitiveFunctions:''') ifTrue:[
  2480 			    (chunkText endsWith:'primitiveFunctions:''') ifTrue:[
  2481                                 sel := 'primitiveFunctions:'.
  2481 				sel := 'primitiveFunctions:'.
  2482                                 chunkText := chunkText copyWithoutLast:1
  2482 				chunkText := chunkText copyWithoutLast:1
  2483                             ].
  2483 			    ].
  2484                         ].
  2484 			].
  2485 
  2485 
  2486                         change chunk: chunkText.
  2486 			change chunk: chunkText.
  2487                         change position: chunkPos. 
  2487 			change position: chunkPos.
  2488                         lastChange notNil ifTrue: [lastChange lastPosition: chunkPos - 1].
  2488 			lastChange notNil ifTrue: [lastChange lastPosition: chunkPos - 1].
  2489                         lastChange := change.
  2489 			lastChange := change.
  2490                         change timeStamp: timeStampInfo.
  2490 			change timeStamp: timeStampInfo.
  2491                         change followUp: false.
  2491 			change followUp: false.
  2492                         headerLine := nil.
  2492 			headerLine := nil.
  2493                         changeDelta := ' '.
  2493 			changeDelta := ' '.
  2494 
  2494 
  2495                         sawExcla ifFalse:[
  2495 			sawExcla ifFalse:[
  2496                             (chunkText startsWith:'''---- snap') ifTrue:[
  2496 			    (chunkText startsWith:'''---- snap') ifTrue:[
  2497                                 changeType := ''.
  2497 				changeType := ''.
  2498                                 headerLine := chunkText.
  2498 				headerLine := chunkText.
  2499                                 changeString := (chunkText contractTo:maxLen).
  2499 				changeString := (chunkText contractTo:maxLen).
  2500                                 timeStampInfo := nil.
  2500 				timeStampInfo := nil.
  2501                             ] ifFalse:[
  2501 			    ] ifFalse:[
  2502 
  2502 
  2503                                 |p cls|
  2503 				|p cls|
  2504 
  2504 
  2505                                 headerLine := chunkText , ' (doIt)'.
  2505 				headerLine := chunkText , ' (doIt)'.
  2506 
  2506 
  2507                                 "
  2507 				"
  2508                                  first, assume doIt - then lets have a more detailed look...
  2508 				 first, assume doIt - then lets have a more detailed look...
  2509                                 "
  2509 				"
  2510                                 ((chunkText startsWith:'''---- file')
  2510 				((chunkText startsWith:'''---- file')
  2511                                 or:[(chunkText startsWith:'''---- check')]) ifTrue:[
  2511 				or:[(chunkText startsWith:'''---- check')]) ifTrue:[
  2512                                     changeType := ''.
  2512 				    changeType := ''.
  2513                                     timeStampInfo := nil.
  2513 				    timeStampInfo := nil.
  2514                                 ] ifFalse:[
  2514 				] ifFalse:[
  2515                                     changeType := 'doIt'.
  2515 				    changeType := 'doIt'.
  2516                                 ].    
  2516 				].
  2517                                 changeString := (chunkText contractTo:maxLen).
  2517 				changeString := (chunkText contractTo:maxLen).
  2518 
  2518 
  2519                                 p := Parser parseExpression:chunkText inNameSpace:Smalltalk.
  2519 				p := Parser parseExpression:chunkText inNameSpace:Smalltalk.
  2520                                 (p notNil 
  2520 				(p notNil
  2521                                  and:[p ~~ #Error
  2521 				 and:[p ~~ #Error
  2522                                  and:[p isMessage]]) ifTrue:[
  2522 				 and:[p isMessage]]) ifTrue:[
  2523                                     sel := p selector.
  2523 				    sel := p selector.
  2524                                 ].
  2524 				].
  2525                                 (sel == #removeSelector:) ifTrue:[
  2525 				(sel == #removeSelector:) ifTrue:[
  2526                                     p receiver isUnaryMessage ifTrue:[
  2526 				    p receiver isUnaryMessage ifTrue:[
  2527                                         cls := p receiver receiver name.
  2527 					cls := p receiver receiver name.
  2528                                         changeClass := (Smalltalk classNamed:cls) class.
  2528 					changeClass := (Smalltalk classNamed:cls) class.
  2529                                         cls := cls , ' class'.
  2529 					cls := cls , ' class'.
  2530                                     ] ifFalse:[
  2530 				    ] ifFalse:[
  2531                                         cls := p receiver name.
  2531 					cls := p receiver name.
  2532                                         changeClass := (Smalltalk classNamed:cls)
  2532 					changeClass := (Smalltalk classNamed:cls)
  2533                                     ].
  2533 				    ].
  2534                                     sel := (p args at:1) evaluate.
  2534 				    sel := (p args at:1) evaluate.
  2535 
  2535 
  2536                                     DeltaInfoColumn ifTrue:[
  2536 				    DeltaInfoColumn ifTrue:[
  2537                                         (changeClass isNil or:[changeClass isLoaded not]) ifTrue:[
  2537 					(changeClass isNil or:[changeClass isLoaded not]) ifTrue:[
  2538                                             changeDelta := '?'
  2538 					    changeDelta := '?'
  2539                                         ] ifFalse:[
  2539 					] ifFalse:[
  2540                                             (changeClass implements:sel asSymbol) ifTrue:[
  2540 					    (changeClass implements:sel asSymbol) ifTrue:[
  2541                                                 changeDelta := '-'.
  2541 						changeDelta := '-'.
  2542                                             ]
  2542 					    ]
  2543                                         ]
  2543 					]
  2544                                     ].
  2544 				    ].
  2545                                     changeType := 'remove'.
  2545 				    changeType := 'remove'.
  2546                                     changeString := self contractClass:cls selector:sel to:maxLen.
  2546 				    changeString := self contractClass:cls selector:sel to:maxLen.
  2547                                 ].
  2547 				].
  2548                                 (p ~~ #Error
  2548 				(p ~~ #Error
  2549                                 and:[p isMessage 
  2549 				and:[p isMessage
  2550                                 and:[p receiver isMessage
  2550 				and:[p receiver isMessage
  2551                                 and:[p receiver selector == #compiledMethodAt:]]]) ifTrue:[
  2551 				and:[p receiver selector == #compiledMethodAt:]]]) ifTrue:[
  2552                                     p receiver receiver isUnaryMessage ifTrue:[
  2552 				    p receiver receiver isUnaryMessage ifTrue:[
  2553                                         cls := p receiver receiver receiver name.
  2553 					cls := p receiver receiver receiver name.
  2554                                         changeClass := (Smalltalk classNamed:cls) class.
  2554 					changeClass := (Smalltalk classNamed:cls) class.
  2555                                         cls := cls , ' class'.
  2555 					cls := cls , ' class'.
  2556                                     ] ifFalse:[
  2556 				    ] ifFalse:[
  2557                                         cls := p receiver receiver name.
  2557 					cls := p receiver receiver name.
  2558                                         changeClass := (Smalltalk classNamed:cls)
  2558 					changeClass := (Smalltalk classNamed:cls)
  2559                                     ].
  2559 				    ].
  2560                                     (sel == #category:) ifTrue:[
  2560 				    (sel == #category:) ifTrue:[
  2561                                         sel := (p receiver args at:1) evaluate.
  2561 					sel := (p receiver args at:1) evaluate.
  2562                                         changeType := '(category change)'.
  2562 					changeType := '(category change)'.
  2563                                         changeString := self contractClass:cls selector:sel to:maxLen.
  2563 					changeString := self contractClass:cls selector:sel to:maxLen.
  2564                                     ].
  2564 				    ].
  2565                                     (sel == #privacy:) ifTrue:[
  2565 				    (sel == #privacy:) ifTrue:[
  2566                                         sel := (p receiver args at:1) evaluate.
  2566 					sel := (p receiver args at:1) evaluate.
  2567                                         changeType := 'privacy change'.
  2567 					changeType := 'privacy change'.
  2568                                         changeString := self contractClass:cls selector:sel to:maxLen.
  2568 					changeString := self contractClass:cls selector:sel to:maxLen.
  2569                                     ].
  2569 				    ].
  2570                                 ].
  2570 				].
  2571                                 (#(#'subclass:'
  2571 				(#(#'subclass:'
  2572                                   #'variableSubclass:'
  2572 				  #'variableSubclass:'
  2573                                   #'variableByteSubclass:'
  2573 				  #'variableByteSubclass:'
  2574                                   #'variableWordSubclass:'
  2574 				  #'variableWordSubclass:'
  2575                                   #'variableLongSubclass:'
  2575 				  #'variableLongSubclass:'
  2576                                   #'variableFloatSubclass:'
  2576 				  #'variableFloatSubclass:'
  2577                                   #'variableDoubleSubclass:'
  2577 				  #'variableDoubleSubclass:'
  2578                                   #'primitiveDefinitions:'
  2578 				  #'primitiveDefinitions:'
  2579                                   #'primitiveFunctions:'
  2579 				  #'primitiveFunctions:'
  2580                                   #'primitiveVariables:'
  2580 				  #'primitiveVariables:'
  2581                                  ) includes:sel) ifTrue:[
  2581 				 ) includes:sel) ifTrue:[
  2582                                     changeType := 'class definition'.
  2582 				    changeType := 'class definition'.
  2583                                 ].
  2583 				].
  2584                             ]
  2584 			    ]
  2585                         ] ifTrue:[
  2585 			] ifTrue:[
  2586                             |done first p className cls text methodPos|
  2586 			    |done first p className cls text methodPos|
  2587 
  2587 
  2588                             "
  2588 			    "
  2589                              method definitions actually consist of
  2589 			     method definitions actually consist of
  2590                              two (or more) chunks; skip next chunk(s)
  2590 			     two (or more) chunks; skip next chunk(s)
  2591                              up to an empty one.
  2591 			     up to an empty one.
  2592                              The system only writes one chunk,
  2592 			     The system only writes one chunk,
  2593                              and we cannot handle more in this ChangesBrowser....
  2593 			     and we cannot handle more in this ChangesBrowser....
  2594                             "
  2594 			    "
  2595                             className := nil.
  2595 			    className := nil.
  2596                             p := Parser parseExpression:chunkText inNameSpace:Smalltalk.
  2596 			    p := Parser parseExpression:chunkText inNameSpace:Smalltalk.
  2597 
  2597 
  2598                             (p notNil and:[p ~~ #Error]) ifTrue:[
  2598 			    (p notNil and:[p ~~ #Error]) ifTrue:[
  2599                                 sel := p selector.
  2599 				sel := p selector.
  2600                                 (sel == #methodsFor:) ifTrue:[
  2600 				(sel == #methodsFor:) ifTrue:[
  2601                                     p receiver isUnaryMessage ifTrue:[
  2601 				    p receiver isUnaryMessage ifTrue:[
  2602                                         className := p receiver receiver name.
  2602 					className := p receiver receiver name.
  2603                                         changeClass := (Smalltalk classNamed:className) class.
  2603 					changeClass := (Smalltalk classNamed:className) class.
  2604                                         className := className , ' class'.
  2604 					className := className , ' class'.
  2605                                     ] ifFalse:[
  2605 				    ] ifFalse:[
  2606                                         className := p receiver name.
  2606 					className := p receiver name.
  2607                                         changeClass := Smalltalk classNamed:className
  2607 					changeClass := Smalltalk classNamed:className
  2608                                     ].
  2608 				    ].
  2609                                     category := (p args at:1) evaluate.
  2609 				    category := (p args at:1) evaluate.
  2610                                 ].
  2610 				].
  2611                             ].
  2611 			    ].
  2612 
  2612 
  2613                             done := false.
  2613 			    done := false.
  2614                             first := true.
  2614 			    first := true.
  2615                             [done] whileFalse:[
  2615 			    [done] whileFalse:[
  2616 
  2616 
  2617                                 changeDelta := ' '.
  2617 				changeDelta := ' '.
  2618                                 methodPos := aStream position.
  2618 				methodPos := aStream position.
  2619 
  2619 
  2620                                 text := aStream nextChunk.
  2620 				text := aStream nextChunk.
  2621                                 text isNil ifTrue:[
  2621 				text isNil ifTrue:[
  2622                                     done := true
  2622 				    done := true
  2623                                 ] ifFalse:[
  2623 				] ifFalse:[
  2624                                     done := text isEmpty
  2624 				    done := text isEmpty
  2625                                 ].
  2625 				].
  2626                                 done ifFalse:[
  2626 				done ifFalse:[
  2627                                     first ifFalse:[
  2627 				    first ifFalse:[
  2628                                         change := Change new.
  2628 					change := Change new.
  2629                                         change chunk: chunkText.
  2629 					change chunk: chunkText.
  2630                                         change string:changeString.
  2630 					change string:changeString.
  2631                                         change position: methodPos. 
  2631 					change position: methodPos.
  2632                                         change className: className. 
  2632 					change className: className.
  2633                                         lastChange notNil ifTrue: [lastChange lastPosition: methodPos - 1].
  2633 					lastChange notNil ifTrue: [lastChange lastPosition: methodPos - 1].
  2634                                         lastChange := change.
  2634 					lastChange := change.
  2635                                         change timeStamp: timeStampInfo.
  2635 					change timeStamp: timeStampInfo.
  2636                                         change followUp: true.
  2636 					change followUp: true.
  2637                                         editingClassSource := true.
  2637 					editingClassSource := true.
  2638                                     ].
  2638 				    ].
  2639 
  2639 
  2640                                     first := false.
  2640 				    first := false.
  2641                                     "
  2641 				    "
  2642                                      try to find the selector
  2642 				     try to find the selector
  2643                                     "
  2643 				    "
  2644                                     sel := nil.
  2644 				    sel := nil.
  2645                                     className notNil ifTrue:[
  2645 				    className notNil ifTrue:[
  2646                                         p := Parser 
  2646 					p := Parser
  2647                                                  parseMethodSpecification:text
  2647 						 parseMethodSpecification:text
  2648                                                  in:nil
  2648 						 in:nil
  2649                                                  ignoreErrors:true
  2649 						 ignoreErrors:true
  2650                                                  ignoreWarnings:true.
  2650 						 ignoreWarnings:true.
  2651                                         (p notNil and:[p ~~ #Error]) ifTrue:[
  2651 					(p notNil and:[p ~~ #Error]) ifTrue:[
  2652                                             sel := p selector.
  2652 					    sel := p selector.
  2653                                         ]
  2653 					]
  2654                                     ].
  2654 				    ].
  2655 
  2655 
  2656                                     sel isNil ifTrue:[
  2656 				    sel isNil ifTrue:[
  2657                                         changeString := (chunkText contractTo:maxLen).
  2657 					changeString := (chunkText contractTo:maxLen).
  2658                                         changeType := 'change'.
  2658 					changeType := 'change'.
  2659                                         headerLine := chunkText , ' (change)'.
  2659 					headerLine := chunkText , ' (change)'.
  2660                                     ] ifFalse:[
  2660 				    ] ifFalse:[
  2661                                         changeString :=  self contractClass:className selector:sel to:maxLen.
  2661 					changeString :=  self contractClass:className selector:sel to:maxLen.
  2662                                         changeType := 'method definition'.
  2662 					changeType := 'method definition'.
  2663                                         changeCategory := category.
  2663 					changeCategory := category.
  2664                                         headerLine := className , ' ' , sel , ' ' , '(change category: ''' , category , ''')'.
  2664 					headerLine := className , ' ' , sel , ' ' , '(change category: ''' , category , ''')'.
  2665                                     ].
  2665 				    ].
  2666 
  2666 
  2667                                     DeltaInfoColumn ifTrue:[ 
  2667 				    DeltaInfoColumn ifTrue:[
  2668                                         changeClass isNil ifFalse:[
  2668 					changeClass isNil ifFalse:[
  2669                                             changeClass isMeta ifTrue:[
  2669 					    changeClass isMeta ifTrue:[
  2670                                                 cls := changeClass soleInstance
  2670 						cls := changeClass soleInstance
  2671                                             ] ifFalse:[
  2671 					    ] ifFalse:[
  2672                                                 cls := changeClass
  2672 						cls := changeClass
  2673                                             ].
  2673 					    ].
  2674                                         ].
  2674 					].
  2675 
  2675 
  2676                                         (changeClass isNil or:[cls isLoaded not]) ifTrue:[
  2676 					(changeClass isNil or:[cls isLoaded not]) ifTrue:[
  2677                                             changeDelta := '?'
  2677 					    changeDelta := '?'
  2678                                         ] ifFalse:[
  2678 					] ifFalse:[
  2679                                             (changeClass implements:sel asSymbol) ifFalse:[
  2679 					    (changeClass implements:sel asSymbol) ifFalse:[
  2680                                                 changeDelta := '+'.
  2680 						changeDelta := '+'.
  2681                                             ] ifTrue:[
  2681 					    ] ifTrue:[
  2682                                                 |m currentText t1 t2|
  2682 						|m currentText t1 t2|
  2683 
  2683 
  2684                                                 m := changeClass compiledMethodAt:sel asSymbol.
  2684 						m := changeClass compiledMethodAt:sel asSymbol.
  2685                                                 currentText := m source.
  2685 						currentText := m source.
  2686                                                 currentText notNil ifTrue:[
  2686 						currentText notNil ifTrue:[
  2687                                                     text asString = currentText asString ifTrue:[
  2687 						    text asString = currentText asString ifTrue:[
  2688                                                         changeDelta := '='
  2688 							changeDelta := '='
  2689                                                     ] ifFalse:[
  2689 						    ] ifFalse:[
  2690                                                         t1 := currentText asCollectionOfLines collect:[:s | s withTabsExpanded].
  2690 							t1 := currentText asCollectionOfLines collect:[:s | s withTabsExpanded].
  2691                                                         t2 := text asCollectionOfLines collect:[:s | s withTabsExpanded].
  2691 							t2 := text asCollectionOfLines collect:[:s | s withTabsExpanded].
  2692                                                         t1 = t2 ifTrue:[
  2692 							t1 = t2 ifTrue:[
  2693                                                             changeDelta := '='
  2693 							    changeDelta := '='
  2694                                                         ]
  2694 							]
  2695                                                     ]
  2695 						    ]
  2696                                                 ]
  2696 						]
  2697                                             ]
  2697 					    ]
  2698                                         ]
  2698 					]
  2699                                     ].
  2699 				    ].
  2700                                     change delta:changeDelta.
  2700 				    change delta:changeDelta.
  2701                                     change string:changeString.
  2701 				    change string:changeString.
  2702                                     change type:changeType.
  2702 				    change type:changeType.
  2703                                     change category: changeCategory.
  2703 				    change category: changeCategory.
  2704                                     change timeStamp:timeStampInfo.
  2704 				    change timeStamp:timeStampInfo.
  2705                                     changes add:change.
  2705 				    changes add:change.
  2706                                 ].
  2706 				].
  2707                                 changeString := nil.
  2707 				changeString := nil.
  2708                                 headerLine := nil.
  2708 				headerLine := nil.
  2709 
  2709 
  2710                             ]
  2710 			    ]
  2711                         ].
  2711 			].
  2712                         changeString notNil ifTrue:[
  2712 			changeString notNil ifTrue:[
  2713                             change delta:changeDelta.
  2713 			    change delta:changeDelta.
  2714                             change string:changeString.
  2714 			    change string:changeString.
  2715                             change type:changeType.
  2715 			    change type:changeType.
  2716                             change timeStamp:timeStampInfo.
  2716 			    change timeStamp:timeStampInfo.
  2717                             changes add:change.
  2717 			    changes add:change.
  2718 
  2718 
  2719                         ] ifFalse:[
  2719 			] ifFalse:[
  2720                             headerLine notNil ifTrue:[     
  2720 			    headerLine notNil ifTrue:[
  2721                                 changes add: change.
  2721 				changes add: change.
  2722                             ]
  2722 			    ]
  2723                         ]
  2723 			]
  2724                     ]
  2724 		    ]
  2725                 ]. 
  2725 		].
  2726                 change lastPosition: aStream position.
  2726 		change lastPosition: aStream position.
  2727             ].
  2727 	    ].
  2728             modified := false.
  2728 	    modified := false.
  2729 
  2729 
  2730         ] valueNowOrOnUnwindDo:[ 
  2730 	] valueNowOrOnUnwindDo:[
  2731             aStream close.
  2731 	    aStream close.
  2732             inBackground ifTrue:[myProcess priority:myPriority].
  2732 	    inBackground ifTrue:[myProcess priority:myPriority].
  2733         ].
  2733 	].
  2734     ].
  2734     ].
  2735     self setChangeList.
  2735     self setChangeList.
  2736     self valueOfNotReading value: true.
  2736     self valueOfNotReading value: true.
  2737     self filterField raise.
  2737     self filterField raise.
  2738     self filterLabel label: 'Filter:'.
  2738     self filterLabel label: 'Filter:'.
  2748     |source parser sel|
  2748     |source parser sel|
  2749 
  2749 
  2750     source := self sourceOfMethodChange:aChange.
  2750     source := self sourceOfMethodChange:aChange.
  2751     source isNil ifTrue:[^ nil].
  2751     source isNil ifTrue:[^ nil].
  2752 
  2752 
  2753     parser := Parser 
  2753     parser := Parser
  2754 		parseMethod:source 
  2754 		parseMethod:source
  2755 		in:nil 
  2755 		in:nil
  2756 		ignoreErrors:true 
  2756 		ignoreErrors:true
  2757 		ignoreWarnings:true.
  2757 		ignoreWarnings:true.
  2758 
  2758 
  2759     (parser notNil and:[parser ~~ #Error]) ifTrue:[
  2759     (parser notNil and:[parser ~~ #Error]) ifTrue:[
  2760 	sel := parser selector.
  2760 	sel := parser selector.
  2761     ].
  2761     ].
  2770 !
  2770 !
  2771 
  2771 
  2772 silentDeleteChange:aChange
  2772 silentDeleteChange:aChange
  2773     "delete aChange do not update changeListView"
  2773     "delete aChange do not update changeListView"
  2774 
  2774 
  2775     modified := true.      
  2775     modified := true.
  2776 
  2776 
  2777     changes remove:aChange
  2777     changes remove:aChange
  2778 !
  2778 !
  2779 
  2779 
  2780 silentDeleteChangesFor:aClassName from:start to:stop
  2780 silentDeleteChangesFor:aClassName from:start to:stop
  2782      and returns the number of the deleted changes"
  2782      and returns the number of the deleted changes"
  2783 
  2783 
  2784     |index numDeleted clsName|
  2784     |index numDeleted clsName|
  2785 
  2785 
  2786     numDeleted := 0.
  2786     numDeleted := 0.
  2787     index := stop.          
  2787     index := stop.
  2788     [index >= start] whileTrue:
  2788     [index >= start] whileTrue:
  2789     [                                         
  2789     [
  2790 	((clsName := self classNameOfChange:(self listOfChanges at: index)) notNil and:
  2790 	((clsName := self classNameOfChange:(self listOfChanges at: index)) notNil and:
  2791 	[(clsName = aClassName or: [PrivateAsSeparate not and: [(clsName upTo: $:) = aClassName]])])
  2791 	[(clsName = aClassName or: [PrivateAsSeparate not and: [(clsName upTo: $:) = aClassName]])])
  2792 	ifTrue:
  2792 	ifTrue:
  2793 	[     
  2793 	[
  2794 	    self silentDeleteChange:(self listOfChanges at: index).
  2794 	    self silentDeleteChange:(self listOfChanges at: index).
  2795 	    numDeleted := numDeleted + 1.
  2795 	    numDeleted := numDeleted + 1.
  2796 	].
  2796 	].
  2797 	index := index - 1
  2797 	index := index - 1
  2798     ].
  2798     ].
  2802 sourceOfMethodChange:aChange
  2802 sourceOfMethodChange:aChange
  2803     "returns the source code of the method change, or nil if it is not a method change."
  2803     "returns the source code of the method change, or nil if it is not a method change."
  2804 
  2804 
  2805     |aStream chunk sawExcla parseTree sourceChunk|
  2805     |aStream chunk sawExcla parseTree sourceChunk|
  2806 
  2806 
  2807     aStream := self streamForChange:aChange. 
  2807     aStream := self streamForChange:aChange.
  2808     aStream isNil ifTrue:[^ nil].
  2808     aStream isNil ifTrue:[^ nil].
  2809 
  2809 
  2810     aChange followUp ifFalse:[
  2810     aChange followUp ifFalse:[
  2811 	sawExcla := aStream peekFor:(aStream class chunkSeparator).
  2811 	sawExcla := aStream peekFor:(aStream class chunkSeparator).
  2812 	chunk := aStream nextChunk.
  2812 	chunk := aStream nextChunk.
  2851     "just a helper, check for a selected change and evaluate aBlock
  2851     "just a helper, check for a selected change and evaluate aBlock
  2852      with busy cursor"
  2852      with busy cursor"
  2853 
  2853 
  2854     |change|
  2854     |change|
  2855 
  2855 
  2856     (change := self selectionOfChange value) notNil 
  2856     (change := self selectionOfChange value) notNil
  2857     ifTrue:[
  2857     ifTrue:[
  2858 	self withExecuteCursorDo:[aBlock value:change]
  2858 	self withExecuteCursorDo:[aBlock value:change]
  2859     ]
  2859     ]
  2860 ! !
  2860 ! !
  2861 
  2861 
  2865     "asks for saving before closing"
  2865     "asks for saving before closing"
  2866 
  2866 
  2867     self valueOfNotSaving value ifFalse: [^ self].
  2867     self valueOfNotSaving value ifFalse: [^ self].
  2868 
  2868 
  2869     modified ifTrue:[
  2869     modified ifTrue:[
  2870         (OptionBox 
  2870 	(OptionBox
  2871               request:(resources string:'Change list was modified. Exit anyway?') withCRs
  2871 	      request:(resources string:'Change list was modified. Exit anyway?') withCRs
  2872               label:'Changes Browser'
  2872 	      label:'Changes Browser'
  2873               form:(WarningBox iconBitmap)
  2873 	      form:(WarningBox iconBitmap)
  2874               buttonLabels:(resources array:#('Cancel' 'Discard Modifications and Exit'))
  2874 	      buttonLabels:(resources array:#('Cancel' 'Discard Modifications and Exit'))
  2875               values:#(abort ignore)
  2875 	      values:#(abort ignore)
  2876               default:#save
  2876 	      default:#save
  2877         ) == #abort ifTrue:[^ self].
  2877 	) == #abort ifTrue:[^ self].
  2878     ].
  2878     ].
  2879     super closeRequest
  2879     super closeRequest
  2880 
  2880 
  2881     "Modified: / 20.5.1998 / 03:53:47 / cg"
  2881     "Modified: / 20.5.1998 / 03:53:47 / cg"
  2882 !
  2882 !
  2885     "starts reading the changes from the file and
  2885     "starts reading the changes from the file and
  2886      builds entryCompletionBlock for the filterField before opening"
  2886      builds entryCompletionBlock for the filterField before opening"
  2887 
  2887 
  2888     super postOpenWith:aBuilder.
  2888     super postOpenWith:aBuilder.
  2889 
  2889 
  2890     builder namedComponents do: 
  2890     builder namedComponents do:
  2891     [:aView|    
  2891     [:aView|
  2892 	aView allSubViewsDo: 
  2892 	aView allSubViewsDo:
  2893 	[:v|
  2893 	[:v|
  2894 	    v redraw
  2894 	    v redraw
  2895 	] 
  2895 	]
  2896     ].
  2896     ].
  2897 
  2897 
  2898     autoUpdateBlock := [self checkIfFileHasChanged].
  2898     autoUpdateBlock := [self checkIfFileHasChanged].
  2899     Processor addTimedBlock:autoUpdateBlock afterSeconds:5.  
  2899     Processor addTimedBlock:autoUpdateBlock afterSeconds:5.
  2900     self updateInfoLabel.
  2900     self updateInfoLabel.
  2901 
  2901 
  2902     self filterField entryCompletionBlock:
  2902     self filterField entryCompletionBlock:
  2903     (filterCompletionBlock := [:value|
  2903     (filterCompletionBlock := [:value|
  2904 	|filter filters i changesCopy|
  2904 	|filter filters i changesCopy|
  2905 	self unselectChange.
  2905 	self unselectChange.
  2906 	filter := self filterField contents.
  2906 	filter := self filterField contents.
  2907 	(filters := filter asArrayOfSubstrings) size > 0 ifTrue: 
  2907 	(filters := filter asArrayOfSubstrings) size > 0 ifTrue:
  2908 	[
  2908 	[
  2909 	    i := 0.
  2909 	    i := 0.
  2910 	    changesCopy := changes copy.
  2910 	    changesCopy := changes copy.
  2911 	    filters do: 
  2911 	    filters do:
  2912 	    [:filter|
  2912 	    [:filter|
  2913 		i := i + 1.
  2913 		i := i + 1.
  2914 		changesCopy contents: 
  2914 		changesCopy contents:
  2915 		    (changesCopy select: [:row| 
  2915 		    (changesCopy select: [:row|
  2916 			filter match: (row string asArrayOfSubstrings at: i ifAbsent: [''''])])
  2916 			filter match: (row string asArrayOfSubstrings at: i ifAbsent: [''''])])
  2917 	    ].            
  2917 	    ].
  2918 	    self listOfChanges contents: changesCopy
  2918 	    self listOfChanges contents: changesCopy
  2919 	] 
  2919 	]
  2920 	ifFalse: 
  2920 	ifFalse:
  2921 	[
  2921 	[
  2922 	    self listOfChanges contents: changes
  2922 	    self listOfChanges contents: changes
  2923 	].
  2923 	].
  2924 	self autoSelectLast.
  2924 	self autoSelectLast.
  2925     ]).
  2925     ]).
  2991 doApplyForClassToEndFrom: start
  2991 doApplyForClassToEndFrom: start
  2992     "applies changes with same class like the selected one from start to end"
  2992     "applies changes with same class like the selected one from start to end"
  2993 
  2993 
  2994     self withSelectedChangeDo:[:change|
  2994     self withSelectedChangeDo:[:change|
  2995 	|classNameToApply thisClassName lastChange change2|
  2995 	|classNameToApply thisClassName lastChange change2|
  2996 	(classNameToApply := self classNameOfChange:change) notNil 
  2996 	(classNameToApply := self classNameOfChange:change) notNil
  2997 	ifTrue:
  2997 	ifTrue:
  2998 	[             
  2998 	[
  2999 	    self unselectChange.
  2999 	    self unselectChange.
  3000 	    skipSignal isNil ifTrue:[skipSignal := Signal new].
  3000 	    skipSignal isNil ifTrue:[skipSignal := Signal new].
  3001 	    start to:self listOfChanges size do:
  3001 	    start to:self listOfChanges size do:
  3002 	    [:changeNr|
  3002 	    [:changeNr|
  3003 		change2 := self listOfChanges at: changeNr.
  3003 		change2 := self listOfChanges at: changeNr.
  3004 		((thisClassName := self classNameOfChange:change2) notNil and:
  3004 		((thisClassName := self classNameOfChange:change2) notNil and:
  3005 		[thisClassName = classNameToApply or:
  3005 		[thisClassName = classNameToApply or:
  3006 		[PrivateAsSeparate not and: [(thisClassName upTo: $:) = classNameToApply]]])
  3006 		[PrivateAsSeparate not and: [(thisClassName upTo: $:) = classNameToApply]]])
  3007 		ifTrue:
  3007 		ifTrue:
  3008 		[                           
  3008 		[
  3009 		    self selectionOfChange value: change2.
  3009 		    self selectionOfChange value: change2.
  3010 		    self applyChange:change2.
  3010 		    self applyChange:change2.
  3011 		    lastChange := change2
  3011 		    lastChange := change2
  3012 		]
  3012 		]
  3013 	    ].
  3013 	    ].
  3044 
  3044 
  3045     |className cls isMeta|
  3045     |className cls isMeta|
  3046 
  3046 
  3047     className := self fullClassNameOfChange:self selectionOfChange value.
  3047     className := self fullClassNameOfChange:self selectionOfChange value.
  3048     className notNil ifTrue:[
  3048     className notNil ifTrue:[
  3049         isMeta := false.
  3049 	isMeta := false.
  3050         (className endsWith:' class') ifTrue:[
  3050 	(className endsWith:' class') ifTrue:[
  3051             className := className copyWithoutLast:6.
  3051 	    className := className copyWithoutLast:6.
  3052             isMeta := true.
  3052 	    isMeta := true.
  3053         ].
  3053 	].
  3054         (cls := Smalltalk classNamed:className) notNil ifTrue:[
  3054 	(cls := Smalltalk classNamed:className) notNil ifTrue:[
  3055             isMeta ifTrue:[cls := cls class].
  3055 	    isMeta ifTrue:[cls := cls class].
  3056             cls browserClass
  3056 	    cls browserClass
  3057                 openInClass:cls 
  3057 		openInClass:cls
  3058                 selector:(self selectorOfMethodChange:self selectionOfChange value)
  3058 		selector:(self selectorOfMethodChange:self selectionOfChange value)
  3059         ]
  3059 	]
  3060     ]
  3060     ]
  3061 
  3061 
  3062     "Modified: / 26.9.2001 / 17:35:50 / cg"
  3062     "Modified: / 26.9.2001 / 17:35:50 / cg"
  3063 !
  3063 !
  3064 
  3064 
  3079     |changesSizeBefore|
  3079     |changesSizeBefore|
  3080     (changesSizeBefore := changes size) == 0 ifTrue: [^self warn: 'Nothing to compress!!'].
  3080     (changesSizeBefore := changes size) == 0 ifTrue: [^self warn: 'Nothing to compress!!'].
  3081     self setChangeList.
  3081     self setChangeList.
  3082     self unselectChange.
  3082     self unselectChange.
  3083     self compressForClass:nil.
  3083     self compressForClass:nil.
  3084     self setChangeList.    
  3084     self setChangeList.
  3085     self updateInfoLabel.
  3085     self updateInfoLabel.
  3086 
  3086 
  3087     self information: 
  3087     self information:
  3088 	'Compression Rate:   ', (((changesSizeBefore - changes size)/changesSizeBefore) * 100) rounded printString, '%\' withCRs,
  3088 	'Compression Rate:   ', (((changesSizeBefore - changes size)/changesSizeBefore) * 100) rounded printString, '%\' withCRs,
  3089 	'Obsolete Changes: ', (changesSizeBefore - changes size) printString, ' from ', changesSizeBefore printString
  3089 	'Obsolete Changes: ', (changesSizeBefore - changes size) printString, ' from ', changesSizeBefore printString
  3090 
  3090 
  3091 
  3091 
  3092 
  3092 
  3153 
  3153 
  3154     self withSelectedChangeDo:[:change|
  3154     self withSelectedChangeDo:[:change|
  3155 	|classNameToDelete|
  3155 	|classNameToDelete|
  3156 	(classNameToDelete := self classNameOfChange:change) notNil ifTrue:[
  3156 	(classNameToDelete := self classNameOfChange:change) notNil ifTrue:[
  3157 	    self unselectChange.
  3157 	    self unselectChange.
  3158 	    self silentDeleteChangesFor:classNameToDelete 
  3158 	    self silentDeleteChangesFor:classNameToDelete
  3159 				   from:start
  3159 				   from:start
  3160 				     to:self listOfChanges size.
  3160 				     to:self listOfChanges size.
  3161 	    self setChangeList.
  3161 	    self setChangeList.
  3162 	    self autoSelectOrEnd: nil
  3162 	    self autoSelectOrEnd: nil
  3163 	]
  3163 	]
  3219     self listOfChanges detect: [:change| change type = 'image'] ifNone: [^self warn: 'No snapshot found!!'].
  3219     self listOfChanges detect: [:change| change type = 'image'] ifNone: [^self warn: 'No snapshot found!!'].
  3220 
  3220 
  3221     self withSelectedChangeDo:[:change|
  3221     self withSelectedChangeDo:[:change|
  3222 	snapshotNr := self listOfChanges indexOf: change.
  3222 	snapshotNr := self listOfChanges indexOf: change.
  3223 	snapshotFound := false.
  3223 	snapshotFound := false.
  3224 	[snapshotNr > 0 and: [snapshotFound not]] 
  3224 	[snapshotNr > 0 and: [snapshotFound not]]
  3225 	whileTrue: 
  3225 	whileTrue:
  3226 	[
  3226 	[
  3227 	    what = 'last'
  3227 	    what = 'last'
  3228 	    ifTrue:
  3228 	    ifTrue:
  3229 	    [
  3229 	    [
  3230 		snapshotNr := snapshotNr - 1.
  3230 		snapshotNr := snapshotNr - 1.
  3231 		snapshotNr == 0 ifTrue: [snapshotNr := self listOfChanges size].   
  3231 		snapshotNr == 0 ifTrue: [snapshotNr := self listOfChanges size].
  3232 	    ]
  3232 	    ]
  3233 	    ifFalse:
  3233 	    ifFalse:
  3234 	    [
  3234 	    [
  3235 		snapshotNr := snapshotNr + 1.
  3235 		snapshotNr := snapshotNr + 1.
  3236 		snapshotNr > self listOfChanges size ifTrue: [snapshotNr := 1].
  3236 		snapshotNr > self listOfChanges size ifTrue: [snapshotNr := 1].
  3237 	    ].
  3237 	    ].
  3238 	    (self listOfChanges at: snapshotNr ifAbsent: [^self autoSelectChange: (what = 'last' ifTrue: [self listOfChanges last] ifFalse: [self listOfChanges first])]) type = 'image'
  3238 	    (self listOfChanges at: snapshotNr ifAbsent: [^self autoSelectChange: (what = 'last' ifTrue: [self listOfChanges last] ifFalse: [self listOfChanges first])]) type = 'image'
  3239 	    ifTrue: 
  3239 	    ifTrue:
  3240 	    [
  3240 	    [
  3241 		snapshotFound := true.
  3241 		snapshotFound := true.
  3242 		self autoSelectChange:(self listOfChanges at: snapshotNr)
  3242 		self autoSelectChange:(self listOfChanges at: snapshotNr)
  3243 	    ]
  3243 	    ]
  3244 	]
  3244 	]
  3278 
  3278 
  3279 !
  3279 !
  3280 
  3280 
  3281 doSave
  3281 doSave
  3282     "write back the changes file. To avoid problems when the disk is full
  3282     "write back the changes file. To avoid problems when the disk is full
  3283      or a crash occurs while writing (well, or someone kills us), 
  3283      or a crash occurs while writing (well, or someone kills us),
  3284      first write the stuff to a new temporary file. If this works ok,
  3284      first write the stuff to a new temporary file. If this works ok,
  3285      rename the old change-file to a .bak file and finally rename the
  3285      rename the old change-file to a .bak file and finally rename the
  3286      tempfile back to the change-file. 
  3286      tempfile back to the change-file.
  3287      That way, if anything happens, either the original file is left unchanged,
  3287      That way, if anything happens, either the original file is left unchanged,
  3288      or we have at least a backup of the previous change file."
  3288      or we have at least a backup of the previous change file."
  3289 
  3289 
  3290     |inStream outStream tempfile stamp f| 
  3290     |inStream outStream tempfile stamp f|
  3291 
  3291 
  3292     self valueOfNotReading value ifFalse: [^nil].
  3292     self valueOfNotReading value ifFalse: [^nil].
  3293 
  3293 
  3294     editingClassSource ifTrue:[
  3294     editingClassSource ifTrue:[
  3295 	(self confirm:'You are editing a classes sourceFile (not a changeFile) !!\Are you certain, you want to overwrite it ?' withCRs)
  3295 	(self confirm:'You are editing a classes sourceFile (not a changeFile) !!\Are you certain, you want to overwrite it ?' withCRs)
  3322 	    self valueOfNotSaving value: false.
  3322 	    self valueOfNotSaving value: false.
  3323 
  3323 
  3324 	    excla := inStream class chunkSeparator.
  3324 	    excla := inStream class chunkSeparator.
  3325 	    nChanges := changes size.
  3325 	    nChanges := changes size.
  3326 
  3326 
  3327 	    1 to:nChanges do:[:index |     
  3327 	    1 to:nChanges do:[:index |
  3328 		inStream position: (changes at: index) position.
  3328 		inStream position: (changes at: index) position.
  3329 		sawExcla := inStream peekFor:excla.
  3329 		sawExcla := inStream peekFor:excla.
  3330 		chunk := inStream nextChunk.
  3330 		chunk := inStream nextChunk.
  3331 
  3331 
  3332 		(chunk notNil
  3332 		(chunk notNil
  3335 			outStream nextPutAll:'''---- timestamp ' , stamp , ' ----'''.
  3335 			outStream nextPutAll:'''---- timestamp ' , stamp , ' ----'''.
  3336 			outStream nextPut:excla; cr.
  3336 			outStream nextPut:excla; cr.
  3337 		    ].
  3337 		    ].
  3338 		].
  3338 		].
  3339 
  3339 
  3340 		sawExcla ifTrue:[     
  3340 		sawExcla ifTrue:[
  3341 		    outStream nextPut:excla.   
  3341 		    outStream nextPut:excla.
  3342 		    outStream nextChunkPut:chunk.
  3342 		    outStream nextChunkPut:chunk.
  3343 		    outStream cr; cr.
  3343 		    outStream cr; cr.
  3344 
  3344 
  3345 		    "
  3345 		    "
  3346 		     a method-definition chunk - skip followups
  3346 		     a method-definition chunk - skip followups
  3462     lastPosition := aValue
  3462     lastPosition := aValue
  3463 !
  3463 !
  3464 
  3464 
  3465 listColor
  3465 listColor
  3466 
  3466 
  3467     (string at: 3) ~~ $- ifTrue: 
  3467     (string at: 3) ~~ $- ifTrue:
  3468     [
  3468     [
  3469 	(self type = 'class') ifTrue: [^Color gray].
  3469 	(self type = 'class') ifTrue: [^Color gray].
  3470 	^Color white
  3470 	^Color white
  3471     ].
  3471     ].
  3472 
  3472 
  3526 ! !
  3526 ! !
  3527 
  3527 
  3528 !NewChangesBrowser class methodsFor:'documentation'!
  3528 !NewChangesBrowser class methodsFor:'documentation'!
  3529 
  3529 
  3530 version
  3530 version
  3531     ^ '$Header: /cvs/stx/stx/libtool/NewChangesBrowser.st,v 1.28 2003-12-04 11:54:00 stefan Exp $'
  3531     ^ '$Header: /cvs/stx/stx/libtool/NewChangesBrowser.st,v 1.29 2005-04-28 17:30:04 cg Exp $'
  3532 ! !
  3532 ! !