# HG changeset patch # User Claus Gittinger # Date 931188497 -7200 # Node ID f536ebd184ef4c5d305e0c83ca1cfcf23fa8ee35 # Parent 1ec72aa513c84b5d1616925ed301cb0d9332c87f initial checkin diff -r 1ec72aa513c8 -r f536ebd184ef VersionDiffBrowser.st --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/VersionDiffBrowser.st Mon Jul 05 17:28:17 1999 +0200 @@ -0,0 +1,955 @@ +ApplicationModel subclass:#VersionDiffBrowser + instanceVariableNames:'classBeingCompared versionA versionB changeSetA changeSetB + indexFromChangedToA indexFromChangedToB diffTextView' + classVariableNames:'' + poolDictionaries:'' + category:'Interface-Browsers' +! + + +!VersionDiffBrowser class methodsFor:'interface specs'! + +windowSpec + "This resource specification was automatically generated + by the UIPainter of ST/X." + + "Do not manually edit this!! If it is corrupted, + the UIPainter may not be able to read the specification." + + " + UIPainter new openOnClass:VersionDiffBrowser andSelector:#windowSpec + VersionDiffBrowser new openInterface:#windowSpec + VersionDiffBrowser open + " + + + + ^ + #(#FullSpec + #name: #windowSpec + #window: + #(#WindowSpec + #label: 'Version DiffBrowser' + #name: 'Version DiffBrowser' + #layout: #(#LayoutFrame 220 0 200 0 1084 0 703 0) + #level: 0 + #min: #(#Point 10 10) + #max: #(#Point nil nil) + #bounds: #(#Rectangle 220 200 1085 704) + #menu: #mainMenu + #usePreferredExtent: false + #returnIsOKInDialog: true + #escapeIsCancelInDialog: true + ) + #component: + #(#SpecCollection + #collection: #( + #(#VariableVerticalPanelSpec + #name: 'VariableVerticalPanel1' + #layout: #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0) + #handles: #(#Any 0.319444 1.0) + #component: + #(#SpecCollection + #collection: #( + #(#HorizontalPanelViewSpec + #name: 'TopHorizontalPanel' + #horizontalLayout: #fit + #verticalLayout: #fit + #horizontalSpace: 3 + #verticalSpace: 3 + #component: + #(#SpecCollection + #collection: #( + #(#ViewSpec + #name: 'BoxA' + #level: 0 + #component: + #(#SpecCollection + #collection: #( + #(#LabelSpec + #label: 'Only in A' + #name: 'Label1' + #layout: #(#LayoutFrame 0 0.0 0 0.0 0 1.0 20 0) + #translateLabel: true + #labelChannel: #onlyInALabelHolder + ) + #(#SequenceViewSpec + #name: 'ListA' + #layout: #(#LayoutFrame 0 0.0 20 0.0 0 1.0 -3 1.0) + #model: #methodsOnlyInASelection + #menu: #menuA + #hasHorizontalScrollBar: true + #hasVerticalScrollBar: true + #miniScrollerHorizontal: true + #valueChangeSelector: #methodsOnlyInASelectionChanged + #useIndex: true + #sequenceList: #methodsOnlyInA + ) + ) + + ) + #extent: #(#Point 286 160) + ) + #(#ViewSpec + #name: 'BoxM' + #component: + #(#SpecCollection + #collection: #( + #(#LabelSpec + #label: 'Changed' + #name: 'Label2' + #layout: #(#LayoutFrame 0 0.0 0 0.0 0 1.0 20 0) + #translateLabel: true + #labelChannel: #changedLabelHolder + ) + #(#SequenceViewSpec + #name: 'ListM' + #layout: #(#LayoutFrame 0 0.0 20 0.0 0 1.0 -3 1.0) + #model: #methodsChangedSelection + #menu: #menuM + #hasHorizontalScrollBar: true + #hasVerticalScrollBar: true + #miniScrollerHorizontal: true + #valueChangeSelector: #methodsChangedSelectionChanged + #useIndex: true + #sequenceList: #methodsChanged + ) + ) + + ) + #extent: #(#Point 286 160) + ) + #(#ViewSpec + #name: 'BoxB' + #component: + #(#SpecCollection + #collection: #( + #(#LabelSpec + #label: 'Only in B' + #name: 'Label3' + #layout: #(#LayoutFrame 0 0.0 0 0.0 0 1.0 20 0) + #translateLabel: true + #labelChannel: #onlyInBLabelHolder + ) + #(#SequenceViewSpec + #name: 'ListB' + #layout: #(#LayoutFrame 0 0.0 20 0.0 0 1.0 -3 1.0) + #model: #methodsOnlyInBSelection + #menu: #menuB + #hasHorizontalScrollBar: true + #hasVerticalScrollBar: true + #miniScrollerHorizontal: true + #valueChangeSelector: #methodsOnlyInBSelectionChanged + #useIndex: true + #sequenceList: #methodsOnlyInB + ) + ) + + ) + #extent: #(#Point 287 160) + ) + ) + + ) + ) + #(#ViewSpec + #name: 'Box4' + #component: + #(#SpecCollection + #collection: #( + #(#ViewSpec + #name: 'diffTextViewBox' + #layout: #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0) + #initiallyInvisible: true + #component: + #(#SpecCollection + #collection: #( + #(#LabelSpec + #label: 'A' + #name: 'DiffTextLabelA' + #layout: #(#LayoutFrame 0 0 0 0 0 0.5 20 0) + #translateLabel: true + #labelChannel: #diffTextLabelA + ) + #(#LabelSpec + #label: 'B' + #name: 'DiffTextLabelB' + #layout: #(#LayoutFrame 0 0.5 0 0 0 1 20 0) + #translateLabel: true + #labelChannel: #diffTextLabelB + ) + #(#ArbitraryComponentSpec + #name: 'diffTextView' + #layout: #(#LayoutFrame 0 0.0 20 0.0 0 1.0 0 1.0) + #hasBorder: false + #component: #diffTextView + ) + ) + + ) + ) + #(#TextEditorSpec + #name: 'singleTextView' + #layout: #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0) + #initiallyInvisible: true + #model: #methodText + #hasHorizontalScrollBar: true + #hasVerticalScrollBar: true + #miniScrollerHorizontal: true + ) + ) + + ) + ) + ) + + ) + ) + ) + + ) + ) +! ! + +!VersionDiffBrowser class methodsFor:'menu specs'! + +mainMenu + "This resource specification was automatically generated + by the MenuEditor of ST/X." + + "Do not manually edit this!! If it is corrupted, + the MenuEditor may not be able to read the specification." + + " + MenuEditor new openOnClass:VersionDiffBrowser andSelector:#mainMenu + (Menu new fromLiteralArrayEncoding:(VersionDiffBrowser mainMenu)) startUp + " + + + + ^ + #(#Menu + #( + #(#MenuItem + #label: 'File' + #translateLabel: true + #submenu: + #(#Menu + #( + #(#MenuItem + #label: 'Exit' + #translateLabel: true + #value: #closeRequest + ) + ) + nil + nil + ) + ) + #(#MenuItem + #label: 'Help' + #translateLabel: true + #startGroup: #right + #submenu: + #(#Menu + #( + #(#MenuItem + #label: 'Documentation' + #translateLabel: true + #value: #openDocumentation + ) + #(#MenuItem + #label: '-' + ) + #(#MenuItem + #label: 'About this Application' + #translateLabel: true + #value: #openAboutThisApplication + ) + ) + nil + nil + ) + ) + ) + nil + nil + ) +! + +menuA + "This resource specification was automatically generated + by the MenuEditor of ST/X." + + "Do not manually edit this!! If it is corrupted, + the MenuEditor may not be able to read the specification." + + " + MenuEditor new openOnClass:VersionDiffBrowser andSelector:#menu1 + (Menu new fromLiteralArrayEncoding:(VersionDiffBrowser menu1)) startUp + " + + + + ^ + #(#Menu + #( + #(#MenuItem + #label: 'Inspect' + #translateLabel: true + #value: #inspectSelectedChangeInA + #choiceValue: 'nil "UndefinedObject" ' + ) + ) + nil + nil + ) +! + +menuB + "This resource specification was automatically generated + by the MenuEditor of ST/X." + + "Do not manually edit this!! If it is corrupted, + the MenuEditor may not be able to read the specification." + + " + MenuEditor new openOnClass:VersionDiffBrowser andSelector:#menuB + (Menu new fromLiteralArrayEncoding:(VersionDiffBrowser menuB)) startUp + " + + + + ^ + #(#Menu + #( + #(#MenuItem + #label: 'Inspect' + #translateLabel: true + #value: #inspectSelectedChangeInB + #choiceValue: 'nil "UndefinedObject" ' + ) + ) + nil + nil + ) +! + +menuM + "This resource specification was automatically generated + by the MenuEditor of ST/X." + + "Do not manually edit this!! If it is corrupted, + the MenuEditor may not be able to read the specification." + + " + MenuEditor new openOnClass:VersionDiffBrowser andSelector:#menu1 + (Menu new fromLiteralArrayEncoding:(VersionDiffBrowser menu1)) startUp + " + + + + ^ + #(#Menu + #( + #(#MenuItem + #label: 'Inspect' + #translateLabel: true + #value: #inspectSelectedChangeInM + #choiceValue: 'nil "UndefinedObject" ' + ) + ) + nil + nil + ) +! ! + +!VersionDiffBrowser class methodsFor:'startup'! + +openOnClass:aClass versionA:vsnA versionB:vsnB + |browser| + + browser := self new. + browser allButOpen. + + browser classBeingCompared:aClass. + browser versionA:vsnA. + browser versionB:vsnB. + + browser openWindow. + + ^ browser. + + " + self openOnClass:Array versionA:'1.116' versionB:'1.113' + " +! ! + +!VersionDiffBrowser methodsFor:'accessing'! + +classBeingCompared + "return the value of the instance variable 'classBeingCompared' (automatically generated)" + + ^ classBeingCompared! + +classBeingCompared:something + "set the value of the instance variable 'classBeingCompared' (automatically generated)" + + classBeingCompared := something. + self updateViewsIfPossible. +! + +versionA + "return the value of the instance variable 'versionA' (automatically generated)" + + ^ versionA! + +versionA:something + "set the value of the instance variable 'versionA' (automatically generated)" + + versionA := something. + self updateViewsIfPossible. + +! + +versionB + "return the value of the instance variable 'versionB' (automatically generated)" + + ^ versionB! + +versionB:something + "set the value of the instance variable 'versionB' (automatically generated)" + + versionB := something. + self updateViewsIfPossible. + +! ! + +!VersionDiffBrowser methodsFor:'actions'! + +methodsChangedSelectionChanged + |sel idxA idxB changeA changeB| + + sel := self methodsChangedSelection value. + sel notNil ifTrue:[ + self methodsOnlyInASelection value:nil. + self methodsOnlyInBSelection value:nil. + + idxA := indexFromChangedToA at:sel ifAbsent:nil. + idxB := indexFromChangedToB at:sel ifAbsent:nil. + + changeA := changeSetA at:idxA. + changeB := changeSetB at:idxB. + + self diffTextView text1:changeA source text2:changeB source. + self diffTextView moveToNextChanged. + + self showDiffTextView. + + ] +! + +methodsOnlyInASelectionChanged + |change sel| + + sel := self methodsOnlyInASelection value. + sel notNil ifTrue:[ + self methodsOnlyInBSelection value:nil. + self methodsChangedSelection value:nil. + + change := changeSetA at:sel. + self methodText value:(change source). + self showSingleTextView. + ] +! + +methodsOnlyInBSelectionChanged + |change sel| + + sel := self methodsOnlyInBSelection value. + sel notNil ifTrue:[ + self methodsOnlyInASelection value:nil. + self methodsChangedSelection value:nil. + + change := changeSetB at:sel. + self methodText value:(change source). + self showSingleTextView. + ] +! ! + +!VersionDiffBrowser methodsFor:'aspects'! + +changedLabelHolder + "automatically generated by UIPainter ..." + + "*** the code below creates a default model when invoked." + "*** (which may not be the one you wanted)" + "*** Please change as required and accept in the browser." + + |holder| + + (holder := builder bindingAt:#changedLabelHolder) isNil ifTrue:[ + builder aspectAt:#changedLabelHolder put:(holder := ValueHolder new). + ]. + ^ holder. +! + +diffTextLabelA + "automatically generated by UIPainter ..." + + "*** the code below creates a default model when invoked." + "*** (which may not be the one you wanted)" + "*** Please change as required and accept in the browser." + + |holder| + + (holder := builder bindingAt:#diffTextLabelA) isNil ifTrue:[ + builder aspectAt:#diffTextLabelA put:(holder := ValueHolder new). + ]. + ^ holder. +! + +diffTextLabelB + "automatically generated by UIPainter ..." + + "*** the code below creates a default model when invoked." + "*** (which may not be the one you wanted)" + "*** Please change as required and accept in the browser." + + |holder| + + (holder := builder bindingAt:#diffTextLabelB) isNil ifTrue:[ + builder aspectAt:#diffTextLabelB put:(holder := ValueHolder new). + ]. + ^ holder. +! + +methodText + "automatically generated by UIPainter ..." + + "*** the code below creates a default model when invoked." + "*** (which may not be the one you wanted)" + "*** Please change as required and accept in the browser." + + |holder| + + (holder := builder bindingAt:#methodText) isNil ifTrue:[ + builder aspectAt:#methodText put:(holder := ValueHolder new). + ]. + ^ holder. +! + +methodsChanged + "automatically generated by UIPainter ..." + + "*** the code below creates a default model when invoked." + "*** (which may not be the one you wanted)" + "*** Please change as required and accept in the browser." + + |holder| + + (holder := builder bindingAt:#methodsChanged) isNil ifTrue:[ + builder aspectAt:#methodsChanged put:(holder := List new). + ]. + ^ holder. +! + +methodsChangedSelection + "automatically generated by UIPainter ..." + + "*** the code below creates a default model when invoked." + "*** (which may not be the one you wanted)" + "*** Please change as required and accept in the browser." + + |holder| + + (holder := builder bindingAt:#methodsChangedSelection) isNil ifTrue:[ + builder aspectAt:#methodsChangedSelection put:(holder := ValueHolder new). + ]. + ^ holder. +! + +methodsOnlyInA + "automatically generated by UIPainter ..." + + "*** the code below creates a default model when invoked." + "*** (which may not be the one you wanted)" + "*** Please change as required and accept in the browser." + + |holder| + + (holder := builder bindingAt:#methodsOnlyInA) isNil ifTrue:[ + builder aspectAt:#methodsOnlyInA put:(holder := List new). + ]. + ^ holder. +! + +methodsOnlyInASelection + "automatically generated by UIPainter ..." + + "*** the code below creates a default model when invoked." + "*** (which may not be the one you wanted)" + "*** Please change as required and accept in the browser." + + |holder| + + (holder := builder bindingAt:#methodsOnlyInASelection) isNil ifTrue:[ + builder aspectAt:#methodsOnlyInASelection put:(holder := ValueHolder new). + ]. + ^ holder. +! + +methodsOnlyInB + "automatically generated by UIPainter ..." + + "*** the code below creates a default model when invoked." + "*** (which may not be the one you wanted)" + "*** Please change as required and accept in the browser." + + |holder| + + (holder := builder bindingAt:#methodsOnlyInB) isNil ifTrue:[ + builder aspectAt:#methodsOnlyInB put:(holder := List new). + ]. + ^ holder. +! + +methodsOnlyInBSelection + "automatically generated by UIPainter ..." + + "*** the code below creates a default model when invoked." + "*** (which may not be the one you wanted)" + "*** Please change as required and accept in the browser." + + |holder| + + (holder := builder bindingAt:#methodsOnlyInBSelection) isNil ifTrue:[ + builder aspectAt:#methodsOnlyInBSelection put:(holder := ValueHolder new). + ]. + ^ holder. +! + +onlyInALabelHolder + "automatically generated by UIPainter ..." + + "*** the code below creates a default model when invoked." + "*** (which may not be the one you wanted)" + "*** Please change as required and accept in the browser." + + |holder| + + (holder := builder bindingAt:#onlyInALabelHolder) isNil ifTrue:[ + builder aspectAt:#onlyInALabelHolder put:(holder := ValueHolder new). + ]. + ^ holder. +! + +onlyInBLabelHolder + "automatically generated by UIPainter ..." + + "*** the code below creates a default model when invoked." + "*** (which may not be the one you wanted)" + "*** Please change as required and accept in the browser." + + |holder| + + (holder := builder bindingAt:#onlyInBLabelHolder) isNil ifTrue:[ + builder aspectAt:#onlyInBLabelHolder put:(holder := ValueHolder new). + ]. + ^ holder. +! ! + +!VersionDiffBrowser methodsFor:'initialization & release'! + +closeDownViews + "This is a hook method generated by the Browser. + It will be invoked when your app/dialog-window is really closed." + + "/ change the code below as required ... + "/ This should cleanup any leftover resources + "/ (for example, temporary files) + "/ super closeRequest will initiate the closeDown + + "/ add your code here + + "/ do not remove the one below ... + ^ super closeDownViews +! + +closeRequest + "This is a hook method generated by the Browser. + It will be invoked when your app/dialog-window is about to be + closed (and has a chance to suppress the close)." + + "/ change the code below as required ... + "/ Closing can be suppressed, by returning. + "/ super closeRequest will initiate the closeDown + + ^ super closeRequest +! + +postBuildWith:aBuilder + "This is a hook method generated by the Browser. + It will be invoked during the initialization of your app/dialog, + after all of the visual components have been built, + but BEFORE the top window is made visible. + Add any app-specific actions here (reading files, setting up + values etc.)" + + "/ add any code here ... + + (aBuilder componentAt:#TopHorizontalPanel) ignoreInvisibleComponents:true. + + ^ super postBuildWith:aBuilder +! ! + +!VersionDiffBrowser methodsFor:'menu action'! + +inspectSelectedChangeInA + |sel| + + sel := self methodsOnlyInASelection value. + sel notNil ifTrue:[ + (changeSetA at:sel) inspect + ] +! + +inspectSelectedChangeInB + |sel| + + sel := self methodsOnlyInBSelection value. + sel notNil ifTrue:[ + (changeSetB at:sel) inspect + ] +! + +inspectSelectedChangeInM + |sel idxA idxB| + + sel := self methodsChangedSelection value. + sel notNil ifTrue:[ + idxA := indexFromChangedToA at:sel ifAbsent:nil. + idxB := indexFromChangedToB at:sel ifAbsent:nil. + + (changeSetA at:idxA) inspect. + (changeSetB at:idxB) inspect. + ] +! ! + +!VersionDiffBrowser methodsFor:'private'! + +change:changeA isForSameMethodAs:changeB + "return true, if the two given changes are for the same method. + Ought to go to changeSet class" + + changeA isMethodChange ifFalse:[^ false]. "/ for now + changeB isMethodChange ifFalse:[^ false]. "/ for now + + changeA className ~= changeB className ifTrue:[^ false]. + changeA selector ~= changeB selector ifTrue:[^ false]. + ^ true. +! + +change:changeA isSameAs:changeB + "return true, if the two given changes are the same. + Ought to go to changeSet class" + + |sourceA sourceB| + + changeA isMethodChange ifFalse:[ + "/ A is not a methodChange - B must not be as well. + changeB isMethodChange ifTrue:[^ false]. + + changeA isClassDefinitionChange ifTrue:[ + changeB isClassDefinitionChange ifFalse:[^ false]. + + changeA className ~= changeB className ifTrue:[^ false]. + changeA source = changeB source ifTrue:[^ true]. + self halt. + ]. + + ^ false "/ for now + ]. + + "/ A is a methodChange - B must be as well. + changeB isMethodChange ifFalse:[^ false]. + + changeA className ~= changeB className ifTrue:[^ false]. + changeA selector ~= changeB selector ifTrue:[^ false]. + + (sourceA := changeA source) = (sourceB := changeB source) ifTrue:[^ true]. + + sourceA := sourceA asCollectionOfLines. + sourceB := sourceB asCollectionOfLines. + sourceA size ~~ sourceB size ifTrue:[^ false]. + sourceA := sourceA collect:[:line | line withTabsExpanded withoutTrailingSeparators]. + sourceB := sourceB collect:[:line | line withTabsExpanded withoutTrailingSeparators]. + sourceA = sourceB ifFalse:[^ false]. + ^ true. +! + +showDiffTextView + (self builder componentAt:#diffTextViewBox) raise; beVisible. + (self builder componentAt:#singleTextView) beInvisible. + (self builder componentAt:#diffTextView) realizeAllSubViews. +! + +showSingleTextView + (self builder componentAt:#singleTextView) raise; beVisible. + (self builder componentAt:#diffTextViewBox) beInvisible. + +! + +updateViews + |mgr versionAStream versionBStream versionAChangeSet versionBChangeSet + allFromA filteredChangeSetA filteredChangeSetB changedMethodsChangeSet + listA listB listM| + + mgr := classBeingCompared sourceCodeManager. + + versionAStream := mgr getSourceStreamFor:classBeingCompared revision:versionA. + changeSetA := ChangeSet fromStream:versionAStream. + versionAStream close. + + versionBStream := mgr getSourceStreamFor:classBeingCompared revision:versionB. + changeSetB := ChangeSet fromStream:versionBStream. + versionBStream close. + + filteredChangeSetA := ChangeSet new. + filteredChangeSetB := ChangeSet new. + changedMethodsChangeSet := ChangeSet new. + + indexFromChangedToA := OrderedCollection new. + indexFromChangedToB := OrderedCollection new. + + changeSetA keysAndValuesDo:[:idxA :aChangeInA | + |anyFound| + + anyFound := false. + + changeSetB do:[:aChangeInB | + (self change:aChangeInA isForSameMethodAs:aChangeInB) ifTrue:[ + anyFound := true. + + "/ also in B - is it different ? + (self change:aChangeInA isSameAs:aChangeInB) ifFalse:[ + changedMethodsChangeSet add:aChangeInA. + indexFromChangedToA add:idxA. + indexFromChangedToB add:nil. + ] + ] ifFalse:[ + (self change:aChangeInA isSameAs:aChangeInB) ifTrue:[ + anyFound := true. + ] + ] + ]. + + anyFound ifFalse:[ + filteredChangeSetA add:aChangeInA. + ] + ]. + + changeSetB keysAndValuesDo:[:idxB :aChangeInB | + |anyFound| + + anyFound := false. + + changeSetA do:[:aChangeInA | + |idxM| + + (self change:aChangeInA isForSameMethodAs:aChangeInB) ifTrue:[ + anyFound := true. + + "/ also in B - is it different ? + (self change:aChangeInA isSameAs:aChangeInB) ifFalse:[ + "/ already there ? + idxM := changedMethodsChangeSet findFirst:[:c | self change:c isForSameMethodAs:aChangeInB]. + idxM == 0 ifTrue:[ + changedMethodsChangeSet add:aChangeInB. + indexFromChangedToB add:idxB. + ] ifFalse:[ + indexFromChangedToB at:idxM put:idxB + ] + ] + ] ifFalse:[ + (self change:aChangeInA isSameAs:aChangeInB) ifTrue:[ + anyFound := true. + ] + ] + ]. + anyFound ifFalse:[ + filteredChangeSetB add:aChangeInB. + ] + ]. + + listA := self methodsOnlyInA. + listA removeAll. + listA addAll:(filteredChangeSetA collect:[:c | c printString]). + + listB := self methodsOnlyInB. + listB removeAll. + listB addAll:(filteredChangeSetB collect:[:c | c printString]). + + listM := self methodsChanged. + listM removeAll. + listM addAll:(changedMethodsChangeSet collect:[:c | c printString]). + + + listA isEmpty ifTrue:[ + (self builder componentAt:#BoxA) beInvisible. + ] ifFalse:[ + (self builder componentAt:#BoxA) beVisible. + ]. + + listB isEmpty ifTrue:[ + (self builder componentAt:#BoxB) beInvisible. + ] ifFalse:[ + (self builder componentAt:#BoxB) beVisible. + ]. + + listM isEmpty ifTrue:[ + (listA notEmpty or:[listB notEmpty]) ifTrue:[ + (self builder componentAt:#BoxM) beInvisible. + ] + ] ifFalse:[ + (self builder componentAt:#BoxM) beVisible. + ] + +! + +updateViewsIfPossible + classBeingCompared notNil ifTrue:[ + self window label:'Version Diff Browser on ' , classBeingCompared name. + versionA notNil ifTrue:[ + self diffTextLabelA value:versionA. + self onlyInALabelHolder value:'Only in ' , versionA. + versionB notNil ifTrue:[ + self diffTextLabelB value:versionB. + self onlyInBLabelHolder value:'Only in ' , versionB. + self updateViews + ] + ] + ] + + +! ! + +!VersionDiffBrowser methodsFor:'values'! + +diffTextView + "automatically generated by UIPainter ..." + + diffTextView isNil ifTrue:[ + diffTextView := HVScrollableView + for:DiffTextView + miniScrollerH:true miniScrollerV:false. + diffTextView addNextPreviousButtons. + ]. + ^ diffTextView +! ! + +!VersionDiffBrowser class methodsFor:'documentation'! + +version + ^ '$Header: /cvs/stx/stx/libtool/VersionDiffBrowser.st,v 1.1 1999-07-05 15:28:17 cg Exp $' +! !