ClassRevisionTree.st
changeset 2520 36b0b3f51128
child 2521 0865a2bcec81
--- /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 $'
+! !