ProcessMonitorV2.st
changeset 17300 48714b269838
parent 17271 34d72ea12f93
child 17379 028adf14bc05
child 17623 db505407fa0c
--- a/ProcessMonitorV2.st	Sat Jan 28 22:05:07 2017 +0100
+++ b/ProcessMonitorV2.st	Sun Jan 29 02:23:23 2017 +0100
@@ -33,7 +33,7 @@
 		hasSelectionWithDisabledInstrumentationHolder
 		hasSelectionWithEnabledInstrumentationHolder interruptCountHolder
 		timerActionCountHolder lastInterruptCount lastTimerActionCount
-		lastUpdateTimestamp'
+		lastUpdateTimestamp showStartTime'
 	classVariableNames:''
 	poolDictionaries:''
 	category:'Monitors-ST/X'
@@ -45,7 +45,8 @@
 		processInstrumentation processApplication processWindowTitle
 		processInstance weakArrayWithProcesses
 		processInstanceIndexInWeakArray processCurrentSegment
-		processSwitch prioVal idVal groupVal processBlocked'
+		processSwitch prioVal idVal groupVal processBlocked
+		startTimestamp'
 	classVariableNames:''
 	poolDictionaries:''
 	privateIn:ProcessMonitorV2
@@ -1832,6 +1833,11 @@
             indication: showWindowTitle
           )
          (MenuItem
+            label: 'Start Time'
+            hideMenuOnActivated: false
+            indication: showStartTime
+          )
+         (MenuItem
             label: '-'
           )
          (MenuItem
@@ -1868,223 +1874,243 @@
 
     ^#(
       (DataSetColumnSpec
-	 label: 'Id'
-	 id: id
-	 activeHelpKeyForLabel: 'processId'
-	 labelAlignment: left
-	 labelButtonType: Button
-	 labelActionSelector: sortProcessListBy:
-	 labelActionArgument: 'idVal'
-	 width: 45
-	 type: number
-	 model: processId
-	 canSelect: false
-	 showRowSeparator: false
-	 showColSeparator: false
+         label: 'Id'
+         id: id
+         labelAlignment: left
+         activeHelpKeyForLabel: 'processId'
+         labelButtonType: Button
+         labelActionSelector: sortProcessListBy:
+         labelActionArgument: 'idVal'
+         width: 45
+         height: heightOfFirstRow
+         type: number
+         model: processId
+         canSelect: false
+         showRowSeparator: false
+         showColSeparator: false
        )
       (DataSetColumnSpec
-	 label: 'Group'
-	 id: group
-	 activeHelpKeyForLabel: 'processGroup'
-	 labelAlignment: left
-	 labelButtonType: Button
-	 labelActionSelector: sortProcessListBy:
-	 labelActionArgument: 'groupVal'
-	 width: 45
-	 model: processGroup
-	 canSelect: false
-	 showRowSeparator: false
-	 showColSeparator: false
+         label: 'Group'
+         id: group
+         labelAlignment: left
+         activeHelpKeyForLabel: 'processGroup'
+         labelButtonType: Button
+         labelActionSelector: sortProcessListBy:
+         labelActionArgument: 'groupVal'
+         width: 45
+         height: heightOfFirstRow
+         model: processGroup
+         canSelect: false
+         showRowSeparator: false
+         showColSeparator: false
        )
       (DataSetColumnSpec
-	 label: 'Name'
-	 id: name
-	 activeHelpKeyForLabel: 'processName'
-	 labelAlignment: left
-	 labelButtonType: Button
-	 labelActionSelector: sortProcessListBy:
-	 labelActionArgument: 'processName'
-	 width: 200
-	 model: processName
-	 canSelect: false
-	 showRowSeparator: false
-	 showColSeparator: false
+         label: 'Name'
+         id: name
+         labelAlignment: left
+         activeHelpKeyForLabel: 'processName'
+         labelButtonType: Button
+         labelActionSelector: sortProcessListBy:
+         labelActionArgument: 'processName'
+         width: 200
+         height: heightOfFirstRow
+         model: processName
+         canSelect: false
+         showRowSeparator: false
+         showColSeparator: false
        )
       (DataSetColumnSpec
-	 label: 'Instr.'
-	 id: instrumentation
-	 labelAlignment: left
-	 width: 50
-	 "/ activeHelpKey: 'processInstrumentation'
-	 activeHelpKeyForLabel: 'processInstrumentation'
-	 labelButtonType: Button
-	 labelActionSelector: sortProcessListBy:
-	 labelActionArgument: 'processInstrumentation'
-	 model: processInstrumentation
-	 menuFromApplication: false
-	 canSelect: false
-	 showRowSeparator: false
-	 showColSeparator: false
+         label: 'Instr.'
+         id: instrumentation
+         labelAlignment: left
+         activeHelpKeyForLabel: 'processInstrumentation'
+         labelButtonType: Button
+         labelActionSelector: sortProcessListBy:
+         labelActionArgument: 'processInstrumentation'
+         width: 50
+         height: heightOfFirstRow
+         model: processInstrumentation
+         menuFromApplication: false
+         canSelect: false
+         showRowSeparator: false
+         showColSeparator: false
+       )
+      (DataSetColumnSpec
+         label: ''
+         id: active
+         activeHelpKeyForLabel: 'processWasActive'
+         labelButtonType: Button
+         labelActionSelector: sortProcessListBy:
+         labelActionArgument: 'processActive'
+         width: 10
+         height: 5
+         model: processActive
+         menuFromApplication: false
+         canSelect: false
+         showRowSeparator: false
+         showColSeparator: false
        )
       (DataSetColumnSpec
-	 label: ''
-	 id: active
-	 "/ activeHelpKey: 'processWasActive'
-	 activeHelpKeyForLabel: 'processWasActive'
-	 labelButtonType: Button
-	 labelActionSelector: sortProcessListBy:
-	 labelActionArgument: 'processActive'
-	 width: 10
-	 height: 5
-	 model: processActive
-	 menuFromApplication: false
-	 canSelect: false
-	 showRowSeparator: false
-	 showColSeparator: false
+         label: 'State'
+         id: state
+         labelAlignment: left
+         activeHelpKeyForLabel: 'processState'
+         labelButtonType: Button
+         labelActionSelector: sortProcessListBy:
+         labelActionArgument: 'processState'
+         width: 100
+         height: heightOfFirstRow
+         model: processState
+         menuFromApplication: false
+         canSelect: false
+         showRowSeparator: false
+         showColSeparator: false
        )
       (DataSetColumnSpec
-	 label: 'State'
-	 id: state
-	 labelAlignment: left
-	 "/ activeHelpKey: 'processState'
-	 activeHelpKeyForLabel: 'processState'
-	 labelButtonType: Button
-	 labelActionSelector: sortProcessListBy:
-	 labelActionArgument: 'processState'
-	 width: 100
-	 model: processState
-	 menuFromApplication: false
-	 canSelect: false
-	 showRowSeparator: false
-	 showColSeparator: false
-       )
-      (DataSetColumnSpec
-	 label: 'Prio'
-	 id: prio
-	 labelAlignment: left
-	 "/ activeHelpKey: 'processPriority'
-	 activeHelpKeyForLabel: 'processPriority'
-	 labelButtonType: Button
-	 labelActionSelector: sortProcessListBy:
-	 labelActionArgument: 'prioVal'
-	 width: 40
-	 model: processPrio
-	 menuFromApplication: false
-	 canSelect: false
-	 showRowSeparator: false
-	 showColSeparator: false
+         label: 'Prio'
+         id: prio
+         labelAlignment: left
+         activeHelpKeyForLabel: 'processPriority'
+         labelButtonType: Button
+         labelActionSelector: sortProcessListBy:
+         labelActionArgument: 'prioVal'
+         width: 40
+         height: heightOfFirstRow
+         model: processPrio
+         menuFromApplication: false
+         canSelect: false
+         showRowSeparator: false
+         showColSeparator: false
        )
       (DataSetColumnSpec
-	 label: 'Used Stack'
-	 id: usedStack
-	 labelAlignment: left
-	 "/ activeHelpKey: 'processUsedStack'
-	 activeHelpKeyForLabel: 'processUsedStack'
-	 labelButtonType: Button
-	 labelActionSelector: sortProcessListBy:
-	 labelActionArgument: 'processUsedStack'
-	 columnAlignment: right
-	 width: 75
-	 type: number
-	 model: processUsedStack
-	 menuFromApplication: false
-	 canSelect: false
-	 showRowSeparator: false
-	 showColSeparator: false
+         label: 'Used Stack'
+         id: usedStack
+         labelAlignment: left
+         activeHelpKeyForLabel: 'processUsedStack'
+         labelButtonType: Button
+         labelActionSelector: sortProcessListBy:
+         labelActionArgument: 'processUsedStack'
+         columnAlignment: right
+         width: 75
+         height: heightOfFirstRow
+         type: number
+         model: processUsedStack
+         menuFromApplication: false
+         canSelect: false
+         showRowSeparator: false
+         showColSeparator: false
        )
       (DataSetColumnSpec
-	 label: 'Total Stack'
-	 id: totalStack
-	 labelAlignment: left
-	 "/ activeHelpKey: 'processTotalStack'
-	 activeHelpKeyForLabel: 'processTotalStack'
-	 labelButtonType: Button
-	 labelActionSelector: sortProcessListBy:
-	 labelActionArgument: 'processTotalStack'
-	 columnAlignment: right
-	 width: 75
-	 model: processTotalStack
-	 menuFromApplication: false
-	 canSelect: false
-	 showRowSeparator: false
-	 showColSeparator: false
+         label: 'Total Stack'
+         id: totalStack
+         labelAlignment: left
+         activeHelpKeyForLabel: 'processTotalStack'
+         labelButtonType: Button
+         labelActionSelector: sortProcessListBy:
+         labelActionArgument: 'processTotalStack'
+         columnAlignment: right
+         width: 75
+         height: heightOfFirstRow
+         model: processTotalStack
+         menuFromApplication: false
+         canSelect: false
+         showRowSeparator: false
+         showColSeparator: false
        )
       (DataSetColumnSpec
-	 label: 'Current-Segment'
-	 id: currentSegment
-	 activeHelpKeyForLabel: 'processCurrentSegment'
-	 labelAlignment: left
-	 labelButtonType: Button
-	 labelActionSelector: sortProcessListBy:
-	 labelActionArgument: 'processCurrentSegment'
-	 width: 110
-	 model: processCurrentSegment
-	 canSelect: false
-	 showRowSeparator: false
-	 showColSeparator: false
+         label: 'Current-Segment'
+         id: currentSegment
+         labelAlignment: left
+         activeHelpKeyForLabel: 'processCurrentSegment'
+         labelButtonType: Button
+         labelActionSelector: sortProcessListBy:
+         labelActionArgument: 'processCurrentSegment'
+         width: 110
+         height: heightOfFirstRow
+         model: processCurrentSegment
+         canSelect: false
+         showRowSeparator: false
+         showColSeparator: false
        )
       (DataSetColumnSpec
-	 label: 'Switch'
-	 id: switch
-	 activeHelpKeyForLabel: 'processSwitch'
-	 labelAlignment: left
-	 labelButtonType: Button
-	 labelActionSelector: sortProcessListBy:
-	 labelActionArgument: 'processSwitch'
-	 columnAlignment: right
-	 width: 55
-	 type: number
-	 model: processSwitch
-	 canSelect: false
-	 showRowSeparator: false
-	 showColSeparator: false
+         label: 'Switch'
+         id: switch
+         labelAlignment: left
+         activeHelpKeyForLabel: 'processSwitch'
+         labelButtonType: Button
+         labelActionSelector: sortProcessListBy:
+         labelActionArgument: 'processSwitch'
+         columnAlignment: right
+         width: 55
+         height: heightOfFirstRow
+         type: number
+         model: processSwitch
+         canSelect: false
+         showRowSeparator: false
+         showColSeparator: false
        )
       (DataSetColumnSpec
-	 label: 'Where'
-	 id: where
-	 labelAlignment: left
-	 "/ activeHelpKey: 'processWhere'
-	 activeHelpKeyForLabel: 'processWhere'
-	 labelButtonType: Button
-	 labelActionSelector: sortProcessListBy:
-	 labelActionArgument: 'processWhere'
-	 model: processWhere
-	 menuFromApplication: false
-	 canSelect: false
-	 showRowSeparator: false
-	 showColSeparator: false
+         label: 'Where'
+         id: where
+         labelAlignment: left
+         activeHelpKeyForLabel: 'processWhere'
+         labelButtonType: Button
+         labelActionSelector: sortProcessListBy:
+         labelActionArgument: 'processWhere'
+         height: heightOfFirstRow
+         model: processWhere
+         menuFromApplication: false
+         canSelect: false
+         showRowSeparator: false
+         showColSeparator: false
        )
       (DataSetColumnSpec
-	 label: 'Application'
-	 id: application
-	 labelAlignment: left
-	 "/ activeHelpKey: 'processApplication'
-	 activeHelpKeyForLabel: 'processApplication'
-	 labelButtonType: Button
-	 labelActionSelector: sortProcessListBy:
-	 labelActionArgument: 'processApplication'
-	 model: processApplication
-	 menuFromApplication: false
-	 canSelect: false
-	 showRowSeparator: false
-	 showColSeparator: false
+         label: 'Application'
+         id: application
+         labelAlignment: left
+         activeHelpKeyForLabel: 'processApplication'
+         labelButtonType: Button
+         labelActionSelector: sortProcessListBy:
+         labelActionArgument: 'processApplication'
+         height: heightOfFirstRow
+         model: processApplication
+         menuFromApplication: false
+         canSelect: false
+         showRowSeparator: false
+         showColSeparator: false
        )
       (DataSetColumnSpec
-	 label: 'Window Title'
-	 id: windowTitle
-	 labelAlignment: left
-	 "/ activeHelpKey: 'processWindowTitle'
-	 activeHelpKeyForLabel: 'processWindowTitle'
-	 labelButtonType: Button
-	 labelActionSelector: sortProcessListBy:
-	 labelActionArgument: 'processWindowTitle'
-	 model: processWindowTitle
-	 menuFromApplication: false
-	 canSelect: false
-	 showRowSeparator: false
-	 showColSeparator: false
+         label: 'Window Title'
+         id: windowTitle
+         labelAlignment: left
+         activeHelpKeyForLabel: 'processWindowTitle'
+         labelButtonType: Button
+         labelActionSelector: sortProcessListBy:
+         labelActionArgument: 'processWindowTitle'
+         height: heightOfFirstRow
+         model: processWindowTitle
+         menuFromApplication: false
+         canSelect: false
+         showRowSeparator: false
+         showColSeparator: false
+       )
+      (DataSetColumnSpec
+         label: 'Start Time'
+         id: startTime
+         activeHelpKeyForLabel: 'processStartTime'
+         labelButtonType: Button
+         labelActionSelector: sortProcessListBy:
+         labelActionArgument: 'processStartTime'
+         height: heightOfFirstRow
+         type: timestamp
+         model: processStartTime
+         formatString: '%(day)-%(shortMonthName) %h:%m:%s'
+         menuFromApplication: false
+         showRowSeparator: false
+         showColSeparator: false
        )
       )
+    
 ! !
 
 !ProcessMonitorV2 methodsFor:'accessing'!
@@ -2401,6 +2427,16 @@
     ^ showProcessId
 !
 
+showStartTime
+    "return/create the 'showStartTime' value holder (automatically generated)"
+
+    showStartTime isNil ifTrue:[
+        showStartTime := false asValue.
+        showStartTime onChangeSend:#viewedColumnsChanged to:self
+    ].
+    ^ showStartTime
+!
+
 showState
     "return/create the 'showState' value holder (automatically generated)"
 
@@ -2658,64 +2694,70 @@
 !
 
 viewedColumnsChanged
+    "take the class's columnSpec and select the one's selected by the user.
+     Stuff this filtered tableColSpec into the value holder"
+    
     | columns buffer locCurrentSortOrder currentSortOrderColumn currentSortOrderReverse oldSelection sel|
 
     "/ remember the selected processes
     sel := self selectedProcesses value.
     sel notNil ifTrue:[
-	oldSelection := OrderedCollection new.
-	sel do:[:proItem|
-	    |process|
-
-	    (process := proItem processInstance) notNil ifTrue:[
-		oldSelection add:process
-	    ].
-	].
+        oldSelection := OrderedCollection new.
+        sel do:[:proItem|
+            |process|
+
+            (process := proItem processInstance) notNil ifTrue:[
+                oldSelection add:process
+            ].
+        ].
     ].
-"/    Transcript showCR:'oldSelection on catch in viewedColumnsChanged', (oldSelection isNil ifTrue:['nil'] ifFalse:[oldSelection first printString]).
+
+    "/ Transcript showCR:'oldSelection on catch in viewedColumnsChanged', (oldSelection isNil ifTrue:['nil'] ifFalse:[oldSelection first printString]).
     columns := OrderedCollection new.
     self class tableColumns do:[:el|
-	columns add:(DataSetColumnSpec decodeFromLiteralArray:el).
+        columns add:(DataSetColumnSpec decodeFromLiteralArray:el).
     ].
     buffer := columns copy.
     locCurrentSortOrder := self currentSortOrder value.
     currentSortOrderColumn := locCurrentSortOrder at:#column ifAbsent:nil.
     currentSortOrderReverse := locCurrentSortOrder at:#reverse ifAbsent:nil.
     buffer do:[:col |
-	| id |
-	id := col id.
-	id notNil ifTrue:[
-	    (col labelActionArgument notNil and:[col labelActionArgument asSymbol == currentSortOrderColumn]) ifTrue:[
-		| label icon|
-		label := col label.
-		icon := currentSortOrderReverse ifTrue:[self class detailsMenuIconDown] ifFalse:[self class detailsMenuIconUp].
-		col label:(LabelAndIcon label:label icon:icon).
-	    ].
-	    #(
-		( #id             #showProcessId)
-		( #group          #showGroup)
-		( #prio           #showPrio)
-		( #currentSegment #showCurrentSegment)
-		( #state          #showState)
-		( #switch         #showSwitch)
-		( #totalStack     #showTotalStack)
-		( #usedStack      #showUsedStack)
-		( #where          #showWhere)
-		( #application    #showApplication)
-		( #windowTitle    #showWindowTitle)
-		( #instrumentation #showInstrumentation)
-	    ) pairsDo:[:colName :holderAccessorSelector |
-		(id == colName and:[(self perform:holderAccessorSelector) value not]) ifTrue:[
-		    columns remove:col.
-		]
-	    ]
-	]
+        | id |
+        id := col id.
+        id notNil ifTrue:[
+            (col labelActionArgument notNil and:[col labelActionArgument asSymbol == currentSortOrderColumn]) ifTrue:[
+                | label icon|
+                label := col label.
+                icon := currentSortOrderReverse ifTrue:[self class detailsMenuIconDown] ifFalse:[self class detailsMenuIconUp].
+                col label:(LabelAndIcon label:label icon:icon).
+            ].
+            #(
+                ( #id             #showProcessId)
+                ( #group          #showGroup)
+                ( #prio           #showPrio)
+                ( #currentSegment #showCurrentSegment)
+                ( #state          #showState)
+                ( #switch         #showSwitch)
+                ( #totalStack     #showTotalStack)
+                ( #usedStack      #showUsedStack)
+                ( #where          #showWhere)
+                ( #application    #showApplication)
+                ( #windowTitle    #showWindowTitle)
+                ( #startTime      #showStartTime)
+                ( #instrumentation #showInstrumentation)
+            ) pairsDo:[:colName :holderAccessorSelector |
+                (id == colName and:[(self perform:holderAccessorSelector) value not]) ifTrue:[
+                    columns remove:col.
+                ]
+            ]
+        ]
     ].
+    
     updateSema critical:[
-	self tableColumns value:columns.
+        self tableColumns value:columns.
 "/        self updateTable:nil.
 "/        Transcript showCR:'oldSelection on set in viewedColumnsChanged', (oldSelection isNil ifTrue:['nil'] ifFalse:[oldSelection first printString]).
-	self changeSelectionToProcesses:oldSelection.
+        self changeSelectionToProcesses:oldSelection.
     ].
 
     "Modified: / 17-08-2011 / 11:11:21 / cg"
@@ -3608,6 +3650,7 @@
     processItem processGroup:(self getGroupStringFor:aProcess).
     processItem groupVal:(processItem processGroup isNumber ifTrue:[processItem processGroup] ifFalse:[-1]).
 
+    processItem processStartTime:aProcess startTimestamp.
     processItem processName:aProcess name ? ''.
 
     state := aProcess state.
@@ -4161,6 +4204,18 @@
     processPrio := something.
 !
 
+processStartTime
+    "return the value of the instance variable 'startTime' (automatically generated)"
+
+    ^ startTimestamp
+!
+
+processStartTime:aTimestamp
+    "set the value of the instance variable 'startTime' (automatically generated)"
+
+    startTimestamp := aTimestamp
+!
+
 processState
     ^ processState
 !