ProcessMonitorV2.st
author penk
Tue, 28 Jan 2003 16:17:59 +0100
changeset 4504 e07fb8560de3
parent 4502 7d40e78aa5b4
child 4505 4c309bc91890
permissions -rw-r--r--
*** empty log message ***

"{ Package: 'stx:libtool' }"

SystemStatusMonitorV2 subclass:#ProcessMonitorV2
	instanceVariableNames:'processList tableColumns selectedProcesses updateSema showDetail
		hasSelection selctionRestartable showProcessId showGroup
		showState showPrio showUsedStack showTotalStack
		showCurrentSegment showSwitch showWhere currentSortOrder
		processTable processes showDead sortBlock selectionRestartable
		updateListDelayTime increaseupdateListDelayTime
		decreaseupdateListDelayTime updateContentsDelayTime
		enableDecreaseListDelayTime enableDecreaseContentsDelayTime
		enableIncreaseListDelayTime enableIncreaseContentsDelayTime'
	classVariableNames:''
	poolDictionaries:''
	category:'Monitors-ST/X'
!

Object subclass:#ProcessItem
	instanceVariableNames:'processId processGroup processName processState processPrio
		processUsedStack processTotalStack processWhere processInstance
		processCurrentSegment processSwitch prioVal idVal groupVal'
	classVariableNames:''
	poolDictionaries:''
	privateIn:ProcessMonitorV2
!

!ProcessMonitorV2 class methodsFor:'documentation'!

documentation
"
    documentation to be added.

    [author:]
        Christian Penk (penk@bierfix)

    [instance variables:]

    [class variables:]

    [see also:]

"
!

examples
"
  Starting the application:
                                                                [exBegin]
    ProcessMonitorV2 open

                                                                [exEnd]

  more examples to be added:
                                                                [exBegin]
    ... add code fragment for 
    ... executable example here ...
                                                                [exEnd]
"
!

history
    "Created: / 14.1.2003 / 11:16:10 / penk"
! !

!ProcessMonitorV2 class methodsFor:'defaults'!

defaultIcon
    |i|

    i := Image fromFile:'ProcMon.xbm'.
    i notNil ifTrue:[^ i].
    ^ super defaultIcon

    "Modified: 23.1.1997 / 02:52:31 / cg"
!

defaultLabel
    ^ 'Process Monitor'
! !

!ProcessMonitorV2 class methodsFor:'help specs'!

helpSpec
    "This resource specification was automatically generated
     by the UIHelpTool of ST/X."

    "Do not manually edit this!! If it is corrupted,
     the UIHelpTool may not be able to read the specification."

    "
     UIHelpTool openOnClass:ProcessMonitorV2    
    "

    <resource: #help>

    ^ super helpSpec addPairsFrom:#(

#Debug
''

#Details
''

#Inspect
''

#'Lower Prio'
''

#'Raise Prio'
''

#Restart
''

#Resume
''

#Stop
''

#Suspend
''

#Terminate
''

#'Terminate Group'
''

#'Update Process List'
''

)
! !

!ProcessMonitorV2 class methodsFor:'image specs'!

detailsMenuIconDown
    "This resource specification was automatically generated
     by the ImageEditor of ST/X."

    "Do not manually edit this!! If it is corrupted,
     the ImageEditor may not be able to read the specification."

    "
     self detailsMenuIconDown inspect
     ImageEditor openOnClass:self andSelector:#detailsMenuIconDown
     Icon flushCachedIcons
    "

    <resource: #image>

    ^Icon
        constantNamed:#'ProcessMonitorV2 class detailsMenuIconDown'
        ifAbsentPut:[(Depth1Image new) width: 7; height: 5; photometric:(#palette); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@b') ; colorMapFromArray:#[0 0 0 255 255 255]; mask:((Depth1Image new) width: 7; height: 5; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@A@(UJ(b') ; yourself); yourself]
!

detailsMenuIconUp
    "This resource specification was automatically generated
     by the ImageEditor of ST/X."

    "Do not manually edit this!! If it is corrupted,
     the ImageEditor may not be able to read the specification."

    "
     self detailsMenuIconUp inspect
     ImageEditor openOnClass:self andSelector:#detailsMenuIconUp
     Icon flushCachedIcons
    "

    <resource: #image>

    ^Icon
        constantNamed:#'ProcessMonitorV2 class detailsMenuIconUp'
        ifAbsentPut:[(Depth1Image new) width: 7; height: 5; photometric:(#palette); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@b') ; colorMapFromArray:#[0 0 0 255 255 255]; mask:((Depth1Image new) width: 7; height: 5; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'*%P(D@@b') ; yourself); yourself]
!

process22x22Icon
    "This resource specification was automatically generated
     by the ImageEditor of ST/X."

    "Do not manually edit this!! If it is corrupted,
     the ImageEditor may not be able to read the specification."

    "
     self process22x22Icon inspect
     ImageEditor openOnClass:self andSelector:#process22x22Icon
     Icon flushCachedIcons
    "

    <resource: #image>

    ^Icon
        constantNamed:#'ProcessMonitorV2 class process22x22Icon'
        ifAbsentPut:[(Depth8Image new) width: 22; height: 22; photometric:(#palette); bitsPerSample:(#(8 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@EA0@@@@@@@@@@@@@@@@@@@@@@@@@@AP\@@@@@@@@@@@@@@@@@
@@@GAP@@APXFB@@@AP\@@@@@@@@@@@@@B@XEAPXFA XEAPXH@@@@@@@@@@@@@@@GA XFA XFA XH@@@@@@@@@@@@@@@@APXFA0 GA XFA0@@@@@@@@@@@@@@
APXFA0 @@@TFA XG@@@@@@@@@@@EAPXFA  @@@@@APXFA TG@@@@@@@@B@ FA XG@@@@@@TFA XHB@@@@@@@@@@@A0\FA T@@@TFA XH@@@@@@@@@@@@@@@G
A XFAPTFA XH@@@@@@@@@@@@@@@@APXFA XFA XFB@@@@@@@@@@@@@@@APXHA0XFA XFAPXH@@@@@@@@@@@@@@\H@@@EA XG@@@GB@@@@@@@@@@@@@@@@@@@
@@TH@@@@@@@@@@@@@@@@@@@@@@@@@@@EB@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@a') ; colorMapFromArray:#[0 0 0 128 128 128 160 160 160 195 195 195 220 220 220 255 255 255 194 194 194 161 161 165 127 127 127]; mask:((Depth1Image new) width: 22; height: 22; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@F@@@O@@COL@G?>@G?>@C?<@C?<@O??@_9? _9? O??@C?<@C?<@G?>@G?>@COL@@O@@@F@@@@@@@@@@@@@@') ; yourself); yourself]
!

processDebug22x22Icon
    "This resource specification was automatically generated
     by the ImageEditor of ST/X."

    "Do not manually edit this!! If it is corrupted,
     the ImageEditor may not be able to read the specification."

    "
     self processDebug22x22Icon inspect
     ImageEditor openOnClass:self andSelector:#processDebug22x22Icon
     Icon flushCachedIcons
    "

    <resource: #image>

    ^Icon
        constantNamed:#'ProcessMonitorV2 class processDebug22x22Icon'
        ifAbsentPut:[(Depth8Image new) width: 22; height: 22; photometric:(#palette); bitsPerSample:(#(8 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@F@0@@@@@@@@@@@@@@@@@@@@@@@@@@A L@@@@@@@@@@@@@@@@@
@@@CA @@A PD@P@@A L@@@@@@@@@@@@@@PPFA PDA@PFA PA@@@@@@@@@@@@@@@CA@PD@@@DA@PA@@@@@@@@@@@@@@@@A P@@0DC@@@D@0@@@@@@@@@@@@@@
A PD@0@@@@X@@@@@@@@@@@@@@@@FA PDA@D@@@@@@@HB@ HB@ @@@@@@@PDDA@@@@@@@@ HBAPTEAPTB@@@@@@@@@0@B@ @B@ HEAPTEAPTEAPH@@@@@@@HB
APTE@@HEAPTEAPTEAPTE@ @@@@@B@ TEAP@BAPTEAPTEAPTEAPH@@@@@@@HEAPT@@@@@@@@@@@@@@@@@@@@@@@HBAPTE@@HBAPTEAPTEAPTE@ @@@@@@@ HE
@ @B@ HEAPTEAPTE@ H@@@@@@@@@@@@@@@HB@ HB@ HB@ @@@@@@@@@@@@@@@@@@@@@B@ HB@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@a') ; colorMapFromArray:#[0 0 0 127 127 127 128 0 0 161 161 165 194 194 194 255 0 0 255 255 255]; mask:((Depth1Image new) width: 22; height: 22; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@F@@@O@@COL@G?>@G?>@C?= C??XO?? _=?0_??8O??<???<C??<G??<???<_??<@??8@G?0@L? @Q#X@FA ') ; yourself); yourself]
!

processInspect22x22Icon
    "This resource specification was automatically generated
     by the ImageEditor of ST/X."

    "Do not manually edit this!! If it is corrupted,
     the ImageEditor may not be able to read the specification."

    "
     self processInspect22x22Icon inspect
     ImageEditor openOnClass:self andSelector:#processInspect22x22Icon
     Icon flushCachedIcons
    "

    <resource: #image>

    ^Icon
        constantNamed:#'ProcessMonitorV2 class processInspect22x22Icon'
        ifAbsentPut:[(Depth8Image new) width: 22; height: 22; photometric:(#palette); bitsPerSample:(#(8 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@EA0@@@@@@@@@@@@@@@@@@@@@@@@@@AP\@@@@@@@@@@@@@@@@@
@@@GAP@@APXFB@@@AP\@@@@@@@@@@@@@B@XEAPXFA XEAPXH@@@@@@@@@@@@@@@GA XFA @@@@XH@@@@@@@@@@@@@@@@APXF@@@BCPH@@@@@@@@@@@@@@@@@
APXF@@0MCP4MCP0@@@@@@@@@@@@EAPXFA @MCPTEAP4M@@TG@@@@@@@@B@ FA @BCPTEAP4MCPH@B@@@@@@@@@@@A0\@CP4EAP4MCP4M@@@@@@@@@@@@@@@G
@@HMAP4MCP4M@ @@@@@@@@@@@@@@APX@CP4MCP4MCP@@@@@@@@@@@@@@APXH@@0MCP4MCP0@BP@@@@@@@@@@@@\H@@@@@@HM@ @@@ @@@@@@@@@@@@@@@@@@
@@T@@@@@B @K@0@@@@@@@@@@@@@@@@@EB@@@@@@@C ,C@@@@@@@@@@@@@@@@@@@@@@@@@@@NB0L@@@@@@@@@@@@@@@@@@@@@@@@@@@8K@0@@@@@@@@@@@@@@
@@@@@@@@@@@@C ,@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@a') ; colorMapFromArray:#[0 0 0 128 128 128 160 160 160 195 195 195 220 220 220 255 255 255 194 194 194 161 161 165 127 127 127 120 120 120 0 64 64 88 88 88 80 80 80 200 200 200 48 48 48]; mask:((Depth1Image new) width: 22; height: 22; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@F@@@O@@COL@G?>@G?>@C?<@C?<@O??@_?? _?? O??@C?>@C?<@G?>@G??@CO/ @OG0@FC8@@A<@@@<@@@X') ; yourself); yourself]
!

processLowerPrio22x22Icon
    "This resource specification was automatically generated
     by the ImageEditor of ST/X."

    "Do not manually edit this!! If it is corrupted,
     the ImageEditor may not be able to read the specification."

    "
     self processLowerPrio22x22Icon inspect
     ImageEditor openOnClass:self andSelector:#processLowerPrio22x22Icon
     Icon flushCachedIcons
    "

    <resource: #image>

    ^Icon
        constantNamed:#'ProcessMonitorV2 class processLowerPrio22x22Icon'
        ifAbsentPut:[(Depth8Image new) width: 22; height: 22; photometric:(#palette); bitsPerSample:(#(8 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@EA0@@@@@@@@@@@@@@@@@@@@@@@@@@AP\@@@@@@@@@@@@@@@@@
@@@GAP@@APXFB@@@AP\@@@@@@@@@@@@@B@XEAPXFA XEAPXH@@@@@@@@@@@@@@@GA XFA XFA XH@@@@@@@@@@@@@@@@APXFA0 GA XFA0@@@@@@@@@@@@@@
APXFA0 @@@TFA XG@@@@@@@@@@@EAPXFA  @@@@@APXFA TG@@@@@@@@B@ FA XG@@TEAPTEAPTEAPTEAPT@@@@@A0\FA TEAPTE@@@@@@@EAPTE@@@@@@@G
A XFAPTEAP@@@@@@APTEAP@@@@@@APXFA TEAPT@@@@@@@TEAPT@@@@@APXHA0XEAPTE@@@@@@@EAPTE@@@@@@\H@@@EAPTEAP@@@@@@APTEAP@@@@@@@@@@
@@TE@@@@@@@@@@@@APT@@@@@@@@@@@@EAPT@@@@@@@@@APTE@@@@@@@@@@@@APTEAP@@@@@@APTEAP@@@@@@@@@@@@TEAPTE@@@@APTEAPT@@@@@@@@@@@@E
APTEAPT@APTEAPTE@@@@@@@@@@@@APTEAPTEAPTEAPTEAP@a') ; colorMapFromArray:#[0 0 0 128 128 128 160 160 160 195 195 195 220 220 220 255 255 255 194 194 194 161 161 165 127 127 127]; mask:((Depth1Image new) width: 22; height: 22; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@F@@@O@@COL@G?>@G?>@C?<@C?<@O??@_9? _??<O??<C??<C??<G??<G??<CO?<@O?<@G?<@G?<@G?<@G?<') ; yourself); yourself]
!

processRaisePrio22x22Icon
    "This resource specification was automatically generated
     by the ImageEditor of ST/X."

    "Do not manually edit this!! If it is corrupted,
     the ImageEditor may not be able to read the specification."

    "
     self processRaisePrio22x22Icon inspect
     ImageEditor openOnClass:self andSelector:#processRaisePrio22x22Icon
     Icon flushCachedIcons
    "

    <resource: #image>

    ^Icon
        constantNamed:#'ProcessMonitorV2 class processRaisePrio22x22Icon'
        ifAbsentPut:[(Depth8Image new) width: 22; height: 22; photometric:(#palette); bitsPerSample:(#(8 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@EA0@@@@@@@@@@@@@@@@@@@@@@@@@@AP\@@@@@@@@@@@@@@@@@
@@@GAP@@APXFB@@@AP\@@@@@@@@@@@@@B@XEAPXFA XEAPXH@@@@@@@@@@@@@@@GA XFA XFA XH@@@@@@@@@@@@@@@@APXFA0 GA XFA0@@@@@@@@@@@@@@
APXFA0 @@@TFA XG@@@@@@@@@@@EAPXFA  @@@@@APXFA TG@@@@@@@@B@ FA XG@@TEAPTEAPTEAPTEAPT@@@@@A0\FA TEAPTEAPT@APTEAPTE@@@@@@@G
A XFAPTEAPT@@@@EAPTEAP@@@@@@APXFA TEAPT@@@@@@@TEAPT@@@@@APXHA0XEAPT@@@@@@@@@APTE@@@@@@\H@@@EAPT@@@@@@@@@@@@EAP@@@@@@@@@@
@@TEAPT@@@@@@@TEAPT@@@@@@@@@@@@EAPTE@@@@@@@EAPTE@@@@@@@@@@@@APTEAP@@@@@@APTEAP@@@@@@@@@@@@TEAPT@@@@@@@TEAPT@@@@@@@@@@@@E
APTE@@@@@@@EAPTE@@@@@@@@@@@@APTEAPTEAPTEAPTEAP@a') ; colorMapFromArray:#[0 0 0 128 128 128 160 160 160 195 195 195 220 220 220 255 255 255 194 194 194 161 161 165 127 127 127]; mask:((Depth1Image new) width: 22; height: 22; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@F@@@O@@COL@G?>@G?>@C?<@C?<@O??@_9? _??<O??<C??<C??<G??<G??<CO?<@O?<@G?<@G?<@G?<@G?<') ; yourself); yourself]
!

processRestart22x22Icon
    "This resource specification was automatically generated
     by the ImageEditor of ST/X."

    "Do not manually edit this!! If it is corrupted,
     the ImageEditor may not be able to read the specification."

    "
     self processRestart22x22Icon inspect
     ImageEditor openOnClass:self andSelector:#processRestart22x22Icon
     Icon flushCachedIcons
    "

    <resource: #image>

    ^Icon
        constantNamed:#'ProcessMonitorV2 class processRestart22x22Icon'
        ifAbsentPut:[(Depth8Image new) width: 22; height: 22; photometric:(#palette); bitsPerSample:(#(8 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@GAP@@@@@@@@@@@@@@@@@@@@@@@@@@A0T@@@@@@@@@@@@@@@@@
@@@EA0@@A0XFA@@@A0T@@@@@@@@@@@@@A@XGA0XFA XGA0XD@@@@@@@@@@@@@@@EA XFA XF@@@@@@@@@@@@@@@@@@@@A0XFAPP@@@LC@0@@@P@@@@@@@@@@
A0XFAPP@@0LC@0@E@@@@@@@@@@@GA0XFA P@@@LC@0@FA \@@@@@@@@@A@PFA XE@@LC@0@FA XD@@@@@@@@@@@@APTFA @C@0L@A XD@@@@@@@@@@@@@@@E
@@LC@0LC@0L@@@@@@@@@@@@@@@@@A0X@@0LC@0L@@@@@@@@@@@@@@@@@A0XDAP@C@0L@@@@@@@@@@@@@@@@@@@TD@@@@@@L@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@a') ; colorMapFromArray:#[0 0 0 0 64 0 0 128 0 0 192 0 127 127 127 161 161 165 194 194 194 255 255 255]; mask:((Depth1Image new) width: 22; height: 22; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@F@@@O@@COL@G?>@G?>@C?>@C?? O??0_?>P_?>HO?<@C?= C?30G?''8G7/<CCO0@PC0@HG @L_ @G?@@A<@') ; yourself); yourself]
!

processResume22x22Icon
    "This resource specification was automatically generated
     by the ImageEditor of ST/X."

    "Do not manually edit this!! If it is corrupted,
     the ImageEditor may not be able to read the specification."

    "
     self processResume22x22Icon inspect
     ImageEditor openOnClass:self andSelector:#processResume22x22Icon
     Icon flushCachedIcons
    "

    <resource: #image>

    ^Icon
        constantNamed:#'ProcessMonitorV2 class processResume22x22Icon'
        ifAbsentPut:[(Depth8Image new) width: 22; height: 22; photometric:(#palette); bitsPerSample:(#(8 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@EA0@@@@@@@@@@@@@@@@@@@@@@@@@@AP\@@@@@@@@@@@@@@@@@
@@@GAP@@APXFB@@@AP\@@@@@@@@@@@@@B@XEAPXFA XEAPXH@@@@@@@@@@@@@@@GA XFA XFA XH@@@@@@@@@@@@@@@@APXFA0 GA XFA0@@@@@@@@@@@@@@
APXFA0 @@@TFA XG@@@@@@@@@@@EAPXFA  @@@@@APXFA TG@@@@@@@@B@ FA XG@@TEAPT@APTEAPTEAPT@@@@@A0\FA TEAPTE@@@EAPTEAPTE@@@@@@@G
A XFAPTEAP@@@@TEAPTEAP@@@@@@APXFA TEAPT@@@@@APTEAPT@@@@@APXHA0XEAPTE@@@@@@@EAPTE@@@@@@\H@@@EAPTEAP@@@@@@@@TEAP@@@@@@@@@@
@@TEAPT@@@@@@@@EAPT@@@@@@@@@@@@EAPTE@@@@@@@EAPTE@@@@@@@@@@@@APTEAP@@@@@EAPTEAP@@@@@@@@@@@@TEAPT@@@@EAPTEAPT@@@@@@@@@@@@E
APTE@@@EAPTEAPTE@@@@@@@@@@@@APTEAP@EAPTEAPTEAP@a') ; colorMapFromArray:#[0 0 0 128 128 128 160 160 160 195 195 195 220 220 220 255 255 255 194 194 194 161 161 165 127 127 127]; mask:((Depth1Image new) width: 22; height: 22; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@F@@@O@@COL@G?>@G?>@C?<@C?<@O??@_9? _??<O??<C??<C??<G??<G??<CO?<@O?<@G?<@G?<@G?<@G?<') ; yourself); yourself]
!

processStop22x22Icon
    "This resource specification was automatically generated
     by the ImageEditor of ST/X."

    "Do not manually edit this!! If it is corrupted,
     the ImageEditor may not be able to read the specification."

    "
     self processStop22x22Icon inspect
     ImageEditor openOnClass:self andSelector:#processStop22x22Icon
     Icon flushCachedIcons
    "

    <resource: #image>

    ^Icon
        constantNamed:#'ProcessMonitorV2 class processStop22x22Icon'
        ifAbsentPut:[(Depth8Image new) width: 22; height: 22; photometric:(#palette); bitsPerSample:(#(8 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@EA0@@@@@@@@@@@@@@@@@@@@@@@@@@AP\@@@@@@@@@@@@@@@@@
@@@GAP@@APXFB@@@AP\@@@@@@@@@@@@@B@XEAPXFA XEAPXH@@@@@@@@@@@@@@@GA XFA XFA XH@@@@@@@@@@@@@@@@APXFA0 GA XFA0@@@@@@@@@@@@@@
APXFA0 @@@TFA XG@@@@@@@@@@@EAPXFA  @@@@@APXFA TG@@@@@@@@B@ FA XG@@TEAPTEAPTEAPTEAPT@@@@@A0\FA TEAPTEAPTEAPTEAPTE@@@@@@@G
A XFAPTE@@@@APT@@@@EAP@@@@@@APXFA TEAP@@@@TE@@@@APT@@@@@APXHA0XEAPT@@@@EAP@@@@TE@@@@@@\H@@@EAPTE@@@@APT@@@@EAP@@@@@@@@@@
@@TEAP@@@@TE@@@@APT@@@@@@@@@@@@EAPT@@@@EAP@@@@TE@@@@@@@@@@@@APTE@@@@APT@@@@EAP@@@@@@@@@@@@TEAP@@@@TE@@@@APT@@@@@@@@@@@@E
APTEAPTEAPTEAPTE@@@@@@@@@@@@APTEAPTEAPTEAPTEAP@a') ; colorMapFromArray:#[0 0 0 128 128 128 160 160 160 195 195 195 220 220 220 255 255 255 194 194 194 161 161 165 127 127 127]; mask:((Depth1Image new) width: 22; height: 22; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@F@@@O@@COL@G?>@G?>@C?<@C?<@O??@_9? _??<O??<C??<C??<G??<G??<CO?<@O?<@G?<@G?<@G?<@G?<') ; yourself); yourself]
!

processSuspend22x22Icon
    "This resource specification was automatically generated
     by the ImageEditor of ST/X."

    "Do not manually edit this!! If it is corrupted,
     the ImageEditor may not be able to read the specification."

    "
     self processSuspend22x22Icon inspect
     ImageEditor openOnClass:self andSelector:#processSuspend22x22Icon
     Icon flushCachedIcons
    "

    <resource: #image>

    ^Icon
        constantNamed:#'ProcessMonitorV2 class processSuspend22x22Icon'
        ifAbsentPut:[(Depth8Image new) width: 22; height: 22; photometric:(#palette); bitsPerSample:(#(8 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@EA0@@@@@@@@@@@@@@@@@@@@@@@@@@AP\@@@@@@@@@@@@@@@@@
@@@GAP@@APXFB@@@AP\@@@@@@@@@@@@@B@XEAPXFA XEAPXH@@@@@@@@@@@@@@@GA XFA XFA XH@@@@@@@@@@@@@@@@APXFA0 GA XFA0@@@@@@@@@@@@@@
APXFA0 @@@TFA XG@@@@@@@@@@@EAPXFA  @@@@@APXFA TG@@@@@@@@B@ FA XG@@TEAPTEAPTEAPTEAPT@@@@@A0\FA TEAPTEAPTEAPTEAPTE@@@@@@@G
A XFAPTE@@@@@@@@@@@EAP@@@@@@APXFA TEAP@@@@@@@@@@APT@@@@@APXHA0XEAPT@@@@@@@@@@@TE@@@@@@\H@@@EAPTE@@@@@@@@@@@EAP@@@@@@@@@@
@@TEAP@@@@@@@@@@APT@@@@@@@@@@@@EAPT@@@@@@@@@@@TE@@@@@@@@@@@@APTE@@@@@@@@@@@EAP@@@@@@@@@@@@TEAP@@@@@@@@@@APT@@@@@@@@@@@@E
APTEAPTEAPTEAPTE@@@@@@@@@@@@APTEAPTEAPTEAPTEAP@a') ; colorMapFromArray:#[0 0 0 128 128 128 160 160 160 195 195 195 220 220 220 255 255 255 194 194 194 161 161 165 127 127 127]; mask:((Depth1Image new) width: 22; height: 22; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@F@@@O@@COL@G?>@G?>@C?<@C?<@O??@_9? _??<O??<C??<C??<G??<G??<CO?<@O?<@G?<@G?<@G?<@G?<') ; yourself); yourself]
!

processTerminate22x22Icon
    "This resource specification was automatically generated
     by the ImageEditor of ST/X."

    "Do not manually edit this!! If it is corrupted,
     the ImageEditor may not be able to read the specification."

    "
     self processTerminate22x22Icon inspect
     ImageEditor openOnClass:self andSelector:#processTerminate22x22Icon
     Icon flushCachedIcons
    "

    <resource: #image>

    ^Icon
        constantNamed:#'ProcessMonitorV2 class processTerminate22x22Icon'
        ifAbsentPut:[(Depth8Image new) width: 22; height: 22; photometric:(#palette); bitsPerSample:(#(8 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@EA0@@@@@@@@@@@@@@@@@@@@@@@@@@AP\@@@@@@@@@@@@@@@@@
@@@GAP@@APXFB@@@AP\@@@@@@@@@@@@@B@XEAPXFA XEAPXH@@@@@@@@@@@@@@@GA XFA XFA XH@@@@@@@@@@@@@@@@APXFA0 GA XFA0@@@@@@@@@@@@@@
APXFA0 @@@TFA XG@@@@@@@@@@@EAPXFA  @@@@@APXFA TGC@@@@@@@B@ FA XG@@@LC@TFA XHC@,K@@@@@@@@A0\FA TLB0,LC@XHC@,KBP@@@@@@@@@G
A XFAPTJB0,LB0,KBP@@@@@@@@@@APXFA XFA (KB0,KBP@@@@@@@@@@APXHA0XFA XFC@,KC@@@@@@@@@@@@@\H@@@EA XGC@,KB00@@@@@@@@@@@@@@@@@
@@THC@,I@@(KC@@@@@@@@@@@@@@@@@@EB@0I@@@@B ,@@@@@@@@@@@@@@@@@@@0K@@@@@@@JB0@@@@@@@@@@@@@@@@@LBP@@@@@@@@,@@@@@@@@@@@@@@@@@
C@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@a') ; colorMapFromArray:#[0 0 0 128 128 128 160 160 160 195 195 195 220 220 220 255 255 255 194 194 194 161 161 165 127 127 127 64 0 0 128 0 0 192 0 0 255 0 0]; mask:((Depth1Image new) width: 22; height: 22; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@F@@@O@@COL@G?>@G?>@C?<@C?<@O??@_9? _;?0O??0C?? C??@G?>@G?>@CO?@@O#@@GA @C@ @B@@@@@@') ; yourself); yourself]
!

processTerminateGroup22x22Icon
    "This resource specification was automatically generated
     by the ImageEditor of ST/X."

    "Do not manually edit this!! If it is corrupted,
     the ImageEditor may not be able to read the specification."

    "
     self processTerminateGroup22x22Icon inspect
     ImageEditor openOnClass:self andSelector:#processTerminateGroup22x22Icon
     Icon flushCachedIcons
    "

    <resource: #image>

    ^Icon
        constantNamed:#'ProcessMonitorV2 class processTerminateGroup22x22Icon'
        ifAbsentPut:[(Depth8Image new) width: 22; height: 22; photometric:(#palette); bitsPerSample:(#(8 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@AP\@@@@@@@@@@@@@@@@@@@@@@@@@@@TG@@@@@@@@@@@@@@@@@@@@A0T@@@TFA  @@@TG@@@@@@@@@@@@
@@ FAPTF@@@FAPTFB@@@@@@@@@@@@@@@A0XF@@TG@@XFB@@@@@@@@@@@@@@@@@@FA @EA0@FA @@@@@@@@@@@@@@@@\E@@@EA XH@@@EA0@@@@@@@@@@AP@H
A TEA XFA TEA  @A0@@@@@@@@ H@@\FA XFA XFA  @B@ @@@@@@@@@@@@EA XGB@\FA XG@@@@@@@L@@@@@@@EA XGB@@@AP0LA \@@@@LB0,@@@TEA XF
B@@FA 0KB00LAP\LB0,I@@@HB@XFA \@A X@AP(KB00KB0,I@@@@@@@GA0XFAP@@APXFB ,KB0,I@@@@@@@@@@\FA XEAPXFA  LB0,L@@@@@@@@@@@EA XF
A XFA XLB0,KC@@@@@@@@@@EA  GA XFA XLB0$@B ,L@@@@@@@@A0 @@@TFA \@C@$H@@@JB0@@@@@@@@@@@@@@AP @C@,@@@@@@@(K@@@@@@@@@@@@@@TH
@@0I@@@@@@@@B0@@@@@@@@@@@@@@@@@L@@@@@@@@@@@@@@@a') ; colorMapFromArray:#[0 0 0 128 128 128 160 160 160 195 195 195 220 220 220 255 255 255 194 194 194 161 161 165 127 127 127 64 0 0 128 0 0 192 0 0 255 0 0]; mask:((Depth1Image new) width: 22; height: 22; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@L@@@^@@F^X@O?<@O?<@G?8@G?8@_?>@???@???@_?>P_?>8???8???0_?? G??@G??@O?? O?= F_80@_ P@M@@') ; yourself); yourself]
!

terminateGroupIcon
    "This resource specification was automatically generated
     by the ImageEditor of ST/X."

    "Do not manually edit this!! If it is corrupted,
     the ImageEditor may not be able to read the specification."

    "
     self terminateGroupIcon inspect
     ImageEditor openOnClass:self andSelector:#terminateGroupIcon
     Icon flushCachedIcons
    "

    <resource: #image>

    ^Icon
        constantNamed:#'ProcessMonitorV2 class terminateGroupIcon'
        ifAbsentPut:[(Depth8Image new) width: 22; height: 20; photometric:(#palette); bitsPerSample:(#(8 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'
@PDA@PXJB (JB (JB (JB TE@PDA@PDA@PXJB (JB (JB (JB (JA0TA@PD@@PXJB (JB (JB (JB (JB (JA D@@@HDB (J@ HJB (JB PDA@(JB X@@@@@
@P\G@PDAA (JB XA@PDFA XA@@@@A DA@PDA@PXJB (F@PDA@PDA@PX@A \A@PD@@@@@@@@@A DJ@@@@@@@@@@XJB DA@@,KB0,K@@@A@@,KB0,KB0@AA XF
B (@B0,KB0,@@@,KB0,KB0@A@PDA@PXJB @KB0,KB0,KB0,KB0@A@PDA@PXJB (J@@,KB0,KB0,KB0@A@PD@@PXJB (JB (@B0,KB0,KB0@JA D@@@HDB (J
@ HJB @KB0,KB0@JB X@@@@@@P\G@PDAA @KB0,KB0,K@@XA@@@@@@DA@PDA@P@KB0,KB0,KB0,@@P@@@@@A@PDA@P@KB0,KB0@KB0,KB0@@@@@@@@DA@P@K
B0,KB0@@@@,KB0,K@@@@@@@@@@@KB0,KB0@A@@@@B0,KB0,@@@@@@@@@@@@@@@@A@P@@@@@@@@@@@@@@@@@@@@@@@@DA@P@@@@@@@@@@@@@b') ; colorMapFromArray:#[0 0 0 48 48 48 56 59 56 64 68 64 88 92 88 128 128 128 160 160 160 192 192 192 216 219 216 239 244 239 248 252 248 160 0 0]; mask:((Depth1Image new) width: 22; height: 20; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'???<???<_??8_??0O??0_??8???<???<???<???<???<_??8_??0O??0O??0O??0G?/8A?''<A?#<@G@@') ; yourself); yourself]
!

terminateIcon
    "This resource specification was automatically generated
     by the ImageEditor of ST/X."

    "Do not manually edit this!! If it is corrupted,
     the ImageEditor may not be able to read the specification."

    "
     self terminateIcon inspect
     ImageEditor openOnClass:self andSelector:#terminateIcon
     Icon flushCachedIcons
    "

    <resource: #image>

    ^Icon
        constantNamed:#'ProcessMonitorV2 class terminateIcon'
        ifAbsentPut:[(Depth8Image new) width: 16; height: 16; photometric:(#palette); bitsPerSample:(#(8 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@C@@@@@@@@@@LC@@@@@@@C@ H@@@@@@@LB@ LC@@@C@ H@@@@@@@@@@@DB@ LB
@ H@@@@@@@@@@@@@@PHB@ H@@@@@@@@@@@@@@@@C@ HC@@@@@@@@@@@@@@@C@ HB@0@@@@@@@@@@@@@C@ @@@PHC@@@@@@@@@@@@@0@@@@@A@ @@@@@@@@@@
@0H@@@@@@@DB@@@@@@@@@@L@@@@@@@@@@ @@@@@@@@@C@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@a') ; colorMapFromArray:#[64 0 0 128 0 0 192 0 0 255 0 0]; mask:((Depth1Image new) width: 16; height: 16; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@HCA0_O@_8@?@A8@O A7@FL@0XC@ H@@@@@@@b') ; yourself); yourself]
!

updateProcesses
    "This resource specification was automatically generated
     by the ImageEditor of ST/X."

    "Do not manually edit this!! If it is corrupted,
     the ImageEditor may not be able to read the specification."

    "
     self updateProcesses inspect
     ImageEditor openOnClass:self andSelector:#updateProcesses
     Icon flushCachedIcons
    "

    <resource: #image>

    ^Icon
        constantNamed:#'ProcessMonitorV2 class updateProcesses'
        ifAbsentPut:[(Depth4Image new) width: 22; height: 22; photometric:(#palette); bitsPerSample:(#(4 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#L@D@@@@@@@@@H3H@@@@@@@@@@@@3H@@@@@@@@@@@@#H@@@@@@@@@@@
@CL @@@@@@@@@@@"L3L @@@@@@@@@@H3L @@@@@@@@@@@BL @@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@b') ; colorMapFromArray:#[0 0 0 0 64 0 0 128 0 0 192 0]; mask:((Depth1Image new) width: 22; height: 22; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@@@@@@@G0@@_<@@?N@@>B@A<A@A<@@G?L@C>^@A<?@@9? @P^@B@^@A@<@A3<@@?8@@O @@@@@@@@@@@@@') ; yourself); yourself]
!

viewDetailsIcon
    "This resource specification was automatically generated
     by the ImageEditor of ST/X."

    "Do not manually edit this!! If it is corrupted,
     the ImageEditor may not be able to read the specification."

    "
     self viewDetailsIcon inspect
     ImageEditor openOnClass:self andSelector:#viewDetailsIcon
     Icon flushCachedIcons
    "

    <resource: #image>

    ^Icon
        constantNamed:#'ProcessMonitorV2 class viewDetailsIcon'
        ifAbsentPut:[(Depth1Image new) width: 16; height: 16; photometric:(#palette); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@b') ; colorMapFromArray:#[0 0 0 255 255 255]; mask:((Depth1Image new) width: 16; height: 16; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@@]+X@@@@@]+X@@@@@]+X@@@@@]+X@@@@@@@@b') ; yourself); yourself]
! !

!ProcessMonitorV2 class methodsFor:'interface specs'!

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:ProcessMonitorV2 andSelector:#windowSpec
     ProcessMonitorV2 new openInterface:#windowSpec
     ProcessMonitorV2 open
    "

    <resource: #canvas>

    ^ 
     #(#FullSpec
        #name: #windowSpec
        #window: 
       #(#WindowSpec
          #label: 'ProcessMonitorV2'
          #name: 'ProcessMonitorV2'
          #min: #(#Point 10 10)
          #max: #(#Point 1024 768)
          #bounds: #(#Rectangle 16 42 807 400)
          #menu: #mainMenu
        )
        #component: 
       #(#SpecCollection
          #collection: #(
           #(#MenuPanelSpec
              #name: 'ToolBar1'
              #layout: #(#LayoutFrame 0 0.0 0 0 0 1.0 32 0)
              #menu: #toolBarMainMenu
              #textDefault: true
            )
           #(#DataSetSpec
              #name: 'Process Table'
              #layout: #(#LayoutFrame 0 0.0 32 0.0 0 1.0 -23 1)
              #model: #selectedProcesses
              #menu: #tableMenu
              #hasHorizontalScrollBar: true
              #hasVerticalScrollBar: true
              #dataList: #processList
              #useIndex: false
              #has3Dsepartors: false
              #doubleClickSelector: #doubleClickedAt:
              #columnHolder: #tableColumns
              #multipleSelectOk: true
              #verticalSpacing: 0
              #postBuildCallback: #postBuildProcessTable:
            )
           #(#ArrowButtonSpec
              #name: 'ArrowButton1'
              #layout: #(#LayoutFrame -22 1 -22 1 0 1 0 1)
              #model: #increaseupdateListDelayTime
              #enableChannel: #enableIncreaseListDelayTime
              #isTriggerOnDown: true
              #actionValue: ''
              #direction: #right
            )
           #(#InputFieldSpec
              #name: 'EntryField1'
              #layout: #(#LayoutFrame -66 1 -22 1 -22 1 0 1)
              #model: #updateListDelayTime
              #acceptOnReturn: true
              #acceptOnTab: true
              #acceptOnLostFocus: true
              #acceptOnPointerLeave: false
            )
           #(#ArrowButtonSpec
              #name: 'ArrowButton2'
              #layout: #(#LayoutFrame -88 1 -22 1 -66 1 0 1)
              #model: #decreaseupdateListDelayTime
              #enableChannel: #enableDecreaseListDelayTime
              #isTriggerOnDown: true
              #actionValue: ''
              #direction: #left
            )
           #(#LabelSpec
              #label: 'Update List Delay:'
              #name: 'Label1'
              #layout: #(#LayoutFrame 559 0 -20 1 698 0 0 1)
              #translateLabel: true
              #adjust: #right
            )
           #(#LabelSpec
              #label: 'Update Contents Delay:'
              #name: 'Label2'
              #layout: #(#LayoutFrame 288 0 -20 1 446 0 0 1)
              #translateLabel: true
              #adjust: #right
            )
           #(#ArrowButtonSpec
              #name: 'ArrowButton3'
              #layout: #(#LayoutFrame -273 1 -22 1 -251 1 0 1)
              #model: #increaseupdateContentsDelayTime
              #enableChannel: #enableIncreaseContentsDelayTime
              #isTriggerOnDown: true
              #actionValue: ''
              #direction: #right
            )
           #(#InputFieldSpec
              #name: 'EntryField2'
              #layout: #(#LayoutFrame -317 1 -22 1 -273 1 0 1)
              #model: #updateContentsDelayTime
              #acceptOnReturn: true
              #acceptOnTab: true
              #acceptOnLostFocus: true
              #acceptOnPointerLeave: false
            )
           #(#ArrowButtonSpec
              #name: 'ArrowButton4'
              #layout: #(#LayoutFrame -339 1 -22 1 -317 1 0 1)
              #model: #decreaseupdateContentsDelayTime
              #enableChannel: #enableDecreaseContentsDelayTime
              #isTriggerOnDown: true
              #actionValue: ''
              #direction: #left
            )
           )
         
        )
      )
! !

!ProcessMonitorV2 class methodsFor:'menu specs'!

mainMenu
    "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:ProcessMonitorV2 andSelector:#mainMenu
     (Menu new fromLiteralArrayEncoding:(ProcessMonitorV2 mainMenu)) startUp
    "

    <resource: #menu>

    ^ 
     #(#Menu
        #(
         #(#MenuItem
            #label: 'File'
            #translateLabel: true
            #submenu: 
           #(#Menu
              #(
               #(#MenuItem
                  #label: 'Exit'
                  #itemValue: #closeRequest
                  #translateLabel: true
                )
               )
              nil
              nil
            )
          )
         #(#MenuItem
            #label: 'Process'
            #translateLabel: true
            #submenuChannel: #tableMenu
          )
         #(#MenuItem
            #label: 'View'
            #translateLabel: true
            #submenuChannel: #viewDetailsMenuSpec
          )
         #(#MenuItem
            #label: 'Help'
            #translateLabel: true
            #startGroup: #right
            #submenu: 
           #(#Menu
              #(
               #(#MenuItem
                  #label: 'Documentation'
                  #itemValue: #openDocumentation
                  #translateLabel: true
                )
               #(#MenuItem
                  #label: '-'
                )
               #(#MenuItem
                  #label: 'About this Application'
                  #itemValue: #openAboutThisApplication
                  #translateLabel: true
                )
               )
              nil
              nil
            )
          )
         )
        nil
        nil
      )
!

tableMenu
    "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:ProcessMonitorV2 andSelector:#tableMenu
     (Menu new fromLiteralArrayEncoding:(ProcessMonitorV2 tableMenu)) startUp
    "

    <resource: #menu>

    ^ 
     #(#Menu
        #(
         #(#MenuItem
            #enabled: #hasSelection
            #label: 'Inspect'
            #itemValue: #inspectSelection
            #translateLabel: true
          )
         #(#MenuItem
            #enabled: #hasSelection
            #label: 'Debug'
            #itemValue: #debugProcess
            #translateLabel: true
          )
         #(#MenuItem
            #label: '-'
          )
         #(#MenuItem
            #enabled: #hasSelection
            #label: 'Resume'
            #itemValue: #resumeProcess
            #translateLabel: true
          )
         #(#MenuItem
            #enabled: #hasSelection
            #label: 'Suspend'
            #itemValue: #suspendProcess
            #translateLabel: true
          )
         #(#MenuItem
            #enabled: #hasSelection
            #label: 'Stop'
            #itemValue: #stopProcess
            #translateLabel: true
          )
         #(#MenuItem
            #label: '-'
          )
         #(#MenuItem
            #enabled: #hasSelection
            #label: 'Abort'
            #itemValue: #abortProcess
            #translateLabel: true
          )
         #(#MenuItem
            #enabled: #hasSelection
            #label: 'Terminate'
            #itemValue: #terminateProcess
            #translateLabel: true
          )
         #(#MenuItem
            #enabled: #hasSelection
            #label: 'Hard Terminate'
            #itemValue: #hardTerminateProcess
            #translateLabel: true
          )
         #(#MenuItem
            #enabled: #hasSelection
            #label: 'Terminate Group'
            #itemValue: #terminateProcessGroup
            #translateLabel: true
          )
         #(#MenuItem
            #enabled: #selectionRestartable
            #label: 'Restart'
            #itemValue: #restartProcess
            #translateLabel: true
          )
         #(#MenuItem
            #label: '-'
          )
         #(#MenuItem
            #enabled: #hasSelection
            #label: 'Raise Prio'
            #itemValue: #raisePrio
            #translateLabel: true
          )
         #(#MenuItem
            #enabled: #hasSelection
            #label: 'Lower Prio'
            #itemValue: #lowerPrio
            #translateLabel: true
          )
         )
        nil
        nil
      )
!

toolBarMainMenu
    "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:ProcessMonitorV2 andSelector:#toolBarMainMenu
     (Menu new fromLiteralArrayEncoding:(ProcessMonitorV2 toolBarMainMenu)) startUp
    "

    <resource: #menu>

    ^ 
     #(#Menu
        #(
         #(#MenuItem
            #activeHelpKey: #Inspect
            #enabled: #hasSelection
            #label: 'Inspect'
            #itemValue: #inspectSelection
            #translateLabel: true
            #isButton: true
            #labelImage: #(#ResourceRetriever #ProcessMonitorV2 #processInspect22x22Icon)
          )
         #(#MenuItem
            #activeHelpKey: #Debug
            #enabled: #hasSelection
            #label: 'Debug'
            #itemValue: #debugProcess
            #translateLabel: true
            #isButton: true
            #labelImage: #(#ResourceRetriever #ProcessMonitorV2 #processDebug22x22Icon)
          )
         #(#MenuItem
            #label: ''
          )
         #(#MenuItem
            #activeHelpKey: #Resume
            #enabled: #hasSelection
            #label: 'Resume'
            #itemValue: #resumeProcess
            #translateLabel: true
            #isButton: true
            #labelImage: #(#ResourceRetriever #ProcessMonitorV2 #processResume22x22Icon)
          )
         #(#MenuItem
            #activeHelpKey: #Suspend
            #enabled: #hasSelection
            #label: 'Suspend'
            #itemValue: #suspendProcess
            #translateLabel: true
            #isButton: true
            #labelImage: #(#ResourceRetriever #ProcessMonitorV2 #processSuspend22x22Icon)
          )
         #(#MenuItem
            #activeHelpKey: #Stop
            #enabled: #hasSelection
            #label: 'Stop'
            #itemValue: #stopProcess
            #translateLabel: true
            #isButton: true
            #labelImage: #(#ResourceRetriever #ProcessMonitorV2 #processStop22x22Icon)
          )
         #(#MenuItem
            #label: ''
          )
         #(#MenuItem
            #activeHelpKey: #Terminate
            #enabled: #hasSelection
            #label: 'Terminate'
            #itemValue: #terminateProcess
            #translateLabel: true
            #isButton: true
            #labelImage: #(#ResourceRetriever #ProcessMonitorV2 #processTerminate22x22Icon)
          )
         #(#MenuItem
            #activeHelpKey: #'Terminate Group'
            #enabled: #hasSelection
            #label: 'Terminate Group'
            #itemValue: #terminateProcessGroup
            #translateLabel: true
            #isButton: true
            #labelImage: #(#ResourceRetriever #ProcessMonitorV2 #processTerminateGroup22x22Icon)
          )
         #(#MenuItem
            #activeHelpKey: #Restart
            #enabled: #selectionRestartable
            #label: 'Restart'
            #itemValue: #restartProcess
            #translateLabel: true
            #isButton: true
            #labelImage: #(#ResourceRetriever #ProcessMonitorV2 #processRestart22x22Icon)
          )
         #(#MenuItem
            #label: ''
          )
         #(#MenuItem
            #activeHelpKey: #'Raise Prio'
            #enabled: #hasSelection
            #label: 'Raise Prio'
            #itemValue: #raisePrio
            #translateLabel: true
            #isButton: true
            #labelImage: #(#ResourceRetriever #ProcessMonitorV2 #processRaisePrio22x22Icon)
          )
         #(#MenuItem
            #activeHelpKey: #'Lower Prio'
            #enabled: #hasSelection
            #label: 'Lower Prio'
            #itemValue: #lowerPrio
            #translateLabel: true
            #isButton: true
            #labelImage: #(#ResourceRetriever #ProcessMonitorV2 #processLowerPrio22x22Icon)
          )
         #(#MenuItem
            #label: ''
          )
         #(#MenuItem
            #activeHelpKey: #'Update Process List'
            #label: 'Update'
            #itemValue: #updateView
            #translateLabel: true
            #isButton: true
            #labelImage: #(#ResourceRetriever #ProcessMonitorV2 #updateProcesses)
          )
         #(#MenuItem
            #activeHelpKey: #Details
            #label: 'View Details'
            #translateLabel: true
            #isButton: true
            #startGroup: #right
            #submenuChannel: #viewDetailsMenuSpec
            #labelImage: #(#ResourceRetriever #ProcessMonitorV2 #viewDetailsIcon)
          )
         )
        nil
        nil
      )
!

viewDetailsMenuSpec
    "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:ProcessMonitorV2 andSelector:#viewDetailsMenuSpec
     (Menu new fromLiteralArrayEncoding:(ProcessMonitorV2 viewDetailsMenuSpec)) startUp
    "

    <resource: #menu>

    ^ 
     #(#Menu
        #(
         #(#MenuItem
            #label: 'Id'
            #translateLabel: true
            #hideMenuOnActivated: false
            #indication: #showProcessId
          )
         #(#MenuItem
            #label: 'Group'
            #translateLabel: true
            #hideMenuOnActivated: false
            #indication: #showGroup
          )
         #(#MenuItem
            #label: 'State'
            #translateLabel: true
            #hideMenuOnActivated: false
            #indication: #showState
          )
         #(#MenuItem
            #label: 'Prio'
            #translateLabel: true
            #hideMenuOnActivated: false
            #indication: #showPrio
          )
         #(#MenuItem
            #label: 'Used Stack'
            #translateLabel: true
            #hideMenuOnActivated: false
            #indication: #showUsedStack
          )
         #(#MenuItem
            #label: 'Total Stack'
            #translateLabel: true
            #hideMenuOnActivated: false
            #indication: #showTotalStack
          )
         #(#MenuItem
            #label: 'Current-Segment'
            #translateLabel: true
            #hideMenuOnActivated: false
            #indication: #showCurrentSegment
          )
         #(#MenuItem
            #label: 'Switch'
            #translateLabel: true
            #hideMenuOnActivated: false
            #indication: #showSwitch
          )
         #(#MenuItem
            #label: 'Where'
            #translateLabel: true
            #hideMenuOnActivated: false
            #indication: #showWhere
          )
         #(#MenuItem
            #label: '-'
          )
         #(#MenuItem
            #label: 'Show dead Processes'
            #translateLabel: true
            #indication: #showDead
          )
         #(#MenuItem
            #label: '-'
          )
         #(#MenuItem
            #label: 'Update'
            #itemValue: #updateView
            #translateLabel: true
          )
         )
        nil
        nil
      )
! !

!ProcessMonitorV2 class methodsFor:'tableColumns specs'!

tableColumns
    "This resource specification was automatically generated
     by the DataSetBuilder of ST/X."

    "Do not manually edit this!! If it is corrupted,
     the DataSetBuilder may not be able to read the specification."

    "
     DataSetBuilder new openOnClass:ProcessMonitorV2 andSelector:#tableColumns
    "

    <resource: #tableColumns>

    ^#(
      #(#DataSetColumnSpec
         #label: 'Id'
         #id: #id
         #labelAlignment: #left
         #labelButtonType: #Button
         #labelActionSelector: #sortProcessListBy:
         #labelActionArgument: 'idVal'
         #width: 45
         #type: #number
         #model: #processId
         #canSelect: false
         #showRowSeparator: false
         #showColSeparator: false
       )
      #(#DataSetColumnSpec
         #label: 'Group'
         #id: #group
         #labelAlignment: #left
         #labelButtonType: #Button
         #labelActionSelector: #sortProcessListBy:
         #labelActionArgument: 'groupVal'
         #width: 45
         #model: #processGroup
         #canSelect: false
         #showRowSeparator: false
         #showColSeparator: false
       )
      #(#DataSetColumnSpec
         #label: 'Name'
         #id: #name
         #labelAlignment: #left
         #labelButtonType: #Button
         #labelActionSelector: #sortProcessListBy:
         #labelActionArgument: 'processName'
         #width: 200
         #model: #processName
         #canSelect: false
         #showRowSeparator: false
         #showColSeparator: false
       )
      #(#DataSetColumnSpec
         #label: 'State'
         #id: #state
         #labelAlignment: #left
         #labelButtonType: #Button
         #labelActionSelector: #sortProcessListBy:
         #labelActionArgument: 'processState'
         #width: 100
         #model: #processState
         #canSelect: false
         #showRowSeparator: false
         #showColSeparator: false
       )
      #(#DataSetColumnSpec
         #label: 'Prio'
         #id: #prio
         #labelAlignment: #left
         #labelButtonType: #Button
         #labelActionSelector: #sortProcessListBy:
         #labelActionArgument: 'prioVal'
         #width: 40
         #model: #processPrio
         #canSelect: false
         #showRowSeparator: false
         #showColSeparator: false
       )
      #(#DataSetColumnSpec
         #label: 'Used Stack'
         #id: #usedStack
         #labelAlignment: #left
         #labelButtonType: #Button
         #labelActionSelector: #sortProcessListBy:
         #labelActionArgument: 'processUsedStack'
         #columnAlignment: #right
         #width: 75
         #type: #number
         #model: #processUsedStack
         #canSelect: false
         #showRowSeparator: false
         #showColSeparator: false
       )
      #(#DataSetColumnSpec
         #label: 'Total Stack'
         #id: #totalStack
         #labelAlignment: #left
         #labelButtonType: #Button
         #labelActionSelector: #sortProcessListBy:
         #labelActionArgument: 'processTotalStack'
         #columnAlignment: #right
         #width: 75
         #model: #processTotalStack
         #canSelect: false
         #showRowSeparator: false
         #showColSeparator: false
       )
      #(#DataSetColumnSpec
         #label: 'Current-Segment'
         #id: #currentSegment
         #labelAlignment: #left
         #labelButtonType: #Button
         #labelActionSelector: #sortProcessListBy:
         #labelActionArgument: 'processCurrentSegment'
         #width: 110
         #model: #processCurrentSegment
         #canSelect: false
         #showRowSeparator: false
         #showColSeparator: false
       )
      #(#DataSetColumnSpec
         #label: 'Switch'
         #id: #switch
         #labelAlignment: #left
         #labelButtonType: #Button
         #labelActionSelector: #sortProcessListBy:
         #labelActionArgument: 'processSwitch'
         #columnAlignment: #right
         #width: 55
         #type: #number
         #model: #processSwitch
         #canSelect: false
         #showRowSeparator: false
         #showColSeparator: false
       )
      #(#DataSetColumnSpec
         #label: 'Where'
         #id: #where
         #labelAlignment: #left
         #labelButtonType: #Button
         #labelActionSelector: #sortProcessListBy:
         #labelActionArgument: 'processWhere'
         #model: #processWhere
         #canSelect: false
         #showRowSeparator: false
         #showColSeparator: false
       )
      )
    
! !

!ProcessMonitorV2 methodsFor:'actions'!

changeSelectionTo:aSelection

    aSelection notNil ifTrue:[
        | newSelection |
        newSelection := OrderedCollection new.
        aSelection do:[:processItem |
            | index | 
            index := processList findFirst:[:anItem | (anItem processInstance == processItem processInstance)].
            index ~~ 0 ifTrue:[
                newSelection add:(processList at:index).
            ].
        ].            
        self selectedProcesses value:newSelection 
    ].
!

changeSelectionToProcess:aProcessList

    aProcessList notNil ifTrue:[
        | newSelection |
        newSelection := OrderedCollection new.
        aProcessList do:[:aProcess |
            | index | 
            index := processList findFirst:[:anItem | (anItem processInstance == aProcess)].
            index ~~ 0 ifTrue:[
                newSelection add:(processList at:index).
            ].
        ].            
        self selectedProcesses value:newSelection 
    ].
!

decreaseupdateContentsDelayTime

    self updateContentsDelayTime value:(self scaledUpdateContentsDelayTime - 0.1).
    self evaluateEnableInDecreaseButtons.
!

decreaseupdateListDelayTime

    self updateListDelayTime value:(self scaledUpdateListDelayTime - 0.1).
    self evaluateEnableInDecreaseButtons.
!

doubleClickedAt:anItemIndex
    "open a debugger on the selected process"

    self debugProcess
!

evaluateEnableInDecreaseButtons

    | contDelaySmallerListDelay |

    contDelaySmallerListDelay := (self scaledUpdateContentsDelayTime <= (self scaledUpdateListDelayTime)).
    self enableDecreaseContentsDelayTime value:((self scaledUpdateContentsDelayTime <= 0.1) not).
    self enableDecreaseListDelayTime value:contDelaySmallerListDelay.
    self enableIncreaseContentsDelayTime value:contDelaySmallerListDelay.
!

getProcessList
    "select processes to display.
     Subclasses may redefine this"

    |coll|

    self needFullInformation ifTrue:[
        coll := Process allSubInstances asOrderedCollection.
    ] ifFalse:[
        coll := ProcessorScheduler knownProcesses asOrderedCollection.
    ].
    ^ coll
!

increaseupdateContentsDelayTime

    self updateContentsDelayTime value:(self scaledUpdateContentsDelayTime + 0.1).
    self evaluateEnableInDecreaseButtons.
!

increaseupdateListDelayTime

    self updateListDelayTime value:(self scaledUpdateListDelayTime + 0.1).
    self evaluateEnableInDecreaseButtons.
!

selectedProcessesDo:aBlock
    | sel|

    sel := self selectedProcesses value.
    sel isNil ifTrue:[^ self].

    sel do:[:processItem |
       aBlock value:(processItem processInstance).
    ]
!

selectedProcessesSend:aSelector
    "send a message to all selected processes"

    self selectedProcessesDo:[:p |
        p perform:aSelector
    ].
    self updateView.
! !

!ProcessMonitorV2 methodsFor:'aspects'!

currentSortOrder
    "return/create the 'currentSortOrder' value holder (automatically generated)"

    currentSortOrder isNil ifTrue:[
        currentSortOrder := Dictionary new asValue.
    ].
    ^ currentSortOrder
!

enableDecreaseContentsDelayTime

    enableDecreaseContentsDelayTime isNil ifTrue:[
        enableDecreaseContentsDelayTime := true asValue.
    ].
    ^ enableDecreaseContentsDelayTime.
!

enableDecreaseListDelayTime

    enableDecreaseListDelayTime isNil ifTrue:[
        enableDecreaseListDelayTime := true asValue.
    ].
    ^ enableDecreaseListDelayTime.
!

enableIncreaseContentsDelayTime

    enableIncreaseContentsDelayTime isNil ifTrue:[
        enableIncreaseContentsDelayTime := true asValue.
    ].
    ^ enableIncreaseContentsDelayTime.
!

enableIncreaseListDelayTime

    enableIncreaseListDelayTime isNil ifTrue:[
        enableIncreaseListDelayTime := true asValue.
    ].
    ^ enableIncreaseListDelayTime.
!

hasSelection

    hasSelection isNil ifTrue:[
        hasSelection := ValueHolder new.
    ].
    ^ hasSelection
!

processList

    processList isNil ifTrue:[
        processList := List new.
    ].
    ^ processList.
!

scaledUpdateContentsDelayTime

    ^ self updateContentsDelayTime value asFloat asFixedPoint:1.
!

scaledUpdateListDelayTime

    ^ self updateListDelayTime value asFloat asFixedPoint:1.
!

selectedProcesses

    selectedProcesses isNil ifTrue:[
        selectedProcesses := ValueHolder new.
        selectedProcesses addDependent:self.
    ].
    ^ selectedProcesses.
!

selectionRestartable

    selectionRestartable isNil ifTrue:[
        selectionRestartable := ValueHolder new.
    ].
    ^ selectionRestartable
!

showDead
    "return/create the 'showDead' value holder (automatically generated)"

    showDead isNil ifTrue:[
        showDead := false asValue.
        showDead addDependent:self.
    ].
    ^ showDead
!

sortBlock

    sortBlock isNil ifTrue:[
        sortBlock := [:a :b |
            a idVal < b idVal
        ].
    ].
    ^ sortBlock
!

tableColumns

    tableColumns isNil ifTrue:[
        tableColumns := self class tableColumns asValue.
    ].
    ^ tableColumns.
!

updateContentsDelayTime

    updateContentsDelayTime isNil ifTrue:[
        updateContentsDelayTime := updateDelay asValue.
        updateContentsDelayTime onChangeSend:#evaluateEnableInDecreaseButtons to:self.
    ].
    ^ updateContentsDelayTime.
!

updateListDelayTime

    updateListDelayTime isNil ifTrue:[
        updateListDelayTime := listUpdateDelay asValue.
        updateListDelayTime onChangeSend:#evaluateEnableInDecreaseButtons to:self.
    ].
    ^ updateListDelayTime.
! !

!ProcessMonitorV2 methodsFor:'aspects column'!

showCurrentSegment
    "return/create the 'showCurrentSegment' value holder (automatically generated)"

    showCurrentSegment isNil ifTrue:[
        showCurrentSegment := showDetail asValue.
        showCurrentSegment onChangeSend:#viewedColumnsChanged to:self.
    ].
    ^ showCurrentSegment
!

showGroup
    "return/create the 'showGroup' value holder (automatically generated)"

    showGroup isNil ifTrue:[
        showGroup := true asValue.
        showGroup onChangeSend:#viewedColumnsChanged to:self.
    ].
    ^ showGroup
!

showPrio
    "return/create the 'showPrio' value holder (automatically generated)"

    showPrio isNil ifTrue:[
        showPrio := true asValue.
        showPrio onChangeSend:#viewedColumnsChanged to:self.
    ].
    ^ showPrio
!

showProcessId

    showProcessId isNil ifTrue:[
        showProcessId := true asValue.
        showProcessId onChangeSend:#viewedColumnsChanged to:self
    ].
    ^ showProcessId
!

showState
    "return/create the 'showState' value holder (automatically generated)"

    showState isNil ifTrue:[
        showState := true asValue.
        showState onChangeSend:#viewedColumnsChanged to:self
    ].
    ^ showState
!

showSwitch
    "return/create the 'showSwitch' value holder (automatically generated)"

    showSwitch isNil ifTrue:[
        showSwitch := showDetail asValue.
        showSwitch onChangeSend:#viewedColumnsChanged to:self
    ].
    ^ showSwitch
!

showTotalStack
    "return/create the 'showTotalStack' value holder (automatically generated)"

    showTotalStack isNil ifTrue:[
        showTotalStack := showDetail asValue.
        showTotalStack onChangeSend:#viewedColumnsChanged to:self
    ].
    ^ showTotalStack
!

showUsedStack
    "return/create the 'showUsedStack' value holder (automatically generated)"

    showUsedStack isNil ifTrue:[
        showUsedStack := showDetail asValue.
        showUsedStack onChangeSend:#viewedColumnsChanged to:self
    ].
    ^ showUsedStack
!

showWhere
    "return/create the 'showWhere' value holder (automatically generated)"

    showWhere isNil ifTrue:[
        showWhere := true asValue.
        showWhere onChangeSend:#viewedColumnsChanged to:self
    ].
    ^ showWhere
! !

!ProcessMonitorV2 methodsFor:'change & update'!

selectionChanged

    |allRestartable|

    self hasSelection value:(self selectedProcesses value notEmptyOrNil).
    self hasSelection value ifFalse:[
        self selectionRestartable value:false.
        ^ self
    ].
    allRestartable := true.
    self selectedProcessesDo:[:p |
        p isRestartable ifFalse:[
            allRestartable := false
        ].
    ].
    self selectionRestartable value:allRestartable.
    ^ self.
!

update:something with:aParameter from:changedObject
    "Invoked when an object that I depend upon sends a change notification."

    "stub code automatically generated - please change as required"

    changedObject == self selectedProcesses ifTrue:[
        self selectionChanged.
        ^ self
    ].
    changedObject == self showDead ifTrue:[
        self updateView.
        ^ self
    ].
    super update:something with:aParameter from:changedObject
!

viewedColumnsChanged

    | columns buffer locCurrentSortOrder currentSortOrderColumn currentSortOrderReverse oldSelection sel|

    sel := self selectedProcesses value.
    sel notNil ifTrue:[
        oldSelection := OrderedCollection new.
        sel do:[:proItem|
            oldSelection add:(proItem processInstance)    
        ].
    ].
"/    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 new fromLiteralArrayEncoding: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 == #id and:[self showProcessId value not]) ifTrue:[
                columns remove:col. 
            ] ifFalse:[
                (id == #group and:[self showGroup value not]) ifTrue:[
                    columns remove:col. 
                ] ifFalse:[
                    (id == #prio and:[self showPrio value not]) ifTrue:[
                        columns remove:col.
                    ] ifFalse:[
                        (id == #currentSegment and:[self showCurrentSegment value not]) ifTrue:[
                            columns remove:col.
                        ] ifFalse:[
                            (id == #state and:[self showState value not]) ifTrue:[
                                columns remove:col.
                            ] ifFalse:[
                                (id == #switch and:[self showSwitch value not]) ifTrue:[
                                    columns remove:col.
                                ] ifFalse:[
                                    (id == #totalStack and:[self showTotalStack value not]) ifTrue:[
                                        columns remove:col.
                                    ] ifFalse:[
                                        (id == #usedStack and:[self showUsedStack value not]) ifTrue:[
                                            columns remove:col.
                                        ] ifFalse:[
                                            (id == #where and:[self showWhere value not]) ifTrue:[
                                                columns remove:col.
                                            ]
                                        ]
                                    ] 
                                ]
                            ]
                        ]
                    ]
                ]
            ]
        ]
    ].
    self tableColumns value:columns.
    self updateTable:nil.
    updateSema critical:[
"/        Transcript showCR:'oldSelection on set in viewedColumnsChanged', (oldSelection isNil ifTrue:['nil'] ifFalse:[oldSelection first printString]).
        self changeSelectionToProcess:oldSelection.
    ].
! !

!ProcessMonitorV2 methodsFor:'event handling'!

processEvent:anEvent
    "filter keyboard events.
     Return true, if I have eaten the event"

    |focusView key rawKey|

    anEvent isKeyPressEvent ifTrue:[
        focusView := anEvent targetView.
        key := anEvent key.
        rawKey := anEvent rawKey.

        (focusView == processList) ifTrue:[
            key == #InspectIt ifTrue:[
                self inspectSelection.
                ^ true.
            ].
        ]
    ].
    ^ false
! !

!ProcessMonitorV2 methodsFor:'initialization & release'!

closeDownViews
    "This is a hook method generated by the Browser.
     It will be invoked when your app/dialog-window is really closed.
     See also #closeDownViews, which is invoked before and may suppress the close
     or ask the user for confirmation."

    "/ change the code below as required ...
    "/ This should cleanup any leftover resources
    "/ (for example, temporary files)
    "/ super closeRequest will initiate the closeDown

    "/ add your code here

    "/ do not remove the one below ...
    ^ super closeDownViews
!

initialize

    super initialize.

    showDetail := (Smalltalk at:#SystemDebugging ifAbsent:false).
    updateSema := Semaphore forMutualExclusion.
    updateDelay := 0.5.
    listUpdateDelay := 5.

    "/ event mode is no longer used;
    "/ this event support may vanish
    Processor isPureEventDriven ifTrue:[
        updateBlock := [self updateStatus:nil].
        listUpdateBlock := [self updateList].
    ].
!

postBuildProcessTable:aWidget

    processTable       := aWidget scrolledView.
    processTable wantsFocusWithPointerEnter.
!

postBuildWith:aBuilder

    ^ super postBuildWith:aBuilder
!

postOpenWith:aBuilder

    super postOpenWith:aBuilder.
    self viewedColumnsChanged.
    self updateList.
    self startUpdateProcess.
    self selectionChanged.
    self sortProcessListBy:#idVal.
    self windowGroup addPreEventHook:self.
! !

!ProcessMonitorV2 methodsFor:'menu actions'!

abortProcess
    "abort (raise AbortSignal in) the selected process"

    self selectedProcessesDo:[:p |
        p abort
    ]
!

debugProcess
    "open a debugger on the selected process"

    self selectedProcessesDo:[:p |
       Debugger openOn:p
    ]
!

debugWhenResumed
    self selectedProcessesDo:[:p |
       p addInterruptAction:[Debugger enter]
    ]
!

hardTerminateProcess
    "hard terminate the selected process"

    self selectedProcessesSend:#terminateNoSignal
!

inspectSelection
    "open an inspector on the selected process"

    self selectedProcessesSend:#inspect
!

lowerPrio
    "lower the selected processes priority"

    self selectedProcessesDo:[:p |
       p priority:(p priority - 1)
    ]
!

openAboutThisApplication
    "This method was generated by the Browser.
     It will be invoked when the menu-item 'help-about' is selected."

    "/ could open a customized aboutBox here ...
    super openAboutThisApplication
!

openDocumentation
    "This method was generated by the Browser.
     It will be invoked when the menu-item 'help-documentation' is selected."

    "/ change below as required ...

    "/ to open an HTML viewer on some document (under 'doc/online/<language>/' ):
    HTMLDocumentView openFullOnDocumentationFile:'TOP.html'.

    "/ add application-specific help files under the 'doc/online/<language>/help/appName'
    "/ directory, and open a viewer with:
    "/ HTMLDocumentView openFullOnDocumentationFile:'help/<MyApplication>/TOP.html'.
!

raisePrio
    "raise the selected processes priority"

    self selectedProcessesDo:[:p |
       p priority:(p priority + 1)
    ]
!

restartProcess
    "abort (raise AbortSignal in) the selected process"

    self selectedProcessesDo:[:p |
        p restart.
    ]
!

resumeProcess
    "resume the selected process (i.e. let it run) "

    self selectedProcessesSend:#resume
!

stopProcess
    "stop the selected process - not even interrupts will wake it up"

    self selectedProcessesSend:#stop
!

suspendProcess
    "suspend the selected process - interrupts will let it run again"

    self selectedProcessesSend:#suspend
!

terminateProcess
    "terminate the selected process"

    self selectedProcessesSend:#terminate.
    self updateList.
!

terminateProcessGroup
    "terminate the selected process with all of its subprocesses"

    self selectedProcessesSend:#terminateGroup.
    self updateList.
! !

!ProcessMonitorV2 methodsFor:'queries'!

needFullInformation

    ^ true
"/    ^ (self showUsedStack value or:[
"/      self showTotalStack value or:[
"/      self showCurrentSegment value or:[
"/      self showSwitch value]]])
!

showDetail
! !

!ProcessMonitorV2 methodsFor:'queries - table string'!

getCurrentSegmentStringFor:con

    con notNil ifTrue:[
        | contextCount c sender|
        contextCount := 1.
        c := con.
        [(sender := c sender) notNil] whileTrue:[
            c := sender.
            contextCount := contextCount + 1.
        ].
        ^ (((ObjectMemory addressOf:con) printStringRadix:16),
           ' .. ',
           ((ObjectMemory addressOf:c) printStringRadix:16)).
    ].
    ^ ''
!

getGroupStringFor:aProcess

    |gId|

    gId := aProcess processGroupId.
    ((gId == aProcess id) or:[gId isNil]) ifTrue:[
        "/ a group leader
        ^ '-'.
    ] ifFalse:[
        ^ gId.
    ].
!

getPrioStringFor:aProcess

    |prioRange|

    Processor supportDynamicPriorities ifTrue:[
        (prioRange := aProcess priorityRange) isNil ifTrue:[
            ^ aProcess priority asString.
        ] ifFalse:[
            ^ (aProcess priority asString, 
                    ' [',
                    prioRange start printString,
                    '..',
                    prioRange stop printString,
                    ']').
        ].
    ].
    ^ ''
!

getStateStringFor:aProcess running:isRunning

    |st stateCharacter |

    st := aProcess state.
    isRunning ifTrue:[
        stateCharacter := '* '.
    ] ifFalse:[
        [
            (Processor scheduledProcesses includes:aProcess) ifTrue:[
                stateCharacter := '+ '
            ] ifFalse:[
                stateCharacter := '  '.
            ].
        ] valueUninterruptably.
    ].
    ^ stateCharacter, (st asString).
!

getTotalStackStringFor:aProcess


    aProcess id == 0 ifTrue:[
        ^ 'unlimited'.
    ] ifFalse:[
        | tStackSize noOfSegs |
        ((tStackSize := aProcess totalStackSize) notNil and:[
         (noOfSegs := aProcess numberOfStackSegments) notNil
        ]) ifTrue:[
            ^ ((tStackSize printString),
               ' (', 
               (noOfSegs printString),
               ')' )
        ]
    ].
    ^ ''
!

getWhereStringFor:con running:isRunning

    con notNil ifTrue:[
        | c found skipping|
        c := con.
        found := false.
        isRunning ifFalse:[
            "/ search for a semaphore-wait in the top 10 contexts

            1 to:10 do:[:n |
                found ifFalse:[
                    c notNil ifTrue:[
                        (c receiver class == Semaphore) ifTrue:[
                            c selector == #wait ifTrue:[
                                found := true.
                            ]
                        ].
                        c := c sender.
                    ]
                ]
            ].
        ].    
        found ifFalse:[
            "/ search for a non-processor, non-process
            "/ receiver in the top 10 contexts

            c := con.
            1 to:10 do:[:n |
                |r|

                found ifFalse:[
                    c notNil ifTrue:[
                        ((r := c receiver) ~~ Processor 
                         and:[r class ~~ Process]) ifTrue:[
                            found := true.
                        ] ifFalse:[
                            c := c sender.
                        ]
                    ]
                ]
            ]
        ].
        found ifFalse:[
            c := con
        ].

        "/ skip, until an interesting context is
        "/ found.
        "/ this skips intermediate contexts, which lead
        "/ to the sema-wait (for example, unwind blocks,
        "/ delay-stuff etc.)

        skipping := true.
        [skipping] whileTrue:[
            skipping := false.
            (c notNil
            and:[c receiver == Delay
                 or:[c receiver class == Delay]]) ifTrue:[
                c := c sender.
                skipping := true.
            ].

            [c notNil
            and:[c receiver isBlock 
            and:[c selector startsWith:'value']]] whileTrue:[
                c := c sender.
                skipping := true.
            ].

            [c notNil
            and:[c receiver isBlock 
            and:[c selector = 'ensure:']]] whileTrue:[
                c := c sender.
                skipping := true.
            ].

            [c notNil
            and:[c receiver == OperatingSystem 
            and:[c selector == #unblockInterrupts]]] whileTrue:[
                c := c sender.
                skipping := true.
            ].

            [c notNil and:[c isBlockContext]] whileTrue:[
                c := c home.
                skipping := true.
            ].
        ].

        c notNil ifTrue:[
            | sel |
            sel := c selector.
            sel isNil ifTrue:[
                sel := '* unknown *'
            ].
            ^ (c receiver class name,
               '>>',
               sel).
        ]
    ].
    ^ ''
! !

!ProcessMonitorV2 methodsFor:'sorting'!

sortProcessListBy:instanceName 
    "method to sort the list of BugReport"

    | aSymbol isReverse cmpOp currentSortOrder|

    aSymbol := instanceName asSymbol.
    isReverse := false.
    currentSortOrder := self currentSortOrder value.
    currentSortOrder isEmpty ifTrue:[
        currentSortOrder at:#column put:aSymbol.
        currentSortOrder at:#reverse put:false.
    ] ifFalse:[
        (currentSortOrder at:#column) = aSymbol ifTrue:[
            "/ same column like before - change sort order ifReverse is true
            isReverse := currentSortOrder at:#reverse.
            currentSortOrder at:#reverse put:(isReverse not).
        ] ifFalse:[
            "/ another column - remark column
            currentSortOrder at:#column put:aSymbol.
        ]
    ].
    (currentSortOrder at:#reverse) ifTrue:[
        cmpOp := #'>'
    ] ifFalse:[
        cmpOp := #'<'
    ].
    sortBlock := [:a :b | 
            |entry1 entry2|

            entry1 := (a perform:aSymbol).
            entry2 := (b perform:aSymbol).
            entry1 = entry2 ifTrue:[
                a idVal < 0 ifTrue:[
                    "/ two dead ones (take anything which remains constant)
                    a processName ~= b processName ifTrue:[
                        a processName < b processName 
                    ] ifFalse:[
                        a processInstance identityHash < b processInstance identityHash 
                    ]
                ] ifFalse:[
                    a idVal < b idVal
                ]
            ] ifFalse:[
                entry1 perform:cmpOp with:entry2 
            ]
        ].
   self viewedColumnsChanged.
! !

!ProcessMonitorV2 methodsFor:'update process'!

redrawChangedItems:oldItem newItem:newItem on:index

    | colIdx |
    colIdx := 1.

    oldItem processInstance:newItem processInstance.
    "/ ID
    oldItem processId ~= newItem processId ifTrue:[
        oldItem processId:newItem processId.
        processTable invalidateRowAt:index colAt:colIdx.
    ].
    "/ GROUP
    self showGroup value ifTrue:[
        colIdx := colIdx + 1.
        oldItem processGroup ~= newItem processGroup ifTrue:[
            oldItem processGroup:newItem processGroup.
            processTable invalidateRowAt:index colAt:colIdx.
        ].
    ].
    "/ NAME
    colIdx := colIdx + 1.
    oldItem processName ~= newItem processName ifTrue:[
        oldItem processName:newItem processName.
        processTable invalidateRowAt:index colAt:colIdx.
    ].
    "/ STATE
    self showState value ifTrue:[
        colIdx := colIdx + 1.
        oldItem processState ~= newItem processState ifTrue:[
            oldItem processState:newItem processState.
"/            self halt.
            (processTable columnAt:colIdx).
            processTable invalidateRowAt:index colAt:colIdx.
        ].
    ].
    "/ PRIO
    self showPrio value ifTrue:[
        colIdx := colIdx + 1.
        oldItem processPrio ~= newItem processPrio ifTrue:[
            oldItem processPrio:newItem processPrio.
            processTable invalidateRowAt:index colAt:colIdx.
        ].
    ].
    "/ USED STACK
    self showUsedStack value ifTrue:[
        colIdx := colIdx + 1.
        oldItem processUsedStack ~= newItem processUsedStack ifTrue:[
            oldItem processUsedStack:newItem processUsedStack.
            processTable invalidateRowAt:index colAt:colIdx.
        ].
    ].
    "/ TOTAL STACK
    self showTotalStack value ifTrue:[
        colIdx := colIdx + 1.
        oldItem processTotalStack ~= newItem processTotalStack ifTrue:[
            oldItem processTotalStack:newItem processTotalStack.
            processTable invalidateRowAt:index colAt:colIdx.
        ].
    ].
    "/ CURRENT SEGMENT
    self showCurrentSegment value ifTrue:[
        colIdx := colIdx + 1.
        oldItem processCurrentSegment ~= newItem processCurrentSegment ifTrue:[
            oldItem processCurrentSegment:newItem processCurrentSegment.
            processTable invalidateRowAt:index colAt:colIdx.
        ].
    ].
    "/ Switch
    self showSwitch value ifTrue:[
        colIdx := colIdx + 1.
        oldItem processSwitch ~= newItem processSwitch ifTrue:[
            oldItem processSwitch:newItem processSwitch.
            processTable invalidateRowAt:index colAt:colIdx.
        ].
    ].
    "/ WHERE
    self showWhere value ifTrue:[
        colIdx := colIdx + 1.
        oldItem processWhere ~= newItem processWhere ifTrue:[
            oldItem processWhere:newItem processWhere.
            processTable invalidateRowAt:index colAt:colIdx.
        ].
    ].
!

startUpdateProcess
    updateBlock notNil ifTrue:[
        Processor addTimedBlock:updateBlock afterSeconds:self scaledUpdateContentsDelayTime.
        Processor addTimedBlock:listUpdateBlock afterSeconds:self scaledUpdateListDelayTime.
    ] ifFalse:[
        updateProcess := [
            [
                |id cnt myDelay|

                myDelay := Delay forSeconds:self scaledUpdateContentsDelayTime.

                "
                 every updateDelay (0.5), we look which process runs;
                 every half second, the status is updated.
                 every listUpdateDelay (5s), the list of processes is
                 built up again
                "
                [true] whileTrue:[
                    ((self scaledUpdateListDelayTime // self scaledUpdateContentsDelayTime) max:2) - 1 timesRepeat:[
                        myDelay wait.
                        self updateStatus:nil.
                    ].
                    myDelay wait.
                    self updateList.
                ]
            ] valueOnUnwindDo:[
                updateProcess := nil
            ]
        ]  forkAt:(Processor userSchedulingPriority + 1).
        updateProcess name:'monitor [' , 
                           Processor activeProcess id printString ,
                           '] update'.
        "
         raise my own priority
        "
        Processor activeProcess priority:(Processor userSchedulingPriority + 2)
    ].
!

updateList

    |newList|

    processTable shown ifTrue:[
        newList := self getProcessList.
        self updateStatus:newList
    ].
    updateBlock notNil ifTrue:[
        Processor removeTimedBlock:listUpdateBlock.
        Processor addTimedBlock:listUpdateBlock afterSeconds:self scaledUpdateListDelayTime.
    ].
!

updateStatus:newProcessList

    |startTime endTime deltaT|


    startTime := AbsoluteTime now.
    self updateTable:newProcessList.

    endTime := AbsoluteTime now.
    deltaT := (endTime millisecondDeltaFrom:startTime) / 1000.0.
"/    Transcript show:deltaT; show:' ' ; showCR:(self scaledUpdateContentsDelayTime / 10.0).
    deltaT > (self scaledUpdateContentsDelayTime / 5) ifTrue:[
        "/ the update took longer than 20% - make delay longer, to reduce cpu load.
        self updateContentsDelayTime value:(self scaledUpdateContentsDelayTime * 2).
        "/ Transcript show:'+++ '; showCR:self scaledUpdateContentsDelayTime.
    ] ifFalse:[
        self scaledUpdateContentsDelayTime > 0.5 ifTrue:[
            deltaT < (self scaledUpdateContentsDelayTime / 20) ifTrue:[
                "/ the update took less than 5% - make delay smaller for better animation.
                self updateContentsDelayTime value:((self scaledUpdateContentsDelayTime / 2) max:0.5).
                "/ Transcript show:'--- ';showCR:self scaledUpdateContentsDelayTime.
            ].
        ].
    ].
    updateBlock notNil ifTrue:[
        Processor removeTimedBlock:updateBlock.
        Processor addTimedBlock:updateBlock afterSeconds:self scaledUpdateContentsDelayTime.
    ]
!

updateTable:newProcessList

    | oldSelection newList locNewProcs sel|


    processTable shown ifTrue:[
"/        Transcript showCR:('update the table', AbsoluteTime now printString, 'with new list:', newProcessList notNil asString).
        updateSema critical:[
            sel := self selectedProcesses value.
            sel notNil ifTrue:[
                oldSelection := OrderedCollection new.
                sel do:[:proItem|
                    oldSelection add:(proItem processInstance)    
                ].
            ].
"/            Transcript showCR:'oldSelection on catch in updateTable: ', (oldSelection isEmptyOrNil ifTrue:['nil'] ifFalse:[oldSelection first printString]).
            newProcessList isNil ifTrue:[
                newList := OrderedCollection new.
                processList do:[:oldItem |
                    | newItem |
                    (self showDead value not and:[oldItem processInstance isDead]) ifFalse:[
                        newItem := oldItem copy.
                        self validateItem:newItem.
                        newList add:newItem.
                    ]
                ].
            ]ifFalse:[
                "/ remove dead processes if not shown
                self showDead value ifTrue:[
                    locNewProcs := newProcessList.
                ] ifFalse:[
                    locNewProcs := OrderedCollection new.
                    newProcessList do:[:proc |
                        proc isDead not ifTrue:[
                            locNewProcs add:proc
                        ]
                    ]
                ].
                newList := OrderedCollection new.
                locNewProcs do:[:process|
                    | processItem |
                    processItem := ProcessItem new.
                    self validateItem:processItem with:process.
                    newList add:processItem.
                ].
            ].
            newList sort:self sortBlock.
            newList doWithIndex:[:newItem :index|
                | oldItem |
                oldItem := (processList at:index ifAbsent:nil).
                oldItem isNil ifTrue:[
                    processList add:newItem beforeIndex:(index)
                ] ifFalse:[
                    self redrawChangedItems:oldItem newItem:newItem on:index
                ]
            ].
"/            Transcript showCR:'oldSelection on set in updateTable: ', (oldSelection isEmptyOrNil ifTrue:['nil'] ifFalse:[oldSelection first printString]).
            self changeSelectionToProcess:oldSelection.
        ]
    ].
!

updateView
    self updateList.
    self updateStatus:nil
!

validateItem:processItem 

    | running con aProcess|

    aProcess := processItem processInstance.

    processItem processId:aProcess id.
    processItem idVal:aProcess id ? -1.

    processItem processGroup:(self getGroupStringFor:aProcess).
    processItem groupVal:(processItem processGroup isNumber ifTrue:[processItem processGroup] ifFalse:[-1]).

    processItem processName:aProcess name ? ''.

    running := (aProcess state == #run and:[aProcess == Processor interruptedProcess]).

    processItem processState:(self getStateStringFor:aProcess running:running).

    processItem prioVal:(aProcess priority).
    processItem processPrio:(self getPrioStringFor:aProcess).

    processItem processUsedStack:aProcess usedStackSize.

    processItem processTotalStack:(self getTotalStackStringFor:aProcess).

    con := aProcess suspendedContext.
    con isNil ifTrue:[
        aProcess == Processor activeProcess ifTrue:[
            con := thisContext
        ]
    ].

    processItem processCurrentSegment:(self getCurrentSegmentStringFor:con).

    processItem processSwitch:(aProcess numberOfStackBoundaryHits).

    processItem processWhere:(self getWhereStringFor:con running:running).
!

validateItem:processItem with:aProcess

    processItem processInstance:aProcess.
    self validateItem:processItem
! !

!ProcessMonitorV2::ProcessItem methodsFor:'accessing'!

groupVal
    "return the value of the instance variable 'groupVal' (automatically generated)"

    ^ groupVal
!

groupVal:something
    "set the value of the instance variable 'groupVal' (automatically generated)"

    groupVal := something.
!

idVal
    "return the value of the instance variable 'idVal' (automatically generated)"

    ^ idVal
!

idVal:something
    "set the value of the instance variable 'idVal' (automatically generated)"

    idVal := something.
!

prioVal
    "return the value of the instance variable 'prioVal' (automatically generated)"

    ^ prioVal
!

prioVal:something
    "set the value of the instance variable 'prioVal' (automatically generated)"

    prioVal := something.
!

processCurrentSegment
    "return the value of the instance variable 'processCurrentSegment' (automatically generated)"

    ^ processCurrentSegment
!

processCurrentSegment:something
    "set the value of the instance variable 'processCurrentSegment' (automatically generated)"

    processCurrentSegment := something.
!

processGroup
    "return the value of the instance variable 'processGroup' (automatically generated)"

    ^ processGroup
!

processGroup:something
    "set the value of the instance variable 'processGroup' (automatically generated)"

    processGroup := something.
!

processId
    "return the value of the instance variable 'processId' (automatically generated)"

    ^ processId
!

processId:something
    "set the value of the instance variable 'processId' (automatically generated)"

    processId := something.
!

processInstance
    "return the value of the instance variable 'processInstance' (automatically generated)"

    ^ processInstance
!

processInstance:something
    "set the value of the instance variable 'processInstance' (automatically generated)"

    processInstance := something.
!

processName
    "return the value of the instance variable 'processName' (automatically generated)"

    ^ processName
!

processName:something
    "set the value of the instance variable 'processName' (automatically generated)"

    processName := something.
!

processPrio
    "return the value of the instance variable 'processPrio' (automatically generated)"

    ^ processPrio
!

processPrio:something
    "set the value of the instance variable 'processPrio' (automatically generated)"

    processPrio := something.
!

processState
    "return the value of the instance variable 'processState' (automatically generated)"

    ^ processState
!

processState:something
    "set the value of the instance variable 'processState' (automatically generated)"

    processState := something.
!

processSwitch
    "return the value of the instance variable 'processSwitch' (automatically generated)"

    ^ processSwitch
!

processSwitch:something
    "set the value of the instance variable 'processSwitch' (automatically generated)"

    processSwitch := something.
!

processTotalStack
    "return the value of the instance variable 'processTotalStack' (automatically generated)"

    ^ processTotalStack
!

processTotalStack:something
    "set the value of the instance variable 'processTotalStack' (automatically generated)"

    processTotalStack := something.
!

processUsedStack
    "return the value of the instance variable 'processUsedStack' (automatically generated)"

    ^ processUsedStack
!

processUsedStack:something
    "set the value of the instance variable 'processUsedStack' (automatically generated)"

    processUsedStack := something.
!

processWhere
    "return the value of the instance variable 'processWhere' (automatically generated)"

    ^ processWhere
!

processWhere:something
    "set the value of the instance variable 'processWhere' (automatically generated)"

    processWhere := something.
! !

!ProcessMonitorV2::ProcessItem methodsFor:'printing'!

displayString

    ^ self processName, '[', self processId asString, ']'
!

printString

    ^ self processName, '[', self processId asString, ']'
! !

!ProcessMonitorV2 class methodsFor:'documentation'!

version
    ^ '$Header: /cvs/stx/stx/libtool/ProcessMonitorV2.st,v 1.6 2003-01-28 15:17:59 penk Exp $'
! !