--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ClassRevisionTree.st Wed Dec 29 16:32:17 1999 +0100
@@ -0,0 +1,432 @@
+ApplicationModel subclass:#ClassRevisionTree
+ instanceVariableNames:'selectionHolder semaphoreCritical revisionInfoList revisionTask
+ currentClassItemInTask'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Browsers'
+!
+
+
+!ClassRevisionTree class methodsFor:'interface spec'!
+
+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:ClassRevisionTree andSelector:#windowSpec
+ ClassRevisionTree new openInterface:#windowSpec
+ ClassRevisionTree open
+ "
+
+ <resource: #canvas>
+
+ ^
+ #(#FullSpec
+ #name: #windowSpec
+ #window:
+ #(#WindowSpec
+ #label: 'ClassVersionTree'
+ #name: 'ClassVersionTree'
+ #min: #(#Point 10 10)
+ #max: #(#Point 9999 9999)
+ #bounds: #(#Rectangle 16 51 881 580)
+ )
+ #component:
+ #(#SpecCollection
+ #collection: #(
+ #(#HierarchicalListViewSpec
+ #name: 'HierarchicalItemListView'
+ #layout: #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0)
+ #model: #hierarchicalItemSelectionAspect
+ #menu: #selectHierarchicalItemMenu
+ #hasHorizontalScrollBar: true
+ #hasVerticalScrollBar: true
+ #listModel: #hierarchicalItemListModel
+ #multipleSelectOk: true
+ #highlightMode: #label
+ #doubleClickSelector: #doubleClick:
+ #selectConditionSelector: #isHierarchicalItemSelectable:
+ #indicatorSelector: #doubleClick:
+ #retrieveIconsSelector: #icons
+ )
+ )
+
+ )
+ )
+! !
+
+!ClassRevisionTree class methodsFor:'menu specs'!
+
+resourceItemMenu
+ "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:ClassRevisionTree andSelector:#resourceItemMenu
+ (Menu new fromLiteralArrayEncoding:(ClassRevisionTree resourceItemMenu)) startUp
+ "
+
+ <resource: #menu>
+
+ ^
+ #(#Menu
+ #(
+ #(#MenuItem
+ #label: 'Compare Changes'
+ #translateLabel: true
+ #value: #menuActionCompareChanges
+ )
+ )
+ nil
+ nil
+ )
+! !
+
+!ClassRevisionTree class methodsFor:'startup'!
+
+openOnClasses:aClassColl withSelectionHolder:aValueHolder
+ |theTree theClassItemColl|
+
+ theTree := self new.
+ theTree allButOpen.
+ theClassItemColl := aClassColl collect:[:eachClass |
+ |theClassItem theClass|
+ theClassItem := ClassItem new.
+ theClass := Smalltalk resolveName:eachClass inClass:self.
+ theClassItem myClass:theClass.
+ theClassItem].
+ theTree hierarchicalItemList addAll: theClassItemColl.
+ theTree selectionHolder:aValueHolder.
+ theTree openWindow.
+ ^theTree
+
+"
+|theSelectionHolder|
+
+theSelectionHolder := ValueHolder new.
+theSelectionHolder compute:[:el |
+ Transcript showCR: el first revisionString.
+ Transcript showCR: el second revisionString].
+ClassRevisionTree openOnClasses:(Smalltalk allClasses asOrderedCollection sort:[:x : y|x name < y name])
+ withSelectionHolder:theSelectionHolder.
+"
+
+
+
+! !
+
+!ClassRevisionTree methodsFor:'accessing'!
+
+hierarchicalListItemForSelectionIndex: anIndex
+
+ ^self hierarchicalItemListModel at:anIndex ifAbsent:nil
+!
+
+hierarchicalListSelectionIndexColl
+
+ ^self hierarchicalItemSelectionAspect value
+!
+
+hierarchicalListSelectionIndexColl:anArray
+
+ ^self hierarchicalItemSelectionAspect value:anArray
+!
+
+revisionInfoList
+ "return the value of the instance variable 'revisionInfoList' (automatically generated)"
+
+ ^ revisionInfoList ifNil:[revisionInfoList := IdentitySet new]
+!
+
+selectionHolder
+ "return the value of the instance variable 'selectionHolder' (automatically generated)"
+
+ ^ selectionHolder!
+
+selectionHolder:something
+ "set the value of the instance variable 'revisionItemSelection' (automatically generated)"
+
+ selectionHolder := something.
+!
+
+semaphoreCritical
+ "return the value of the instance variable 'semaphoreCritical' (automatically generated)"
+
+ ^ semaphoreCritical ifNil:[semaphoreCritical := RecursionLock new]
+! !
+
+!ClassRevisionTree methodsFor:'actions'!
+
+doubleClick: anIndex
+ "automatically generated by UIPainter ..."
+
+ "*** the code below performs no action"
+ "*** (except for some feedback on the Transcript)"
+ "*** Please change as required and accept in the browser."
+
+ "action to be added ..."
+
+ (self hierarchicalItemListModel at: anIndex) toggleExpand
+!
+
+getRevisionInfoForClassItem: aClassItem
+
+ self semaphoreCritical critical:[
+ |theList|
+ currentClassItemInTask == aClassItem ifTrue:[^self].
+ (theList := self revisionInfoList) removeIdentical:aClassItem ifAbsent:[nil].
+ theList add:aClassItem.
+ Transcript showCR:theList.
+ self startRevisionTask]
+!
+
+isHierarchicalItemSelectable: anIndex
+
+ |theSelectionIndexColl theSelectionIndexSize theSelectedItem|
+
+ "nur eine Revision kann selektiert werden"
+ (theSelectedItem := self hierarchicalListItemForSelectionIndex: anIndex) isRevisionItem
+ ifFalse:[^false].
+ "ist keine selektiert ist alles ok -> mit true zurueck"
+ (theSelectionIndexColl := self hierarchicalListSelectionIndexColl) size == 0
+ ifTrue:[^true].
+ "wurde deselektiert"
+ (self window sensor ctrlDown)
+ ifTrue: [
+ "ist eine Rev selektiert und die Klassen sind nicht gleich, dann falsch"
+ (self hierarchicalListItemForSelectionIndex:theSelectionIndexColl first) parent myClass == theSelectedItem parent myClass
+ ifFalse:[^false].
+ theSelectionIndexColl size ~~ 2
+ ifTrue:[^true].
+ (theSelectionIndexColl includes:anIndex)
+ ifTrue: [^true]
+ ifFalse:[self hierarchicalListSelectionIndexColl:(Array with:theSelectionIndexColl first).
+ ^true]]
+ ifFalse:[
+ (theSelectionIndexColl size == 2)
+ ifTrue:[self hierarchicalListSelectionIndexColl:(Array with:anIndex)].
+ ^true]
+!
+
+menuActionCompareChanges
+
+ |theSelectionIndexColl theFirstRevisionItem theSecondRevisionItem|
+
+ theSelectionIndexColl := self hierarchicalListSelectionIndexColl.
+ theFirstRevisionItem := self hierarchicalListItemForSelectionIndex:theSelectionIndexColl first.
+ theSecondRevisionItem := self hierarchicalListItemForSelectionIndex:theSelectionIndexColl last.
+ self selectionHolder notNil
+ ifTrue:[self selectionHolder value:(Array with:theFirstRevisionItem with:theSecondRevisionItem)]
+!
+
+selectHierarchicalItemMenu
+"
+<return: Block>
+"
+
+ ^[|menu|
+ self checkIfTwoResourceItemsSelected
+ ifFalse:[menu := nil]
+ ifTrue: [menu := Menu new fromLiteralArrayEncoding:(self class resourceItemMenu).
+ menu receiver:self].
+ menu
+ ]
+! !
+
+!ClassRevisionTree methodsFor:'aspects'!
+
+hierarchicalItemList
+ "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 it in the browser."
+
+ ^ self hierarchicalItemListModel root
+
+
+
+
+
+!
+
+hierarchicalItemListModel
+ "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 it in the browser."
+
+ |holder|
+
+ (holder := builder bindingAt:#hierarchicalItemListModel) isNil ifTrue:[
+ holder := HierarchicalList new.
+ holder root:(ClassItemRoot new).
+ holder showRoot:false.
+ builder aspectAt:#hierarchicalItemListModel put:holder.
+ holder application:self.
+ ].
+
+ ^ holder.
+
+!
+
+hierarchicalItemSelectionAspect
+ "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 it in the browser."
+
+ |holder|
+
+ (holder := builder bindingAt:#hierarchicalItemSelectionAspect) isNil ifTrue:[
+ holder := ValueHolder new.
+ builder aspectAt:#hierarchicalItemSelectionAspect put:holder.
+ holder addDependent: self.
+ ].
+ ^ holder.
+
+!
+
+icons
+ |icons|
+ icons := Dictionary new.
+ icons at:#loadedRevision put:Icon leftIcon.
+ icons at:#notLoadedRevision put:Icon rightIcon.
+ ^icons
+! !
+
+!ClassRevisionTree methodsFor:'interface opening'!
+
+postOpenWith: aBuilder
+
+
+ super postOpenWith: aBuilder.
+ self hierarchicalItemList expand.
+!
+
+release
+
+ self stopRevisionTask.
+ ^super release
+
+
+! !
+
+!ClassRevisionTree methodsFor:'private'!
+
+computeChildrenForClassItem:aClassItem
+
+ |theRevisionLog|
+ theRevisionLog := self computeRevisionInfoForClassItem:aClassItem.
+ aClassItem setChildrensForRevisionInfo:theRevisionLog
+!
+
+computeRevisionInfoForClassItem:aClassItem
+
+ |theClass theSourceCodeManager|
+
+ theClass := aClassItem myClass.
+ theSourceCodeManager:=theClass sourceCodeManager.
+ ^theSourceCodeManager revisionLogOf:theClass.
+!
+
+revisionTaskCycle
+
+ |theClassItem|
+
+ [
+ theClassItem := nil.
+ self semaphoreCritical critical:[
+ self revisionInfoList notEmpty
+ ifTrue:[theClassItem := self revisionInfoList remove:(self revisionInfoList last) ifAbsent:[nil]]
+ ].
+ theClassItem notNil ifTrue:[
+ theClassItem isExpanded
+ ifTrue: [currentClassItemInTask:=theClassItem.
+ self computeChildrenForClassItem:theClassItem]
+ ifFalse:[currentClassItemInTask:=nil]
+ ].
+ theClassItem notNil
+ ] whileTrue.
+!
+
+startRevisionTask
+
+ self semaphoreCritical critical:[
+ revisionTask ifNil:[
+ revisionTask := Process for:[
+ self revisionTaskCycle
+ ]
+ priority:(Processor userBackgroundPriority).
+ revisionTask addExitAction:[revisionTask := nil].
+ revisionTask resume.
+ ].
+ ].
+!
+
+stopRevisionTask
+ |task|
+
+ self semaphoreCritical critical:[
+ (task := revisionTask) notNil ifTrue:[
+ revisionTask := nil.
+ Exception handle:[:ex|] do:[
+ task terminateWithAllSubprocesses.
+ task waitUntilTerminated.
+ ]
+ ]
+ ].
+
+! !
+
+!ClassRevisionTree methodsFor:'setup'!
+
+setupOnClasses:aClassColl withSelectionHolder:aValueHolder
+
+ |theClassItemColl|
+
+ theClassItemColl := aClassColl collect:[:eachClass |
+ |theClassItem theClass|
+ theClassItem := ClassItem new.
+ theClass := Smalltalk resolveName:eachClass inClass:Smalltalk.
+ theClassItem myClass:theClass.
+ theClassItem].
+ self hierarchicalItemList addAll: theClassItemColl.
+ self selectionHolder:aValueHolder.
+
+"
+|theTree|
+
+theTree := ClassRevisionTree new.
+theTree open.
+theTree setupOnClasses:#(VersionDiffBrowser HierarchicalVersionDiffBrowser SourceRevisionItem Project) withSelectionHolder:nil.
+"
+! !
+
+!ClassRevisionTree methodsFor:'testing'!
+
+checkIfTwoResourceItemsSelected
+
+ |theSelectionIndexColl|
+
+ ((theSelectionIndexColl := self hierarchicalListSelectionIndexColl) isNil or:
+ [theSelectionIndexColl size ~~ 2])
+ ifTrue:[^false].
+ ^((self hierarchicalListItemForSelectionIndex:theSelectionIndexColl first) isRevisionItem
+ and:[(self hierarchicalListItemForSelectionIndex:theSelectionIndexColl last) isRevisionItem])
+! !
+
+!ClassRevisionTree class methodsFor:'documentation'!
+
+version
+ ^ '$Header: /cvs/stx/stx/libtool/ClassRevisionTree.st,v 1.1 1999-12-29 15:32:17 ps Exp $'
+! !