'From Cuis 2.0 of 4 January 2010 [latest update: #393] on 11 February 2010 at 10:13:08 am'!

!CodeHolder methodsFor: 'controls' stamp: 'jmv 2/11/2010 10:04'!
contentsSymbolQuints
	"Answer a list of quintuplets representing information on the alternative views available in the code pane
		first element:	the contentsSymbol used
		second element:	the selector to call when this item is chosen.
		third element:	the selector to call to obtain the wording of the menu item.
		fourth element:	the wording to represent this view
		fifth element:	balloon help
	A hypen indicates a need for a seperator line in a menu of such choices"

	^ #(
(source			togglePlainSource 			showingPlainSourceString
														'source'			'the textual source code as writen')
(documentation	toggleShowDocumentation showingDocumentationString
														'documentation'	'the first comment in the method')
-
(prettyPrint		togglePrettyPrint 			prettyPrintString
														'prettyPrint'			'the method source presented in a standard text format')
-
(showDiffs		toggleRegularDiffing		showingRegularDiffsString
														'lineDiffs'			'the textual source lines diffed from its prior version')
(showDiffs2		toggleRegularDiffing2		showingRegularDiffsString2
														'wordDiffs'			'the textual source words diffed from its prior version')
(prettyDiffs		togglePrettyDiffing			showingPrettyDiffsString
														'linePrettyDiffs'		'formatted source lines diffed from formatted prior version')
(prettyDiffs2		togglePrettyDiffing2		showingPrettyDiffsString2
														'wordPrettyDiffs'	'formatted source words diffed from prior version')
-
(decompile		toggleDecompile			showingDecompileString
														'decompile'			'source code decompiled from byteCodes')
(byteCodes		toggleShowingByteCodes	showingByteCodesString
														'byteCodes'		'the bytecodes that comprise the compiled method')
	)! !

!CodeHolder methodsFor: 'controls' stamp: 'jmv 2/11/2010 10:05'!
sourceAndDiffsQuintsOnly
	"Answer a list of quintuplets representing information on the alternative views available in the code pane for the case where the only plausible choices are showing source or either of the two kinds of diffs"

	^ #(
(source			togglePlainSource 			showingPlainSourceString
														'source'			'the textual source code as writen')
(showDiffs		toggleRegularDiffing		showingRegularDiffsString
														'lineDiffs'			'the textual source diffed from its prior version')
(showDiffs2		toggleRegularDiffing2		showingRegularDiffsString2
														'wordDiffs'			'the textual source words diffed from its prior version')
(prettyDiffs		togglePrettyDiffing			showingPrettyDiffsString
														'linePrettyDiffs'		'formatted source diffed from formatted prior version')
(prettyDiffs2		togglePrettyDiffing2		showingPrettyDiffsString2
														'linePrettyDiffs'		'formatted source words diffed from prior version')
	)! !

!CodeHolder methodsFor: 'diffs' stamp: 'jmv 2/8/2010 11:08'!
diffFromPriorSourceFor: sourceCode 
	"If there is a prior version of source for the selected method, return a diff, else just return the source code"

	^ self priorSourceOrNil
		ifNil: [sourceCode]
		ifNotNil: [ :prior |
			(self shouldUseAlternativeDiffer
				ifTrue: [ DifferenceFinder ]
				ifFalse: [ TextDiffBuilder ])
					buildDisplayPatchFrom: prior 
					to: sourceCode inClass: self selectedClass 
					prettyDiffs: self showingAnyKindOfPrettyDiffs ]! !

!CodeHolder methodsFor: 'diffs' stamp: 'jmv 2/11/2010 09:59'!
prettyDiffButton
	"Return a checkbox that lets the user decide whether prettyDiffs should be shown or not"

	|  outerButton button |
	outerButton _ AlignmentMorph proportional.
	outerButton borderWidth: 2; borderColor: #raised.
	outerButton color:  Color transparent.
	button _ UpdatingThreePhaseButtonMorph checkBox.
	button
		target: self;
		actionSelector: #togglePrettyDiffing;
		getSelector: #showingPrettyDiffs.
	outerButton 
		addMorph: button
			fullFrame: (LayoutFrame fractions: (0@0 corner: 0@1) offsets: (2@3 corner: 18@0));
		addMorph: (StringMorph contents: 'linePrettyDiffs') lock
			fullFrame: (LayoutFrame fractions: (0@0 corner: 1@1) offsets: (18@2 corner: 0@0)).
	(self isKindOf: VersionsBrowser)
		ifTrue:
			[outerButton setBalloonText: 'If checked, then pretty-printed code differences from the previous version, if any, will be shown.']
		ifFalse:
			[outerButton setBalloonText: 'If checked, then pretty-printed code differences between the file-based method and the in-memory version, if any, will be shown.'].

	^ outerButton
! !

!CodeHolder methodsFor: 'diffs' stamp: 'jmv 2/11/2010 10:00'!
prettyDiffButton2
	"Return a checkbox that lets the user decide whether prettyDiffs should be shown or not"

	|  outerButton button |
	outerButton _ AlignmentMorph proportional.
	outerButton borderWidth: 2; borderColor: #raised.
	outerButton color:  Color transparent.
	button _ UpdatingThreePhaseButtonMorph checkBox.
	button
		target: self;
		actionSelector: #togglePrettyDiffing2;
		getSelector: #showingPrettyDiffs2.
	outerButton 
		addMorph: button
			fullFrame: (LayoutFrame fractions: (0@0 corner: 0@1) offsets: (2@3 corner: 18@0));
		addMorph: (StringMorph contents: 'wordPrettyDiffs') lock
			fullFrame: (LayoutFrame fractions: (0@0 corner: 1@1) offsets: (18@2 corner: 0@0)).
	(self isKindOf: VersionsBrowser)
		ifTrue:
			[outerButton setBalloonText: 'If checked, then pretty-printed code differences (better algorithm) from the previous version, if any, will be shown.']
		ifFalse:
			[outerButton setBalloonText: 'If checked, then pretty-printed code differences (better algorithm) between the file-based method and the in-memory version, if any, will be shown.'].

	^ outerButton
! !

!CodeHolder methodsFor: 'diffs' stamp: 'jmv 2/11/2010 09:59'!
regularDiffButton
	"Return a checkbox that lets the user decide whether regular diffs should be shown or not"

	|  outerButton button |
	outerButton _ AlignmentMorph proportional.
	outerButton borderWidth: 2; borderColor: #raised.
	outerButton color:  Color transparent.
	button _ UpdatingThreePhaseButtonMorph checkBox.
	button
		target: self;
		actionSelector: #toggleRegularDiffing;
		getSelector: #showingRegularDiffs.
	outerButton 
		addMorph: button
			fullFrame: (LayoutFrame fractions: (0@0 corner: 0@1) offsets: (2@3 corner: 18@0));
		addMorph: (StringMorph contents: 'lineDiffs') lock
			fullFrame: (LayoutFrame fractions: (0@0 corner: 1@1) offsets: (18@2 corner: 0@0)).
	outerButton setBalloonText: 'If checked, then code differences from the previous version, if any, will be shown.'.

	^ outerButton
! !

!CodeHolder methodsFor: 'diffs' stamp: 'jmv 2/11/2010 09:59'!
regularDiffButton2
	"Return a checkbox that lets the user decide whether regular diffs should be shown or not"

	|  outerButton button |
	outerButton _ AlignmentMorph proportional.
	outerButton borderWidth: 2; borderColor: #raised.
	outerButton color:  Color transparent.
	button _ UpdatingThreePhaseButtonMorph checkBox.
	button
		target: self;
		actionSelector: #toggleRegularDiffing2;
		getSelector: #showingRegularDiffs2.
	outerButton 
		addMorph: button
			fullFrame: (LayoutFrame fractions: (0@0 corner: 0@1) offsets: (2@3 corner: 18@0));
		addMorph: (StringMorph contents: 'wordDiffs') lock
			fullFrame: (LayoutFrame fractions: (0@0 corner: 1@1) offsets: (18@2 corner: 0@0)).
	outerButton setBalloonText: 'If checked, then code differences (better algorithm) from the previous version, if any, will be shown.'.

	^ outerButton
! !

!CodeHolder methodsFor: 'diffs' stamp: 'jmv 2/8/2010 11:06'!
shouldUseAlternativeDiffer
	"Answer whether the receiver is currently set to use the alternative (slower but better) differ"

	^ #(showDiffs2 prettyDiffs2) includes: contentsSymbol! !

!CodeHolder methodsFor: 'diffs' stamp: 'jmv 2/8/2010 11:29'!
showPrettyDiffs2: aBoolean
	"Set whether I'm showing pretty diffs as indicated"

	self showingPrettyDiffs2
		ifFalse: [
			aBoolean ifTrue: [
				contentsSymbol _ #prettyDiffs2]]
		ifTrue: [
			aBoolean ifFalse: [
				contentsSymbol _ #source]].
	self setContentsToForceRefetch.
	self contentsChanged! !

!CodeHolder methodsFor: 'diffs' stamp: 'jmv 2/8/2010 10:50'!
showRegularDiffs2: aBoolean
	"Set whether I'm showing regular diffs as indicated"

	self showingRegularDiffs2
		ifFalse: [
			aBoolean ifTrue: [
				contentsSymbol _ #showDiffs2]]
		ifTrue: [
			aBoolean ifFalse: [
				contentsSymbol _ #source]].
	self setContentsToForceRefetch.
	self contentsChanged! !

!CodeHolder methodsFor: 'diffs' stamp: 'jmv 2/8/2010 10:54'!
showingAnyKindOfDiffs
	"Answer whether the receiver is currently set to show any kind of diffs"

	^ #(showDiffs prettyDiffs showDiffs2 prettyDiffs2) includes: contentsSymbol! !

!CodeHolder methodsFor: 'diffs' stamp: 'jmv 2/8/2010 11:08'!
showingAnyKindOfPrettyDiffs
	"Answer whether the receiver is currently set to show any kind of pretty diffs"

	^ #(prettyDiffs prettyDiffs2) includes: contentsSymbol! !

!CodeHolder methodsFor: 'diffs' stamp: 'jmv 2/8/2010 10:52'!
showingPrettyDiffs2
	"Answer whether the receiver is showing pretty diffs of source code"

	^ contentsSymbol == #prettyDiffs2
! !

!CodeHolder methodsFor: 'diffs' stamp: 'jmv 2/11/2010 10:00'!
showingPrettyDiffsString
	"Answer a string representing whether I'm showing pretty diffs"

	^ (self showingPrettyDiffs
		ifTrue:
			['<yes>']
		ifFalse:
			['<no>']), 'linePrettyDiffs'! !

!CodeHolder methodsFor: 'diffs' stamp: 'jmv 2/11/2010 10:00'!
showingPrettyDiffsString2
	"Answer a string representing whether I'm showing pretty diffs"

	^ (self showingPrettyDiffs2
		ifTrue:
			['<yes>']
		ifFalse:
			['<no>']), 'wordPrettyDiffs'! !

!CodeHolder methodsFor: 'diffs' stamp: 'jmv 2/8/2010 10:49'!
showingRegularDiffs2
	"Answer whether the receiver is showing regular diffs (alternative algorithm) of source code"

	^ contentsSymbol == #showDiffs2
! !

!CodeHolder methodsFor: 'diffs' stamp: 'jmv 2/11/2010 10:01'!
showingRegularDiffsString
	"Answer a string representing whether I'm showing regular diffs"

	^ (self showingRegularDiffs
		ifTrue:
			['<yes>']
		ifFalse:
			['<no>']), 'lineDiffs'! !

!CodeHolder methodsFor: 'diffs' stamp: 'jmv 2/11/2010 10:01'!
showingRegularDiffsString2
	"Answer a string representing whether I'm showing regular diffs"

	^ (self showingRegularDiffs2
		ifTrue:
			['<yes>']
		ifFalse:
			['<no>']), 'wordDiffs'! !

!CodeHolder methodsFor: 'diffs' stamp: 'jmv 2/8/2010 10:52'!
togglePrettyDiffing2
	"Toggle whether pretty-diffing should be shown in the code pane"

	| wasShowingDiffs |
	self okToChange ifTrue: [
		wasShowingDiffs _ self showingPrettyDiffs2.
		self showPrettyDiffs2: wasShowingDiffs not.
		self setContentsToForceRefetch.
		self contentsChanged]

! !

!CodeHolder methodsFor: 'diffs' stamp: 'jmv 2/8/2010 10:49'!
toggleRegularDiffing2
	"Toggle whether regular-diffing should be shown in the code pane"

	| wasShowingDiffs |
	self okToChange ifTrue: [
		wasShowingDiffs _ self showingRegularDiffs2.
		self showRegularDiffs2: wasShowingDiffs not.
		self setContentsToForceRefetch.
		self contentsChanged]

! !

!CodeHolder methodsFor: 'message list' stamp: 'jmv 2/8/2010 11:05'!
sourceStringPrettifiedAndDiffed
	"Answer a copy of the source code for the selected message, transformed by diffing and pretty-printing exigencies"

	| class selector sourceString |
	class _ self selectedClassOrMetaClass.
	selector _ self selectedMessageName.
	(class isNil or: [selector isNil]) ifTrue: [^ 'missing'].

	sourceString _ class ultimateSourceCodeAt: selector ifAbsent: [^ 'error'].
	self validateMessageSource: sourceString forSelector: selector.

	(#(prettyPrint prettyDiffs prettyDiffs2) includes: contentsSymbol) ifTrue: [
		sourceString _ class compilerClass new
						format: sourceString 
						in: class 
						notifying: nil].
	self showingAnyKindOfDiffs ifTrue:
		[sourceString _ self diffFromPriorSourceFor: sourceString].

	^ sourceString! !


!ChangeList methodsFor: 'menu actions' stamp: 'jmv 2/11/2010 09:56'!
compareToCurrentVersion
	"If the current selection corresponds to a method in the system, then spawn a window showing the diffs as text"

	| change class s1 s2 differ differDesc |
	listIndex = 0
		ifTrue: [^ self].
	change _ changeList at: listIndex.
	((class _ change methodClass) notNil
			and: [class includesSelector: change methodSelector])
		ifTrue: [
			s1 _ (class sourceCodeAt: change methodSelector) asString.
			s2 _ change string.
			s1 = s2
				ifTrue: [^ self inform: 'Exact Match'].
			self shouldUseAlternativeDiffer
				ifTrue: [
					differ _ DifferenceFinder.
					differDesc _ 'Words']
				ifFalse: [
					differ _ TextDiffBuilder.
					differDesc _ 'Lines'].
			(StringHolder new
				textContents: (
					(differ
						buildDisplayPatchFrom: s1 to: s2 inClass: class  prettyDiffs: self showingAnyKindOfPrettyDiffs)
							initialFont: Preferences standardCodeFont))
				openLabel: 'Comparison to Current Version: ', differDesc, 
					(self showingAnyKindOfPrettyDiffs ifTrue: [', using prettyPrint'] ifFalse: [''])]
		ifFalse: [self flash]! !

!ChangeList methodsFor: 'menu actions' stamp: 'jmv 2/11/2010 10:12'!
optionalButtonRow
	"Answer a row of buttons to occur in a tool pane"

	| row button buttons widths |
	buttons _ OrderedCollection new.
	widths _ OrderedCollection new.
	self buttonSpecs do: [ :tuple | 
		widths add: tuple first.
		button _ PluggableButtonMorph 
					model: self
					stateGetter: nil
					action: tuple third.
		button
			label: tuple second asString;
			askBeforeChanging: true.
		buttons add: button.
		button setBalloonText: tuple fourth].
	buttons add: self regularDiffButton.
	widths add: 14.
	buttons add: self regularDiffButton2.
	widths add: 16.
	self wantsPrettyDiffOption ifTrue: [
		buttons add:  self prettyDiffButton.
		widths add: 21.
		buttons add:  self prettyDiffButton2.
		widths add: 23 ].
	row _ AlignmentMorph proportional.
	row addInRow: buttons widthProportionalTo: widths.
	^row! !

!ChangeList methodsFor: 'viewing access' stamp: 'jmv 2/8/2010 13:18'!
contentsDiffedFromCurrent
	"Answer the contents diffed forward from current (in-memory) method version"

	|  aChange aClass  name aSelector |
	listIndex = 0
		ifTrue: [^ ''].
	aChange _ changeList at: listIndex.
	((aChange type == #method 
			and: [(aClass _ aChange methodClass) notNil]) 
			and: [aClass includesSelector: aChange methodSelector]) ifTrue: [
		aSelector _ aChange methodSelector.
		(aClass notNil and: [aClass includesSelector: aSelector])
			ifFalse: [ ^aChange text copy ].
		^(self shouldUseAlternativeDiffer
				ifTrue: [ DifferenceFinder ]
				ifFalse: [ TextDiffBuilder ])
				buildDisplayPatchFrom: (aClass sourceCodeAt: aSelector)
				to: aChange text
				inClass: aClass
				prettyDiffs: self showingAnyKindOfPrettyDiffs ].
	(aChange type == #classDefinition and: [
			name _ aChange methodClassName.
			Smalltalk includesKey: name]) ifTrue: [
		aClass _ Smalltalk at: name.
		aChange isMetaClassChange ifTrue: [ aClass _ aClass class ].
		^(self shouldUseAlternativeDiffer
			ifTrue: [ DifferenceFinder ]
			ifFalse: [ TextDiffBuilder ])
				buildDisplayPatchFrom: aClass definition to: aChange text].
	^(changeList at: listIndex) text! !

!ChangeList methodsFor: 'viewing access' stamp: 'jmv 2/8/2010 14:21'!
diffedVersionContents
	"Answer diffed version contents, maybe pretty maybe not"

	| change class earlier later |
	(listIndex = 0
			or: [changeList size < listIndex])
		ifTrue: [^ ''].
	change _ changeList at: listIndex.
	later _ change text.
	class _ change methodClass.
	(listIndex = changeList size or: [class == nil])
		ifTrue: [^ later].

	earlier _ (changeList at: listIndex + 1) text.

	^ (self shouldUseAlternativeDiffer
		ifTrue: [ DifferenceFinder ]
		ifFalse: [ TextDiffBuilder ]) 
			buildDisplayPatchFrom: earlier to: later inClass: class prettyDiffs: self showingAnyKindOfPrettyDiffs! !


!ChangeSorter methodsFor: 'code pane' stamp: 'jmv 2/8/2010 11:04'!
setContents
	"return the source code that shows in the bottom pane"

	| sel class strm changeType |
	self clearUserEditFlag.
	currentClassName ifNil: [^ contents _ myChangeSet preambleString ifNil: ['']].
	class _ self selectedClassOrMetaClass.
	(sel _ currentSelector) == nil
		ifFalse: [changeType _ (myChangeSet atSelector: (sel _ sel asSymbol) class: class).
			changeType == #remove
				ifTrue: [^ contents _ 'Method has been removed (see versions)'].
			changeType == #addedThenRemoved
				ifTrue: [^ contents _ 'Added then removed (see versions)'].
			class ifNil: [^ contents _ 'Method was added, but cannot be found!!'].
			(class includesSelector: sel)
				ifFalse: [^ contents _ 'Method was added, but cannot be found!!'].
			contents _ class sourceCodeAt: sel.
			(#(prettyPrint prettyDiffs prettyDiffs2) includes: contentsSymbol) ifTrue:
				[contents _ class compilerClass new
						format: contents 
						in: class 
						notifying: nil].
			self showingAnyKindOfDiffs
				ifTrue: [contents _ self diffFromPriorSourceFor: contents].
			^ contents _ contents asText makeSelectorBoldIn: class]
		ifTrue: [strm _ WriteStream on: (String new: 100).
			(myChangeSet classChangeAt: currentClassName) do:
				[:each |
				each = #remove ifTrue: [strm nextPutAll: 'Entire class was removed.'; cr].
				each = #addedThenRemoved ifTrue: [strm nextPutAll: 'Class was added then removed.'].
				each = #rename ifTrue: [strm nextPutAll: 'Class name was changed.'; cr].
				each = #add ifTrue: [strm nextPutAll: 'Class definition was added.'; cr].
				each = #change ifTrue: [strm nextPutAll: 'Class definition was changed.'; cr].
				each = #reorganize ifTrue: [strm nextPutAll: 'Class organization was changed.'; cr].
				each = #comment ifTrue: [strm nextPutAll: 'New class comment.'; cr.
				]].
			^ contents _ strm contents].! !


!FileContentsBrowser methodsFor: 'diffs' stamp: 'jmv 2/8/2010 14:37'!
methodDiffFor: aString class: aPseudoClass selector: selector meta: meta 
	"Answer the diff between the current copy of the given class/selector/meta for the string provided"

	| theClass source |
	theClass _ Smalltalk
				at: aPseudoClass name
				ifAbsent: [^ aString copy].
	meta
		ifTrue: [theClass _ theClass class].
	(theClass includesSelector: selector)
		ifFalse: [^ aString copy].
	source _ theClass sourceCodeAt: selector.
	^ Cursor wait
		showWhile: [
			(self shouldUseAlternativeDiffer
				ifTrue: [ DifferenceFinder ]
				ifFalse: [ TextDiffBuilder ]) 
					buildDisplayPatchFrom: source 
					to: aString inClass: theClass 
					prettyDiffs: self showingAnyKindOfPrettyDiffs]! !

!FileContentsBrowser methodsFor: 'diffs' stamp: 'jmv 2/8/2010 14:37'!
modifiedClassDefinition
	| pClass rClass old new diff |
	pClass := self selectedClassOrMetaClass.
	pClass hasDefinition ifFalse:[^pClass definition].
	rClass := Smalltalk at: self selectedClass name asSymbol ifAbsent:[nil].
	rClass isNil ifTrue:[^pClass definition].
	self metaClassIndicated ifTrue:[ rClass := rClass class].
	old := rClass definition.
	new := pClass definition.
	Cursor wait showWhile:[
		diff := (self shouldUseAlternativeDiffer
				ifTrue: [ DifferenceFinder ]
				ifFalse: [ TextDiffBuilder ])
					buildDisplayPatchFrom: old to: new
	].
	^diff! !


!TextDiffBuilder methodsFor: 'initialize' stamp: 'jmv 2/8/2010 13:23'!
fromString: xString toString: yString

	xLines := (self split: xString asString) replace: [ :each | DiffElement string: each ].
	yLines := (self split: yString asString) replace: [ :each | DiffElement string: each ].
	self findMatches! !


!TextDiffBuilder class methodsFor: 'instance creation' stamp: 'jmv 2/8/2010 13:23'!
buildDisplayPatchFrom: sourceText to: destinationText

	^(self new
		fromString: sourceText toString: destinationText;
		yourself) buildDisplayPatch! !

!TextDiffBuilder class methodsFor: 'instance creation' stamp: 'jmv 2/8/2010 13:26'!
buildDisplayPatchFrom: sourceText to: destinationText inClass: sourceClass prettyDiffs: prettyDiffs
	
	^(sourceClass notNil and: [ prettyDiffs ])
		ifFalse: [ self buildDisplayPatchFrom: sourceText to: destinationText ]
		ifTrue: [
			((PrettyTextDiffBuilder new sourceClass: sourceClass) 
				fromString: sourceText toString: destinationText) 
					buildDisplayPatch ]! !


!TextEditor methodsFor: 'menu messages' stamp: 'LC 1/24/2010 15:36'!
compareToClipboard
	"Check to see if whether the receiver's text is the same as the text currently on the clipboard, and inform the user."
	| s1 s2 |
	s1 _ self clipboardText string.
	s2 _ paragraph text string.
	s1 = s2 ifTrue: [^ self inform: 'Exact match'].

	(StringHolder new textContents:
		(DifferenceFinder buildDisplayPatchFrom: s1 to: s2))
		openLabel: 'Comparison to Clipboard Text'! !


!VersionsBrowser methodsFor: 'menu' stamp: 'jmv 2/11/2010 10:06'!
compareToOtherVersion
	"Prompt the user for a reference version, then spawn a window 
	showing the diffs between the older and the newer of the current 
	version and the reference version as text."

	| change1 change2 s1 s2 differ differDesc |
	change1 := changeList at: listIndex ifAbsent: [ ^self ].

	change2 := ((SelectionMenu
				labels: (list copyWithoutIndex: listIndex)
				selections: (changeList copyWithoutIndex: listIndex)) startUp) ifNil: [ ^self ].
	
	"compare earlier -> later"
	"change1 timeStamp < change2 timeStamp
		ifFalse: [ | temp | temp _ change1. change1 _ change2. change2 _ temp ]."

	s1 := change1 string.
	s2 := change2 string.
	s1 = s2
		ifTrue: [^ self inform: 'Exact Match' translated].

	self shouldUseAlternativeDiffer
		ifTrue: [
			differ _ DifferenceFinder.
			differDesc _ 'Words']
		ifFalse: [
			differ _ TextDiffBuilder.
			differDesc _ 'Lines'].

	(StringHolder new
		textContents: (differ
				buildDisplayPatchFrom: s1
				to: s2
				inClass: classOfMethod
				prettyDiffs: self showingAnyKindOfPrettyDiffs))
		openLabel: 
			(('Comparison from {1} to {2}: ', differDesc, 
				(self showingAnyKindOfPrettyDiffs ifTrue: [', using prettyPrint'] ifFalse: [''])) 
					format: { change1 stamp. change2 stamp })! !


!ClassCommentVersionsBrowser methodsFor: 'menu' stamp: 'jmv 2/11/2010 09:57'!
compareToCurrentVersion
	"If the current selection corresponds to a method in the system, then spawn a window showing the diffs as text"

	| change s1 s2 differ differDesc |
	listIndex = 0
		ifTrue: [^ self].
	change _ changeList at: listIndex.
	s1 _ classOfMethod organization classComment.
	s2 _ change string.
	s1 = s2
		ifTrue: [^ self inform: 'Exact Match'].
	self shouldUseAlternativeDiffer
		ifTrue: [
			differ _ DifferenceFinder.
			differDesc _ 'Words']
		ifFalse: [
			differ _ TextDiffBuilder.
			differDesc _ 'Lines'].
	(StringHolder new
		textContents: (differ
				buildDisplayPatchFrom: s1 to: s2 inClass: classOfMethod  prettyDiffs: self showingAnyKindOfPrettyDiffs))
					openLabel: 'Comparison to Current Version: ', differDesc! !

!ClassCommentVersionsBrowser methodsFor: 'basic function' stamp: 'jmv 2/8/2010 14:22'!
diffedVersionContents
	"Answer diffed version contents, maybe pretty maybe not"

	| change class earlier later |
	(listIndex = 0
			or: [changeList size < listIndex])
		ifTrue: [^ ''].
	change _ changeList at: listIndex.
	later _ change text.
	class _ self selectedClass.
	(listIndex = changeList size or: [class == nil])
		ifTrue: [^ later].

	earlier _ (changeList at: listIndex + 1) text.

	^(self shouldUseAlternativeDiffer
		ifTrue: [ DifferenceFinder ]
		ifFalse: [ TextDiffBuilder ]) 
			buildDisplayPatchFrom: earlier to: later inClass: class prettyDiffs: self showingAnyKindOfPrettyDiffs! !

!ClassCommentVersionsBrowser methodsFor: 'misc' stamp: 'jmv 2/8/2010 10:31'!
contentsSymbolQuints
	"Answer a list of quintuplets representing information on the alternative views available in the code pane"

	^ #(
(source		togglePlainSource 		showingPlainSourceString		'source'	'the textual source code as writen')
(showDiffs	toggleRegularDiffing	showingRegularDiffsString	'showDiffs'	'the textual source diffed from its prior version')
	)! !

Utilities class removeSelector: #methodDiffFor:class:selector:prettyDiffs:!
PrettyTextDiffBuilder class removeSelector: #from:to:inClass:!
TextDiffBuilder class removeSelector: #from:to:!
TextDiffBuilder removeSelector: #from:to:!
CodeHolder removeSelector: #showDiffs!
Object removeSelector: #showDiffs!
