ClassRevisionTree.st
author ps
Wed, 29 Dec 1999 16:32:17 +0100
changeset 2520 36b0b3f51128
child 2521 0865a2bcec81
permissions -rw-r--r--
initial checkin

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 $'
! !