VDBVariableObjectListApplication.st
author Jan Vrany <jan.vrany@labware.com>
Tue, 26 Jul 2022 15:01:33 +0100
changeset 265 f2470f0dd9cd
parent 264 23960fcb9dac
permissions -rw-r--r--
Do not show address for (pseudo) instructions with no code While such instructions do not appear in GDB-produced disassembly, they may appear in some manually-generated instruction lists. One example of such (pseudo) instruction is label.

"
jv:libgdbs - GNU Debugger Interface Library
Copyright (C) 2015-now Jan Vrany
Copyright (C) 2020-2022 LabWare

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the 'Software'), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
"
"{ Package: 'jv:vdb' }"

"{ NameSpace: Smalltalk }"

VDBAbstractTreeApplication subclass:#VDBVariableObjectListApplication
	instanceVariableNames:'variableObjectListHolder selectedVariableObjectHolder'
	classVariableNames:''
	poolDictionaries:''
	category:'VDB-UI-Others'
!

!VDBVariableObjectListApplication class methodsFor:'documentation'!

copyright
"
jv:libgdbs - GNU Debugger Interface Library
Copyright (C) 2015-now Jan Vrany
Copyright (C) 2020-2022 LabWare

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the 'Software'), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
"
! !

!VDBVariableObjectListApplication class methodsFor:'accessing'!

defaultWindowTitle
    ^ self resources string:'Variables'

    "Created: / 11-07-2017 / 16:37:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 01-10-2018 / 12:08:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!VDBVariableObjectListApplication class methodsFor:'interface specs'!

columnsSpec
    "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:VDBFrameApplication andSelector:#columnsSpec
    "

    <resource: #tableColumns>

    ^#(
      (DataSetColumnSpec
         label: 'Value'
         labelAlignment: left
         labelButtonType: Button
         width: 1.0
         height: heightOfFirstRow
         menuFromApplication: false
         printSelector: value
         backgroundSelector: backgroundColor
         showRowSeparator: false
         showColSeparator: false
       )
      )
    
! !

!VDBVariableObjectListApplication class methodsFor:'plugIn spec'!

aspectSelectors
    "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."

    "Return a description of exported aspects;
     these can be connected to aspects of an embedding application
     (if this app is embedded in a subCanvas)."

    ^ #(
        #debuggerHolder
        #variableObjectListHolder
        #selectedVariableHolder
      ).

    "Modified: / 03-02-2018 / 09:52:45 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!VDBVariableObjectListApplication class methodsFor:'startup-web applications'!

initialPageSpec
    "this is only required for web-applications"

    ^ self shouldImplement
!

pageSpecs
    "this is only required for web-applications"

    ^ self shouldImplement
! !

!VDBVariableObjectListApplication methodsFor:'accessing'!

variableObjectList: aSequencableCollection
    self variableObjectListHolder value: aSequencableCollection

    "Created: / 03-02-2018 / 08:07:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!VDBVariableObjectListApplication methodsFor:'aspects'!

backgroundColorFor: aVDBVariableOjectPresenter
    <resource: #style (#'variableObjectListApplication.changedVariableObjectBackgroundColor')>

    aVDBVariableOjectPresenter hasChanged ifTrue:[ 
        ^ self styleSheet colorAt: 'variableObjectListApplication.changedVariableObjectBackgroundColor' default:[ Color yellow lighter lighter ]
    ].
    ^ nil

    "
    VDBVariableObjectListApplication initializeDefaultStyleSheet; defaultStyleSheet.
    "

    "Created: / 01-02-2018 / 09:08:42 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 25-09-2019 / 00:59:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified (comment): / 18-03-2022 / 11:43:24 / Jan Vrany <jan.vrany@labware.com>"
!

foregroundColorFor: aVDBVariableOjectPresenter
    <resource: #style (#'variableObjectListApplication.invalidVariableObjectForegroundColor')>

    | value |

    value := aVDBVariableOjectPresenter valueString.
    (value notNil and:[((value includesSubString: 'invalid') or:[ value includesSubString: 'cannot'])]) ifTrue:[ 
        ^ self styleSheet colorAt: 'variableObjectListApplication.invalidVariableObjectForegroundColor' default:[ Color red ]
    ].
    ^ nil

    "Created: / 30-07-2018 / 11:14:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 06-10-2018 / 09:09:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified (format): / 18-03-2022 / 11:30:18 / Jan Vrany <jan.vrany@labware.com>"
!

frameHolder: aValueModel
    | variableObjectList |

    variableObjectList := (AspectAdaptor forAspect:#variables)
                    subjectChannel: aValueModel;
                    yourself.
    self variableObjectListHolder: variableObjectList

    "Created: / 17-03-2022 / 15:46:00 / Jan Vrany <jan.vrany@labware.com>"
!

selectedVariableObjectHolder
    "return/create the 'selectedVariableHolder' value holder (automatically generated)"
    
    selectedVariableObjectHolder isNil ifTrue:[
        selectedVariableObjectHolder := ValueHolder new.
        selectedVariableObjectHolder addDependent:self.
    ].
    ^ selectedVariableObjectHolder
!

selectedVariableObjectHolder:something 
    "set the 'selectedVariableHolder' value holder (automatically generated)"
    
    | oldValue  newValue |

    selectedVariableObjectHolder notNil ifTrue:[
        oldValue := selectedVariableObjectHolder value.
        selectedVariableObjectHolder removeDependent:self.
    ].
    selectedVariableObjectHolder := something.
    selectedVariableObjectHolder notNil ifTrue:[
        selectedVariableObjectHolder addDependent:self.
    ].
    newValue := selectedVariableObjectHolder value.
    oldValue ~~ newValue ifTrue:[
        self 
            update:#value
            with:newValue
            from:selectedVariableObjectHolder.
    ].
!

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

    variableObjectListHolder isNil ifTrue:[
        variableObjectListHolder := ValueHolder with: #().
        variableObjectListHolder addDependent:self.
    ].
    ^ variableObjectListHolder

    "Modified: / 03-02-2018 / 07:33:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

variableObjectListHolder:something
    "set the 'variableObjectListHolder' value holder (automatically generated)"

    |oldValue newValue|

    variableObjectListHolder notNil ifTrue:[
        oldValue := variableObjectListHolder value.
        variableObjectListHolder removeDependent:self.
    ].
    variableObjectListHolder := something.
    variableObjectListHolder notNil ifTrue:[
        variableObjectListHolder addDependent:self.
    ].
    newValue := variableObjectListHolder value.
    oldValue ~~ newValue ifTrue:[
        self update:#value with:newValue from:variableObjectListHolder.
    ].
! !

!VDBVariableObjectListApplication methodsFor:'change & update'!

update:aspect with:param from:sender
    "Invoked when an object that I depend upon sends a change notification."

    sender == variableObjectListHolder ifTrue:[ 
         self enqueueDelayedUpdateContents.
         ^ self.
    ].
    super update:aspect with:param from:sender

    "Modified: / 14-02-2019 / 16:31:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!VDBVariableObjectListApplication methodsFor:'change & update-delayed'!

delayedInvalidateInternalList

    "/ Updating children may take a while as it needs to issue
    "/ several commands to the GDB and wait for results. To avoid
    "/ flickering, we first force an update of all values
    "/ in background and then force an invalidate.
    "/ 
    "/ Note, that update of each individual variable is pushed back 
    "/ to event queue, allowing the UI to react for user events that 
    "/ may have come meanwhile.

    | children changed |

    children := internalListHolder root children.
    changed := false.
    children do:[:each | 
        self enqueueDelayedAction: [ 
            "/ Update the child, but only if the list of currently displayed
            "/ children remains the same. Keep in mind that user may have
            "/ have switched to another frame before we're finished with the update.
            internalListHolder root children == children ifTrue: [ changed := (each varobj notNil and:[each varobj hasChanged]) or:[changed] ] 
        ].
    ].
    self enqueueDelayedAction:[ 
        (internalListHolder root children == children and:[changed]) ifTrue:[ super delayedInvalidateInternalList ].
    ]

    "Created: / 06-02-2018 / 12:52:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 25-09-2019 / 01:09:34 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

delayedUpdateInternalList
    | root variables variablePs mustUpdate |

    debugger isNil ifTrue:[
        self internalListHolder root children:#().
        ^ self.
    ].

    variables := self variableObjectListHolder value ? #().
    variablePs := self internalListHolder root children.

    mustUpdate := variables size ~~ variablePs size.
    mustUpdate ifFalse: [ 
        | i |

        i := 1.
        [ mustUpdate not and: [ i <= variables size ] ] whileTrue: [
            (variables at: i) expression = (variablePs at: i) varobj expression ifTrue: [
                "/ Good, this presenter is for the same variable, so just
                "/ updates it's value
                (variablePs at: i) setVarobj: (variables at: i)
            ] ifFalse: [ 
                "/ Hmm...some other variable, we need a full update
                "/ (this also short-circuits the loop)
                mustUpdate := true.
            ].
            i := i + 1.
        ]
    ].

    mustUpdate ifTrue: [
        variablePs := 
            variables collect:[:v | 
                (VDBVariableObjectPresenter new) setVarobj:v;
                    parent:root;
                    yourself
            ].
    ].

    "/ A little trick to avoid flickering when updating variable list
    "/ (VDBVariableObjectListApplication):
    "/ Force GDB variables to eagerly fetch and cache info used by the
    "/ list.
    variablePs do: [:each | each hasChildren; hasChanged ].

    mustUpdate ifTrue: [
        "/ Full update is needed, regenerate a list of variables
        | root |

        root := self internalListHolder root.
        root children: variablePs. 
        root expand.
        root children size == 1 ifTrue:[ 
            root children first expand
        ].
    ] ifFalse: [ 
        "/ No full update needed, but some of the values may have changed,
        "/ so redraw the list (remember, variable values in presenter objects
        "/ are already updated, see the loop above).
        self delayedInvalidateInternalList.   
    ].

    "Created: / 27-02-2015 / 15:47:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 25-05-2018 / 10:40:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 18-03-2022 / 11:22:38 / Jan Vrany <jan.vrany@labware.com>"
!

delayedUpdateSelection
    | internalSelection |

    internalSelection := self internalSelectionHolder value.
    internalSelection notNil ifTrue:[
        self selectedVariableObjectHolder value: internalSelection varobj
    ] ifFalse:[ 
        self selectedVariableObjectHolder value: nil
    ].

    "Modified: / 28-01-2018 / 22:50:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!VDBVariableObjectListApplication methodsFor:'drag & drop'!

dropObjects:aCollectionOfDropObjects
    "drop manager wants to drop.
     This is ony sent, if #canDrop: returned true.
     Must be redefined in order for drop to work."

    ^ self shouldImplement
! !

!VDBVariableObjectListApplication methodsFor:'event handling'!

onStoppedEvent: aGDBStoppedEvent
    self enqueueDelayedInvalidateInternalList

    "Created: / 01-02-2018 / 23:14:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!VDBVariableObjectListApplication methodsFor:'initialization & release'!

subscribe   
    super subscribe.

    debugger announcer
        when: GDBStoppedEvent               send: #onStoppedEvent: to: self

    "Created: / 01-02-2018 / 23:07:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 17-11-2021 / 16:38:16 / Jan Vrany <jan.vrany@labware.com>"
    "Modified (comment): / 18-11-2021 / 16:25:05 / Jan Vrany <jan.vrany@labware.com>"
! !

!VDBVariableObjectListApplication class methodsFor:'documentation'!

version_HG

    ^ '$Changeset: <not expanded> $'
! !